summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/test-current.txt9
-rw-r--r--cmds/statsd/src/atoms.proto2
-rw-r--r--cmds/statsd/src/external/PowerStatsPuller.cpp2
-rw-r--r--core/java/android/app/ActivityView.java11
-rw-r--r--core/java/android/app/ITaskStackListener.aidl8
-rw-r--r--core/java/android/app/Notification.java21
-rw-r--r--core/java/android/app/StatusBarManager.java64
-rw-r--r--core/java/android/app/TaskStackListener.java4
-rw-r--r--core/java/android/hardware/biometrics/BiometricManager.java10
-rw-r--r--core/java/android/hardware/biometrics/IBiometricService.aidl2
-rw-r--r--core/java/android/hardware/display/AmbientDisplayConfiguration.java13
-rw-r--r--core/java/android/hardware/face/FaceManager.java18
-rw-r--r--core/java/android/hardware/face/IFaceService.aidl11
-rw-r--r--core/java/android/os/IVibratorService.aidl5
-rw-r--r--core/java/android/os/RecoverySystem.java129
-rw-r--r--core/java/android/os/SystemVibrator.java6
-rw-r--r--core/java/android/provider/Settings.java102
-rw-r--r--core/java/android/util/FeatureFlagUtils.java1
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java28
-rw-r--r--core/java/android/view/Choreographer.java3
-rw-r--r--core/java/android/view/DisplayEventReceiver.java24
-rw-r--r--core/java/android/view/IWindow.aidl7
-rw-r--r--core/java/android/view/Surface.java29
-rw-r--r--core/java/android/view/SurfaceControl.java3
-rw-r--r--core/java/android/view/View.java571
-rw-r--r--core/java/android/view/ViewGroup.java60
-rw-r--r--core/java/android/view/ViewRootImpl.java189
-rw-r--r--core/java/android/view/WindowManager.java16
-rw-r--r--core/java/android/view/WindowManagerPolicyConstants.java3
-rw-r--r--core/java/android/view/contentcapture/MainContentCaptureSession.java14
-rw-r--r--core/java/android/webkit/WebView.java9
-rw-r--r--core/java/android/widget/AdapterView.java3
-rw-r--r--core/java/android/widget/TextView.java39
-rw-r--r--core/java/com/android/internal/colorextraction/ColorExtractor.java9
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java7
-rw-r--r--core/java/com/android/internal/view/BaseIWindow.java5
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java7
-rw-r--r--core/jni/android_view_DisplayEventReceiver.cpp15
-rw-r--r--core/jni/android_view_Surface.cpp28
-rw-r--r--core/proto/android/providers/settings/secure.proto10
-rw-r--r--core/res/res/anim/lock_in.xml227
-rw-r--r--core/res/res/anim/lock_screen_behind_enter_subtle.xml33
-rw-r--r--core/res/res/drawable/ic_audio_alarm.xml4
-rw-r--r--core/res/res/drawable/ic_audio_alarm_mute.xml4
-rw-r--r--core/res/res/drawable/ic_battery_80_24dp.xml28
-rw-r--r--core/res/res/drawable/ic_bluetooth_share_icon.xml2
-rw-r--r--core/res/res/drawable/ic_corp_badge.xml4
-rw-r--r--core/res/res/drawable/ic_file_copy.xml3
-rw-r--r--core/res/res/drawable/ic_qs_auto_rotate.xml4
-rw-r--r--core/res/res/drawable/ic_qs_battery_saver.xml4
-rw-r--r--core/res/res/drawable/ic_qs_flashlight.xml4
-rw-r--r--core/res/res/drawable/ic_qs_ui_mode_night.xml8
-rw-r--r--core/res/res/drawable/perm_group_activity_recognition.xml1
-rw-r--r--core/res/res/drawable/perm_group_aural.xml1
-rw-r--r--core/res/res/drawable/perm_group_calendar.xml5
-rw-r--r--core/res/res/drawable/perm_group_call_log.xml1
-rw-r--r--core/res/res/drawable/perm_group_camera.xml1
-rw-r--r--core/res/res/drawable/perm_group_contacts.xml1
-rw-r--r--core/res/res/drawable/perm_group_location.xml1
-rw-r--r--core/res/res/drawable/perm_group_microphone.xml1
-rw-r--r--core/res/res/drawable/perm_group_phone_calls.xml3
-rw-r--r--core/res/res/drawable/perm_group_sensors.xml1
-rw-r--r--core/res/res/drawable/perm_group_sms.xml1
-rw-r--r--core/res/res/drawable/perm_group_storage.xml1
-rw-r--r--core/res/res/drawable/perm_group_visual.xml3
-rw-r--r--core/res/res/values-mcc313-mnc100/config.xml45
-rw-r--r--core/res/res/values/config.xml83
-rw-r--r--core/res/res/values/strings.xml30
-rw-r--r--core/res/res/values/symbols.xml19
-rw-r--r--core/tests/coretests/res/values/overlayable_icons_test.xml6
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--libs/androidfw/DisplayEventDispatcher.cpp5
-rw-r--r--libs/androidfw/include/androidfw/DisplayEventDispatcher.h3
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp4
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java5
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java14
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java60
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java8
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java29
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java16
-rw-r--r--packages/SystemUI/Android.bp6
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java8
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java2
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java4
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java32
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java11
-rw-r--r--packages/SystemUI/res-keyguard/drawable/bubble_hour_hand.xml2
-rw-r--r--packages/SystemUI/res-keyguard/drawable/bubble_minute_hand.xml2
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml2
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml11
-rw-r--r--packages/SystemUI/res-keyguard/values/dimens.xml4
-rw-r--r--packages/SystemUI/res-keyguard/values/strings.xml15
-rw-r--r--packages/SystemUI/res/anim/lock_lock.xml (renamed from core/res/res/anim/lock_lock.xml)29
-rw-r--r--packages/SystemUI/res/anim/lock_lock_circular.xml320
-rw-r--r--packages/SystemUI/res/anim/lock_lock_filled.xml215
-rw-r--r--packages/SystemUI/res/anim/lock_lock_rounded.xml314
-rw-r--r--packages/SystemUI/res/anim/lock_scanning.xml (renamed from core/res/res/anim/lock_scanning.xml)0
-rw-r--r--packages/SystemUI/res/anim/lock_scanning_circular.xml537
-rw-r--r--packages/SystemUI/res/anim/lock_scanning_filled.xml339
-rw-r--r--packages/SystemUI/res/anim/lock_scanning_rounded.xml531
-rw-r--r--packages/SystemUI/res/anim/lock_to_error.xml (renamed from core/res/res/anim/lock_to_error.xml)0
-rw-r--r--packages/SystemUI/res/anim/lock_to_error_circular.xml276
-rw-r--r--packages/SystemUI/res/anim/lock_to_error_filled.xml188
-rw-r--r--packages/SystemUI/res/anim/lock_to_error_rounded.xml270
-rw-r--r--packages/SystemUI/res/anim/lock_unlock.xml (renamed from core/res/res/anim/lock_unlock.xml)8
-rw-r--r--packages/SystemUI/res/anim/lock_unlock_circular.xml212
-rw-r--r--packages/SystemUI/res/anim/lock_unlock_filled.xml158
-rw-r--r--packages/SystemUI/res/anim/lock_unlock_rounded.xml209
-rw-r--r--packages/SystemUI/res/drawable/ic_info_outline.xml4
-rw-r--r--packages/SystemUI/res/drawable/ic_invert_colors.xml4
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml4
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_no_sim.xml4
-rw-r--r--packages/SystemUI/res/drawable/ic_screenshot_delete.xml4
-rw-r--r--packages/SystemUI/res/values/config.xml30
-rw-r--r--packages/SystemUI/res/values/dimens.xml4
-rw-r--r--packages/SystemUI/res/values/ids.xml10
-rw-r--r--packages/SystemUI/res/values/strings.xml6
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java36
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java8
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java18
-rw-r--r--packages/SystemUI/src/com/android/keyguard/CarrierTextController.java5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java59
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java10
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java38
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java124
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java5
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java26
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java26
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java3
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java26
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt73
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java95
-rw-r--r--packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIFactory.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/AssistManager.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java33
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSFragment.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java162
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java50
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt75
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java91
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt125
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt119
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java56
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt175
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt147
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java74
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java147
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java124
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java130
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java88
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationChildrenContainer.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java405
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java157
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java118
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java72
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java167
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt158
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt84
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java316
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java55
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java259
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java367
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java150
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java63
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java31
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java6
-rw-r--r--packages/SystemUI/tests/res/values/overlayable_icons_test.xml2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java85
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt97
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/clock/SettingsWrapperTest.kt93
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java192
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java32
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java79
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt109
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java27
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java61
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java159
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java19
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java40
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java25
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java16
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java24
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java10
-rw-r--r--packages/overlays/Android.mk1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_battery_80_24dp.xml (renamed from packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml)2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_misc_hid.xml1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_file_copy.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_notifications_alerted.xml (renamed from packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_delete_accent.xml)10
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_battery_saver.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml27
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_0_4_bar.xml52
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_1_4_bar.xml47
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_2_4_bar.xml42
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_3_4_bar.xml37
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_4_4_bar.xml32
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_activity_recognition.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml40
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_calendar.xml1
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_call_log.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_camera.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_contacts.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_location.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_microphone.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_phone_calls.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sensors.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_storage.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_visual.xml2
-rw-r--r--packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml8
-rw-r--r--packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_arrow_back.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml29
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml28
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_cellular_off.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml2
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml19
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_eject_24dp.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_find_in_page_24px.xml32
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help_actionbar.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_network_cell.xml33
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml1
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_scan_24dp.xml55
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_data_usage.xml7
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml37
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml37
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_language.xml26
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_multiuser.xml (renamed from packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml)5
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml34
-rw-r--r--packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml37
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_arrow_back.xml1
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml2
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml4
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml22
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml7
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml1
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml1
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml51
-rw-r--r--packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml56
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_battery_80_24dp.xml (renamed from packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_delete_accent.xml)8
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_misc_hid.xml1
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_file_copy.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml1
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml1
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml1
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml1
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_notifications_alerted.xml (renamed from packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml)9
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_battery_saver.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml3
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml (renamed from packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml)5
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_activity_recognition.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml27
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_calendar.xml1
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_call_log.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_camera.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_contacts.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_location.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_microphone.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_phone_calls.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sensors.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_storage.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_visual.xml2
-rw-r--r--packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml8
-rw-r--r--packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_arrow_back.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_cellular_off.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml2
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_eject_24dp.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_find_in_page_24px.xml27
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help_actionbar.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_network_cell.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml1
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_scan_24dp.xml27
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml36
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml36
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_language.xml26
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_multiuser.xml29
-rw-r--r--packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml27
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_arrow_back.xml1
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml2
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml4
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml4
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml4
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml1
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml1
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml31
-rw-r--r--packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml29
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_battery_80_24dp.xml25
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_file_copy.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml1
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml1
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml1
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml13
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_notifications_alerted.xml (renamed from packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_delete_accent.xml)10
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_battery_saver.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml1
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml27
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_activity_recognition.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml40
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_calendar.xml1
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_call_log.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_camera.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_contacts.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_location.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_microphone.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_phone_calls.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sensors.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_storage.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_visual.xml2
-rw-r--r--packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml8
-rw-r--r--packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_arrow_back.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_cellular_off.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml2
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml19
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_eject_24dp.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_find_in_page_24px.xml32
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help_actionbar.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_network_cell.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml1
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_scan_24dp.xml55
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_data_usage.xml7
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml37
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml37
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_language.xml26
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_multiuser.xml (renamed from packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml)6
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml34
-rw-r--r--packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml37
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_arrow_back.xml1
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml2
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml4
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml4
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml22
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml7
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml1
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml1
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml51
-rw-r--r--packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml61
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java14
-rw-r--r--services/core/java/com/android/server/VibratorService.java129
-rw-r--r--services/core/java/com/android/server/Watchdog.java1
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java2
-rw-r--r--services/core/java/com/android/server/attention/AttentionManagerService.java2
-rw-r--r--services/core/java/com/android/server/biometrics/AuthenticationClient.java6
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java31
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricServiceBase.java4
-rw-r--r--services/core/java/com/android/server/biometrics/LoggableMonitor.java16
-rw-r--r--services/core/java/com/android/server/biometrics/Utils.java5
-rw-r--r--services/core/java/com/android/server/biometrics/face/FaceService.java233
-rw-r--r--services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java3
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java46
-rw-r--r--services/core/java/com/android/server/display/LocalDisplayAdapter.java2
-rw-r--r--services/core/java/com/android/server/display/color/ColorDisplayService.java24
-rw-r--r--services/core/java/com/android/server/display/whitebalance/AmbientFilter.java4
-rw-r--r--services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java132
-rw-r--r--services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java23
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java134
-rw-r--r--services/core/java/com/android/server/policy/PhoneWindowManager.java15
-rw-r--r--services/core/java/com/android/server/policy/WindowManagerPolicy.java2
-rw-r--r--services/core/java/com/android/server/power/AttentionDetector.java18
-rw-r--r--services/core/java/com/android/server/statusbar/StatusBarShellCommand.java13
-rw-r--r--services/core/java/com/android/server/wm/AccessibilityController.java54
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java22
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java26
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java28
-rw-r--r--services/core/java/com/android/server/wm/AppTransition.java9
-rw-r--r--services/core/java/com/android/server/wm/AppTransitionController.java14
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java13
-rw-r--r--services/core/java/com/android/server/wm/DisplayContent.java40
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java5
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java131
-rw-r--r--services/core/java/com/android/server/wm/RootActivityContainer.java10
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java3
-rw-r--r--services/core/java/com/android/server/wm/TapExcludeRegionHolder.java7
-rw-r--r--services/core/java/com/android/server/wm/TaskChangeNotificationController.java20
-rw-r--r--services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskSnapshotSurface.java15
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java7
-rw-r--r--services/core/java/com/android/server/wm/WindowState.java82
-rw-r--r--services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java490
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java15
-rw-r--r--services/tests/wmtests/AndroidManifest.xml3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java13
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java54
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java65
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestIWindow.java5
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java2
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java100
-rwxr-xr-xtelephony/java/android/telephony/CarrierConfigManager.java17
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java4
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java3
-rw-r--r--telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl3
-rw-r--r--tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java9
-rw-r--r--tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java12
522 files changed, 13588 insertions, 3691 deletions
diff --git a/api/test-current.txt b/api/test-current.txt
index fa018a316644..59bd80a190ee 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3256,10 +3256,13 @@ package android.view {
}
@UiThread public class View implements android.view.accessibility.AccessibilityEventSource android.graphics.drawable.Drawable.Callback android.view.KeyEvent.Callback {
+ method @android.view.ViewDebug.ExportedProperty(mapping={@android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to="auto"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES, to="yes"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO, to="no"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS, to="yesExcludeDescendants"), @android.view.ViewDebug.IntToString(from=android.view.View.IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS, to="noExcludeDescendants")}) public int getImportantForContentCapture();
method public android.view.View getTooltipView();
method public boolean isAutofilled();
method public static boolean isDefaultFocusHighlightEnabled();
method public boolean isDefaultFocusHighlightNeeded(android.graphics.drawable.Drawable, android.graphics.drawable.Drawable);
+ method public final boolean isImportantForContentCapture();
+ method public void onProvideContentCaptureStructure(@NonNull android.view.ViewStructure, int);
method protected void resetResolvedDrawables();
method public void resetResolvedLayoutDirection();
method public void resetResolvedPadding();
@@ -3270,7 +3273,13 @@ package android.view {
method public boolean restoreFocusNotInCluster();
method public void setAutofilled(boolean);
method public final void setFocusedInCluster();
+ method public void setImportantForContentCapture(int);
method public void setIsRootNamespace(boolean);
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0; // 0x0
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 2; // 0x2
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 8; // 0x8
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 1; // 0x1
+ field public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 4; // 0x4
}
public class ViewConfiguration {
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index c676e622f3e2..f76037af0508 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -3291,6 +3291,8 @@ message BiometricErrorOccurred {
optional int32 error_info_vendor = 7;
// Dictates if this message should trigger additional debugging.
optional bool debug = 8;
+ // Time spent during the authentication attempt.
+ optional int64 latency_millis = 9;
}
/**
diff --git a/cmds/statsd/src/external/PowerStatsPuller.cpp b/cmds/statsd/src/external/PowerStatsPuller.cpp
index c56f9a27086e..b142caca3acc 100644
--- a/cmds/statsd/src/external/PowerStatsPuller.cpp
+++ b/cmds/statsd/src/external/PowerStatsPuller.cpp
@@ -85,7 +85,6 @@ bool PowerStatsPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
std::lock_guard<std::mutex> lock(gPowerStatsHalMutex);
if (!getPowerStatsHalLocked()) {
- ALOGE("power.stats Hal not loaded");
return false;
}
@@ -116,6 +115,7 @@ bool PowerStatsPuller::PullInternal(vector<shared_ptr<LogEvent>>* data) {
if (gRailInfo.empty()) {
ALOGE("power.stats has no rail information");
gPowerStatsExist = false; // No rail info, so never try again.
+ gPowerStatsHal = nullptr;
return false;
}
}
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 4771f9f6ad04..3bf659b663b0 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -120,6 +120,7 @@ public class ActivityView extends ViewGroup {
mActivityTaskManager = ActivityTaskManager.getService();
mSurfaceView = new SurfaceView(context);
+ mSurfaceView.setAlpha(0f);
mSurfaceCallback = new SurfaceCallback();
mSurfaceView.getHolder().addCallback(mSurfaceCallback);
addView(mSurfaceView);
@@ -347,6 +348,16 @@ public class ActivityView extends ViewGroup {
}
@Override
+ public void setAlpha(float alpha) {
+ mSurfaceView.setAlpha(alpha);
+ }
+
+ @Override
+ public float getAlpha() {
+ return mSurfaceView.getAlpha();
+ }
+
+ @Override
public boolean gatherTransparentRegion(Region region) {
// The tap exclude region may be affected by any view on top of it, so we detect the
// possible change by monitoring this function.
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 0df3bbe42c7e..650147b45bd2 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -170,6 +170,14 @@ oneway interface ITaskStackListener {
*/
void onBackPressedOnTaskRoot(in ActivityManager.RunningTaskInfo taskInfo);
+ /*
+ * Called when contents are drawn for the first time on a display which can only contain one
+ * task.
+ *
+ * @param displayId the id of the display on which contents are drawn.
+ */
+ void onSingleTaskDisplayDrawn(int displayId);
+
/**
* Called when a task is reparented to a stack on a different display.
*
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 789351e0d157..475dccb0923e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3386,11 +3386,7 @@ public class Notification implements Parcelable
*/
private int mCachedContrastColor = COLOR_INVALID;
private int mCachedContrastColorIsFor = COLOR_INVALID;
- /**
- * Caches a ambient version of {@link #mCachedAmbientColorIsFor}.
- */
- private int mCachedAmbientColor = COLOR_INVALID;
- private int mCachedAmbientColorIsFor = COLOR_INVALID;
+
/**
* A neutral color color that can be used for icons.
*/
@@ -5445,22 +5441,9 @@ public class Notification implements Parcelable
*/
@UnsupportedAppUsage
public RemoteViews makePublicContentView() {
- return makePublicView(false /* ambient */);
- }
-
- /**
- * Construct a RemoteViews for the display in public contexts like on the lockscreen.
- *
- * @hide
- */
- public RemoteViews makePublicAmbientNotification() {
- return makePublicView(true /* ambient */);
- }
-
- private RemoteViews makePublicView(boolean ambient) {
if (mN.publicVersion != null) {
final Builder builder = recoverBuilder(mContext, mN.publicVersion);
- return ambient ? builder.makeAmbientNotification() : builder.createContentView();
+ return builder.createContentView();
}
Bundle savedBundle = mN.extras;
Style style = mStyle;
diff --git a/core/java/android/app/StatusBarManager.java b/core/java/android/app/StatusBarManager.java
index af2d774508c4..205e7a13092b 100644
--- a/core/java/android/app/StatusBarManager.java
+++ b/core/java/android/app/StatusBarManager.java
@@ -433,6 +433,9 @@ public class StatusBarManager {
private boolean mNotificationPeeking;
private boolean mRecents;
private boolean mSearch;
+ private boolean mSystemIcons;
+ private boolean mClock;
+ private boolean mNotificationIcons;
/** @hide */
public DisableInfo(int flags1, int flags2) {
@@ -441,6 +444,9 @@ public class StatusBarManager {
mNotificationPeeking = (flags1 & DISABLE_NOTIFICATION_ALERTS) != 0;
mRecents = (flags1 & DISABLE_RECENT) != 0;
mSearch = (flags1 & DISABLE_SEARCH) != 0;
+ mSystemIcons = (flags1 & DISABLE_SYSTEM_INFO) != 0;
+ mClock = (flags1 & DISABLE_CLOCK) != 0;
+ mNotificationIcons = (flags1 & DISABLE_NOTIFICATION_ICONS) != 0;
}
/** @hide */
@@ -527,6 +533,48 @@ public class StatusBarManager {
}
/**
+ * @return {@code true} if system icons are disabled
+ *
+ * @hide
+ */
+ public boolean areSystemIconsDisabled() {
+ return mSystemIcons;
+ }
+
+ /** * @hide */
+ public void setSystemIconsDisabled(boolean disabled) {
+ mSystemIcons = disabled;
+ }
+
+ /**
+ * @return {@code true} if the clock icon is disabled
+ *
+ * @hide
+ */
+ public boolean isClockDisabled() {
+ return mClock;
+ }
+
+ /** * @hide */
+ public void setClockDisabled(boolean disabled) {
+ mClock = disabled;
+ }
+
+ /**
+ * @return {@code true} if notification icons are disabled
+ *
+ * @hide
+ */
+ public boolean areNotificationIconsDisabled() {
+ return mNotificationIcons;
+ }
+
+ /** * @hide */
+ public void setNotificationIconsDisabled(boolean disabled) {
+ mNotificationIcons = disabled;
+ }
+
+ /**
* @return {@code true} if no components are disabled (default state)
*
* @hide
@@ -535,7 +583,7 @@ public class StatusBarManager {
@TestApi
public boolean areAllComponentsEnabled() {
return !mStatusBarExpansion && !mNavigateHome && !mNotificationPeeking && !mRecents
- && !mSearch;
+ && !mSearch && !mSystemIcons && !mClock && !mNotificationIcons;
}
/** @hide */
@@ -545,6 +593,9 @@ public class StatusBarManager {
mNotificationPeeking = false;
mRecents = false;
mSearch = false;
+ mSystemIcons = false;
+ mClock = false;
+ mNotificationIcons = false;
}
/**
@@ -554,7 +605,7 @@ public class StatusBarManager {
*/
public boolean areAllComponentsDisabled() {
return mStatusBarExpansion && mNavigateHome && mNotificationPeeking
- && mRecents && mSearch;
+ && mRecents && mSearch && mSystemIcons && mClock && mNotificationIcons;
}
/** @hide */
@@ -564,6 +615,9 @@ public class StatusBarManager {
mNotificationPeeking = true;
mRecents = true;
mSearch = true;
+ mSystemIcons = true;
+ mClock = true;
+ mNotificationIcons = true;
}
@Override
@@ -576,6 +630,9 @@ public class StatusBarManager {
.append(mNotificationPeeking ? "disabled" : "enabled");
sb.append(" mRecents=").append(mRecents ? "disabled" : "enabled");
sb.append(" mSearch=").append(mSearch ? "disabled" : "enabled");
+ sb.append(" mSystemIcons=").append(mSystemIcons ? "disabled" : "enabled");
+ sb.append(" mClock=").append(mClock ? "disabled" : "enabled");
+ sb.append(" mNotificationIcons=").append(mNotificationIcons ? "disabled" : "enabled");
return sb.toString();
@@ -596,6 +653,9 @@ public class StatusBarManager {
if (mNotificationPeeking) disable1 |= DISABLE_NOTIFICATION_ALERTS;
if (mRecents) disable1 |= DISABLE_RECENT;
if (mSearch) disable1 |= DISABLE_SEARCH;
+ if (mSystemIcons) disable1 |= DISABLE_SYSTEM_INFO;
+ if (mClock) disable1 |= DISABLE_CLOCK;
+ if (mNotificationIcons) disable1 |= DISABLE_NOTIFICATION_ICONS;
return new Pair<Integer, Integer>(disable1, disable2);
}
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 73fc7a3db6c7..b63feb590ad1 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -176,6 +176,10 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
}
@Override
+ public void onSingleTaskDisplayDrawn(int displayId) throws RemoteException {
+ }
+
+ @Override
public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
}
}
diff --git a/core/java/android/hardware/biometrics/BiometricManager.java b/core/java/android/hardware/biometrics/BiometricManager.java
index 6c497d47c645..af66dc161343 100644
--- a/core/java/android/hardware/biometrics/BiometricManager.java
+++ b/core/java/android/hardware/biometrics/BiometricManager.java
@@ -104,9 +104,17 @@ public class BiometricManager {
*/
@RequiresPermission(USE_BIOMETRIC)
public @BiometricError int canAuthenticate() {
+ return canAuthenticate(mContext.getUserId());
+ }
+
+ /**
+ * @hide
+ */
+ @RequiresPermission(USE_BIOMETRIC_INTERNAL)
+ public @BiometricError int canAuthenticate(int userId) {
if (mService != null) {
try {
- return mService.canAuthenticate(mContext.getOpPackageName());
+ return mService.canAuthenticate(mContext.getOpPackageName(), userId);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/hardware/biometrics/IBiometricService.aidl b/core/java/android/hardware/biometrics/IBiometricService.aidl
index 90d4921c3c18..18c14cb835a8 100644
--- a/core/java/android/hardware/biometrics/IBiometricService.aidl
+++ b/core/java/android/hardware/biometrics/IBiometricService.aidl
@@ -40,7 +40,7 @@ interface IBiometricService {
void cancelAuthentication(IBinder token, String opPackageName);
// Checks if biometrics can be used.
- int canAuthenticate(String opPackageName);
+ int canAuthenticate(String opPackageName, int userId);
// Register callback for when keyguard biometric eligibility changes.
void registerEnabledOnKeyguardCallback(IBiometricEnabledOnKeyguardCallback callback);
diff --git a/core/java/android/hardware/display/AmbientDisplayConfiguration.java b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
index c45b8ed52187..3e995b624112 100644
--- a/core/java/android/hardware/display/AmbientDisplayConfiguration.java
+++ b/core/java/android/hardware/display/AmbientDisplayConfiguration.java
@@ -48,7 +48,8 @@ public class AmbientDisplayConfiguration {
return pulseOnNotificationEnabled(user)
|| pulseOnLongPressEnabled(user)
|| alwaysOnEnabled(user)
- || wakeScreenGestureEnabled(user)
+ || wakeLockScreenGestureEnabled(user)
+ || wakeDisplayGestureEnabled(user)
|| pickupGestureEnabled(user)
|| tapGestureEnabled(user)
|| doubleTapGestureEnabled(user);
@@ -105,8 +106,14 @@ public class AmbientDisplayConfiguration {
}
/** {@hide} */
- public boolean wakeScreenGestureEnabled(int user) {
- return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_SCREEN_GESTURE, user)
+ public boolean wakeLockScreenGestureEnabled(int user) {
+ return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE, user)
+ && wakeScreenGestureAvailable();
+ }
+
+ /** {@hide} */
+ public boolean wakeDisplayGestureEnabled(int user) {
+ return boolSettingDefaultOn(Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE, user)
&& wakeScreenGestureAvailable();
}
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 8596af107ac1..12b285a0f0ab 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -262,7 +262,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public void enroll(byte[] token, CancellationSignal cancel,
+ public void enroll(int userId, byte[] token, CancellationSignal cancel,
EnrollmentCallback callback, int[] disabledFeatures) {
if (callback == null) {
throw new IllegalArgumentException("Must supply an enrollment callback");
@@ -281,7 +281,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
try {
mEnrollmentCallback = callback;
Trace.beginSection("FaceManager#enroll");
- mService.enroll(mToken, token, mServiceReceiver,
+ mService.enroll(userId, mToken, token, mServiceReceiver,
mContext.getOpPackageName(), disabledFeatures);
} catch (RemoteException e) {
Log.w(TAG, "Remote exception in enroll: ", e);
@@ -339,12 +339,13 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public void setFeature(int feature, boolean enabled, byte[] token,
+ public void setFeature(int userId, int feature, boolean enabled, byte[] token,
SetFeatureCallback callback) {
if (mService != null) {
try {
mSetFeatureCallback = callback;
- mService.setFeature(feature, enabled, token, mServiceReceiver);
+ mService.setFeature(userId, feature, enabled, token, mServiceReceiver,
+ mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -355,11 +356,11 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
* @hide
*/
@RequiresPermission(MANAGE_BIOMETRIC)
- public void getFeature(int feature, GetFeatureCallback callback) {
+ public void getFeature(int userId, int feature, GetFeatureCallback callback) {
if (mService != null) {
try {
mGetFeatureCallback = callback;
- mService.getFeature(feature, mServiceReceiver);
+ mService.getFeature(userId, feature, mServiceReceiver, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -414,7 +415,8 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
try {
mRemovalCallback = callback;
mRemovalFace = face;
- mService.remove(mToken, face.getBiometricId(), userId, mServiceReceiver);
+ mService.remove(mToken, face.getBiometricId(), userId, mServiceReceiver,
+ mContext.getOpPackageName());
} catch (RemoteException e) {
Log.w(TAG, "Remote exception in remove: ", e);
if (callback != null) {
@@ -637,7 +639,7 @@ public class FaceManager implements BiometricAuthenticator, BiometricFaceConstan
}
}
Slog.w(TAG, "Invalid error message: " + errMsg + ", " + vendorCode);
- return null;
+ return "";
}
/**
diff --git a/core/java/android/hardware/face/IFaceService.aidl b/core/java/android/hardware/face/IFaceService.aidl
index 601be7595581..b6a0afbf716c 100644
--- a/core/java/android/hardware/face/IFaceService.aidl
+++ b/core/java/android/hardware/face/IFaceService.aidl
@@ -50,14 +50,15 @@ interface IFaceService {
int callingUid, int callingPid, int callingUserId, boolean fromClient);
// Start face enrollment
- void enroll(IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
+ void enroll(int userId, IBinder token, in byte [] cryptoToken, IFaceServiceReceiver receiver,
String opPackageName, in int [] disabledFeatures);
// Cancel enrollment in progress
void cancelEnrollment(IBinder token);
// Any errors resulting from this call will be returned to the listener
- void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver);
+ void remove(IBinder token, int faceId, int userId, IFaceServiceReceiver receiver,
+ String opPackageName);
// Rename the face specified by faceId to the given name
void rename(int faceId, String name);
@@ -98,10 +99,10 @@ interface IFaceService {
// Enumerate all faces
void enumerate(IBinder token, int userId, IFaceServiceReceiver receiver);
- void setFeature(int feature, boolean enabled, in byte [] token,
- IFaceServiceReceiver receiver);
+ void setFeature(int userId, int feature, boolean enabled, in byte [] token,
+ IFaceServiceReceiver receiver, String opPackageName);
- void getFeature(int feature, IFaceServiceReceiver receiver);
+ void getFeature(int userId, int feature, IFaceServiceReceiver receiver, String opPackageName);
void userActivity();
}
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl
index e8b3ca6cb7ae..1456ff7e6c5e 100644
--- a/core/java/android/os/IVibratorService.aidl
+++ b/core/java/android/os/IVibratorService.aidl
@@ -16,6 +16,7 @@
package android.os;
+import android.media.AudioAttributes;
import android.os.VibrationEffect;
/** {@hide} */
@@ -23,8 +24,8 @@ interface IVibratorService
{
boolean hasVibrator();
boolean hasAmplitudeControl();
- void vibrate(int uid, String opPkg, in VibrationEffect effect, int usageHint, String reason,
- IBinder token);
+ void vibrate(int uid, String opPkg, in VibrationEffect effect, in AudioAttributes attributes,
+ String reason, IBinder token);
void cancelVibrate(IBinder token);
}
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 53298d8d8aed..48fc2a6bf449 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -31,6 +31,8 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.provider.Settings;
+import android.telephony.SubscriptionInfo;
+import android.telephony.SubscriptionManager;
import android.telephony.euicc.EuiccManager;
import android.text.TextUtils;
import android.text.format.DateFormat;
@@ -56,10 +58,12 @@ import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashSet;
+import java.util.List;
import java.util.Locale;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;
@@ -87,11 +91,14 @@ public class RecoverySystem {
private static final long PUBLISH_PROGRESS_INTERVAL_MS = 500;
private static final long DEFAULT_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 30000L; // 30 s
-
private static final long MIN_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 5000L; // 5 s
-
private static final long MAX_EUICC_FACTORY_RESET_TIMEOUT_MILLIS = 60000L; // 60 s
+ private static final long DEFAULT_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS =
+ 45000L; // 45 s
+ private static final long MIN_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS = 15000L; // 15 s
+ private static final long MAX_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS = 90000L; // 90 s
+
/** Used to communicate with recovery. See bootable/recovery/recovery.cpp. */
private static final File RECOVERY_DIR = new File("/cache/recovery");
private static final File LOG_FILE = new File(RECOVERY_DIR, "log");
@@ -99,9 +106,14 @@ public class RecoverySystem {
private static final String LAST_PREFIX = "last_";
private static final String ACTION_EUICC_FACTORY_RESET =
"com.android.internal.action.EUICC_FACTORY_RESET";
+ private static final String ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS =
+ "com.android.internal.action.EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS";
- /** used in {@link #wipeEuiccData} as package name of callback intent */
- private static final String PACKAGE_NAME_WIPING_EUICC_DATA_CALLBACK = "android";
+ /**
+ * Used in {@link #wipeEuiccData} & {@link #removeEuiccInvisibleSubs} as package name of
+ * callback intent.
+ */
+ private static final String PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK = "android";
/**
* The recovery image uses this file to identify the location (i.e. blocks)
@@ -754,8 +766,11 @@ public class RecoverySystem {
// Block until the ordered broadcast has completed.
condition.block();
+ EuiccManager euiccManager = context.getSystemService(EuiccManager.class);
if (wipeEuicc) {
- wipeEuiccData(context, PACKAGE_NAME_WIPING_EUICC_DATA_CALLBACK);
+ wipeEuiccData(context, PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK);
+ } else {
+ removeEuiccInvisibleSubs(context, euiccManager);
}
String shutdownArg = null;
@@ -851,6 +866,110 @@ public class RecoverySystem {
return false;
}
+ private static void removeEuiccInvisibleSubs(
+ Context context, EuiccManager euiccManager) {
+ ContentResolver cr = context.getContentResolver();
+ if (Settings.Global.getInt(cr, Settings.Global.EUICC_PROVISIONED, 0) == 0) {
+ // If the eUICC isn't provisioned, there's no need to remove euicc invisible profiles,
+ // as there's nothing to be removed.
+ Log.i(TAG, "Skip removing eUICC invisible profiles as it is not provisioned.");
+ return;
+ } else if (euiccManager == null || !euiccManager.isEnabled()) {
+ Log.i(TAG, "Skip removing eUICC invisible profiles as eUICC manager is not available.");
+ return;
+ }
+ SubscriptionManager subscriptionManager =
+ context.getSystemService(SubscriptionManager.class);
+ List<SubscriptionInfo> availableSubs =
+ subscriptionManager.getAvailableSubscriptionInfoList();
+ if (availableSubs == null || availableSubs.isEmpty()) {
+ Log.i(TAG, "Skip removing eUICC invisible profiles as no available profiles found.");
+ return;
+ }
+ List<SubscriptionInfo> invisibleSubs = new ArrayList<>();
+ for (SubscriptionInfo sub : availableSubs) {
+ if (sub.isEmbedded() && !subscriptionManager.isSubscriptionVisible(sub)) {
+ invisibleSubs.add(sub);
+ }
+ }
+ removeEuiccInvisibleSubs(context, invisibleSubs, euiccManager);
+ }
+
+ private static boolean removeEuiccInvisibleSubs(
+ Context context, List<SubscriptionInfo> subscriptionInfos, EuiccManager euiccManager) {
+ if (subscriptionInfos == null || subscriptionInfos.isEmpty()) {
+ Log.i(TAG, "There are no eUICC invisible profiles needed to be removed.");
+ return true;
+ }
+ CountDownLatch removeSubsLatch = new CountDownLatch(subscriptionInfos.size());
+ final AtomicInteger removedSubsCount = new AtomicInteger(0);
+
+ BroadcastReceiver removeEuiccSubsReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS.equals(intent.getAction())) {
+ if (getResultCode() != EuiccManager.EMBEDDED_SUBSCRIPTION_RESULT_OK) {
+ int detailedCode = intent.getIntExtra(
+ EuiccManager.EXTRA_EMBEDDED_SUBSCRIPTION_DETAILED_CODE, 0);
+ Log.e(TAG, "Error removing euicc opportunistic profile, Detailed code = "
+ + detailedCode);
+ } else {
+ Log.e(TAG, "Successfully remove euicc opportunistic profile.");
+ removedSubsCount.incrementAndGet();
+ }
+ removeSubsLatch.countDown();
+ }
+ }
+ };
+
+ Intent intent = new Intent(ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS);
+ intent.setPackage(PACKAGE_NAME_EUICC_DATA_MANAGEMENT_CALLBACK);
+ PendingIntent callbackIntent = PendingIntent.getBroadcastAsUser(
+ context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT, UserHandle.SYSTEM);
+ IntentFilter intentFilter = new IntentFilter();
+ intentFilter.addAction(ACTION_EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS);
+ HandlerThread euiccHandlerThread =
+ new HandlerThread("euiccRemovingSubsReceiverThread");
+ euiccHandlerThread.start();
+ Handler euiccHandler = new Handler(euiccHandlerThread.getLooper());
+ context.getApplicationContext()
+ .registerReceiver(
+ removeEuiccSubsReceiver, intentFilter, null, euiccHandler);
+ for (SubscriptionInfo subscriptionInfo : subscriptionInfos) {
+ Log.i(
+ TAG,
+ "Remove invisible subscription " + subscriptionInfo.getSubscriptionId()
+ + " from card " + subscriptionInfo.getCardId());
+ euiccManager.createForCardId(subscriptionInfo.getCardId())
+ .deleteSubscription(subscriptionInfo.getSubscriptionId(), callbackIntent);
+ }
+ try {
+ long waitingTimeMillis = Settings.Global.getLong(
+ context.getContentResolver(),
+ Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS,
+ DEFAULT_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS);
+ if (waitingTimeMillis < MIN_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS) {
+ waitingTimeMillis = MIN_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS;
+ } else if (waitingTimeMillis > MAX_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS) {
+ waitingTimeMillis = MAX_EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS;
+ }
+ if (!removeSubsLatch.await(waitingTimeMillis, TimeUnit.MILLISECONDS)) {
+ Log.e(TAG, "Timeout removing invisible euicc profiles.");
+ return false;
+ }
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ Log.e(TAG, "Removing invisible euicc profiles interrupted", e);
+ return false;
+ } finally {
+ context.getApplicationContext().unregisterReceiver(removeEuiccSubsReceiver);
+ if (euiccHandlerThread != null) {
+ euiccHandlerThread.quit();
+ }
+ }
+ return removedSubsCount.get() == subscriptionInfos.size();
+ }
+
/** {@hide} */
public static void rebootPromptAndWipeUserData(Context context, String reason)
throws IOException {
diff --git a/core/java/android/os/SystemVibrator.java b/core/java/android/os/SystemVibrator.java
index 4af514abfd69..a5188e7cd58d 100644
--- a/core/java/android/os/SystemVibrator.java
+++ b/core/java/android/os/SystemVibrator.java
@@ -77,16 +77,12 @@ public class SystemVibrator extends Vibrator {
return;
}
try {
- mService.vibrate(uid, opPkg, effect, usageForAttributes(attributes), reason, mToken);
+ mService.vibrate(uid, opPkg, effect, attributes, reason, mToken);
} catch (RemoteException e) {
Log.w(TAG, "Failed to vibrate.", e);
}
}
- private static int usageForAttributes(AudioAttributes attributes) {
- return attributes != null ? attributes.getUsage() : AudioAttributes.USAGE_UNKNOWN;
- }
-
@Override
public void cancel() {
if (mService == null) {
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 383d8dbce791..bf8b0066cb64 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -88,6 +88,7 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
import android.util.MemoryIntArray;
+import android.view.Display;
import android.view.inputmethod.InputMethodSystemProperty;
import com.android.internal.annotations.GuardedBy;
@@ -4073,7 +4074,7 @@ public final class Settings {
* preference, this rotation value will be used. Must be one of the
* {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
*
- * @see android.view.Display#getRotation
+ * @see Display#getRotation
*/
public static final String USER_ROTATION = "user_rotation";
@@ -6321,13 +6322,15 @@ public final class Settings {
"lock_screen_allow_remote_input";
/**
- * Indicates which clock face to show on lock screen and AOD.
+ * Indicates which clock face to show on lock screen and AOD formatted as a serialized
+ * {@link org.json.JSONObject} with the format:
+ * {"clock": id, "_applied_timestamp": timestamp}
* @hide
*/
public static final String LOCK_SCREEN_CUSTOM_CLOCK_FACE = "lock_screen_custom_clock_face";
private static final Validator LOCK_SCREEN_CUSTOM_CLOCK_FACE_VALIDATOR =
- ANY_STRING_VALIDATOR;
+ SettingsValidators.JSON_OBJECT_VALIDATOR;
/**
* Indicates which clock face to show on lock screen and AOD while docked.
@@ -7731,12 +7734,21 @@ public final class Settings {
private static final Validator DOZE_TAP_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
/**
- * Gesture that wakes up the display, showing the ambient version of the status bar.
+ * Gesture that wakes up the display, showing some version of the lock screen.
+ * @hide
+ */
+ public static final String DOZE_WAKE_LOCK_SCREEN_GESTURE = "doze_wake_screen_gesture";
+
+ private static final Validator DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
+ * Gesture that wakes up the display, toggling between {@link Display.STATE_OFF} and
+ * {@link Display.STATE_DOZE}.
* @hide
*/
- public static final String DOZE_WAKE_SCREEN_GESTURE = "doze_wake_screen_gesture";
+ public static final String DOZE_WAKE_DISPLAY_GESTURE = "doze_wake_display_gesture";
- private static final Validator DOZE_WAKE_SCREEN_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
+ private static final Validator DOZE_WAKE_DISPLAY_GESTURE_VALIDATOR = BOOLEAN_VALIDATOR;
/**
* Gesture that skips media.
@@ -7752,10 +7764,30 @@ public final class Settings {
*/
public static final String SKIP_GESTURE_COUNT = "skip_gesture_count";
+ /**
+ * Count of non-gesture interaction.
+ * @hide
+ */
+ public static final String SKIP_TOUCH_COUNT = "skip_touch_count";
+
private static final Validator SKIP_GESTURE_COUNT_VALIDATOR =
NON_NEGATIVE_INTEGER_VALIDATOR;
/**
+ * Direction to advance media for skip gesture
+ * @hide
+ */
+ public static final String SKIP_DIRECTION = "skip_gesture_direction";
+
+ /**
+ * Only used if FeatureFlag "settings_skip_direction_mutable" is enabled.
+ * If feature flag is disabled, should assume SKIP_DIRECTION = 0.
+ * 0 / false = right to left to advance to next
+ * 1 / true = left to right to advance to next
+ */
+ private static final Validator SKIP_DIRECTION_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
* Gesture that silences sound (alarms, notification, calls).
* @hide
*/
@@ -7782,11 +7814,22 @@ public final class Settings {
public static final String SILENCE_CALL_GESTURE_COUNT = "silence_call_gesture_count";
/**
- * Count of successful silence notification gestures.
+ * Count of non-gesture interaction.
* @hide
*/
- public static final String SILENCE_NOTIFICATION_GESTURE_COUNT =
- "silence_notification_gesture_count";
+ public static final String SILENCE_ALARMS_TOUCH_COUNT = "silence_alarms_touch_count";
+
+ /**
+ * Count of non-gesture interaction.
+ * @hide
+ */
+ public static final String SILENCE_TIMER_TOUCH_COUNT = "silence_timer_touch_count";
+
+ /**
+ * Count of non-gesture interaction.
+ * @hide
+ */
+ public static final String SILENCE_CALL_TOUCH_COUNT = "silence_call_touch_count";
private static final Validator SILENCE_GESTURE_COUNT_VALIDATOR =
NON_NEGATIVE_INTEGER_VALIDATOR;
@@ -8250,6 +8293,16 @@ public final class Settings {
BOOLEAN_VALIDATOR;
/**
+ * Whether or not media is shown automatically when bypassing as a heads up.
+ * @hide
+ */
+ public static final String SHOW_MEDIA_WHEN_BYPASSING =
+ "show_media_when_bypassing";
+
+ private static final Validator SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR =
+ BOOLEAN_VALIDATOR;
+
+ /**
* Whether or not face unlock requires attention. This is a cached value, the source of
* truth is obtained through the HAL.
* @hide
@@ -8948,10 +9001,12 @@ public final class Settings {
DOZE_PICK_UP_GESTURE,
DOZE_DOUBLE_TAP_GESTURE,
DOZE_TAP_SCREEN_GESTURE,
- DOZE_WAKE_SCREEN_GESTURE,
+ DOZE_WAKE_LOCK_SCREEN_GESTURE,
+ DOZE_WAKE_DISPLAY_GESTURE,
NFC_PAYMENT_DEFAULT_COMPONENT,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
FACE_UNLOCK_KEYGUARD_ENABLED,
+ SHOW_MEDIA_WHEN_BYPASSING,
FACE_UNLOCK_DISMISSES_KEYGUARD,
FACE_UNLOCK_APP_ENABLED,
FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
@@ -8992,15 +9047,19 @@ public final class Settings {
UI_NIGHT_MODE,
LOCK_SCREEN_WHEN_TRUST_LOST,
SKIP_GESTURE,
+ SKIP_DIRECTION,
SILENCE_GESTURE,
THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
NAVIGATION_MODE,
AWARE_ENABLED,
SKIP_GESTURE_COUNT,
+ SKIP_TOUCH_COUNT,
SILENCE_ALARMS_GESTURE_COUNT,
- SILENCE_NOTIFICATION_GESTURE_COUNT,
SILENCE_CALL_GESTURE_COUNT,
SILENCE_TIMER_GESTURE_COUNT,
+ SILENCE_ALARMS_TOUCH_COUNT,
+ SILENCE_CALL_TOUCH_COUNT,
+ SILENCE_TIMER_TOUCH_COUNT,
DARK_MODE_DIALOG_SEEN,
GLOBAL_ACTIONS_PANEL_ENABLED,
AWARE_LOCK_ENABLED
@@ -9119,13 +9178,15 @@ public final class Settings {
VALIDATORS.put(DOZE_PICK_UP_GESTURE, DOZE_PICK_UP_GESTURE_VALIDATOR);
VALIDATORS.put(DOZE_DOUBLE_TAP_GESTURE, DOZE_DOUBLE_TAP_GESTURE_VALIDATOR);
VALIDATORS.put(DOZE_TAP_SCREEN_GESTURE, DOZE_TAP_SCREEN_GESTURE_VALIDATOR);
- VALIDATORS.put(DOZE_WAKE_SCREEN_GESTURE, DOZE_WAKE_SCREEN_GESTURE_VALIDATOR);
+ VALIDATORS.put(DOZE_WAKE_LOCK_SCREEN_GESTURE, DOZE_WAKE_LOCK_SCREEN_GESTURE_VALIDATOR);
+ VALIDATORS.put(DOZE_WAKE_DISPLAY_GESTURE, DOZE_WAKE_DISPLAY_GESTURE_VALIDATOR);
VALIDATORS.put(NFC_PAYMENT_DEFAULT_COMPONENT, NFC_PAYMENT_DEFAULT_COMPONENT_VALIDATOR);
VALIDATORS.put(AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN,
AUTOMATIC_STORAGE_MANAGER_DAYS_TO_RETAIN_VALIDATOR);
VALIDATORS.put(FACE_UNLOCK_KEYGUARD_ENABLED, FACE_UNLOCK_KEYGUARD_ENABLED_VALIDATOR);
VALIDATORS.put(FACE_UNLOCK_DISMISSES_KEYGUARD,
FACE_UNLOCK_DISMISSES_KEYGUARD_VALIDATOR);
+ VALIDATORS.put(SHOW_MEDIA_WHEN_BYPASSING, SHOW_MEDIA_WHEN_BYPASSING_VALIDATOR);
VALIDATORS.put(FACE_UNLOCK_APP_ENABLED, FACE_UNLOCK_APP_ENABLED_VALIDATOR);
VALIDATORS.put(FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION,
FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION_VALIDATOR);
@@ -9178,16 +9239,21 @@ public final class Settings {
VALIDATORS.put(LOCK_SCREEN_CUSTOM_CLOCK_FACE, LOCK_SCREEN_CUSTOM_CLOCK_FACE_VALIDATOR);
VALIDATORS.put(LOCK_SCREEN_WHEN_TRUST_LOST, LOCK_SCREEN_WHEN_TRUST_LOST_VALIDATOR);
VALIDATORS.put(SKIP_GESTURE, SKIP_GESTURE_VALIDATOR);
+ VALIDATORS.put(SKIP_DIRECTION, SKIP_DIRECTION_VALIDATOR);
+ VALIDATORS.put(SKIP_DIRECTION, SKIP_DIRECTION_VALIDATOR);
VALIDATORS.put(SILENCE_GESTURE, SILENCE_GESTURE_VALIDATOR);
VALIDATORS.put(THEME_CUSTOMIZATION_OVERLAY_PACKAGES,
THEME_CUSTOMIZATION_OVERLAY_PACKAGES_VALIDATOR);
VALIDATORS.put(NAVIGATION_MODE, NAVIGATION_MODE_VALIDATOR);
VALIDATORS.put(AWARE_ENABLED, AWARE_ENABLED_VALIDATOR);
VALIDATORS.put(SKIP_GESTURE_COUNT, SKIP_GESTURE_COUNT_VALIDATOR);
+ VALIDATORS.put(SKIP_TOUCH_COUNT, SKIP_GESTURE_COUNT_VALIDATOR);
VALIDATORS.put(SILENCE_ALARMS_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
VALIDATORS.put(SILENCE_TIMER_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
VALIDATORS.put(SILENCE_CALL_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
- VALIDATORS.put(SILENCE_NOTIFICATION_GESTURE_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
+ VALIDATORS.put(SILENCE_ALARMS_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
+ VALIDATORS.put(SILENCE_TIMER_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
+ VALIDATORS.put(SILENCE_CALL_TOUCH_COUNT, SILENCE_GESTURE_COUNT_VALIDATOR);
VALIDATORS.put(ODI_CAPTIONS_ENABLED, ODI_CAPTIONS_ENABLED_VALIDATOR);
VALIDATORS.put(DARK_MODE_DIALOG_SEEN, BOOLEAN_VALIDATOR);
VALIDATORS.put(UI_NIGHT_MODE, UI_NIGHT_MODE_VALIDATOR);
@@ -13549,6 +13615,16 @@ public final class Settings {
"location_settings_link_to_permissions_enabled";
/**
+ * Flag to set the waiting time for removing invisible euicc profiles inside System >
+ * Settings.
+ * Type: long
+ *
+ * @hide
+ */
+ public static final String EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS =
+ "euicc_removing_invisible_profiles_timeout_millis";
+
+ /**
* Flag to set the waiting time for euicc factory reset inside System > Settings
* Type: long
*
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 324e02ceb1d5..0e0c676c2782 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -57,6 +57,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
DEFAULT_FLAGS.put(PIXEL_WALLPAPER_CATEGORY_SWITCH, "false");
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
+ DEFAULT_FLAGS.put("settings_skip_direction_mutable", "true");
}
/**
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index bbd44c8b85af..4b929683fd6d 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -830,6 +830,32 @@ public final class AccessibilityInteractionController {
return false;
}
+ private void adjustBoundsInScreenIfNeeded(List<AccessibilityNodeInfo> infos) {
+ if (infos == null || shouldBypassAdjustBoundsInScreen()) {
+ return;
+ }
+ final int infoCount = infos.size();
+ for (int i = 0; i < infoCount; i++) {
+ final AccessibilityNodeInfo info = infos.get(i);
+ adjustBoundsInScreenIfNeeded(info);
+ }
+ }
+
+ private void adjustBoundsInScreenIfNeeded(AccessibilityNodeInfo info) {
+ if (info == null || shouldBypassAdjustBoundsInScreen()) {
+ return;
+ }
+ final Rect boundsInScreen = mTempRect;
+ info.getBoundsInScreen(boundsInScreen);
+ boundsInScreen.offset(mViewRootImpl.mAttachInfo.mLocationInParentDisplay.x,
+ mViewRootImpl.mAttachInfo.mLocationInParentDisplay.y);
+ info.setBoundsInScreen(boundsInScreen);
+ }
+
+ private boolean shouldBypassAdjustBoundsInScreen() {
+ return mViewRootImpl.mAttachInfo.mLocationInParentDisplay.equals(0, 0);
+ }
+
private void applyAppScaleAndMagnificationSpecIfNeeded(AccessibilityNodeInfo info,
MagnificationSpec spec) {
if (info == null) {
@@ -921,6 +947,7 @@ public final class AccessibilityInteractionController {
MagnificationSpec spec, Region interactiveRegion) {
try {
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
+ adjustBoundsInScreenIfNeeded(infos);
applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
@@ -939,6 +966,7 @@ public final class AccessibilityInteractionController {
MagnificationSpec spec, Region interactiveRegion) {
try {
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
+ adjustBoundsInScreenIfNeeded(info);
applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
callback.setFindAccessibilityNodeInfoResult(info, interactionId);
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index c64386e8db79..e95b5caa4fa0 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -16,6 +16,7 @@
package android.view;
+import static android.view.DisplayEventReceiver.CONFIG_CHANGED_EVENT_SUPPRESS;
import static android.view.DisplayEventReceiver.VSYNC_SOURCE_APP;
import static android.view.DisplayEventReceiver.VSYNC_SOURCE_SURFACE_FLINGER;
@@ -910,7 +911,7 @@ public final class Choreographer {
private int mFrame;
public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
- super(looper, vsyncSource);
+ super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS);
}
// TODO(b/116025192): physicalDisplayId is ignored because SF only emits VSYNC events for
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index 60daddd663d5..91acc4638c26 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -53,6 +53,20 @@ public abstract class DisplayEventReceiver {
*/
public static final int VSYNC_SOURCE_SURFACE_FLINGER = 1;
+ /**
+ * Specifies to suppress config changed events from being generated from Surface Flinger.
+ * <p>
+ * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
+ */
+ public static final int CONFIG_CHANGED_EVENT_SUPPRESS = 0;
+
+ /**
+ * Specifies to generate config changed events from Surface Flinger.
+ * <p>
+ * Needs to be kept in sync with frameworks/native/include/gui/ISurfaceComposer.h
+ */
+ public static final int CONFIG_CHANGED_EVENT_DISPATCH = 1;
+
private static final String TAG = "DisplayEventReceiver";
private final CloseGuard mCloseGuard = CloseGuard.get();
@@ -65,7 +79,7 @@ public abstract class DisplayEventReceiver {
private MessageQueue mMessageQueue;
private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver,
- MessageQueue messageQueue, int vsyncSource);
+ MessageQueue messageQueue, int vsyncSource, int configChanged);
private static native void nativeDispose(long receiverPtr);
@FastNative
private static native void nativeScheduleVsync(long receiverPtr);
@@ -77,7 +91,7 @@ public abstract class DisplayEventReceiver {
*/
@UnsupportedAppUsage
public DisplayEventReceiver(Looper looper) {
- this(looper, VSYNC_SOURCE_APP);
+ this(looper, VSYNC_SOURCE_APP, CONFIG_CHANGED_EVENT_SUPPRESS);
}
/**
@@ -85,15 +99,17 @@ public abstract class DisplayEventReceiver {
*
* @param looper The looper to use when invoking callbacks.
* @param vsyncSource The source of the vsync tick. Must be on of the VSYNC_SOURCE_* values.
+ * @param configChanged Whether to dispatch config changed events. Must be one of the
+ * CONFIG_CHANGED_EVENT_* values.
*/
- public DisplayEventReceiver(Looper looper, int vsyncSource) {
+ public DisplayEventReceiver(Looper looper, int vsyncSource, int configChanged) {
if (looper == null) {
throw new IllegalArgumentException("looper must not be null");
}
mMessageQueue = looper.getQueue();
mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue,
- vsyncSource);
+ vsyncSource, configChanged);
mCloseGuard.open("dispose");
}
diff --git a/core/java/android/view/IWindow.aidl b/core/java/android/view/IWindow.aidl
index 699e795be980..f34f9e6d5ce8 100644
--- a/core/java/android/view/IWindow.aidl
+++ b/core/java/android/view/IWindow.aidl
@@ -17,6 +17,7 @@
package android.view;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -57,6 +58,12 @@ oneway interface IWindow {
in DisplayCutout.ParcelableWrapper displayCutout);
/**
+ * Called when the window location in parent display has changed. The offset will only be a
+ * nonzero value if the window is on an embedded display that is re-parented to another window.
+ */
+ void locationInParentDisplayChanged(in Point offset);
+
+ /**
* Called when the window insets configuration has changed.
*/
void insetsChanged(in InsetsState insetsState);
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index cb64ab1fd921..17f07b5a2ad4 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.UnsupportedAppUsage;
import android.content.res.CompatibilityInfo.Translator;
import android.graphics.Canvas;
+import android.graphics.ColorSpace;
import android.graphics.GraphicBuffer;
import android.graphics.Matrix;
import android.graphics.RecordingCanvas;
@@ -80,7 +81,8 @@ public class Surface implements Parcelable {
private static native long nativeGetNextFrameNumber(long nativeObject);
private static native int nativeSetScalingMode(long nativeObject, int scalingMode);
private static native int nativeForceScopedDisconnect(long nativeObject);
- private static native int nativeAttachAndQueueBuffer(long nativeObject, GraphicBuffer buffer);
+ private static native int nativeAttachAndQueueBufferWithColorSpace(long nativeObject,
+ GraphicBuffer buffer, int colorSpaceId);
private static native int nativeSetSharedBufferModeEnabled(long nativeObject, boolean enabled);
private static native int nativeSetAutoRefreshEnabled(long nativeObject, boolean enabled);
@@ -699,21 +701,38 @@ public class Surface implements Parcelable {
}
/**
- * Transfer ownership of buffer and present it on the Surface.
+ * Transfer ownership of buffer with a color space and present it on the Surface.
+ * The supported color spaces are SRGB and Display P3, other color spaces will be
+ * treated as SRGB.
* @hide
*/
- public void attachAndQueueBuffer(GraphicBuffer buffer) {
+ public void attachAndQueueBufferWithColorSpace(GraphicBuffer buffer, ColorSpace colorSpace) {
synchronized (mLock) {
checkNotReleasedLocked();
- int err = nativeAttachAndQueueBuffer(mNativeObject, buffer);
+ if (colorSpace == null) {
+ colorSpace = ColorSpace.get(ColorSpace.Named.SRGB);
+ }
+ int err = nativeAttachAndQueueBufferWithColorSpace(mNativeObject, buffer,
+ colorSpace.getId());
if (err != 0) {
throw new RuntimeException(
- "Failed to attach and queue buffer to Surface (bad object?)");
+ "Failed to attach and queue buffer to Surface (bad object?), "
+ + "native error: " + err);
}
}
}
/**
+ * Deprecated, use attachAndQueueBufferWithColorSpace instead.
+ * Transfer ownership of buffer and present it on the Surface.
+ * The color space of the buffer is treated as SRGB.
+ * @hide
+ */
+ public void attachAndQueueBuffer(GraphicBuffer buffer) {
+ attachAndQueueBufferWithColorSpace(buffer, ColorSpace.get(ColorSpace.Named.SRGB));
+ }
+
+ /**
* Returns whether or not this Surface is backed by a single-buffered SurfaceTexture
* @hide
*/
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 63e14853b51d..3c045f4fdb88 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -1866,7 +1866,8 @@ public final class SurfaceControl implements Parcelable {
final ScreenshotGraphicBuffer buffer = screenshotToBuffer(display, sourceCrop, width,
height, useIdentityTransform, rotation);
try {
- consumer.attachAndQueueBuffer(buffer.getGraphicBuffer());
+ consumer.attachAndQueueBufferWithColorSpace(buffer.getGraphicBuffer(),
+ buffer.getColorSpace());
} catch (RuntimeException e) {
Log.w(TAG, "Failed to take screenshot - " + e.getMessage());
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index bf6191ec61eb..fd4dafc81f36 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -1377,6 +1377,74 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public static final int AUTOFILL_FLAG_INCLUDE_NOT_IMPORTANT_VIEWS = 0x1;
+ /** @hide */
+ @IntDef(prefix = { "IMPORTANT_FOR_CONTENT_CAPTURE_" }, value = {
+ IMPORTANT_FOR_CONTENT_CAPTURE_AUTO,
+ IMPORTANT_FOR_CONTENT_CAPTURE_YES,
+ IMPORTANT_FOR_CONTENT_CAPTURE_NO,
+ IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS,
+ IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ContentCaptureImportance {}
+
+ /**
+ * Automatically determine whether a view is important for content capture.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ *
+ * @hide
+ */
+ @TestApi
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_AUTO = 0x0;
+
+ /**
+ * The view is important for content capture, and its children (if any) will be traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ *
+ * @hide
+ */
+ @TestApi
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES = 0x1;
+
+ /**
+ * The view is not important for content capture, but its children (if any) will be traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ *
+ * @hide
+ */
+ @TestApi
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO = 0x2;
+
+ /**
+ * The view is important for content capture, but its children (if any) will not be traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ *
+ * @hide
+ */
+ @TestApi
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS = 0x4;
+
+ /**
+ * The view is not important for content capture, and its children (if any) will not be
+ * traversed.
+ *
+ * @see #isImportantForContentCapture()
+ * @see #setImportantForContentCapture(int)
+ *
+ * @hide
+ */
+ @TestApi
+ public static final int IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS = 0x8;
+
+
/**
* This view is enabled. Interpretation varies by subclass.
* Use with ENABLED_MASK when calling setFlags.
@@ -3349,6 +3417,55 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
/* End of masks for mPrivateFlags3 */
+ /*
+ * Masks for mPrivateFlags4, as generated by dumpFlags():
+ *
+ * |-------|-------|-------|-------|
+ * 1111 PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK
+ * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED
+ * 1 PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED
+ * 1 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED
+ * 1 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE
+ * 11 PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK
+ * |-------|-------|-------|-------|
+ */
+
+ /**
+ * Mask for obtaining the bits which specify how to determine
+ * whether a view is important for autofill.
+ *
+ * <p>NOTE: the important for content capture values were the first flags added and are set in
+ * the rightmost position, so we don't need to shift them
+ */
+ private static final int PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK =
+ IMPORTANT_FOR_CONTENT_CAPTURE_AUTO | IMPORTANT_FOR_CONTENT_CAPTURE_YES
+ | IMPORTANT_FOR_CONTENT_CAPTURE_NO
+ | IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS
+ | IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS;
+
+ /*
+ * Variables used to control when the IntelligenceManager.notifyNodeAdded()/removed() methods
+ * should be called.
+ *
+ * The idea is to call notifyAppeared() after the view is layout and visible, then call
+ * notifyDisappeared() when it's gone (without known when it was removed from the parent).
+ */
+ private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED = 0x10;
+ private static final int PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED = 0x20;
+
+ /*
+ * Flags used to cache the value returned by isImportantForContentCapture while the view
+ * hierarchy is being traversed.
+ */
+ private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED = 0x40;
+ private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE = 0x80;
+
+ private static final int PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK =
+ PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED
+ | PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE;
+
+ /* End of masks for mPrivateFlags4 */
+
/** @hide */
protected static final int VIEW_STRUCTURE_FOR_ASSIST = 0;
/** @hide */
@@ -3972,6 +4089,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 129147060)
int mPrivateFlags3;
+ private int mPrivateFlags4;
+
/**
* This view's request for the visibility of the status bar.
* @hide
@@ -8427,6 +8546,65 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
onProvideStructure(structure, VIEW_STRUCTURE_FOR_AUTOFILL, flags);
}
+ /**
+ * Populates a {@link ViewStructure} for content capture.
+ *
+ * <p>This method is called after a view is that is eligible for content capture
+ * (for example, if it {@link #isImportantForAutofill()}, an intelligence service is enabled for
+ * the user, and the activity rendering the view is enabled for content capture) is laid out and
+ * is visible.
+ *
+ * <p>The populated structure is then passed to the service through
+ * {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)}.
+ *
+ * <p><b>Note: </b>views that manage a virtual structure under this view must populate just
+ * the node representing this view and return right away, then asynchronously report (not
+ * necessarily in the UI thread) when the children nodes appear, disappear or have their text
+ * changed by calling
+ * {@link ContentCaptureSession#notifyViewAppeared(ViewStructure)},
+ * {@link ContentCaptureSession#notifyViewDisappeared(AutofillId)}, and
+ * {@link ContentCaptureSession#notifyViewTextChanged(AutofillId, CharSequence)}
+ * respectively. The structure for the a child must be created using
+ * {@link ContentCaptureSession#newVirtualViewStructure(AutofillId, long)}, and the
+ * {@code autofillId} for a child can be obtained either through
+ * {@code childStructure.getAutofillId()} or
+ * {@link ContentCaptureSession#newAutofillId(AutofillId, long)}.
+ *
+ * <p>When the virtual view hierarchy represents a web page, you should also:
+ *
+ * <ul>
+ * <li>Call {@link ContentCaptureManager#getContentCaptureConditions()} to infer content
+ * capture events should be generate for that URL.
+ * <li>Create a new {@link ContentCaptureSession} child for every HTML element that
+ * renders a new URL (like an {@code IFRAME}) and use that session to notify events from
+ * that subtree.
+ * </ul>
+ *
+ * <p><b>Note: </b>the following methods of the {@code structure} will be ignored:
+ * <ul>
+ * <li>{@link ViewStructure#setChildCount(int)}
+ * <li>{@link ViewStructure#addChildCount(int)}
+ * <li>{@link ViewStructure#getChildCount()}
+ * <li>{@link ViewStructure#newChild(int)}
+ * <li>{@link ViewStructure#asyncNewChild(int)}
+ * <li>{@link ViewStructure#asyncCommit()}
+ * <li>{@link ViewStructure#setWebDomain(String)}
+ * <li>{@link ViewStructure#newHtmlInfoBuilder(String)}
+ * <li>{@link ViewStructure#setHtmlInfo(android.view.ViewStructure.HtmlInfo)}
+ * <li>{@link ViewStructure#setDataIsSensitive(boolean)}
+ * <li>{@link ViewStructure#setAlpha(float)}
+ * <li>{@link ViewStructure#setElevation(float)}
+ * <li>{@link ViewStructure#setTransformation(Matrix)}
+ *
+ * </ul>
+ *
+ * @hide
+ */
+ @TestApi
+ public void onProvideContentCaptureStructure(@NonNull ViewStructure structure, int flags) {
+ onProvideStructure(structure, VIEW_STRUCTURE_FOR_CONTENT_CAPTURE, flags);
+ }
+
/** @hide */
protected void onProvideStructure(@NonNull ViewStructure structure,
@ViewStructureType int viewFor, int flags) {
@@ -9065,6 +9243,280 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Gets the mode for determining whether this view is important for content capture.
+ *
+ * <p>See {@link #setImportantForContentCapture(int)} and
+ * {@link #isImportantForContentCapture()} for more info about this mode.
+ *
+ * @return {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO} by default, or value passed to
+ * {@link #setImportantForContentCapture(int)}.
+ *
+ * @attr ref android.R.styleable#View_importantForContentCapture
+ *
+ * @hide
+ */
+ @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, to = "auto"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES, to = "yes"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO, to = "no"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS,
+ to = "yesExcludeDescendants"),
+ @ViewDebug.IntToString(from = IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS,
+ to = "noExcludeDescendants")})
+// @InspectableProperty(enumMapping = {
+// @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_AUTO, name = "auto"),
+// @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_YES, name = "yes"),
+// @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_NO, name = "no"),
+// @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS,
+// name = "yesExcludeDescendants"),
+// @EnumEntry(value = IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS,
+// name = "noExcludeDescendants"),
+// })
+ @TestApi
+ public @ContentCaptureImportance int getImportantForContentCapture() {
+ // NOTE: the important for content capture values were the first flags added and are set in
+ // the rightmost position, so we don't need to shift them
+ return mPrivateFlags4 & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK;
+ }
+
+ /**
+ * Sets the mode for determining whether this view is considered important for content capture.
+ *
+ * <p>The platform determines the importance for autofill automatically but you
+ * can use this method to customize the behavior. Typically, a view that provides text should
+ * be marked as {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}.
+ *
+ * @param mode {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO},
+ * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES}, {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO},
+ * {@link #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS},
+ * or {@link #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS}.
+ *
+ * @attr ref android.R.styleable#View_importantForContentCapture
+ *
+ * @hide
+ */
+ @TestApi
+ public void setImportantForContentCapture(@ContentCaptureImportance int mode) {
+ // Reset first
+ mPrivateFlags4 &= ~PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK;
+ // Then set again
+ // NOTE: the important for content capture values were the first flags added and are set in
+ // the rightmost position, so we don't need to shift them
+ mPrivateFlags4 |= (mode & PFLAG4_IMPORTANT_FOR_CONTENT_CAPTURE_MASK);
+ }
+
+ /**
+ * Hints the Android System whether this view is considered important for content capture, based
+ * on the value explicitly set by {@link #setImportantForContentCapture(int)} and heuristics
+ * when it's {@link #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO}.
+ *
+ * <p>See {@link ContentCaptureManager} for more info about content capture.
+ *
+ * @return whether the view is considered important for content capture.
+ *
+ * @see #setImportantForContentCapture(int)
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_AUTO
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS
+ * @see #IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ *
+ * @hide
+ */
+ @TestApi
+ public final boolean isImportantForContentCapture() {
+ boolean isImportant;
+ if ((mPrivateFlags4 & PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED) != 0) {
+ isImportant = (mPrivateFlags4 & PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE) != 0;
+ return isImportant;
+ }
+
+ isImportant = calculateIsImportantForContentCapture();
+
+ mPrivateFlags4 &= ~PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE;
+ if (isImportant) {
+ mPrivateFlags4 |= PFLAG4_CONTENT_CAPTURE_IMPORTANCE_CACHED_VALUE;
+ }
+ mPrivateFlags4 |= PFLAG4_CONTENT_CAPTURE_IMPORTANCE_IS_CACHED;
+ return isImportant;
+ }
+
+ /**
+ * Calculates whether the flag is important for content capture so it can be used by
+ * {@link #isImportantForContentCapture()} while the tree is traversed.
+ */
+ private boolean calculateIsImportantForContentCapture() {
+ // Check parent mode to ensure we're important
+ ViewParent parent = mParent;
+ while (parent instanceof View) {
+ final int parentImportance = ((View) parent).getImportantForContentCapture();
+ if (parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ || parentImportance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for "
+ + "content capture because parent " + parent + "'s importance is "
+ + parentImportance);
+ }
+ return false;
+ }
+ parent = parent.getParent();
+ }
+
+ final int importance = getImportantForContentCapture();
+
+ // First, check the explicit states.
+ if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES_EXCLUDE_DESCENDANTS
+ || importance == IMPORTANT_FOR_CONTENT_CAPTURE_YES) {
+ return true;
+ }
+ if (importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO_EXCLUDE_DESCENDANTS
+ || importance == IMPORTANT_FOR_CONTENT_CAPTURE_NO) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.VERBOSE)) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "View (" + this + ") is not important for content "
+ + "capture because its importance is " + importance);
+ }
+ return false;
+ }
+
+ // Then use some heuristics to handle AUTO.
+ if (importance != IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) {
+ Log.w(CONTENT_CAPTURE_LOG_TAG, "invalid content capture importance (" + importance
+ + " on view " + this);
+ return false;
+ }
+
+ // View group is important if at least one children also is
+ if (this instanceof ViewGroup) {
+ final ViewGroup group = (ViewGroup) this;
+ for (int i = 0; i < group.getChildCount(); i++) {
+ final View child = group.getChildAt(i);
+ if (child.isImportantForContentCapture()) {
+ return true;
+ }
+ }
+ }
+
+ // If the app developer explicitly set hints or autofill hintsfor it, it's important.
+ if (getAutofillHints() != null) {
+ return true;
+ }
+
+ // Otherwise, assume it's not important...
+ return false;
+ }
+
+ /**
+ * Helper used to notify the {@link ContentCaptureManager} when the view is removed or
+ * added, based on whether it's laid out and visible, and without knowing if the parent removed
+ * it from the view hierarchy.
+ *
+ * <p>This method is called from many places (visibility changed, view laid out, view attached
+ * or detached to/from window, etc...) and hence must contain the logic to call the manager, as
+ * described below:
+ *
+ * <ol>
+ * <li>It should only be called when content capture is enabled for the view.
+ * <li>It must call viewAppeared() before viewDisappeared()
+ * <li>viewAppearead() can only be called when the view is visible and laidout
+ * <li>It should not call the same event twice.
+ * </ol>
+ */
+ private void notifyAppearedOrDisappearedForContentCaptureIfNeeded(boolean appeared) {
+ AttachInfo ai = mAttachInfo;
+ // Skip it while the view is being laided out for the first time
+ if (ai != null && !ai.mReadyForContentCaptureUpdates) return;
+
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW,
+ "notifyContentCapture(" + appeared + ") for " + getClass().getSimpleName());
+ }
+ try {
+ notifyAppearedOrDisappearedForContentCaptureIfNeededNoTrace(appeared);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
+ }
+
+ private void notifyAppearedOrDisappearedForContentCaptureIfNeededNoTrace(boolean appeared) {
+ AttachInfo ai = mAttachInfo;
+
+ // First check if context has client, so it saves a service lookup when it doesn't
+ if (mContext.getContentCaptureOptions() == null) return;
+
+ // Then check if it's enabled in the context...
+ final ContentCaptureManager ccm = ai != null ? ai.getContentCaptureManager(mContext)
+ : mContext.getSystemService(ContentCaptureManager.class);
+ if (ccm == null || !ccm.isContentCaptureEnabled()) return;
+
+ // ... and finally at the view level
+ // NOTE: isImportantForContentCapture() is more expensive than cm.isContentCaptureEnabled()
+ if (!isImportantForContentCapture()) return;
+
+ ContentCaptureSession session = getContentCaptureSession();
+ if (session == null) return;
+
+ if (appeared) {
+ if (!isLaidOut() || getVisibility() != VISIBLE
+ || (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0) {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'appeared' on " + this + ": laid="
+ + isLaidOut() + ", visibleToUser=" + isVisibleToUser()
+ + ", visible=" + (getVisibility() == VISIBLE)
+ + ": alreadyNotifiedAppeared=" + ((mPrivateFlags4
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0)
+ + ", alreadyNotifiedDisappeared=" + ((mPrivateFlags4
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0));
+ }
+ return;
+ }
+ setNotifiedContentCaptureAppeared();
+
+ if (ai != null) {
+ ai.delayNotifyContentCaptureEvent(session, this, appeared);
+ } else {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.w(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on appeared for " + this);
+ }
+ }
+ } else {
+ if ((mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) == 0
+ || (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0) {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "Ignoring 'disappeared' on " + this + ": laid="
+ + isLaidOut() + ", visibleToUser=" + isVisibleToUser()
+ + ", visible=" + (getVisibility() == VISIBLE)
+ + ": alreadyNotifiedAppeared=" + ((mPrivateFlags4
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0)
+ + ", alreadyNotifiedDisappeared=" + ((mPrivateFlags4
+ & PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED) != 0));
+ }
+ return;
+ }
+ mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
+ mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
+
+ if (ai != null) {
+ ai.delayNotifyContentCaptureEvent(session, this, appeared);
+ } else {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.v(CONTENT_CAPTURE_LOG_TAG, "no AttachInfo on disappeared for " + this);
+ }
+ }
+ }
+ }
+
+ private void setNotifiedContentCaptureAppeared() {
+ mPrivateFlags4 |= PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED;
+ mPrivateFlags4 &= ~PFLAG4_NOTIFIED_CONTENT_CAPTURE_DISAPPEARED;
+ }
+
+ /** @hide */
+ protected boolean getNotifiedContentCaptureAppeared() {
+ return (mPrivateFlags4 & PFLAG4_NOTIFIED_CONTENT_CAPTURE_APPEARED) != 0;
+ }
+
+
+ /**
* Sets the (optional) {@link ContentCaptureSession} associated with this view.
*
* <p>This method should be called when you need to associate a {@link ContentCaptureContext} to
@@ -9317,6 +9769,68 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
+ * Dispatches the initial content capture events for a view structure.
+ *
+ * @hide
+ */
+ public void dispatchInitialProvideContentCaptureStructure() {
+ AttachInfo ai = mAttachInfo;
+ if (ai == null) {
+ Log.w(CONTENT_CAPTURE_LOG_TAG,
+ "dispatchProvideContentCaptureStructure(): no AttachInfo for " + this);
+ return;
+ }
+ ContentCaptureManager ccm = ai.mContentCaptureManager;
+ if (ccm == null) {
+ Log.w(CONTENT_CAPTURE_LOG_TAG, "dispatchProvideContentCaptureStructure(): "
+ + "no ContentCaptureManager for " + this);
+ return;
+ }
+
+ // We must set it before checkign if the view itself is important, because it might
+ // initially not be (for example, if it's empty), although that might change later (for
+ // example, if important views are added)
+ ai.mReadyForContentCaptureUpdates = true;
+
+ if (!isImportantForContentCapture()) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.DEBUG)) {
+ Log.d(CONTENT_CAPTURE_LOG_TAG,
+ "dispatchProvideContentCaptureStructure(): decorView is not important");
+ }
+ return;
+ }
+
+ ai.mContentCaptureManager = ccm;
+
+ ContentCaptureSession session = getContentCaptureSession();
+ if (session == null) {
+ if (Log.isLoggable(CONTENT_CAPTURE_LOG_TAG, Log.DEBUG)) {
+ Log.d(CONTENT_CAPTURE_LOG_TAG,
+ "dispatchProvideContentCaptureStructure(): no session for " + this);
+ }
+ return;
+ }
+
+ session.internalNotifyViewTreeEvent(/* started= */ true);
+ try {
+ dispatchProvideContentCaptureStructure();
+ } finally {
+ session.internalNotifyViewTreeEvent(/* started= */ false);
+ }
+ }
+
+ /** @hide */
+ void dispatchProvideContentCaptureStructure() {
+ ContentCaptureSession session = getContentCaptureSession();
+ if (session != null) {
+ ViewStructure structure = session.newViewStructure(this);
+ onProvideContentCaptureStructure(structure, /* flags= */ 0);
+ setNotifiedContentCaptureAppeared();
+ session.notifyViewAppeared(structure);
+ }
+ }
+
+ /**
* @see #onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)
*
* Note: Called from the default {@link AccessibilityDelegate}.
@@ -13266,6 +13780,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void dispatchStartTemporaryDetach() {
mPrivateFlags3 |= PFLAG3_TEMPORARY_DETACH;
notifyEnterOrExitForAutoFillIfNeeded(false);
+ notifyAppearedOrDisappearedForContentCaptureIfNeeded(false);
onStartTemporaryDetach();
}
@@ -13292,6 +13807,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
notifyFocusChangeToInputMethodManager(true /* hasFocus */);
}
notifyEnterOrExitForAutoFillIfNeeded(true);
+ notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
}
/**
@@ -13883,6 +14399,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
: AccessibilityEvent.CONTENT_CHANGE_TYPE_PANE_DISAPPEARED);
}
}
+
+ notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible);
}
/**
@@ -17578,6 +18096,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
// Reset content capture caches
+ mPrivateFlags4 &= ~PFLAG4_CONTENT_CAPTURE_IMPORTANCE_MASK;
mCachedContentCaptureSession = null;
if ((mPrivateFlags & (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)) == (PFLAG_DRAWN | PFLAG_HAS_BOUNDS)
@@ -19587,6 +20106,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
needGlobalAttributesUpdate(false);
notifyEnterOrExitForAutoFillIfNeeded(true);
+ notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
@@ -19636,6 +20156,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
notifyEnterOrExitForAutoFillIfNeeded(false);
+ notifyAppearedOrDisappearedForContentCaptureIfNeeded(false);
}
/**
@@ -21970,6 +22491,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mPrivateFlags3 &= ~PFLAG3_NOTIFY_AUTOFILL_ENTER_ON_LAYOUT;
notifyEnterOrExitForAutoFillIfNeeded(true);
}
+
+ notifyAppearedOrDisappearedForContentCaptureIfNeeded(true);
}
private boolean hasParentWantsFocus() {
@@ -28035,6 +28558,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
boolean mHandlingPointerEvent;
/**
+ * The offset of this view's window when it's on an embedded display that is re-parented
+ * to another window.
+ */
+ final Point mLocationInParentDisplay = new Point();
+
+ /**
* Global to the view hierarchy used as a temporary for dealing with
* x/y points in the transparent region computations.
*/
@@ -28181,6 +28710,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
View mTooltipHost;
/**
+ * The initial structure has been reported so the view is ready to report updates.
+ */
+ boolean mReadyForContentCaptureUpdates;
+
+ /**
+ * Map(keyed by session) of content capture events that need to be notified after the view
+ * hierarchy is traversed: value is either the view itself for appearead events, or its
+ * autofill id for disappeared.
+ */
+ SparseArray<ArrayList<Object>> mContentCaptureEvents;
+
+ /**
+ * Cached reference to the {@link ContentCaptureManager}.
+ */
+ ContentCaptureManager mContentCaptureManager;
+
+ /**
* Creates a new set of attachment information with the specified
* events handler and thread.
*
@@ -28198,6 +28744,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
mRootCallbacks = effectPlayer;
mTreeObserver = new ViewTreeObserver(context);
}
+
+ private void delayNotifyContentCaptureEvent(@NonNull ContentCaptureSession session,
+ @NonNull View view, boolean appeared) {
+ if (mContentCaptureEvents == null) {
+ // Most of the time there will be just one session, so intial capacity is 1
+ mContentCaptureEvents = new SparseArray<>(1);
+ }
+ int sessionId = session.getId();
+ // TODO: life would be much easier if we provided a MultiMap implementation somwhere...
+ ArrayList<Object> events = mContentCaptureEvents.get(sessionId);
+ if (events == null) {
+ events = new ArrayList<>();
+ mContentCaptureEvents.put(sessionId, events);
+ }
+ events.add(appeared ? view : view.getAutofillId());
+ }
+
+ @Nullable
+ ContentCaptureManager getContentCaptureManager(@NonNull Context context) {
+ if (mContentCaptureManager != null) {
+ return mContentCaptureManager;
+ }
+ mContentCaptureManager = context.getSystemService(ContentCaptureManager.class);
+ return mContentCaptureManager;
+ }
}
/**
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d362024ed525..937bd1b34e61 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -3606,7 +3606,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
return;
}
- final ChildListForAutofill children = getChildrenForAutofill(flags);
+ final ChildListForAutoFillOrContentCapture children = getChildrenForAutofill(flags);
final int childrenCount = children.size();
structure.setChildCount(childrenCount);
for (int i = 0; i < childrenCount; i++) {
@@ -3617,14 +3617,30 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
children.recycle();
}
+ /** @hide */
+ @Override
+ public void dispatchProvideContentCaptureStructure() {
+ super.dispatchProvideContentCaptureStructure();
+
+ if (!isLaidOut()) return;
+
+ final ChildListForAutoFillOrContentCapture children = getChildrenForContentCapture();
+ final int childrenCount = children.size();
+ for (int i = 0; i < childrenCount; i++) {
+ final View child = children.get(i);
+ child.dispatchProvideContentCaptureStructure();
+ }
+ children.recycle();
+ }
+
/**
* Gets the children for autofill. Children for autofill are the first
* level descendants that are important for autofill. The returned
* child list object is pooled and the caller must recycle it once done.
* @hide */
- private @NonNull ChildListForAutofill getChildrenForAutofill(
+ private @NonNull ChildListForAutoFillOrContentCapture getChildrenForAutofill(
@AutofillFlags int flags) {
- final ChildListForAutofill children = ChildListForAutofill
+ final ChildListForAutoFillOrContentCapture children = ChildListForAutoFillOrContentCapture
.obtain();
populateChildrenForAutofill(children, flags);
return children;
@@ -3652,6 +3668,34 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
}
}
+ private @NonNull ChildListForAutoFillOrContentCapture getChildrenForContentCapture() {
+ final ChildListForAutoFillOrContentCapture children = ChildListForAutoFillOrContentCapture
+ .obtain();
+ populateChildrenForContentCapture(children);
+ return children;
+ }
+
+ /** @hide */
+ private void populateChildrenForContentCapture(ArrayList<View> list) {
+ final int childrenCount = mChildrenCount;
+ if (childrenCount <= 0) {
+ return;
+ }
+ final ArrayList<View> preorderedList = buildOrderedChildList();
+ final boolean customOrder = preorderedList == null
+ && isChildrenDrawingOrderEnabled();
+ for (int i = 0; i < childrenCount; i++) {
+ final int childIndex = getAndVerifyPreorderedIndex(childrenCount, i, customOrder);
+ final View child = (preorderedList == null)
+ ? mChildren[childIndex] : preorderedList.get(childIndex);
+ if (child.isImportantForContentCapture()) {
+ list.add(child);
+ } else if (child instanceof ViewGroup) {
+ ((ViewGroup) child).populateChildrenForContentCapture(list);
+ }
+ }
+ }
+
private static View getAndVerifyPreorderedView(ArrayList<View> preorderedList, View[] children,
int childIndex) {
final View child;
@@ -8634,16 +8678,16 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
/**
* Pooled class that to hold the children for autifill.
*/
- private static class ChildListForAutofill extends ArrayList<View> {
+ private static class ChildListForAutoFillOrContentCapture extends ArrayList<View> {
private static final int MAX_POOL_SIZE = 32;
- private static final Pools.SimplePool<ChildListForAutofill> sPool =
+ private static final Pools.SimplePool<ChildListForAutoFillOrContentCapture> sPool =
new Pools.SimplePool<>(MAX_POOL_SIZE);
- public static ChildListForAutofill obtain() {
- ChildListForAutofill list = sPool.acquire();
+ public static ChildListForAutoFillOrContentCapture obtain() {
+ ChildListForAutoFillOrContentCapture list = sPool.acquire();
if (list == null) {
- list = new ChildListForAutofill();
+ list = new ChildListForAutoFillOrContentCapture();
}
return list;
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index aceb276e9fc0..440df89f814f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -105,7 +105,11 @@ import android.view.accessibility.IAccessibilityInteractionConnection;
import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Interpolator;
+import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
+import android.view.contentcapture.ContentCaptureManager;
+import android.view.contentcapture.ContentCaptureSession;
+import android.view.contentcapture.MainContentCaptureSession;
import android.view.inputmethod.InputMethodManager;
import android.widget.Scroller;
@@ -220,6 +224,21 @@ public final class ViewRootImpl implements ViewParent,
*/
static final int MAX_TRACKBALL_DELAY = 250;
+ /**
+ * Initial value for {@link #mContentCaptureEnabled}.
+ */
+ private static final int CONTENT_CAPTURE_ENABLED_NOT_CHECKED = 0;
+
+ /**
+ * Value for {@link #mContentCaptureEnabled} when it was checked and set to {@code true}.
+ */
+ private static final int CONTENT_CAPTURE_ENABLED_TRUE = 1;
+
+ /**
+ * Value for {@link #mContentCaptureEnabled} when it was checked and set to {@code false}.
+ */
+ private static final int CONTENT_CAPTURE_ENABLED_FALSE = 2;
+
@UnsupportedAppUsage
static final ThreadLocal<HandlerActionQueue> sRunQueues = new ThreadLocal<HandlerActionQueue>();
@@ -410,6 +429,10 @@ public final class ViewRootImpl implements ViewParent,
boolean mLayoutRequested;
boolean mFirst;
+ @Nullable
+ int mContentCaptureEnabled = CONTENT_CAPTURE_ENABLED_NOT_CHECKED;
+ boolean mPerformContentCapture;
+
boolean mReportNextDraw;
boolean mFullRedrawNeeded;
boolean mNewSurfaceNeeded;
@@ -607,6 +630,7 @@ public final class ViewRootImpl implements ViewParent,
mTransparentRegion = new Region();
mPreviousTransparentRegion = new Region();
mFirst = true; // true for the first time the view is added
+ mPerformContentCapture = true; // also true for the first time the view is added
mAdded = false;
mAttachInfo = new View.AttachInfo(mWindowSession, mWindow, display, this, mHandler, this,
context);
@@ -2765,9 +2789,55 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ if (mAttachInfo.mContentCaptureEvents != null) {
+ notifyContentCatpureEvents();
+ }
+
mIsInTraversal = false;
}
+ private void notifyContentCatpureEvents() {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "notifyContentCaptureEvents");
+ try {
+ MainContentCaptureSession mainSession = mAttachInfo.mContentCaptureManager
+ .getMainContentCaptureSession();
+ for (int i = 0; i < mAttachInfo.mContentCaptureEvents.size(); i++) {
+ int sessionId = mAttachInfo.mContentCaptureEvents.keyAt(i);
+ mainSession.notifyViewTreeEvent(sessionId, /* started= */ true);
+ ArrayList<Object> events = mAttachInfo.mContentCaptureEvents
+ .valueAt(i);
+ for_each_event: for (int j = 0; j < events.size(); j++) {
+ Object event = events.get(j);
+ if (event instanceof AutofillId) {
+ mainSession.notifyViewDisappeared(sessionId, (AutofillId) event);
+ } else if (event instanceof View) {
+ View view = (View) event;
+ ContentCaptureSession session = view.getContentCaptureSession();
+ if (session == null) {
+ Log.w(mTag, "no content capture session on view: " + view);
+ continue for_each_event;
+ }
+ int actualId = session.getId();
+ if (actualId != sessionId) {
+ Log.w(mTag, "content capture session mismatch for view (" + view
+ + "): was " + sessionId + " before, it's " + actualId + " now");
+ continue for_each_event;
+ }
+ ViewStructure structure = session.newViewStructure(view);
+ view.onProvideContentCaptureStructure(structure, /* flags= */ 0);
+ session.notifyViewAppeared(structure);
+ } else {
+ Log.w(mTag, "invalid content capture event: " + event);
+ }
+ }
+ mainSession.notifyViewTreeEvent(sessionId, /* started= */ false);
+ }
+ mAttachInfo.mContentCaptureEvents = null;
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
+ }
+
private void notifySurfaceDestroyed() {
mSurfaceHolder.ungetCallbacks();
SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
@@ -2902,6 +2972,13 @@ public final class ViewRootImpl implements ViewParent,
}
}
mFirstInputStage.onWindowFocusChanged(hasWindowFocus);
+
+ // NOTE: there's no view visibility (appeared / disapparead) events when the windows focus
+ // is lost, so we don't need to to force a flush - there might be other events such as
+ // text changes, but these should be flushed independently.
+ if (hasWindowFocus) {
+ handleContentCaptureFlush();
+ }
}
private void fireAccessibilityFocusEventIfHasFocusedNode() {
@@ -3468,6 +3545,86 @@ public final class ViewRootImpl implements ViewParent,
pendingDrawFinished();
}
}
+ if (mPerformContentCapture) {
+ performContentCaptureInitialReport();
+ }
+ }
+
+ /**
+ * Checks (and caches) if content capture is enabled for this context.
+ */
+ private boolean isContentCaptureEnabled() {
+ switch (mContentCaptureEnabled) {
+ case CONTENT_CAPTURE_ENABLED_TRUE:
+ return true;
+ case CONTENT_CAPTURE_ENABLED_FALSE:
+ return false;
+ case CONTENT_CAPTURE_ENABLED_NOT_CHECKED:
+ final boolean reallyEnabled = isContentCaptureReallyEnabled();
+ mContentCaptureEnabled = reallyEnabled ? CONTENT_CAPTURE_ENABLED_TRUE
+ : CONTENT_CAPTURE_ENABLED_FALSE;
+ return reallyEnabled;
+ default:
+ Log.w(TAG, "isContentCaptureEnabled(): invalid state " + mContentCaptureEnabled);
+ return false;
+ }
+
+ }
+
+ /**
+ * Checks (without caching) if content capture is enabled for this context.
+ */
+ private boolean isContentCaptureReallyEnabled() {
+ // First check if context supports it, so it saves a service lookup when it doesn't
+ if (mContext.getContentCaptureOptions() == null) return false;
+
+ final ContentCaptureManager ccm = mAttachInfo.getContentCaptureManager(mContext);
+ // Then check if it's enabled in the contex itself.
+ if (ccm == null || !ccm.isContentCaptureEnabled()) return false;
+
+ return true;
+ }
+
+ private void performContentCaptureInitialReport() {
+ mPerformContentCapture = false; // One-time offer!
+ final View rootView = mView;
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.v(mTag, "performContentCaptureInitialReport() on " + rootView);
+ }
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "dispatchContentCapture() for "
+ + getClass().getSimpleName());
+ }
+ try {
+ if (!isContentCaptureEnabled()) return;
+
+ // Content capture is a go!
+ rootView.dispatchInitialProvideContentCaptureStructure();
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
+ }
+
+ private void handleContentCaptureFlush() {
+ if (DEBUG_CONTENT_CAPTURE) {
+ Log.v(mTag, "handleContentCaptureFlush()");
+ }
+ if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
+ Trace.traceBegin(Trace.TRACE_TAG_VIEW, "flushContentCapture for "
+ + getClass().getSimpleName());
+ }
+ try {
+ if (!isContentCaptureEnabled()) return;
+
+ final ContentCaptureManager ccm = mAttachInfo.mContentCaptureManager;
+ if (ccm == null) {
+ Log.w(TAG, "No ContentCapture on AttachInfo");
+ return;
+ }
+ ccm.flush(ContentCaptureSession.FLUSH_REASON_VIEW_ROOT_ENTERED);
+ } finally {
+ Trace.traceEnd(Trace.TRACE_TAG_VIEW);
+ }
}
private boolean draw(boolean fullRedrawNeeded) {
@@ -3834,6 +3991,13 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ void updateLocationInParentDisplay(int x, int y) {
+ if (mAttachInfo != null
+ && !mAttachInfo.mLocationInParentDisplay.equals(x, y)) {
+ mAttachInfo.mLocationInParentDisplay.set(x, y);
+ }
+ }
+
/**
* Set the root-level system gesture exclusion rects. These are added to those provided by
* the root's view hierarchy.
@@ -4338,6 +4502,7 @@ public final class ViewRootImpl implements ViewParent,
private static final int MSG_INSETS_CHANGED = 30;
private static final int MSG_INSETS_CONTROL_CHANGED = 31;
private static final int MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED = 32;
+ private static final int MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED = 33;
final class ViewRootHandler extends Handler {
@Override
@@ -4399,6 +4564,8 @@ public final class ViewRootImpl implements ViewParent,
return "MSG_INSETS_CONTROL_CHANGED";
case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED:
return "MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED";
+ case MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED:
+ return "MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED";
}
return super.getMessageName(message);
}
@@ -4634,6 +4801,9 @@ public final class ViewRootImpl implements ViewParent,
case MSG_SYSTEM_GESTURE_EXCLUSION_CHANGED: {
systemGestureExclusionChanged();
} break;
+ case MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED: {
+ updateLocationInParentDisplay(msg.arg1, msg.arg2);
+ } break;
}
}
}
@@ -7840,6 +8010,17 @@ public final class ViewRootImpl implements ViewParent,
mHandler.sendMessage(msg);
}
+ /**
+ * Dispatch the offset changed.
+ *
+ * @param offset the offset of this view in the parent window.
+ */
+ public void dispatchLocationInParentDisplayChanged(Point offset) {
+ Message msg =
+ mHandler.obtainMessage(MSG_LOCATION_IN_PARENT_DISPLAY_CHANGED, offset.x, offset.y);
+ mHandler.sendMessage(msg);
+ }
+
public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
synchronized (this) {
mWindowFocusChanged = true;
@@ -8367,6 +8548,14 @@ public final class ViewRootImpl implements ViewParent,
}
@Override
+ public void locationInParentDisplayChanged(Point offset) {
+ final ViewRootImpl viewAncestor = mViewAncestor.get();
+ if (viewAncestor != null) {
+ viewAncestor.dispatchLocationInParentDisplayChanged(offset);
+ }
+ }
+
+ @Override
public void insetsChanged(InsetsState insetsState) {
final ViewRootImpl viewAncestor = mViewAncestor.get();
if (viewAncestor != null) {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index a25f2eede905..2e5a7501f898 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -261,6 +261,13 @@ public interface WindowManager extends ViewManager {
int TRANSIT_TASK_CHANGE_WINDOWING_MODE = 27;
/**
+ * A display which can only contain one task is being shown because the first activity is
+ * started or it's being turned on.
+ * @hide
+ */
+ int TRANSIT_SHOW_SINGLE_TASK_DISPLAY = 28;
+
+ /**
* @hide
*/
@IntDef(prefix = { "TRANSIT_" }, value = {
@@ -287,7 +294,8 @@ public interface WindowManager extends ViewManager {
TRANSIT_TRANSLUCENT_ACTIVITY_OPEN,
TRANSIT_TRANSLUCENT_ACTIVITY_CLOSE,
TRANSIT_CRASHING_ACTIVITY_CLOSE,
- TRANSIT_TASK_CHANGE_WINDOWING_MODE
+ TRANSIT_TASK_CHANGE_WINDOWING_MODE,
+ TRANSIT_SHOW_SINGLE_TASK_DISPLAY
})
@Retention(RetentionPolicy.SOURCE)
@interface TransitionType {}
@@ -311,6 +319,12 @@ public interface WindowManager extends ViewManager {
int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER = 0x4;
/**
+ * Transition flag: Keyguard is going away with subtle animation.
+ * @hide
+ */
+ int TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION = 0x8;
+
+ /**
* @hide
*/
@IntDef(flag = true, prefix = { "TRANSIT_FLAG_" }, value = {
diff --git a/core/java/android/view/WindowManagerPolicyConstants.java b/core/java/android/view/WindowManagerPolicyConstants.java
index 46a59f09eca7..a22f5a576ab6 100644
--- a/core/java/android/view/WindowManagerPolicyConstants.java
+++ b/core/java/android/view/WindowManagerPolicyConstants.java
@@ -38,10 +38,11 @@ public interface WindowManagerPolicyConstants {
int FLAG_INTERACTIVE = 0x20000000;
int FLAG_PASS_TO_USER = 0x40000000;
- // Flags for IActivityManager.keyguardGoingAway()
+ // Flags for IActivityTaskManager.keyguardGoingAway()
int KEYGUARD_GOING_AWAY_FLAG_TO_SHADE = 1 << 0;
int KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS = 1 << 1;
int KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER = 1 << 2;
+ int KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS = 1 << 3;
// Flags used for indicating whether the internal and/or external input devices
// of some type are available.
diff --git a/core/java/android/view/contentcapture/MainContentCaptureSession.java b/core/java/android/view/contentcapture/MainContentCaptureSession.java
index c5a5f7360321..cee79439d1b3 100644
--- a/core/java/android/view/contentcapture/MainContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/MainContentCaptureSession.java
@@ -428,14 +428,16 @@ public final class MainContentCaptureSession extends ContentCaptureSession {
}
final int flushFrequencyMs;
- if (reason == FLUSH_REASON_IDLE_TIMEOUT) {
- flushFrequencyMs = mManager.mOptions.idleFlushingFrequencyMs;
- } else if (reason == FLUSH_REASON_TEXT_CHANGE_TIMEOUT) {
+ if (reason == FLUSH_REASON_TEXT_CHANGE_TIMEOUT) {
flushFrequencyMs = mManager.mOptions.textChangeFlushingFrequencyMs;
} else {
- Log.e(TAG, "handleScheduleFlush(" + getDebugState(reason) + "): not called with a "
- + "timeout reason.");
- return;
+ if (reason != FLUSH_REASON_IDLE_TIMEOUT) {
+ if (sDebug) {
+ Log.d(TAG, "handleScheduleFlush(" + getDebugState(reason) + "): not a timeout "
+ + "reason because mDirectServiceInterface is not ready yet");
+ }
+ }
+ flushFrequencyMs = mManager.mOptions.idleFlushingFrequencyMs;
}
mNextFlush = System.currentTimeMillis() + flushFrequencyMs;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 14be73dec41c..87963636a003 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -413,6 +413,9 @@ public class WebView extends AbsoluteLayout
if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) {
setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES);
}
+ if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) {
+ setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES);
+ }
if (context == null) {
throw new IllegalArgumentException("Invalid context argument");
@@ -2803,6 +2806,12 @@ public class WebView extends AbsoluteLayout
mProvider.getViewDelegate().onProvideAutofillVirtualStructure(structure, flags);
}
+ /** @hide */
+ @Override
+ public void onProvideContentCaptureStructure(ViewStructure structure, int flags) {
+ mProvider.getViewDelegate().onProvideContentCaptureStructure(structure, flags);
+ }
+
@Override
public void autofill(SparseArray<AutofillValue>values) {
mProvider.getViewDelegate().autofill(values);
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index c3bb9a0201d0..c55f7d654548 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -1318,7 +1318,8 @@ public abstract class AdapterView<T extends Adapter> extends ViewGroup {
@ViewStructureType int viewFor, int flags) {
super.onProvideStructure(structure, viewFor, flags);
- if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) {
+ if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL
+ || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
final Adapter adapter = getAdapter();
if (adapter == null) return;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 62598fce5947..0918c5fdefa8 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -162,6 +162,8 @@ import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.AnimationUtils;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
+import android.view.contentcapture.ContentCaptureManager;
+import android.view.contentcapture.ContentCaptureSession;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.CorrectionInfo;
@@ -977,6 +979,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (getImportantForAutofill() == IMPORTANT_FOR_AUTOFILL_AUTO) {
setImportantForAutofill(IMPORTANT_FOR_AUTOFILL_YES);
}
+ if (getImportantForContentCapture() == IMPORTANT_FOR_CONTENT_CAPTURE_AUTO) {
+ setImportantForContentCapture(IMPORTANT_FOR_CONTENT_CAPTURE_YES);
+ }
setTextInternal("");
@@ -10558,7 +10563,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
/**
- * Notify managers (such as {@link AutofillManager}) that are interested in text changes.
+ * Notify managers (such as {@link AutofillManager} and {@link ContentCaptureManager}) that are
+ * interested on text changes.
*/
private void notifyListeningManagersAfterTextChanged() {
@@ -10574,6 +10580,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
afm.notifyValueChanged(TextView.this);
}
}
+
+ // TODO(b/121045053): should use a flag / boolean to keep status of SHOWN / HIDDEN instead
+ // of using isLaidout(), so it's not called in cases where it's laid out but a
+ // notifyAppeared was not sent.
+
+ // ContentCapture
+ if (isLaidOut() && isImportantForContentCapture() && getNotifiedContentCaptureAppeared()) {
+ final ContentCaptureManager cm = mContext.getSystemService(ContentCaptureManager.class);
+ if (cm != null && cm.isContentCaptureEnabled()) {
+ final ContentCaptureSession session = getContentCaptureSession();
+ if (session != null) {
+ // TODO(b/111276913): pass flags when edited by user / add CTS test
+ session.notifyViewTextChanged(getAutofillId(), getText());
+ }
+ }
+ }
}
private boolean isAutofillable() {
@@ -11417,7 +11439,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
final boolean isPassword = hasPasswordTransformationMethod()
|| isPasswordInputType(getInputType());
- if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) {
+ if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL
+ || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) {
structure.setDataIsSensitive(!mTextSetFromXmlOrResourceId);
}
@@ -11433,8 +11456,12 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- if (!isPassword || viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) {
+ if (!isPassword || viewFor == VIEW_STRUCTURE_FOR_AUTOFILL
+ || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
if (mLayout == null) {
+ if (viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
+ Log.w(LOG_TAG, "onProvideContentCaptureStructure(): calling assumeLayout()");
+ }
assumeLayout();
}
Layout layout = mLayout;
@@ -11522,7 +11549,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
}
- if (viewFor == VIEW_STRUCTURE_FOR_ASSIST) {
+ if (viewFor == VIEW_STRUCTURE_FOR_ASSIST
+ || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
// Extract style information that applies to the TextView as a whole.
int style = 0;
int typefaceStyle = getTypefaceStyle();
@@ -11550,7 +11578,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
structure.setTextStyle(getTextSize(), getCurrentTextColor(),
AssistStructure.ViewNode.TEXT_COLOR_UNDEFINED /* bgColor */, style);
}
- if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL) {
+ if (viewFor == VIEW_STRUCTURE_FOR_AUTOFILL
+ || viewFor == VIEW_STRUCTURE_FOR_CONTENT_CAPTURE) {
structure.setMinTextEms(getMinEms());
structure.setMaxTextEms(getMaxEms());
int maxLength = -1;
diff --git a/core/java/com/android/internal/colorextraction/ColorExtractor.java b/core/java/com/android/internal/colorextraction/ColorExtractor.java
index b27c11b524e5..3003ce80cbc1 100644
--- a/core/java/com/android/internal/colorextraction/ColorExtractor.java
+++ b/core/java/com/android/internal/colorextraction/ColorExtractor.java
@@ -73,13 +73,8 @@ public class ColorExtractor implements WallpaperManager.OnColorsChangedListener
}
mOnColorsChangedListeners = new ArrayList<>();
-
- if (wallpaperManager == null) {
- Log.w(TAG, "Can't listen to color changes!");
- } else {
- wallpaperManager.addOnColorsChangedListener(this, null /* handler */);
- initExtractColors(wallpaperManager, immediately);
- }
+ wallpaperManager.addOnColorsChangedListener(this, null /* handler */);
+ initExtractColors(wallpaperManager, immediately);
}
private void initExtractColors(WallpaperManager wallpaperManager, boolean immediately) {
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 4daddfbfb204..40189d225a81 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -106,7 +106,7 @@ public final class SystemUiDeviceConfigFlags {
*/
public static final String HASH_SALT_MAX_DAYS = "hash_salt_max_days";
- // Flags related to Assistant Handles
+ // Flags related to Assistant
/**
* (String) Which behavior mode for the Assistant Handles to use.
@@ -177,6 +177,11 @@ public final class SystemUiDeviceConfigFlags {
"assist_handles_suppress_on_apps";
/**
+ * Allow touch passthrough above assist area during a session.
+ */
+ public static final String ASSIST_TAP_PASSTHROUGH = "assist_tap_passthrough";
+
+ /**
* (bool) Whether to show handles when taught.
*/
public static final String ASSIST_HANDLES_SHOW_WHEN_TAUGHT = "assist_handles_show_when_taught";
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index fb9ff15c79ac..f9cdf3d0be61 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -16,6 +16,7 @@
package com.android.internal.view;
+import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.input.InputManager;
import android.os.Bundle;
@@ -55,6 +56,10 @@ public class BaseIWindow extends IWindow.Stub {
}
@Override
+ public void locationInParentDisplayChanged(Point offset) {
+ }
+
+ @Override
public void insetsChanged(InsetsState insetsState) {
}
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index 22182677babe..3f6c4d4f5634 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -627,6 +627,13 @@ public class LockPatternView extends View {
}
/**
+ * If there are any cells being drawn.
+ */
+ public boolean isEmpty() {
+ return mPattern.isEmpty();
+ }
+
+ /**
* Clear the pattern lookup table. Also reset the line fade start times for
* the next attempt.
*/
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 8d702d11d8fe..ba538a855f81 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -48,7 +48,8 @@ static struct {
class NativeDisplayEventReceiver : public DisplayEventDispatcher {
public:
NativeDisplayEventReceiver(JNIEnv* env,
- jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource);
+ jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource,
+ jint configChanged);
void dispose();
@@ -68,9 +69,11 @@ private:
NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env,
- jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource) :
+ jobject receiverWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource,
+ jint configChanged) :
DisplayEventDispatcher(messageQueue->getLooper(),
- static_cast<ISurfaceComposer::VsyncSource>(vsyncSource)),
+ static_cast<ISurfaceComposer::VsyncSource>(vsyncSource),
+ static_cast<ISurfaceComposer::ConfigChanged>(configChanged)),
mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)),
mMessageQueue(messageQueue) {
ALOGV("receiver %p ~ Initializing display event receiver.", this);
@@ -136,7 +139,7 @@ void NativeDisplayEventReceiver::dispatchConfigChanged(nsecs_t timestamp,
static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
- jobject messageQueueObj, jint vsyncSource) {
+ jobject messageQueueObj, jint vsyncSource, jint configChanged) {
sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj);
if (messageQueue == NULL) {
jniThrowRuntimeException(env, "MessageQueue is not initialized.");
@@ -144,7 +147,7 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak,
}
sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env,
- receiverWeak, messageQueue, vsyncSource);
+ receiverWeak, messageQueue, vsyncSource, configChanged);
status_t status = receiver->initialize();
if (status) {
String8 message;
@@ -179,7 +182,7 @@ static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */
{ "nativeInit",
- "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;I)J",
+ "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J",
(void*)nativeInit },
{ "nativeDispose",
"(J)V",
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index ccadc7d7c22a..ff14a2acc4d7 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -75,6 +75,24 @@ static struct {
jfieldID bottom;
} gRectClassInfo;
+class JNamedColorSpace {
+public:
+ // ColorSpace.Named.SRGB.ordinal() = 0;
+ static constexpr jint SRGB = 0;
+
+ // ColorSpace.Named.DISPLAY_P3.ordinal() = 7;
+ static constexpr jint DISPLAY_P3 = 7;
+};
+
+constexpr ui::Dataspace fromNamedColorSpaceValueToDataspace(const jint colorSpace) {
+ switch (colorSpace) {
+ case JNamedColorSpace::DISPLAY_P3:
+ return ui::Dataspace::DISPLAY_P3;
+ default:
+ return ui::Dataspace::V0_SRGB;
+ }
+}
+
// ----------------------------------------------------------------------------
// this is just a pointer we use to pass to inc/decStrong
@@ -425,11 +443,12 @@ static jint nativeForceScopedDisconnect(JNIEnv *env, jclass clazz, jlong nativeO
return surface->disconnect(-1, IGraphicBufferProducer::DisconnectMode::AllLocal);
}
-static jint nativeAttachAndQueueBuffer(JNIEnv *env, jclass clazz, jlong nativeObject,
- jobject graphicBuffer) {
+static jint nativeAttachAndQueueBufferWithColorSpace(JNIEnv *env, jclass clazz, jlong nativeObject,
+ jobject graphicBuffer, jint colorSpaceId) {
Surface* surface = reinterpret_cast<Surface*>(nativeObject);
sp<GraphicBuffer> bp = graphicBufferForJavaObject(env, graphicBuffer);
- int err = Surface::attachAndQueueBuffer(surface, bp);
+ int err = Surface::attachAndQueueBufferWithDataspace(surface, bp,
+ fromNamedColorSpaceValueToDataspace(colorSpaceId));
return err;
}
@@ -531,7 +550,8 @@ static const JNINativeMethod gSurfaceMethods[] = {
{"nativeGetNextFrameNumber", "(J)J", (void*)nativeGetNextFrameNumber },
{"nativeSetScalingMode", "(JI)I", (void*)nativeSetScalingMode },
{"nativeForceScopedDisconnect", "(J)I", (void*)nativeForceScopedDisconnect},
- {"nativeAttachAndQueueBuffer", "(JLandroid/graphics/GraphicBuffer;)I", (void*)nativeAttachAndQueueBuffer},
+ {"nativeAttachAndQueueBufferWithColorSpace", "(JLandroid/graphics/GraphicBuffer;I)I",
+ (void*)nativeAttachAndQueueBufferWithColorSpace},
{"nativeSetSharedBufferModeEnabled", "(JZ)I", (void*)nativeSetSharedBufferModeEnabled},
{"nativeSetAutoRefreshEnabled", "(JZ)I", (void*)nativeSetAutoRefreshEnabled},
diff --git a/core/proto/android/providers/settings/secure.proto b/core/proto/android/providers/settings/secure.proto
index fed2efaf8a78..61799eefdca6 100644
--- a/core/proto/android/providers/settings/secure.proto
+++ b/core/proto/android/providers/settings/secure.proto
@@ -198,11 +198,19 @@ message SecureSettingsProto {
optional SettingProto silence_alarms_count = 2 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto silence_calls_count = 3 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto silence_enabled = 4 [ (android.privacy).dest = DEST_AUTOMATIC ];
- optional SettingProto silence_notification_count = 5 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ // del: silence_notification_count = 5
optional SettingProto silence_timer_count = 6 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto skip_count = 7 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto skip_enabled = 8 [ (android.privacy).dest = DEST_AUTOMATIC ];
+
+ optional SettingProto silence_alarms_touch_count = 9 [ (android.privacy).dest =
+ DEST_AUTOMATIC ];
+ optional SettingProto silence_calls_touch_count = 10 [ (android.privacy).dest =
+ DEST_AUTOMATIC ];
+ optional SettingProto silence_timer_touch_count = 11 [ (android.privacy).dest =
+ DEST_AUTOMATIC ];
+ optional SettingProto skip_touch_count = 12 [ (android.privacy).dest = DEST_AUTOMATIC ];
}
optional Gesture gesture = 74;
diff --git a/core/res/res/anim/lock_in.xml b/core/res/res/anim/lock_in.xml
deleted file mode 100644
index c7014e80d33e..000000000000
--- a/core/res/res/anim/lock_in.xml
+++ /dev/null
@@ -1,227 +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.
--->
-<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:aapt="http://schemas.android.com/aapt">
- <aapt:attr name="android:drawable">
- <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
- android:viewportWidth="32">
- <group android:name="_R_G">
- <group android:name="_R_G_L_2_G" android:translateX="1.6669999999999998"
- android:translateY="11.992999999999999" android:pivotX="14.333"
- android:pivotY="13" android:scaleX="0" android:scaleY="0">
- <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#ffffff"
- android:strokeLineCap="round" android:strokeLineJoin="round"
- android:strokeWidth="2" android:strokeAlpha="1"
- android:pathData=" M22.33 21 C22.33,21 6.33,21 6.33,21 C5.6,21 5,20.4 5,19.67 C5,19.67 5,6.33 5,6.33 C5,5.6 5.6,5 6.33,5 C6.33,5 22.33,5 22.33,5 C23.07,5 23.67,5.6 23.67,6.33 C23.67,6.33 23.67,19.67 23.67,19.67 C23.67,20.4 23.07,21 22.33,21c "/>
- </group>
- <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="1.6669999999999998"
- android:translateY="11.992999999999999" android:pivotX="14.333"
- android:pivotY="13" android:scaleX="0" android:scaleY="0">
- <group android:name="_R_G_L_1_G" android:translateX="11.583"
- android:translateY="10.257">
- <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
- android:fillAlpha="1" android:fillType="nonZero"
- android:pathData=" M2.75 0.25 C4.13,0.25 5.25,1.37 5.25,2.75 C5.25,4.13 4.13,5.25 2.75,5.25 C1.37,5.25 0.25,4.13 0.25,2.75 C0.25,1.37 1.37,0.25 2.75,0.25c "/>
- </group>
- </group>
- <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="1.6669999999999998"
- android:translateY="11.992999999999999" android:pivotX="14.333"
- android:pivotY="13" android:scaleX="0" android:scaleY="0">
- <group android:name="_R_G_L_0_G_T_1" android:translateX="14.333"
- android:translateY="3.172">
- <group android:name="_R_G_L_0_G" android:translateX="-9.667"
- android:translateY="-9.667">
- <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
- android:strokeLineCap="round" android:strokeLineJoin="round"
- android:strokeWidth="2" android:strokeAlpha="1"
- android:trimPathStart="0.14" android:trimPathEnd="0.89"
- android:trimPathOffset="0"
- android:pathData=" M14.33 14.33 C14.33,14.33 14.33,9.67 14.33,9.67 C14.33,7.09 12.24,5 9.67,5 C7.09,5 5,7.09 5,9.67 C5,9.67 5,14.33 5,14.33 "/>
- </group>
- </group>
- </group>
- </group>
- <group android:name="time_group"/>
- </vector>
- </aapt:attr>
- <target android:name="_R_G_L_2_G">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator android:propertyName="scaleX" android:duration="233"
- android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleY" android:duration="233"
- android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleX" android:duration="117"
- android:startOffset="233" android:valueFrom="1.02"
- android:valueTo="1" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleY" android:duration="117"
- android:startOffset="233" android:valueFrom="1.02"
- android:valueTo="1" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_1_G_N_4_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator android:propertyName="scaleX" android:duration="233"
- android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleY" android:duration="233"
- android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleX" android:duration="117"
- android:startOffset="233" android:valueFrom="1.02"
- android:valueTo="1" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleY" android:duration="117"
- android:startOffset="233" android:valueFrom="1.02"
- android:valueTo="1" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator android:propertyName="trimPathStart" android:duration="50"
- android:startOffset="0" android:valueFrom="0.14"
- android:valueTo="0.14" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator
- android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="trimPathStart" android:duration="67"
- android:startOffset="50" android:valueFrom="0.14"
- android:valueTo="0" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator
- android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_D_0_P_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator android:propertyName="trimPathEnd" android:duration="50"
- android:startOffset="0" android:valueFrom="0.89"
- android:valueTo="0.89" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator
- android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="trimPathEnd" android:duration="67"
- android:startOffset="50" android:valueFrom="0.89"
- android:valueTo="1" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator
- android:pathData="M 0.0,0.0 c0.167,0.167 0.833,0.833 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_T_1">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator android:propertyName="translateY" android:duration="150"
- android:startOffset="0" android:valueFrom="3.172"
- android:valueTo="0.34" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.23,-0.46 0.2,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="_R_G_L_0_G_N_4_T_0">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator android:propertyName="scaleX" android:duration="233"
- android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleY" android:duration="233"
- android:startOffset="0" android:valueFrom="0" android:valueTo="1.02"
- android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.001,0 0.438,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleX" android:duration="117"
- android:startOffset="233" android:valueFrom="1.02"
- android:valueTo="1" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- <objectAnimator android:propertyName="scaleY" android:duration="117"
- android:startOffset="233" android:valueFrom="1.02"
- android:valueTo="1" android:valueType="floatType">
- <aapt:attr name="android:interpolator">
- <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.565,1 1.0,1.0"/>
- </aapt:attr>
- </objectAnimator>
- </set>
- </aapt:attr>
- </target>
- <target android:name="time_group">
- <aapt:attr name="android:animation">
- <set android:ordering="together">
- <objectAnimator android:propertyName="translateX" android:duration="717"
- android:startOffset="0" android:valueFrom="0" android:valueTo="1"
- android:valueType="floatType"/>
- </set>
- </aapt:attr>
- </target>
-</animated-vector> \ No newline at end of file
diff --git a/core/res/res/anim/lock_screen_behind_enter_subtle.xml b/core/res/res/anim/lock_screen_behind_enter_subtle.xml
new file mode 100644
index 000000000000..f9f69b12514c
--- /dev/null
+++ b/core/res/res/anim/lock_screen_behind_enter_subtle.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<set xmlns:android="http://schemas.android.com/apk/res/android"
+ android:detachWallpaper="true"
+ android:shareInterpolator="false">
+
+ <alpha
+ android:fromAlpha="0.0" android:toAlpha="1.0"
+ android:fillEnabled="true" android:fillBefore="true"
+ android:interpolator="@interpolator/linear"
+ android:startOffset="80"
+ android:duration="233"/>
+ <translate android:fromYDelta="5%p" android:toYDelta="0"
+ android:fillEnabled="true" android:fillBefore="true" android:fillAfter="true"
+ android:interpolator="@interpolator/fast_out_slow_in"
+ android:startOffset="80"
+ android:duration="233" />
+</set> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_audio_alarm.xml b/core/res/res/drawable/ic_audio_alarm.xml
index 96206ea3ce57..93f9f8f99cdc 100644
--- a/core/res/res/drawable/ic_audio_alarm.xml
+++ b/core/res/res/drawable/ic_audio_alarm.xml
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0"
android:tint="?attr/colorControlNormal">
diff --git a/core/res/res/drawable/ic_audio_alarm_mute.xml b/core/res/res/drawable/ic_audio_alarm_mute.xml
index 7f248c3b33e6..510a7c630fd2 100644
--- a/core/res/res/drawable/ic_audio_alarm_mute.xml
+++ b/core/res/res/drawable/ic_audio_alarm_mute.xml
@@ -14,8 +14,8 @@ Copyright (C) 2014 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32.0dp"
- android:height="32.0dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="48.0"
android:viewportHeight="48.0"
android:tint="?attr/colorControlNormal">
diff --git a/core/res/res/drawable/ic_battery_80_24dp.xml b/core/res/res/drawable/ic_battery_80_24dp.xml
new file mode 100644
index 000000000000..2513d0d6d615
--- /dev/null
+++ b/core/res/res/drawable/ic_battery_80_24dp.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M9.5,2v2H7.33C6.6,4 6,4.6 6,5.33V15v5.67C6,21.4 6.6,22 7.33,22h9.33C17.4,22 18,21.4 18,20.67V15V5.33C18,4.6 17.4,4 16.67,4H14.5V2H9.5zM8,20v-5V6h8v9v5H8L8,20z"/>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M16.67,22H7.33C6.6,22 6,21.4 6,20.67V8h12v12.67C18,21.4 17.4,22 16.67,22z"/>
+</vector> \ No newline at end of file
diff --git a/core/res/res/drawable/ic_bluetooth_share_icon.xml b/core/res/res/drawable/ic_bluetooth_share_icon.xml
index 2152af55d5b6..6acfd57e669f 100644
--- a/core/res/res/drawable/ic_bluetooth_share_icon.xml
+++ b/core/res/res/drawable/ic_bluetooth_share_icon.xml
@@ -19,7 +19,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="@android:color/accent_device_default_light">
+ android:tint="@*android:color/accent_device_default_light">
<path
android:fillColor="@android:color/white"
diff --git a/core/res/res/drawable/ic_corp_badge.xml b/core/res/res/drawable/ic_corp_badge.xml
index 6a7ac4a20ff3..16df45290302 100644
--- a/core/res/res/drawable/ic_corp_badge.xml
+++ b/core/res/res/drawable/ic_corp_badge.xml
@@ -15,8 +15,8 @@ Copyright (C) 2018 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
+ android:width="24dp"
+ android:height="24dp"
android:tint="@*android:color/accent_device_default_light"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/ic_file_copy.xml b/core/res/res/drawable/ic_file_copy.xml
index b6d5e7328c40..d05b55f1279f 100644
--- a/core/res/res/drawable/ic_file_copy.xml
+++ b/core/res/res/drawable/ic_file_copy.xml
@@ -16,9 +16,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="@*android:color/material_grey_600"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M16,1L4,1c-1.1,0 -2,0.9 -2,2v14h2L4,3h12L16,1zM15,5l6,6v10c0,1.1 -0.9,2 -2,2L7.99,23C6.89,23 6,22.1 6,21l0.01,-14c0,-1.1 0.89,-2 1.99,-2h7zM14,12h5.5L14,6.5L14,12z"
- android:fillColor="#FF737373"/>
+ android:fillColor="@android:color/white"/>
</vector>
diff --git a/core/res/res/drawable/ic_qs_auto_rotate.xml b/core/res/res/drawable/ic_qs_auto_rotate.xml
index 47e1059fab44..8858e2b778bb 100644
--- a/core/res/res/drawable/ic_qs_auto_rotate.xml
+++ b/core/res/res/drawable/ic_qs_auto_rotate.xml
@@ -16,8 +16,8 @@
-->
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="48dp"
- android:width="48dp"
+ android:height="24dp"
+ android:width="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/core/res/res/drawable/ic_qs_battery_saver.xml b/core/res/res/drawable/ic_qs_battery_saver.xml
index 93975b61948e..6e1ced083ba7 100644
--- a/core/res/res/drawable/ic_qs_battery_saver.xml
+++ b/core/res/res/drawable/ic_qs_battery_saver.xml
@@ -15,8 +15,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:autoMirrored="true"
- android:width="32.0dp"
- android:height="32.0dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal">
diff --git a/core/res/res/drawable/ic_qs_flashlight.xml b/core/res/res/drawable/ic_qs_flashlight.xml
index e63595300d5f..59b0ccd493dd 100644
--- a/core/res/res/drawable/ic_qs_flashlight.xml
+++ b/core/res/res/drawable/ic_qs_flashlight.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/core/res/res/drawable/ic_qs_ui_mode_night.xml b/core/res/res/drawable/ic_qs_ui_mode_night.xml
index 72278272e330..34b535bd40c3 100644
--- a/core/res/res/drawable/ic_qs_ui_mode_night.xml
+++ b/core/res/res/drawable/ic_qs_ui_mode_night.xml
@@ -15,11 +15,11 @@
~ limitations under the License
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
- android:fillColor="#FF000000"
+ android:fillColor="@android:color/white"
android:pathData="M12,22C17.52,22 22,17.52 22,12 22,6.48 17.52,2 12,2 6.48,2 2,6.48 2,12 2,17.52 6.48,22 12,22ZM12,3.915c3.889,0 8,4.005 8,8.085 0,4.08 -3.927,7.992 -7.928,7.992z"/>
-</vector> \ No newline at end of file
+</vector>
diff --git a/core/res/res/drawable/perm_group_activity_recognition.xml b/core/res/res/drawable/perm_group_activity_recognition.xml
index 0ade6c674171..ef025acbcb0c 100644
--- a/core/res/res/drawable/perm_group_activity_recognition.xml
+++ b/core/res/res/drawable/perm_group_activity_recognition.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/perm_group_aural.xml b/core/res/res/drawable/perm_group_aural.xml
index b2737f24b86e..4b4c62cb73b6 100644
--- a/core/res/res/drawable/perm_group_aural.xml
+++ b/core/res/res/drawable/perm_group_aural.xml
@@ -16,6 +16,7 @@ Copyright (C) 2015 The Android Open Source Project
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/core/res/res/drawable/perm_group_calendar.xml b/core/res/res/drawable/perm_group_calendar.xml
index 4b46dd36e3b1..0dfb30150535 100644
--- a/core/res/res/drawable/perm_group_calendar.xml
+++ b/core/res/res/drawable/perm_group_calendar.xml
@@ -17,13 +17,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#000000"
android:pathData="M19 4h-1V2h-2v2H8V2H6v2H5c-1.11 0-1.99 0.9 -1.99 2L3 20c0 1.1 0.89 2 2 2h14c1.1 0 2-0.9 2-2V6c0-1.1-0.9-2-2-2zm0 16H5V10h14v10zm-4.5-7c-1.38 0-2.5 1.12-2.5 2.5s1.12 2.5 2.5 2.5 2.5-1.12 2.5-2.5-1.12-2.5-2.5-2.5z" />
- <path
- android:pathData="M0 0h24v24H0V0z" />
-</vector> \ No newline at end of file
+</vector>
diff --git a/core/res/res/drawable/perm_group_call_log.xml b/core/res/res/drawable/perm_group_call_log.xml
index 0dfdbee4e600..a37ed88bebfc 100644
--- a/core/res/res/drawable/perm_group_call_log.xml
+++ b/core/res/res/drawable/perm_group_call_log.xml
@@ -18,6 +18,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/core/res/res/drawable/perm_group_camera.xml b/core/res/res/drawable/perm_group_camera.xml
index db7833f63faf..e65501c4efcc 100644
--- a/core/res/res/drawable/perm_group_camera.xml
+++ b/core/res/res/drawable/perm_group_camera.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/perm_group_contacts.xml b/core/res/res/drawable/perm_group_contacts.xml
index b834a27bac4b..dd6ae210181f 100644
--- a/core/res/res/drawable/perm_group_contacts.xml
+++ b/core/res/res/drawable/perm_group_contacts.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/perm_group_location.xml b/core/res/res/drawable/perm_group_location.xml
index a7fa52471ab4..a87fc0dc43df 100644
--- a/core/res/res/drawable/perm_group_location.xml
+++ b/core/res/res/drawable/perm_group_location.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/perm_group_microphone.xml b/core/res/res/drawable/perm_group_microphone.xml
index 9b532c1a7376..a1ed72510cf8 100644
--- a/core/res/res/drawable/perm_group_microphone.xml
+++ b/core/res/res/drawable/perm_group_microphone.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/perm_group_phone_calls.xml b/core/res/res/drawable/perm_group_phone_calls.xml
index 324d86492703..563222698b46 100644
--- a/core/res/res/drawable/perm_group_phone_calls.xml
+++ b/core/res/res/drawable/perm_group_phone_calls.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
@@ -25,4 +26,4 @@
.37 2.33 .57 3.57 .57 .55 0 1 .45 1 1V20c0 .55-.45 1-1 1-9.39 0-17-7.61-17-17
0-.55 .45 -1 1-1h3.5c.55 0 1 .45 1 1 0 1.25 .2 2.45 .57 3.57 .11 .35 .03 .74-.25
1.02l-2.2 2.2z" />
-</vector> \ No newline at end of file
+</vector>
diff --git a/core/res/res/drawable/perm_group_sensors.xml b/core/res/res/drawable/perm_group_sensors.xml
index e4663d7206fc..f800965b6058 100644
--- a/core/res/res/drawable/perm_group_sensors.xml
+++ b/core/res/res/drawable/perm_group_sensors.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
<path
diff --git a/core/res/res/drawable/perm_group_sms.xml b/core/res/res/drawable/perm_group_sms.xml
index ebcf3d1fcd82..44ccdd6394e6 100644
--- a/core/res/res/drawable/perm_group_sms.xml
+++ b/core/res/res/drawable/perm_group_sms.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/perm_group_storage.xml b/core/res/res/drawable/perm_group_storage.xml
index 4b8965bd9ef8..fceda2b84885 100644
--- a/core/res/res/drawable/perm_group_storage.xml
+++ b/core/res/res/drawable/perm_group_storage.xml
@@ -17,6 +17,7 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24"
android:viewportHeight="24">
diff --git a/core/res/res/drawable/perm_group_visual.xml b/core/res/res/drawable/perm_group_visual.xml
index 9b21c279e30a..bf3edea74199 100644
--- a/core/res/res/drawable/perm_group_visual.xml
+++ b/core/res/res/drawable/perm_group_visual.xml
@@ -16,11 +16,10 @@ Copyright (C) 2015 The Android Open Source Project
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#000000"
android:pathData="M20,4v12H8V4H20 M20,2H8C6.9,2,6,2.9,6,4v12c0,1.1,0.9,2,2,2h12c1.1,0,2-0.9,2-2V4C22,2.9,21.1,2,20,2L20,2z M2,6v14 c0,1.1,0.9,2,2,2h14v-2H4V6H2z M15.67,11l-2.5,2.98L11.5,11.8L9,15h10L15.67,11z" />
- <path
- android:pathData="M0,0h24v24H0V0z" />
</vector>
diff --git a/core/res/res/values-mcc313-mnc100/config.xml b/core/res/res/values-mcc313-mnc100/config.xml
new file mode 100644
index 000000000000..ccd03f10616a
--- /dev/null
+++ b/core/res/res/values-mcc313-mnc100/config.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string-array translatable="false" name="config_twoDigitNumberPattern">
+ <item>"0"</item>
+ <item>"00"</item>
+ <item>"*0"</item>
+ <item>"*1"</item>
+ <item>"*2"</item>
+ <item>"*3"</item>
+ <item>"*4"</item>
+ <item>"*5"</item>
+ <item>"*6"</item>
+ <item>"*7"</item>
+ <item>"*8"</item>
+ <item>"*9"</item>
+ <item>"#0"</item>
+ <item>"#1"</item>
+ <item>"#2"</item>
+ <item>"#3"</item>
+ <item>"#4"</item>
+ <item>"#5"</item>
+ <item>"#6"</item>
+ <item>"#7"</item>
+ <item>"#8"</item>
+ <item>"#9"</item>
+ </string-array>
+</resources>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9a642add609e..dc564ec6ce25 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2283,7 +2283,7 @@
effectively and terminate the dream. Use -1 to disable this safety feature. -->
<integer name="config_dreamsBatteryLevelDrainCutoff">5</integer>
<!-- Limit of how long the device can remain unlocked due to attention checking. -->
- <integer name="config_attentionMaximumExtension">240000</integer> <!-- 4 minutes -->
+ <integer name="config_attentionMaximumExtension">330000</integer> <!-- 5 minutes and 30 sec.-->
<!-- How long we should wait until we give up on receiving an attention API callback. -->
<integer name="config_attentionApiTimeout">2000</integer> <!-- 2 seconds -->
@@ -2316,7 +2316,7 @@
<!-- If the sensor that wakes up the lock screen is available or not. -->
<bool name="config_dozeWakeLockScreenSensorAvailable">false</bool>
- <integer name="config_dozeWakeLockScreenDebounce">1500</integer>
+ <integer name="config_dozeWakeLockScreenDebounce">300</integer>
<!-- Control whether the always on display mode is available. This should only be enabled on
devices where the display has been tuned to be power efficient in DOZE and/or DOZE_SUSPEND
@@ -3795,9 +3795,11 @@
<integer name="config_stableDeviceDisplayWidth">-1</integer>
<integer name="config_stableDeviceDisplayHeight">-1</integer>
- <!-- Decide whether to display 'No service' on status bar instead of 'Emergency calls only'
- when SIM is unready. -->
- <bool name="config_display_no_service_when_sim_unready">false</bool>
+ <!-- List of countries in which we display 'No service' on status bar
+ instead of 'Emergency calls only' when SIM is unready. -->
+ <string-array translatable="false" name="config_display_no_service_when_sim_unready">
+ <item>"DE"</item>
+ </string-array>
<!-- Class names of device specific services inheriting com.android.server.SystemService. The
classes are instantiated in the order of the array. -->
@@ -4037,16 +4039,62 @@
</array>
<!-- See DisplayWhiteBalanceController.
- The ambient brightness threshold (in lux) beneath which we fall back to a fixed ambient
- color temperature. -->
- <item name="config_displayWhiteBalanceLowLightAmbientBrightnessThreshold" format="float" type="dimen">10.0</item>
+ A float array containing a list of ambient brightnesses, in Lux. This array,
+ together with config_displayWhiteBalanceLowLightAmbientBiases, is used to generate a
+ lookup table used in DisplayWhiteBalanceController. This lookup table is used to map
+ ambient brightness readings to a bias, where the bias is used to linearly interpolate
+ between ambient color temperature and
+ config_displayWhiteBalanceLowLightAmbientColorTemperature.
+ This table is optional. If used, this array must,
+ 1) Contain at least two entries
+ 2) Be the same length as config_displayWhiteBalanceLowLightAmbientBiases. -->
+ <array name ="config_displayWhiteBalanceLowLightAmbientBrightnesses">
+ <item>10.0</item>
+ <item>10.0</item>
+ </array>
+
+ <!-- See DisplayWhiteBalanceController.
+ An array containing a list of biases. See
+ config_displayWhiteBalanceLowLightAmbientBrightnesses for additional details.
+ This array must be in the range of [0.0, 1.0]. -->
+ <array name ="config_displayWhiteBalanceLowLightAmbientBiases">
+ <item>0.0</item>
+ <item>1.0</item>
+ </array>
<!-- See DisplayWhiteBalanceController.
- The ambient color temperature (in cct) to which we fall back when the ambient brightness
- drops beneath a certain threshold. -->
+ The ambient color temperature (in cct) to which we interpolate towards using the
+ the look up table generated by config_displayWhiteBalanceLowLightAmbientBrightnesses
+ and config_displayWhiteBalanceLowLightAmbientBiases. -->
<item name="config_displayWhiteBalanceLowLightAmbientColorTemperature" format="float" type="dimen">6500.0</item>
<!-- See DisplayWhiteBalanceController.
+ A float array containing a list of ambient brightnesses, in Lux. This array,
+ together with config_displayWhiteBalanceHighLightAmbientBiases, is used to generate a
+ lookup table used in DisplayWhiteBalanceController. This lookup table is used to map
+ ambient brightness readings to a bias, where the bias is used to linearly interpolate
+ between ambient color temperature and
+ config_displayWhiteBalanceHighLightAmbientColorTemperature.
+ This table is optional. If used, this array must,
+ 1) Contain at least two entries
+ 2) Be the same length as config_displayWhiteBalanceHighLightAmbientBiases. -->
+ <array name ="config_displayWhiteBalanceHighLightAmbientBrightnesses">
+ </array>
+
+ <!-- See DisplayWhiteBalanceController.
+ An array containing a list of biases. See
+ config_displayWhiteBalanceHighLightAmbientBrightnesses for additional details.
+ This array must be in the range of [0.0, 1.0]. -->
+ <array name ="config_displayWhiteBalanceHighLightAmbientBiases">
+ </array>
+
+ <!-- See DisplayWhiteBalanceController.
+ The ambient color temperature (in cct) to which we interpolate towards using the
+ the look up table generated by config_displayWhiteBalanceHighLightAmbientBrightnesses
+ and config_displayWhiteBalanceHighLightAmbientBiases. -->
+ <item name="config_displayWhiteBalanceHighLightAmbientColorTemperature" format="float" type="dimen">8000.0</item>
+
+ <!-- See DisplayWhiteBalanceController.
A float array containing a list of ambient color temperatures, in Kelvin. This array,
together with config_displayWhiteBalanceDisplayColorTemperatures, is used to generate a
lookup table used in DisplayWhiteBalanceController. This lookup table is used to map
@@ -4080,6 +4128,15 @@
M9,10l-2,0l0,-2l-2,0l0,2l-2,0l0,2l2,0l0,2l2,0l0,-2l2,0z
</string>
+ <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+ <string name="config_signalXPath" translatable="false">
+ M22,16.41L20.59,15l-2.09,2.09L16.41,15L15,16.41l2.09,2.09L15,20.59L16.41,22l2.09-2.08L20.59,22L22,20.59l-2.08-2.09 L22,16.41z
+ </string>
+ <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+ should be cut out to display config_signalXPath.-->
+ <item name="config_signalCutoutWidthFraction" format="float" type="dimen">11</item>
+ <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item>
+
<!-- A dual tone battery meter draws the perimeter path twice - once to define the shape
and a second time clipped to the fill level to indicate charge -->
<bool name="config_batterymeterDualTone">false</bool>
@@ -4088,6 +4145,9 @@
for higher refresh rates to be automatically used out of the box -->
<integer name="config_defaultPeakRefreshRate">60</integer>
+ <!-- The default brightness threshold that allows to switch to higher refresh rate -->
+ <integer name="config_brightnessThresholdOfPeakRefreshRate">-1</integer>
+
<!-- The type of the light sensor to be used by the display framework for things like
auto-brightness. If unset, then it just gets the default sensor of type TYPE_LIGHT. -->
<string name="config_displayLightSensorType" translatable="false" />
@@ -4150,6 +4210,9 @@
<integer-array name="config_face_acquire_vendor_biometricprompt_ignorelist" translatable="false" >
</integer-array>
+ <!-- If face auth sends the user directly to home/last open app, or stays on keyguard -->
+ <bool name="config_faceAuthDismissesKeyguard">true</bool>
+
<!-- The component name for the default profile supervisor, which can be set as a profile owner
even after user setup is complete. The defined component should be used for supervision purposes
only. The component must be part of a system app. -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 152b131af8f5..e265162cc116 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1502,16 +1502,16 @@
<string name="fingerprint_icon_content_description">Fingerprint icon</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=70] -->
- <string name="permlab_manageFace">manage face authentication hardware</string>
+ <string name="permlab_manageFace">manage face unlock hardware</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=90] -->
<string name="permdesc_manageFace">Allows the app to invoke methods to add and delete facial templates for use.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=70] -->
- <string name="permlab_useFaceAuthentication">use face authentication hardware</string>
+ <string name="permlab_useFaceAuthentication">use face unlock hardware</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=90] -->
- <string name="permdesc_useFaceAuthentication">Allows the app to use face authentication hardware for authentication</string>
+ <string name="permdesc_useFaceAuthentication">Allows the app to use face unlock hardware for authentication</string>
<!-- Notification name shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] -->
- <string name="face_recalibrate_notification_name">Face Authentication</string>
+ <string name="face_recalibrate_notification_name">Face unlock</string>
<!-- Notification title shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] -->
<string name="face_recalibrate_notification_title">Re-enroll your face</string>
<!-- Notification content shown when the system requires the user to re-enroll their face. [CHAR LIMIT=NONE] -->
@@ -1538,7 +1538,7 @@
<!-- Message shown during face acquisition when the user is not front facing the sensor [CHAR LIMIT=50] -->
<string name="face_acquired_poor_gaze">Please look more directly at your device.</string>
<!-- Message shown during face acquisition when the user is not detected [CHAR LIMIT=50] -->
- <string name="face_acquired_not_detected">Can\u2019t see your face. Look at the phone.</string>
+ <string name="face_acquired_not_detected">Position your face directly in front of the phone.</string>
<!-- Message shown during face acquisition when the device is not steady [CHAR LIMIT=50] -->
<string name="face_acquired_too_much_motion">Too much motion. Hold phone steady.</string>
<!-- Message shown during face acquisition when the sensor needs to be recalibrated [CHAR LIMIT=50] -->
@@ -1555,8 +1555,8 @@
<string name="face_acquired_roll_too_extreme">Turn your head a little less.</string>
<!-- Message shown during acquisition when the user's face is obscured [CHAR LIMIT=50] -->
<string name="face_acquired_obscured">Remove anything hiding your face.</string>
- <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=50] -->
- <string name="face_acquired_sensor_dirty">Clean the sensor at the top edge of the screen.</string>
+ <!-- Message shown during acquisition when the sensor is dirty [CHAR LIMIT=100] -->
+ <string name="face_acquired_sensor_dirty">Clean the top of your screen, including the black bar</string>
<!-- Array containing custom messages shown during face acquisition from vendor. Vendor is expected to add and translate these strings -->
<string-array name="face_acquired_vendor">
</string-array>
@@ -1564,23 +1564,23 @@
<!-- Error message shown when the face hardware can't be accessed. [CHAR LIMIT=69] -->
<string name="face_error_hw_not_available">Can\u2019t verify face. Hardware not available.</string>
<!-- Error message shown when the face hardware timer has expired and the user needs to restart the operation. [CHAR LIMIT=50] -->
- <string name="face_error_timeout">Try face authentication again.</string>
+ <string name="face_error_timeout">Try face unlock again.</string>
<!-- Error message shown when the face hardware has run out of room for storing faces. [CHAR LIMIT=69] -->
<string name="face_error_no_space">Can\u2019t store new face data. Delete an old one first.</string>
<!-- Generic error message shown when the face operation (e.g. enrollment or authentication) is canceled. Generally not shown to the user. [CHAR LIMIT=50] -->
- <string name="face_error_canceled">Face operation canceled</string>
- <!-- Generic error message shown when the face authentication operation is canceled due to user input. Generally not shown to the user [CHAR LIMIT=54] -->
- <string name="face_error_user_canceled">Face authentication canceled by user</string>
+ <string name="face_error_canceled">Face operation canceled.</string>
+ <!-- Generic error message shown when the face unlock operation is canceled due to user input. Generally not shown to the user [CHAR LIMIT=54] -->
+ <string name="face_error_user_canceled">Face unlock canceled by user.</string>
<!-- Generic error message shown when the face operation fails because too many attempts have been made. [CHAR LIMIT=50] -->
<string name="face_error_lockout">Too many attempts. Try again later.</string>
<!-- Generic error message shown when the face operation fails because strong authentication is required. [CHAR LIMIT=71] -->
- <string name="face_error_lockout_permanent">Too many attempts. Face authentication disabled.</string>
+ <string name="face_error_lockout_permanent">Too many attempts. Face unlock disabled.</string>
<!-- Generic error message shown when the face hardware can't recognize the face. [CHAR LIMIT=50] -->
<string name="face_error_unable_to_process">Can\u2019t verify face. Try again.</string>
<!-- Generic error message shown when the user has no enrolled face. [CHAR LIMIT=52] -->
- <string name="face_error_not_enrolled">You haven\u2019t set up face authentication</string>
- <!-- Generic error message shown when the app requests face authentication on a device without a sensor. [CHAR LIMIT=61] -->
- <string name="face_error_hw_not_present">Face authentication is not supported on this device</string>
+ <string name="face_error_not_enrolled">You haven\u2019t set up face unlock.</string>
+ <!-- Generic error message shown when the app requests face unlock on a device without a sensor. [CHAR LIMIT=61] -->
+ <string name="face_error_hw_not_present">Face unlock is not supported on this device.</string>
<!-- Template to be used to name enrolled faces by default. [CHAR LIMIT=10] -->
<string name="face_name_template">Face <xliff:g id="faceId" example="1">%d</xliff:g></string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 544fd4457c7a..988be59d6d24 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2273,14 +2273,10 @@
<java-symbol type="anim" name="lock_screen_behind_enter" />
<java-symbol type="anim" name="lock_screen_behind_enter_wallpaper" />
<java-symbol type="anim" name="lock_screen_behind_enter_fade_in" />
+ <java-symbol type="anim" name="lock_screen_behind_enter_subtle" />
<java-symbol type="anim" name="lock_screen_wallpaper_exit" />
<java-symbol type="anim" name="launch_task_behind_source" />
<java-symbol type="anim" name="wallpaper_open_exit" />
- <java-symbol type="anim" name="lock_to_error" />
- <java-symbol type="anim" name="lock_lock" />
- <java-symbol type="anim" name="lock_unlock" />
- <java-symbol type="anim" name="lock_in" />
- <java-symbol type="anim" name="lock_scanning" />
<java-symbol type="bool" name="config_alwaysUseCdmaRssi" />
<java-symbol type="dimen" name="status_bar_icon_size" />
@@ -2591,6 +2587,7 @@
<java-symbol type="array" name="config_face_acquire_vendor_keyguard_ignorelist" />
<java-symbol type="array" name="config_face_acquire_biometricprompt_ignorelist" />
<java-symbol type="array" name="config_face_acquire_vendor_biometricprompt_ignorelist" />
+ <java-symbol type="bool" name="config_faceAuthDismissesKeyguard" />
<!-- Face config -->
<java-symbol type="integer" name="config_faceMaxTemplatesPerUser" />
@@ -3273,6 +3270,9 @@
<java-symbol type="string" name="config_batterymeterBoltPath" />
<java-symbol type="string" name="config_batterymeterPowersavePath" />
<java-symbol type="bool" name="config_batterymeterDualTone" />
+ <java-symbol type="string" name="config_signalXPath" />
+ <java-symbol type="dimen" name="config_signalCutoutWidthFraction" />
+ <java-symbol type="dimen" name="config_signalCutoutHeightFraction" />
<java-symbol type="bool" name="config_debugEnableAutomaticSystemServerHeapDumps" />
<java-symbol type="integer" name="config_debugSystemServerPssThresholdBytes" />
@@ -3557,7 +3557,7 @@
<java-symbol type="integer" name="config_stableDeviceDisplayWidth" />
<java-symbol type="integer" name="config_stableDeviceDisplayHeight" />
- <java-symbol type="bool" name="config_display_no_service_when_sim_unready" />
+ <java-symbol type="array" name="config_display_no_service_when_sim_unready" />
<java-symbol type="layout" name="slice_grid" />
<java-symbol type="layout" name="slice_message_local" />
@@ -3757,8 +3757,12 @@
<java-symbol type="array" name="config_displayWhiteBalanceBaseThresholds" />
<java-symbol type="array" name="config_displayWhiteBalanceIncreaseThresholds" />
<java-symbol type="array" name="config_displayWhiteBalanceDecreaseThresholds" />
- <java-symbol type="dimen" name="config_displayWhiteBalanceLowLightAmbientBrightnessThreshold" />
+ <java-symbol type="array" name="config_displayWhiteBalanceLowLightAmbientBrightnesses" />
+ <java-symbol type="array" name="config_displayWhiteBalanceLowLightAmbientBiases" />
<java-symbol type="dimen" name="config_displayWhiteBalanceLowLightAmbientColorTemperature" />
+ <java-symbol type="array" name="config_displayWhiteBalanceHighLightAmbientBrightnesses" />
+ <java-symbol type="array" name="config_displayWhiteBalanceHighLightAmbientBiases" />
+ <java-symbol type="dimen" name="config_displayWhiteBalanceHighLightAmbientColorTemperature" />
<java-symbol type="array" name="config_displayWhiteBalanceAmbientColorTemperatures" />
<java-symbol type="array" name="config_displayWhiteBalanceDisplayColorTemperatures" />
<java-symbol type="drawable" name="ic_action_open" />
@@ -3786,6 +3790,7 @@
<!-- For high refresh rate displays -->
<java-symbol type="integer" name="config_defaultPeakRefreshRate" />
+ <java-symbol type="integer" name="config_brightnessThresholdOfPeakRefreshRate" />
<!-- For Auto-Brightness -->
<java-symbol type="string" name="config_displayLightSensorType" />
diff --git a/core/tests/coretests/res/values/overlayable_icons_test.xml b/core/tests/coretests/res/values/overlayable_icons_test.xml
index 68de2c0caf18..6503f3ee6d57 100644
--- a/core/tests/coretests/res/values/overlayable_icons_test.xml
+++ b/core/tests/coretests/res/values/overlayable_icons_test.xml
@@ -20,15 +20,18 @@
<array name="overlayable_icons">
<item>@*android:drawable/ic_audio_alarm</item>
<item>@*android:drawable/ic_audio_alarm_mute</item>
+ <item>@*android:drawable/ic_battery_80_24dp</item>
<item>@*android:drawable/ic_bluetooth_share_icon</item>
<item>@*android:drawable/ic_bt_headphones_a2dp</item>
<item>@*android:drawable/ic_bt_headset_hfp</item>
<item>@*android:drawable/ic_bt_hearing_aid</item>
<item>@*android:drawable/ic_bt_laptop</item>
+ <item>@*android:drawable/ic_bt_misc_hid</item>
<item>@*android:drawable/ic_bt_network_pan</item>
<item>@*android:drawable/ic_bt_pointing_hid</item>
<item>@*android:drawable/ic_corp_badge</item>
<item>@*android:drawable/ic_expand_more</item>
+ <item>@*android:drawable/ic_faster_emergency</item>
<item>@*android:drawable/ic_file_copy</item>
<item>@*android:drawable/ic_lock</item>
<item>@*android:drawable/ic_lock_bugreport</item>
@@ -36,6 +39,7 @@
<item>@*android:drawable/ic_lock_power_off</item>
<item>@*android:drawable/ic_lockscreen_ime</item>
<item>@*android:drawable/ic_mode_edit</item>
+ <item>@*android:drawable/ic_notifications_alerted</item>
<item>@*android:drawable/ic_phone</item>
<item>@*android:drawable/ic_qs_airplane</item>
<item>@*android:drawable/ic_qs_auto_rotate</item>
@@ -44,6 +48,7 @@
<item>@*android:drawable/ic_qs_dnd</item>
<item>@*android:drawable/ic_qs_flashlight</item>
<item>@*android:drawable/ic_qs_night_display_on</item>
+ <item>@*android:drawable/ic_qs_ui_mode_night</item>
<item>@*android:drawable/ic_restart</item>
<item>@*android:drawable/ic_screenshot</item>
<item>@*android:drawable/ic_settings_bluetooth</item>
@@ -65,6 +70,7 @@
<item>@*android:drawable/ic_wifi_signal_3</item>
<item>@*android:drawable/ic_wifi_signal_4</item>
<item>@*android:drawable/perm_group_activity_recognition</item>
+ <item>@*android:drawable/perm_group_aural</item>
<item>@*android:drawable/perm_group_calendar</item>
<item>@*android:drawable/perm_group_call_log</item>
<item>@*android:drawable/perm_group_camera</item>
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index cd36ba746a39..88bda9d64084 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -264,6 +264,7 @@ public class SettingsBackupTest {
Settings.Global.EUICC_PROVISIONED,
Settings.Global.EUICC_SUPPORTED_COUNTRIES,
Settings.Global.EUICC_FACTORY_RESET_TIMEOUT_MILLIS,
+ Settings.Global.EUICC_REMOVING_INVISIBLE_PROFILES_TIMEOUT_MILLIS,
Settings.Global.FANCY_IME_ANIMATIONS,
Settings.Global.FORCE_ALLOW_ON_EXTERNAL,
Settings.Global.FORCED_APP_STANDBY_ENABLED,
diff --git a/libs/androidfw/DisplayEventDispatcher.cpp b/libs/androidfw/DisplayEventDispatcher.cpp
index 660614895603..d8a3f42690f4 100644
--- a/libs/androidfw/DisplayEventDispatcher.cpp
+++ b/libs/androidfw/DisplayEventDispatcher.cpp
@@ -34,8 +34,9 @@ namespace android {
static const size_t EVENT_BUFFER_SIZE = 100;
DisplayEventDispatcher::DisplayEventDispatcher(const sp<Looper>& looper,
- ISurfaceComposer::VsyncSource vsyncSource) :
- mLooper(looper), mReceiver(vsyncSource), mWaitingForVsync(false) {
+ ISurfaceComposer::VsyncSource vsyncSource,
+ ISurfaceComposer::ConfigChanged configChanged) :
+ mLooper(looper), mReceiver(vsyncSource, configChanged), mWaitingForVsync(false) {
ALOGV("dispatcher %p ~ Initializing display event dispatcher.", this);
}
diff --git a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
index 5381c0174cb0..8bc25202b3ab 100644
--- a/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
+++ b/libs/androidfw/include/androidfw/DisplayEventDispatcher.h
@@ -23,7 +23,8 @@ namespace android {
class DisplayEventDispatcher : public LooperCallback {
public:
explicit DisplayEventDispatcher(const sp<Looper>& looper,
- ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp);
+ ISurfaceComposer::VsyncSource vsyncSource = ISurfaceComposer::eVsyncSourceApp,
+ ISurfaceComposer::ConfigChanged configChanged = ISurfaceComposer::eConfigChangedSuppress);
status_t initialize();
void dispose();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 41cb8fdc66bd..71c5b53f727a 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -156,7 +156,9 @@ void RenderThread::initializeDisplayEventReceiver() {
LOG_ALWAYS_FATAL_IF(mVsyncSource, "Initializing a second DisplayEventReceiver?");
if (!Properties::isolatedProcess) {
- auto receiver = std::make_unique<DisplayEventReceiver>();
+ auto receiver = std::make_unique<DisplayEventReceiver>(
+ ISurfaceComposer::eVsyncSourceApp,
+ ISurfaceComposer::eConfigChangedDispatch);
status_t status = receiver->initCheck();
LOG_ALWAYS_FATAL_IF(status != NO_ERROR,
"Initialization of DisplayEventReceiver "
diff --git a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
index 769fc52a574c..f9cfafa5c471 100644
--- a/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
+++ b/packages/CarSystemUI/src/com/android/systemui/qs/car/CarQSFragment.java
@@ -171,11 +171,6 @@ public class CarQSFragment extends Fragment implements QS {
}
@Override
- public void setKeyguardShowing(boolean keyguardShowing) {
- // No keyguard to show.
- }
-
- @Override
public void animateHeaderSlidingIn(long delay) {
// No header to animate.
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java
index 320380fc0ed9..869de0debd37 100644
--- a/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java
+++ b/packages/SettingsLib/src/com/android/settingslib/core/instrumentation/SharedPreferencesLogger.java
@@ -102,7 +102,8 @@ public class SharedPreferencesLogger implements SharedPreferences {
OnSharedPreferenceChangeListener listener) {
}
- private void logValue(String key, Object value) {
+ @VisibleForTesting
+ protected void logValue(String key, Object value) {
logValue(key, value, false /* forceLog */);
}
@@ -138,11 +139,18 @@ public class SharedPreferencesLogger implements SharedPreferences {
} else {
intVal = (int) floatValue;
}
+ } else if (value instanceof String) {
+ try {
+ intVal = Integer.parseInt((String) value);
+ } catch (NumberFormatException e) {
+ Log.w(LOG_TAG, "Tried to log unloggable object=" + value);
+ return;
+ }
} else {
- Log.w(LOG_TAG, "Tried to log unloggable object" + value);
+ Log.w(LOG_TAG, "Tried to log unloggable object=" + value);
return;
}
- // Pref key exists in set, log it's change in metrics.
+ // Pref key exists in set, log its change in metrics.
mMetricsFeature.action(SettingsEnums.PAGE_UNKNOWN,
SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE,
SettingsEnums.PAGE_UNKNOWN,
diff --git a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
index c7380c580e2f..5ac788e1b374 100644
--- a/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
+++ b/packages/SettingsLib/src/com/android/settingslib/graph/SignalDrawable.java
@@ -22,6 +22,7 @@ import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
+import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Path.Direction;
@@ -33,6 +34,7 @@ import android.graphics.drawable.DrawableWrapper;
import android.os.Handler;
import android.telephony.SignalStrength;
import android.util.LayoutDirection;
+import android.util.PathParser;
import com.android.settingslib.R;
import com.android.settingslib.Utils;
@@ -48,7 +50,6 @@ public class SignalDrawable extends DrawableWrapper {
private static final float VIEWPORT = 24f;
private static final float PAD = 2f / VIEWPORT;
- private static final float CUT_OUT = 7.9f / VIEWPORT;
private static final float DOT_SIZE = 3f / VIEWPORT;
private static final float DOT_PADDING = 1.5f / VIEWPORT;
@@ -65,21 +66,6 @@ public class SignalDrawable extends DrawableWrapper {
private static final long DOT_DELAY = 1000;
- private static float[][] X_PATH = new float[][]{
- {21.9f / VIEWPORT, 17.0f / VIEWPORT},
- {-1.1f / VIEWPORT, -1.1f / VIEWPORT},
- {-1.9f / VIEWPORT, 1.9f / VIEWPORT},
- {-1.9f / VIEWPORT, -1.9f / VIEWPORT},
- {-1.1f / VIEWPORT, 1.1f / VIEWPORT},
- {1.9f / VIEWPORT, 1.9f / VIEWPORT},
- {-1.9f / VIEWPORT, 1.9f / VIEWPORT},
- {1.1f / VIEWPORT, 1.1f / VIEWPORT},
- {1.9f / VIEWPORT, -1.9f / VIEWPORT},
- {1.9f / VIEWPORT, 1.9f / VIEWPORT},
- {1.1f / VIEWPORT, -1.1f / VIEWPORT},
- {-1.9f / VIEWPORT, -1.9f / VIEWPORT},
- };
-
private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mTransparentPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final int mDarkModeFillColor;
@@ -87,7 +73,11 @@ public class SignalDrawable extends DrawableWrapper {
private final Path mCutoutPath = new Path();
private final Path mForegroundPath = new Path();
private final Path mXPath = new Path();
+ private final Matrix mXScaleMatrix = new Matrix();
+ private final Path mScaledXPath = new Path();
private final Handler mHandler;
+ private final float mCutoutWidthFraction;
+ private final float mCutoutHeightFraction;
private float mDarkIntensity = -1;
private final int mIntrinsicSize;
private boolean mAnimating;
@@ -95,6 +85,14 @@ public class SignalDrawable extends DrawableWrapper {
public SignalDrawable(Context context) {
super(context.getDrawable(com.android.internal.R.drawable.ic_signal_cellular));
+ final String xPathString = context.getString(
+ com.android.internal.R.string.config_signalXPath);
+ mXPath.set(PathParser.createPathFromPathData(xPathString));
+ updateScaledXPath();
+ mCutoutWidthFraction = context.getResources().getFloat(
+ com.android.internal.R.dimen.config_signalCutoutWidthFraction);
+ mCutoutHeightFraction = context.getResources().getFloat(
+ com.android.internal.R.dimen.config_signalCutoutHeightFraction);
mDarkModeFillColor = Utils.getColorStateListDefaultColor(context,
R.color.dark_mode_icon_color_single_tone);
mLightModeFillColor = Utils.getColorStateListDefaultColor(context,
@@ -106,6 +104,15 @@ public class SignalDrawable extends DrawableWrapper {
setDarkIntensity(0);
}
+ private void updateScaledXPath() {
+ if (getBounds().isEmpty()) {
+ mXScaleMatrix.setScale(1f, 1f);
+ } else {
+ mXScaleMatrix.setScale(getBounds().width() / VIEWPORT, getBounds().height() / VIEWPORT);
+ }
+ mXPath.transform(mXScaleMatrix, mScaledXPath);
+ }
+
@Override
public int getIntrinsicWidth() {
return mIntrinsicSize;
@@ -170,6 +177,7 @@ public class SignalDrawable extends DrawableWrapper {
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
+ updateScaledXPath();
invalidateSelf();
}
@@ -205,19 +213,15 @@ public class SignalDrawable extends DrawableWrapper {
canvas.drawPath(mCutoutPath, mTransparentPaint);
canvas.drawPath(mForegroundPath, mForegroundPaint);
} else if (isInState(STATE_CUT)) {
- float cut = (CUT_OUT * width);
- mCutoutPath.moveTo(width - padding, height - padding);
- mCutoutPath.rLineTo(-cut, 0);
- mCutoutPath.rLineTo(0, -cut);
- mCutoutPath.rLineTo(cut, 0);
- mCutoutPath.rLineTo(0, cut);
+ float cutX = (mCutoutWidthFraction * width / VIEWPORT);
+ float cutY = (mCutoutHeightFraction * height / VIEWPORT);
+ mCutoutPath.moveTo(width, height);
+ mCutoutPath.rLineTo(-cutX, 0);
+ mCutoutPath.rLineTo(0, -cutY);
+ mCutoutPath.rLineTo(cutX, 0);
+ mCutoutPath.rLineTo(0, cutY);
canvas.drawPath(mCutoutPath, mTransparentPaint);
- mXPath.reset();
- mXPath.moveTo(X_PATH[0][0] * width, X_PATH[0][1] * height);
- for (int i = 1; i < X_PATH.length; i++) {
- mXPath.rLineTo(X_PATH[i][0] * width, X_PATH[i][1] * height);
- }
- canvas.drawPath(mXPath, mForegroundPaint);
+ canvas.drawPath(mScaledXPath, mForegroundPaint);
}
if (isRtl) {
canvas.restore();
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
index 6fd874989c35..60c9984e5ed4 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -90,12 +90,16 @@ public class RecentLocationApps {
for (int i = 0; i < appOpsCount; ++i) {
AppOpsManager.PackageOps ops = appOps.get(i);
+ // Don't show the Android System in the list - it's not actionable for the user.
+ // Also don't show apps belonging to background users except managed users.
String packageName = ops.getPackageName();
int uid = ops.getUid();
final UserHandle user = UserHandle.getUserHandleForUid(uid);
- // Don't show apps belonging to background users except managed users.
- if (!profiles.contains(user)) {
+ boolean isAndroidOs =
+ (uid == android.os.Process.SYSTEM_UID) && ANDROID_SYSTEM_PACKAGE_NAME.equals(
+ packageName);
+ if (isAndroidOs || !profiles.contains(user)) {
continue;
}
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
index 8f51dece64e5..89de81fde889 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/core/instrumentation/SharedPreferenceLoggerTest.java
@@ -162,4 +162,33 @@ public class SharedPreferenceLoggerTest {
"tag/key:com.android.settings",
0);
}
+
+ @Test
+ public void putString_shouldNotLogInitialPut() {
+ mSharedPrefLogger.logValue(TEST_KEY, "1");
+ mSharedPrefLogger.logValue(TEST_KEY, "2");
+ mSharedPrefLogger.logValue(TEST_KEY, "62");
+ mSharedPrefLogger.logValue(TEST_KEY, "0");
+
+ verify(mMetricsFeature, times(3)).action(eq(SettingsEnums.PAGE_UNKNOWN),
+ eq(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE),
+ eq(SettingsEnums.PAGE_UNKNOWN),
+ eq(TEST_TAGGED_KEY),
+ anyInt());
+ }
+
+ @Test
+ public void putString_shouldNotLogAnyNonIntegers() {
+ mSharedPrefLogger.logValue(TEST_KEY, "string");
+ mSharedPrefLogger.logValue(TEST_KEY, "not an int");
+ mSharedPrefLogger.logValue(TEST_KEY, "1.234f");
+ mSharedPrefLogger.logValue(TEST_KEY, "4.2");
+ mSharedPrefLogger.logValue(TEST_KEY, "3.0");
+
+ verify(mMetricsFeature, times(0)).action(eq(SettingsEnums.PAGE_UNKNOWN),
+ eq(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE),
+ eq(SettingsEnums.PAGE_UNKNOWN),
+ eq(TEST_TAGGED_KEY),
+ anyInt());
+ }
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 3cd82dfca6b6..b2c10ec8ea7f 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1944,9 +1944,6 @@ class SettingsProtoDumpUtil {
Settings.Secure.SILENCE_GESTURE,
SecureSettingsProto.Gesture.SILENCE_ENABLED);
dumpSetting(s, p,
- Settings.Secure.SILENCE_NOTIFICATION_GESTURE_COUNT,
- SecureSettingsProto.Gesture.SILENCE_NOTIFICATION_COUNT);
- dumpSetting(s, p,
Settings.Secure.SILENCE_TIMER_GESTURE_COUNT,
SecureSettingsProto.Gesture.SILENCE_TIMER_COUNT);
@@ -1956,6 +1953,19 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.Secure.SKIP_GESTURE,
SecureSettingsProto.Gesture.SKIP_ENABLED);
+
+ dumpSetting(s, p,
+ Settings.Secure.SILENCE_ALARMS_TOUCH_COUNT,
+ SecureSettingsProto.Gesture.SILENCE_ALARMS_TOUCH_COUNT);
+ dumpSetting(s, p,
+ Settings.Secure.SILENCE_CALL_TOUCH_COUNT,
+ SecureSettingsProto.Gesture.SILENCE_CALLS_TOUCH_COUNT);
+ dumpSetting(s, p,
+ Settings.Secure.SILENCE_TIMER_TOUCH_COUNT,
+ SecureSettingsProto.Gesture.SILENCE_TIMER_TOUCH_COUNT);
+ dumpSetting(s, p,
+ Settings.Secure.SKIP_TOUCH_COUNT,
+ SecureSettingsProto.Gesture.SKIP_TOUCH_COUNT);
p.end(gestureToken);
dumpSetting(s, p,
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 91a8ab5f692f..4c52b1324781 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -75,6 +75,7 @@ android_library {
"--extra-packages",
"com.android.keyguard",
],
+ kotlincflags: ["-Xjvm-default=enable"],
plugins: ["dagger2-compiler-2.19"],
}
@@ -128,6 +129,7 @@ android_library {
"telephony-common",
"android.test.base",
],
+ kotlincflags: ["-Xjvm-default=enable"],
aaptflags: [
"--extra-packages",
"com.android.keyguard:com.android.systemui",
@@ -155,6 +157,8 @@ android_app {
"telephony-common",
],
+ kotlincflags: ["-Xjvm-default=enable"],
+
dxflags: ["--multi-dex"],
aaptflags: [
"--extra-packages",
@@ -191,6 +195,8 @@ android_app {
"telephony-common",
],
+ kotlincflags: ["-Xjvm-default=enable"],
+
srcs: [
"legacy/recents/src/**/*.java",
"legacy/recents/src/**/I*.aidl",
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java
index 90fc86bc5b51..075df75f938a 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/OverlayPlugin.java
@@ -16,12 +16,13 @@ package com.android.systemui.plugins;
import android.view.View;
import com.android.systemui.plugins.annotations.ProvidesInterface;
+import com.android.systemui.plugins.statusbar.DozeParameters;
@ProvidesInterface(action = OverlayPlugin.ACTION, version = OverlayPlugin.VERSION)
public interface OverlayPlugin extends Plugin {
String ACTION = "com.android.systemui.action.PLUGIN_OVERLAY";
- int VERSION = 3;
+ int VERSION = 4;
/**
* Setup overlay plugin
@@ -29,9 +30,10 @@ public interface OverlayPlugin extends Plugin {
void setup(View statusBar, View navBar);
/**
- * Setup overlay plugin with callback
+ * Setup overlay plugin with callback and DozeParameters
*/
- default void setup(View statusBar, View navBar, Callback callback) {
+ default void setup(View statusBar, View navBar, Callback callback,
+ DozeParameters dozeParameters) {
setup(statusBar, navBar);
}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
index 2cbd788d0a30..60435d0dec35 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/SensorManagerPlugin.java
@@ -58,7 +58,7 @@ public interface SensorManagerPlugin extends Plugin {
public static final int TYPE_WAKE_LOCK_SCREEN = 1;
public static final int TYPE_WAKE_DISPLAY = 2;
public static final int TYPE_SWIPE = 3;
- public static final int TYPE_STATUS = 4;
+ public static final int TYPE_SKIP_STATUS = 4;
private int mType;
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
index 30d1352c8a01..85a9fec859f3 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QS.java
@@ -34,7 +34,7 @@ public interface QS extends FragmentBase {
String ACTION = "com.android.systemui.action.PLUGIN_QS";
- int VERSION = 6;
+ int VERSION = 7;
String TAG = "QS";
@@ -51,7 +51,7 @@ public interface QS extends FragmentBase {
void setListening(boolean listening);
boolean isShowingDetail();
void closeDetail();
- void setKeyguardShowing(boolean keyguardShowing);
+ default void setShowCollapsedOnKeyguard(boolean showCollapsedOnKeyguard) {}
void animateHeaderSlidingIn(long delay);
void animateHeaderSlidingOut();
void setQsExpansion(float qsExpansionFraction, float headerTranslation);
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java
new file mode 100644
index 000000000000..678eb31304a1
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/DozeParameters.java
@@ -0,0 +1,32 @@
+/*
+ * 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.plugins.statusbar;
+
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Retrieve doze information
+ */
+@ProvidesInterface(version = DozeParameters.VERSION)
+public interface DozeParameters {
+ int VERSION = 1;
+
+ /**
+ * Whether to doze when the screen turns off
+ */
+ boolean shouldControlScreenOff();
+}
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
index 3ee69b4c3224..fe547a0a16fa 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
@@ -18,7 +18,6 @@ package com.android.systemui.plugins.statusbar;
import com.android.systemui.plugins.annotations.DependsOn;
import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
/**
@@ -94,5 +93,15 @@ public interface StatusBarStateController {
* performance regressions.
*/
default void onDozeAmountChanged(float linear, float eased) {}
+
+ /**
+ * Callback to be notified when the sysui visibility changes
+ */
+ default void onSystemUiVisibilityChanged(int visibility) {}
+
+ /**
+ * Callback to be notified when the pulsing state changes
+ */
+ default void onPulsingChanged(boolean pulsing) {}
}
}
diff --git a/packages/SystemUI/res-keyguard/drawable/bubble_hour_hand.xml b/packages/SystemUI/res-keyguard/drawable/bubble_hour_hand.xml
index 65f7a0e29843..8c611f61dc23 100644
--- a/packages/SystemUI/res-keyguard/drawable/bubble_hour_hand.xml
+++ b/packages/SystemUI/res-keyguard/drawable/bubble_hour_hand.xml
@@ -6,5 +6,5 @@
<path
android:pathData="M170,40m-39,0a39,39 0,1 1,78 0a39,39 0,1 1,-78 0"
android:strokeColor="#000000"
- android:strokeWidth="2"/>
+ android:strokeWidth="3"/>
</vector>
diff --git a/packages/SystemUI/res-keyguard/drawable/bubble_minute_hand.xml b/packages/SystemUI/res-keyguard/drawable/bubble_minute_hand.xml
index 95b4b1ad0b9b..27bc43638f06 100644
--- a/packages/SystemUI/res-keyguard/drawable/bubble_minute_hand.xml
+++ b/packages/SystemUI/res-keyguard/drawable/bubble_minute_hand.xml
@@ -6,5 +6,5 @@
<path
android:pathData="M170,1L170,1A39,39 0,0 1,209 40L209,130A39,39 0,0 1,170 169L170,169A39,39 0,0 1,131 130L131,40A39,39 0,0 1,170 1z"
android:strokeColor="#000000"
- android:strokeWidth="2"/>
+ android:strokeWidth="3"/>
</vector>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
index a9ba19d2d393..f4d34f4ca141 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_presentation.xml
@@ -41,7 +41,7 @@
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/widget_vertical_padding"
+ android:layout_marginTop="24dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/kg_security_lock_normal" />
</LinearLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
index 04d6afc1935f..847fba41f593 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml
@@ -25,14 +25,13 @@
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- androidprv:layout_maxWidth="@dimen/keyguard_security_width"
- androidprv:layout_maxHeight="@dimen/keyguard_security_height"
android:gravity="center_horizontal|top">
<LinearLayout
android:id="@+id/status_view_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginBottom="@dimen/widget_vertical_padding"
+ android:clipChildren="false"
+ android:clipToPadding="false"
android:orientation="vertical">
<TextView
android:id="@+id/logout"
@@ -71,5 +70,11 @@
android:letterSpacing="0.05"
android:ellipsize="marquee"
android:singleLine="true" />
+ <com.android.systemui.statusbar.phone.NotificationIconContainer
+ android:id="@+id/clock_notification_icon_container"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/notification_shelf_height"
+ android:layout_marginTop="@dimen/widget_vertical_padding"
+ />
</LinearLayout>
</com.android.keyguard.KeyguardStatusView>
diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml
index 8e00efeed62c..f9389ce24d96 100644
--- a/packages/SystemUI/res-keyguard/values/dimens.xml
+++ b/packages/SystemUI/res-keyguard/values/dimens.xml
@@ -53,8 +53,8 @@
<dimen name="title_clock_padding">4dp</dimen>
<!-- Clock with header -->
<dimen name="widget_small_font_size">@dimen/widget_title_font_size</dimen>
- <dimen name="widget_vertical_padding">24dp</dimen>
- <dimen name="widget_vertical_padding_with_header">32dp</dimen>
+ <dimen name="widget_vertical_padding">17dp</dimen>
+ <dimen name="widget_vertical_padding_with_header">25dp</dimen>
<dimen name="widget_vertical_padding_clock">12dp</dimen>
<!-- Subtitle paddings -->
<dimen name="widget_horizontal_padding">8dp</dimen>
diff --git a/packages/SystemUI/res-keyguard/values/strings.xml b/packages/SystemUI/res-keyguard/values/strings.xml
index 9b47e1436ede..0fe7084bb145 100644
--- a/packages/SystemUI/res-keyguard/values/strings.xml
+++ b/packages/SystemUI/res-keyguard/values/strings.xml
@@ -407,14 +407,11 @@ number">%d</xliff:g> remaining attempt before SIM becomes permanently unusable.
number">%d</xliff:g> remaining attempts before SIM becomes permanently unusable. Contact carrier for details.</item>
</plurals>
- <!-- Title for default clock face that will appear in the picker app next to a preview image of
- the clock face. [CHAR LIMIT=8] -->
- <string name="clock_title_default" translatable="false">Default</string>
- <!-- Title for Bubble clock face that will appear in the picker app next to a preview image of
- the clock face. [CHAR LIMIT=8] -->
- <string name="clock_title_bubble" translatable="false">Bubble</string>
- <!-- Title for Stretch clock face that will appear in the picker app next to a preview image of
- the clock face. [CHAR LIMIT=8] -->
- <string name="clock_title_analog" translatable="false">Analog</string>
+ <!-- Name of the "Default" clock face, which is the clock face that will be shown by default. [CHAR LIMIT=15]-->
+ <string name="clock_title_default">Default</string>
+ <!-- Name of the "Bubble" clock face, which is an analog clock with hands shaped like large bubbles [CHAR LIMIT=15]-->
+ <string name="clock_title_bubble">Bubble</string>
+ <!-- Name of the "Analog" clock face [CHAR LIMIT=15]-->
+ <string name="clock_title_analog">Analog</string>
</resources>
diff --git a/core/res/res/anim/lock_lock.xml b/packages/SystemUI/res/anim/lock_lock.xml
index 3b8c4855fc8f..3167e7cd616d 100644
--- a/core/res/res/anim/lock_lock.xml
+++ b/packages/SystemUI/res/anim/lock_lock.xml
@@ -1,17 +1,18 @@
-<!-- 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.
--->
+<!--
+ ~ 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
+ -->
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt">
<aapt:attr name="android:drawable">
diff --git a/packages/SystemUI/res/anim/lock_lock_circular.xml b/packages/SystemUI/res/anim/lock_lock_circular.xml
new file mode 100644
index 000000000000..81694407b640
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_lock_circular.xml
@@ -0,0 +1,320 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="42dp"
+ android:viewportHeight="42"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_2_G_T_1"
+ android:translateX="15.999"
+ android:translateY="24.333" >
+ <group
+ android:name="_R_G_L_2_G"
+ android:translateX="-9.583"
+ android:translateY="-8.916" >
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M17.42 1.75 C17.42,1.75 17.42,14.58 17.42,14.58 C17.42,15.41 16.74,16.08 15.92,16.08 C15.92,16.08 3.25,16.08 3.25,16.08 C2.42,16.08 1.75,15.41 1.75,14.58 C1.75,14.58 1.75,1.75 1.75,1.75 C1.75,1.75 17.42,1.75 17.42,1.75c M18.92 0.25 C18.92,0.25 0.25,0.25 0.25,0.25 C0.25,0.25 0.25,14.58 0.25,14.58 C0.25,16.24 1.59,17.58 3.25,17.58 C3.25,17.58 15.92,17.58 15.92,17.58 C17.57,17.58 18.92,16.24 18.92,14.58 C18.92,14.58 18.92,0.25 18.92,0.25c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_4_T_1"
+ android:translateX="15.999"
+ android:translateY="24.333" >
+ <group
+ android:name="_R_G_L_1_G_N_4_T_0"
+ android:translateX="-9.583"
+ android:translateY="-8.916" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:pivotX="2.25"
+ android:pivotY="3.334"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="7.334"
+ android:translateY="5.333" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M4.25 2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25 C3.35,0.25 4.25,1.15 4.25,2.25c " />
+ <path
+ android:name="_R_G_L_1_G_D_1_P_0"
+ android:pathData=" M2.25 2.25 C2.25,2.25 2.25,5.92 2.25,5.92 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_4_T_1"
+ android:translateX="15.999"
+ android:translateY="24.333" >
+ <group
+ android:name="_R_G_L_0_G_N_4_T_0"
+ android:translateX="-9.583"
+ android:translateY="-8.916" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="1.5"
+ android:translateY="-11.835" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M12.42 12.6 C12.42,12.6 12.41,8.16 12.41,8.16 C12.41,5.81 14.36,3.75 16.75,3.77 C19.15,3.78 21.07,5.71 21.07,8.05 C21.07,8.05 21.08,8.22 21.08,8.22 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_2_G_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="translateY"
+ android:startOffset="0"
+ android:valueFrom="24.333"
+ android:valueTo="24.333"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="translateY"
+ android:startOffset="400"
+ android:valueFrom="24.333"
+ android:valueTo="25.833"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="translateY"
+ android:startOffset="517"
+ android:valueFrom="25.833"
+ android:valueTo="24.333"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="450"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="450"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="450"
+ android:valueFrom="1"
+ android:valueTo="1.05"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="450"
+ android:valueFrom="1"
+ android:valueTo="1.05"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="scaleX"
+ android:startOffset="533"
+ android:valueFrom="1.05"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="scaleY"
+ android:startOffset="533"
+ android:valueFrom="1.05"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_4_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="translateY"
+ android:startOffset="0"
+ android:valueFrom="24.333"
+ android:valueTo="24.333"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="translateY"
+ android:startOffset="400"
+ android:valueFrom="24.333"
+ android:valueTo="25.833"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="translateY"
+ android:startOffset="517"
+ android:valueFrom="25.833"
+ android:valueTo="24.333"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="333"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M12.42 12.6 C12.42,12.6 12.41,8.16 12.41,8.16 C12.41,5.81 14.36,3.75 16.75,3.77 C19.15,3.78 21.07,5.71 21.07,8.05 C21.07,8.05 21.08,8.22 21.08,8.22 "
+ android:valueTo="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.635,0 0.43,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="67"
+ android:propertyName="pathData"
+ android:startOffset="333"
+ android:valueFrom="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
+ android:valueTo="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.512,0 0.41,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_4_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:propertyName="translateY"
+ android:startOffset="0"
+ android:valueFrom="24.333"
+ android:valueTo="24.333"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="translateY"
+ android:startOffset="400"
+ android:valueFrom="24.333"
+ android:valueTo="25.833"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="translateY"
+ android:startOffset="517"
+ android:valueFrom="25.833"
+ android:valueTo="24.333"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_lock_filled.xml b/packages/SystemUI/res/anim/lock_lock_filled.xml
new file mode 100644
index 000000000000..017c3299c3b2
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_lock_filled.xml
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="42dp"
+ android:viewportHeight="42"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_1_G_T_1"
+ android:translateX="16"
+ android:translateY="25" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="-10.917"
+ android:translateY="-9.583" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_3_T_1"
+ android:translateX="16"
+ android:translateY="25" >
+ <group
+ android:name="_R_G_L_0_G_N_3_T_0"
+ android:translateX="-10.917"
+ android:translateY="-9.583" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="9.917000000000002"
+ android:translateY="-12.75" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M13 9 C13,7.9 12.55,6.9 11.83,6.17 C11.1,5.45 10.11,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_1_G_D_0_P_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="450"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="pathData"
+ android:startOffset="450"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.58 C9.27,12.58 7.92,11.23 7.92,9.58 C7.92,7.93 9.27,6.58 10.92,6.58 C12.57,6.58 13.92,7.93 13.92,9.58 C13.92,11.23 12.57,12.58 10.92,12.58c "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="pathData"
+ android:startOffset="533"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.58 C9.27,12.58 7.92,11.23 7.92,9.58 C7.92,7.93 9.27,6.58 10.92,6.58 C12.57,6.58 13.92,7.93 13.92,9.58 C13.92,11.23 12.57,12.58 10.92,12.58c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:pathData="M 16,25C 16,25.27083334326744 16,25 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,25C 16,25.27083334326744 16,26.625 16,26.625"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="400" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,26.625C 16,26.625 16,25.27083334326744 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="517" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M13 9 C13,7.9 12.55,6.9 11.83,6.17 C11.1,5.45 10.11,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
+ android:valueTo="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.637,0 0.437,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="pathData"
+ android:startOffset="317"
+ android:valueFrom="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
+ android:valueTo="M-3 13.04 C-3,13.04 -3,9.04 -3,9.04 C-3,6.83 -1.25,5.05 0.69,5.01 C2.9,4.97 5,6.79 5,9 C5,9 5,13 5,13 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.497,0 0.408,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_3_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:pathData="M 16,25C 16,25.27083334326744 16,25 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,25C 16,25.27083334326744 16,26.625 16,26.625"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="400" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,26.625C 16,26.625 16,25.27083334326744 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="517" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_lock_rounded.xml b/packages/SystemUI/res/anim/lock_lock_rounded.xml
new file mode 100644
index 000000000000..fc4545c4323d
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_lock_rounded.xml
@@ -0,0 +1,314 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="42dp"
+ android:viewportHeight="42"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_2_G_T_1"
+ android:translateX="16"
+ android:translateY="25" >
+ <group
+ android:name="_R_G_L_2_G"
+ android:translateX="-14.667"
+ android:translateY="-12.667" >
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:pathData=" M22.09 5 C22.09,5 6,5 6,5 C5.45,5 5,5.45 5,6 C5,6 5,19.33 5,19.33 C5,19.89 5.45,20.33 6,20.33 C6,20.33 23.33,20.33 23.33,20.33 C23.89,20.33 24.33,19.89 24.33,19.33 C24.33,19.33 24.33,6 24.33,6 C24.33,5.45 23.89,5 23.33,5 C23.33,5 22.09,5 22.09,5c "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_5_T_1"
+ android:translateX="16"
+ android:translateY="25" >
+ <group
+ android:name="_R_G_L_1_G_N_5_T_0"
+ android:translateX="-14.667"
+ android:translateY="-12.667" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:pivotX="2.25"
+ android:pivotY="2.25"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="12.416"
+ android:translateY="10.417" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c " />
+ </group>
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_5_T_1"
+ android:translateX="16"
+ android:translateY="25" >
+ <group
+ android:name="_R_G_L_0_G_N_5_T_0"
+ android:translateX="-14.667"
+ android:translateY="-12.667" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="5.333"
+ android:translateY="-9.425999999999998" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.68,6.62 15.69,5.03 18.01,5.04 C20.46,5.04 22.32,6.89 22.34,8.85 C22.34,8.85 22.33,8.89 22.33,8.89 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_2_G_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:pathData="M 16,25C 16,25.35416665673256 16,25 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,25C 16,25.35416665673256 16,27.125 16,27.125"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="400" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,27.125C 16,27.125 16,25.35416665673256 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="517" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="450"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="450"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="450"
+ android:valueFrom="1"
+ android:valueTo="1.12"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="450"
+ android:valueFrom="1"
+ android:valueTo="1.12"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="scaleX"
+ android:startOffset="533"
+ android:valueFrom="1.12"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="scaleY"
+ android:startOffset="533"
+ android:valueFrom="1.12"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_5_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:pathData="M 16,25C 16,25.35416665673256 16,25 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,25C 16,25.35416665673256 16,27.125 16,27.125"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="400" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,27.125C 16,27.125 16,25.35416665673256 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="517" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.68,6.62 15.69,5.03 18.01,5.04 C20.46,5.04 22.32,6.89 22.34,8.85 C22.34,8.85 22.33,8.89 22.33,8.89 "
+ android:valueTo="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.825,0 0.321,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="pathData"
+ android:startOffset="317"
+ android:valueFrom="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
+ android:valueTo="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.683,0 0.342,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_5_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="400"
+ android:pathData="M 16,25C 16,25.35416665673256 16,25 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,25C 16,25.35416665673256 16,27.125 16,27.125"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="400" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:pathData="M 16,27.125C 16,27.125 16,25.35416665673256 16,25"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="517" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/core/res/res/anim/lock_scanning.xml b/packages/SystemUI/res/anim/lock_scanning.xml
index db7972f542b3..db7972f542b3 100644
--- a/core/res/res/anim/lock_scanning.xml
+++ b/packages/SystemUI/res/anim/lock_scanning.xml
diff --git a/packages/SystemUI/res/anim/lock_scanning_circular.xml b/packages/SystemUI/res/anim/lock_scanning_circular.xml
new file mode 100644
index 000000000000..9468213562f4
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_scanning_circular.xml
@@ -0,0 +1,537 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="42dp"
+ android:viewportHeight="42"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_2_G"
+ android:pivotX="9.583"
+ android:pivotY="8.916"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="6.416"
+ android:translateY="15.416999999999998" >
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M17.42 1.75 C17.42,1.75 17.42,14.58 17.42,14.58 C17.42,15.41 16.74,16.08 15.92,16.08 C15.92,16.08 3.25,16.08 3.25,16.08 C2.42,16.08 1.75,15.41 1.75,14.58 C1.75,14.58 1.75,1.75 1.75,1.75 C1.75,1.75 17.42,1.75 17.42,1.75c M18.92 0.25 C18.92,0.25 0.25,0.25 0.25,0.25 C0.25,0.25 0.25,14.58 0.25,14.58 C0.25,16.24 1.59,17.58 3.25,17.58 C3.25,17.58 15.92,17.58 15.92,17.58 C17.57,17.58 18.92,16.24 18.92,14.58 C18.92,14.58 18.92,0.25 18.92,0.25c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_3_T_0"
+ android:pivotX="9.583"
+ android:pivotY="8.916"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="6.416"
+ android:translateY="15.416999999999998" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:pivotX="2.25"
+ android:pivotY="3.334"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="7.334"
+ android:translateY="5.333" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M4.25 2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25 C3.35,0.25 4.25,1.15 4.25,2.25c " />
+ <path
+ android:name="_R_G_L_1_G_D_1_P_0"
+ android:pathData=" M2.25 2.25 C2.25,2.25 2.25,5.92 2.25,5.92 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_3_T_0"
+ android:pivotX="9.583"
+ android:pivotY="8.916"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="6.416"
+ android:translateY="15.416999999999998" >
+ <group
+ android:name="_R_G_L_0_G_T_1"
+ android:translateX="9.583"
+ android:translateY="-3.662" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="-8.083"
+ android:translateY="-8.173" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_2_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.613,0 0.396,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.613,0 0.396,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="scaleX"
+ android:startOffset="150"
+ android:valueFrom="1"
+ android:valueTo="0.6"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.613,0 0.396,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="scaleY"
+ android:startOffset="150"
+ android:valueFrom="1"
+ android:valueTo="0.6"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.613,0 0.396,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleX"
+ android:startOffset="267"
+ android:valueFrom="0.6"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.429,0 0.613,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleY"
+ android:startOffset="267"
+ android:valueFrom="0.6"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.429,0 0.613,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_3_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:valueTo="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="83"
+ android:valueFrom="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:valueTo="M12.39 9.16 C12.39,9.16 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.73,9.16 3.73,9.16 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="pathData"
+ android:startOffset="250"
+ android:valueFrom="M12.39 9.16 C12.39,9.16 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.73,9.16 3.73,9.16 "
+ android:valueTo="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:pathData="M 9.583,-3.662C 9.583,-3.03073584985733 9.583,-3.662 9.583,-3.662"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:pathData="M 9.583,-3.662C 9.583,-3.03073584985733 9.583,0.126 9.583,0.126"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="83" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:pathData="M 9.583,0.126C 9.583,0.126 9.583,-3.03073584985733 9.583,-3.662"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="250" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_3_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_scanning_filled.xml b/packages/SystemUI/res/anim/lock_scanning_filled.xml
new file mode 100644
index 000000000000..83ac8ad205f7
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_scanning_filled.xml
@@ -0,0 +1,339 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="42dp"
+ android:viewportHeight="42"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:pivotX="10.917"
+ android:pivotY="9.583"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="5.083"
+ android:translateY="15.417" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_2_T_0"
+ android:pivotX="10.917"
+ android:pivotY="9.583"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="5.083"
+ android:translateY="15.417" >
+ <group
+ android:name="_R_G_L_0_G_T_1"
+ android:translateX="10.917"
+ android:translateY="-3.75" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="-9"
+ android:translateY="-9" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M13 13 C13,13 13,9 13,9 C13,6.79 11.21,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_1_G_D_0_P_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="pathData"
+ android:startOffset="150"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.4 C9.91,11.4 9.1,10.59 9.1,9.58 C9.1,8.58 9.91,7.76 10.92,7.76 C11.92,7.76 12.74,8.58 12.74,9.58 C12.74,10.59 11.92,11.4 10.92,11.4c "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="pathData"
+ android:startOffset="267"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.4 C9.91,11.4 9.1,10.59 9.1,9.58 C9.1,8.58 9.91,7.76 10.92,7.76 C11.92,7.76 12.74,8.58 12.74,9.58 C12.74,10.59 11.92,11.4 10.92,11.4c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:pathData="M 10.917,-3.75C 10.917,-3.13846284151077 10.917,-3.75 10.917,-3.75"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:pathData="M 10.917,-3.75C 10.917,-3.13846284151077 10.917,-0.081 10.917,-0.081"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="83" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:pathData="M 10.917,-0.081C 10.917,-0.081 10.917,-3.13846284151077 10.917,-3.75"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="250" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_2_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.532,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_scanning_rounded.xml b/packages/SystemUI/res/anim/lock_scanning_rounded.xml
new file mode 100644
index 000000000000..983549230b54
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_scanning_rounded.xml
@@ -0,0 +1,531 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="38dp"
+ android:viewportHeight="38"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_2_G"
+ android:pivotX="14.667"
+ android:pivotY="12.667"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="1.3330000000000002"
+ android:translateY="10.333" >
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:pathData=" M22.09 5 C22.09,5 6,5 6,5 C5.45,5 5,5.45 5,6 C5,6 5,19.33 5,19.33 C5,19.89 5.45,20.33 6,20.33 C6,20.33 23.33,20.33 23.33,20.33 C23.89,20.33 24.33,19.89 24.33,19.33 C24.33,19.33 24.33,6 24.33,6 C24.33,5.45 23.89,5 23.33,5 C23.33,5 22.09,5 22.09,5c "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_4_T_0"
+ android:pivotX="14.667"
+ android:pivotY="12.667"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="1.3330000000000002"
+ android:translateY="10.333" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:pivotX="2.25"
+ android:pivotY="2.25"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="12.416"
+ android:translateY="10.417" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_4_T_0"
+ android:pivotX="14.667"
+ android:pivotY="12.667"
+ android:scaleX="1"
+ android:scaleY="1"
+ android:translateX="1.3330000000000002"
+ android:translateY="10.333" >
+ <group
+ android:name="_R_G_L_0_G_T_1"
+ android:translateX="14.666"
+ android:translateY="0.287" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="-9.333"
+ android:translateY="-9.713" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_2_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.397,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.397,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="150"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="scaleX"
+ android:startOffset="150"
+ android:valueFrom="1"
+ android:valueTo="0.8"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="117"
+ android:propertyName="scaleY"
+ android:startOffset="150"
+ android:valueFrom="1"
+ android:valueTo="0.8"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleX"
+ android:startOffset="267"
+ android:valueFrom="0.8"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="317"
+ android:propertyName="scaleY"
+ android:startOffset="267"
+ android:valueFrom="0.8"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_4_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.397,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.397,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="pathData"
+ android:startOffset="0"
+ android:valueFrom="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:valueTo="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="pathData"
+ android:startOffset="83"
+ android:valueFrom="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:valueTo="M13.7 10.21 C13.7,10.21 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5.03,10.21 5.03,10.21 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="pathData"
+ android:startOffset="250"
+ android:valueFrom="M13.7 10.21 C13.7,10.21 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5.03,10.21 5.03,10.21 "
+ android:valueTo="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:valueType="pathType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_T_1" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:pathData="M 14.666,0.287C 14.666,0.8689466710090599 14.666,0.287 14.666,0.287"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="0" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:pathData="M 14.666,0.287C 14.666,0.8689466710090599 14.666,3.779 14.666,3.779"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="83" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:pathData="M 14.666,3.779C 14.666,3.779 14.666,0.8689466710090599 14.666,0.287"
+ android:propertyName="translateXY"
+ android:propertyXName="translateX"
+ android:propertyYName="translateY"
+ android:startOffset="250" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_4_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="0"
+ android:valueFrom="1"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleX"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="83"
+ android:propertyName="scaleY"
+ android:startOffset="83"
+ android:valueFrom="1"
+ android:valueTo="0.9500000000000001"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.36,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleX"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="183"
+ android:propertyName="scaleY"
+ android:startOffset="167"
+ android:valueFrom="0.9500000000000001"
+ android:valueTo="1.2"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.461,0 0.526,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleX"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.397,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="233"
+ android:propertyName="scaleY"
+ android:startOffset="350"
+ android:valueFrom="1.2"
+ android:valueTo="1"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.428,0 0.397,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/core/res/res/anim/lock_to_error.xml b/packages/SystemUI/res/anim/lock_to_error.xml
index e356f26dde59..e356f26dde59 100644
--- a/core/res/res/anim/lock_to_error.xml
+++ b/packages/SystemUI/res/anim/lock_to_error.xml
diff --git a/packages/SystemUI/res/anim/lock_to_error_circular.xml b/packages/SystemUI/res/anim/lock_to_error_circular.xml
new file mode 100644
index 000000000000..9a847232d80b
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_to_error_circular.xml
@@ -0,0 +1,276 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="32dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_2_G"
+ android:pivotX="9.583"
+ android:pivotY="8.916"
+ android:rotation="0"
+ android:translateX="6.416"
+ android:translateY="10.416999999999998" >
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M17.42 1.75 C17.42,1.75 17.42,14.58 17.42,14.58 C17.42,15.41 16.74,16.08 15.92,16.08 C15.92,16.08 3.25,16.08 3.25,16.08 C2.42,16.08 1.75,15.41 1.75,14.58 C1.75,14.58 1.75,1.75 1.75,1.75 C1.75,1.75 17.42,1.75 17.42,1.75c M18.92 0.25 C18.92,0.25 0.25,0.25 0.25,0.25 C0.25,0.25 0.25,14.58 0.25,14.58 C0.25,16.24 1.59,17.58 3.25,17.58 C3.25,17.58 15.92,17.58 15.92,17.58 C17.57,17.58 18.92,16.24 18.92,14.58 C18.92,14.58 18.92,0.25 18.92,0.25c " />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_3_T_0"
+ android:pivotX="9.583"
+ android:pivotY="8.916"
+ android:rotation="0"
+ android:translateX="6.416"
+ android:translateY="10.416999999999998" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="7.334"
+ android:translateY="5.333" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M4.25 2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25 C3.35,0.25 4.25,1.15 4.25,2.25c " />
+ <path
+ android:name="_R_G_L_1_G_D_1_P_0"
+ android:pathData=" M2.25 2.25 C2.25,2.25 2.25,5.92 2.25,5.92 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_3_T_0"
+ android:pivotX="9.583"
+ android:pivotY="8.916"
+ android:rotation="0"
+ android:translateX="6.416"
+ android:translateY="10.416999999999998" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="1.5"
+ android:translateY="-11.835" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_2_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_3_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_3_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_to_error_filled.xml b/packages/SystemUI/res/anim/lock_to_error_filled.xml
new file mode 100644
index 000000000000..6eb7425d9002
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_to_error_filled.xml
@@ -0,0 +1,188 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="32dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:pivotX="10.917"
+ android:pivotY="9.583"
+ android:rotation="0"
+ android:translateX="5.083"
+ android:translateY="10.417" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c " />
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_2_T_0"
+ android:pivotX="10.917"
+ android:pivotY="9.583"
+ android:rotation="0"
+ android:translateX="5.083"
+ android:translateY="10.417" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="1.9169999999999998"
+ android:translateY="-12.75" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M13 13 C13,13 13,9 13,9 C13,6.79 11.21,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="2" />
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_1_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_2_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_to_error_rounded.xml b/packages/SystemUI/res/anim/lock_to_error_rounded.xml
new file mode 100644
index 000000000000..46043caf8862
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_to_error_rounded.xml
@@ -0,0 +1,270 @@
+<?xml version="1.0" encoding="utf-8"?>
+<animated-vector xmlns:aapt="http://schemas.android.com/aapt"
+ xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <aapt:attr name="android:drawable" >
+ <vector
+ android:height="32dp"
+ android:viewportHeight="32"
+ android:viewportWidth="32"
+ android:width="32dp" >
+ <group android:name="_R_G" >
+ <group
+ android:name="_R_G_L_2_G"
+ android:pivotX="14.667"
+ android:pivotY="12.667"
+ android:rotation="0"
+ android:translateX="1.3330000000000002"
+ android:translateY="7.333" >
+ <path
+ android:name="_R_G_L_2_G_D_0_P_0"
+ android:pathData=" M22.09 5 C22.09,5 6,5 6,5 C5.45,5 5,5.45 5,6 C5,6 5,19.33 5,19.33 C5,19.89 5.45,20.33 6,20.33 C6,20.33 23.33,20.33 23.33,20.33 C23.89,20.33 24.33,19.89 24.33,19.33 C24.33,19.33 24.33,6 24.33,6 C24.33,5.45 23.89,5 23.33,5 C23.33,5 22.09,5 22.09,5c "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ <group
+ android:name="_R_G_L_1_G_N_4_T_0"
+ android:pivotX="14.667"
+ android:pivotY="12.667"
+ android:rotation="0"
+ android:translateX="1.3330000000000002"
+ android:translateY="7.333" >
+ <group
+ android:name="_R_G_L_1_G"
+ android:translateX="12.416"
+ android:translateY="10.417" >
+ <path
+ android:name="_R_G_L_1_G_D_0_P_0"
+ android:fillAlpha="1"
+ android:fillColor="#ffffff"
+ android:fillType="nonZero"
+ android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c " />
+ </group>
+ </group>
+ <group
+ android:name="_R_G_L_0_G_N_4_T_0"
+ android:pivotX="14.667"
+ android:pivotY="12.667"
+ android:rotation="0"
+ android:translateX="1.3330000000000002"
+ android:translateY="7.333" >
+ <group
+ android:name="_R_G_L_0_G"
+ android:translateX="5.333"
+ android:translateY="-9.425999999999998" >
+ <path
+ android:name="_R_G_L_0_G_D_0_P_0"
+ android:pathData=" M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:strokeAlpha="1"
+ android:strokeColor="#ffffff"
+ android:strokeLineCap="round"
+ android:strokeLineJoin="round"
+ android:strokeWidth="1.5" />
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group" />
+ </vector>
+ </aapt:attr>
+
+ <target android:name="_R_G_L_2_G" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_4_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_4_T_0" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="133"
+ android:propertyName="rotation"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="120"
+ android:propertyName="rotation"
+ android:startOffset="133"
+ android:valueFrom="0"
+ android:valueTo="-10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.44,0 0.601,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="97"
+ android:propertyName="rotation"
+ android:startOffset="253"
+ android:valueFrom="-10"
+ android:valueTo="10"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.531,0 0.389,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="100"
+ android:propertyName="rotation"
+ android:startOffset="350"
+ android:valueFrom="10"
+ android:valueTo="-5"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.499,0 0.489,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator
+ android:duration="167"
+ android:propertyName="rotation"
+ android:startOffset="450"
+ android:valueFrom="-5"
+ android:valueTo="0"
+ android:valueType="floatType" >
+ <aapt:attr name="android:interpolator" >
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.293,0 0.689,1 1.0,1.0" />
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group" >
+ <aapt:attr name="android:animation" >
+ <set android:ordering="together" >
+ <objectAnimator
+ android:duration="717"
+ android:propertyName="translateX"
+ android:startOffset="0"
+ android:valueFrom="0"
+ android:valueTo="1"
+ android:valueType="floatType" />
+ </set>
+ </aapt:attr>
+ </target>
+
+</animated-vector> \ No newline at end of file
diff --git a/core/res/res/anim/lock_unlock.xml b/packages/SystemUI/res/anim/lock_unlock.xml
index 91d44320d8c2..64456ce47eaa 100644
--- a/core/res/res/anim/lock_unlock.xml
+++ b/packages/SystemUI/res/anim/lock_unlock.xml
@@ -34,7 +34,7 @@
android:pathData=" M22.33 21 C22.33,21 6.33,21 6.33,21 C5.6,21 5,20.4 5,19.67 C5,19.67 5,6.33 5,6.33 C5,5.6 5.6,5 6.33,5 C6.33,5 22.33,5 22.33,5 C23.07,5 23.67,5.6 23.67,6.33 C23.67,6.33 23.67,19.67 23.67,19.67 C23.67,20.4 23.07,21 22.33,21c "
android:strokeWidth="2"
android:strokeAlpha="1"
- android:strokeColor="#ffffff" />
+ android:strokeColor="#ffffff"/>
</group>
</group>
<group
@@ -79,7 +79,7 @@
android:pathData=" M14.33 14.33 C14.33,14.33 14.33,9.67 14.33,9.67 C14.33,7.09 12.24,5 9.67,5 C7.09,5 5,7.09 5,9.67 C5,9.67 5,14.33 5,14.33 "
android:strokeWidth="2"
android:strokeAlpha="1"
- android:strokeColor="#ffffff" />
+ android:strokeColor="#ffffff"/>
</group>
</group>
</group>
@@ -230,7 +230,7 @@
</aapt:attr>
</objectAnimator>
<objectAnimator
- android:duration="333"
+ android:duration="183"
android:propertyName="pathData"
android:startOffset="67"
android:valueFrom="M14.33 14.33 C14.33,14.33 14.29,6.17 14.29,6.17 C14.29,3.59 12.2,1.5 9.63,1.5 C7.05,1.5 4.96,3.59 4.96,6.17 C4.96,6.17 4.96,7.33 4.96,7.33 "
@@ -286,7 +286,7 @@
<aapt:attr name="android:animation">
<set android:ordering="together">
<objectAnimator
- android:duration="717"
+ android:duration="983"
android:propertyName="translateX"
android:startOffset="0"
android:valueFrom="0"
diff --git a/packages/SystemUI/res/anim/lock_unlock_circular.xml b/packages/SystemUI/res/anim/lock_unlock_circular.xml
new file mode 100644
index 000000000000..c3968ac8a624
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_unlock_circular.xml
@@ -0,0 +1,212 @@
+<!-- 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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
+ android:viewportWidth="32">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_2_G_T_1" android:translateX="15.999"
+ android:translateY="24.333">
+ <group android:name="_R_G_L_2_G" android:translateX="-9.583"
+ android:translateY="-8.916">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:fillColor="#ffffff"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M17.42 1.75 C17.42,1.75 17.42,14.58 17.42,14.58 C17.42,15.41 16.74,16.08 15.92,16.08 C15.92,16.08 3.25,16.08 3.25,16.08 C2.42,16.08 1.75,15.41 1.75,14.58 C1.75,14.58 1.75,1.75 1.75,1.75 C1.75,1.75 17.42,1.75 17.42,1.75c M18.92 0.25 C18.92,0.25 0.25,0.25 0.25,0.25 C0.25,0.25 0.25,14.58 0.25,14.58 C0.25,16.24 1.59,17.58 3.25,17.58 C3.25,17.58 15.92,17.58 15.92,17.58 C17.57,17.58 18.92,16.24 18.92,14.58 C18.92,14.58 18.92,0.25 18.92,0.25c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_N_3_T_1" android:translateX="15.999"
+ android:translateY="24.333">
+ <group android:name="_R_G_L_1_G_N_3_T_0" android:translateX="-9.583"
+ android:translateY="-8.916">
+ <group android:name="_R_G_L_1_G" android:translateX="7.334"
+ android:translateY="5.333" android:pivotX="2.25"
+ android:pivotY="3.334" android:scaleX="1" android:scaleY="1">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M4.25 2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25 C3.35,0.25 4.25,1.15 4.25,2.25c "/>
+ <path android:name="_R_G_L_1_G_D_1_P_0" android:strokeColor="#ffffff"
+ android:strokeLineCap="round" android:strokeLineJoin="round"
+ android:strokeWidth="1.5" android:strokeAlpha="1"
+ android:pathData=" M2.25 2.25 C2.25,2.25 2.25,5.92 2.25,5.92 "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_N_3_T_1" android:translateX="15.999"
+ android:translateY="24.333">
+ <group android:name="_R_G_L_0_G_N_3_T_0" android:translateX="-9.583"
+ android:translateY="-8.916">
+ <group android:name="_R_G_L_0_G" android:translateX="1.5"
+ android:translateY="-11.835">
+ <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
+ android:strokeLineCap="round" android:strokeLineJoin="round"
+ android:strokeWidth="1.5" android:strokeAlpha="1"
+ android:pathData=" M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_2_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="24.333"
+ android:valueTo="22.458" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="22.458"
+ android:valueTo="25.333" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="25.333"
+ android:valueTo="24.333" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="100"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="0.9"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="100"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="0.9"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="283"
+ android:startOffset="100" android:valueFrom="0.9"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="283"
+ android:startOffset="100" android:valueFrom="0.9"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_3_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="24.333"
+ android:valueTo="22.458" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="22.458"
+ android:valueTo="25.333" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="25.333"
+ android:valueTo="24.333" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="67"
+ android:startOffset="0"
+ android:valueFrom="M12.42 12.6 C12.42,12.6 12.42,8.17 12.42,8.17 C12.42,5.83 10.48,3.75 8.08,3.75 C5.69,3.75 3.75,5.83 3.75,8.17 C3.75,8.17 3.75,12.6 3.75,12.6 "
+ android:valueTo="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.59,0 0.488,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="183"
+ android:startOffset="67"
+ android:valueFrom="M12.42 12.6 C12.42,12.6 12.4,5.86 12.4,5.86 C12.4,3.52 10.46,1.44 8.06,1.44 C5.67,1.44 3.73,3.52 3.73,5.86 C3.73,5.86 3.75,7.41 3.75,7.41 "
+ android:valueTo="M12.42 12.6 C12.42,12.6 12.41,8.16 12.41,8.16 C12.41,5.81 14.36,3.75 16.75,3.77 C19.15,3.78 21.07,5.71 21.07,8.05 C21.07,8.05 21.08,8.22 21.08,8.22 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.57,0 0.365,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_3_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="24.333"
+ android:valueTo="22.458" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.705,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="22.458"
+ android:valueTo="25.333" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.289,0 0.724,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="25.333"
+ android:valueTo="24.333" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.624,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="717"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_unlock_filled.xml b/packages/SystemUI/res/anim/lock_unlock_filled.xml
new file mode 100644
index 000000000000..b2238ada3851
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_unlock_filled.xml
@@ -0,0 +1,158 @@
+<!-- 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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
+ android:viewportWidth="32">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_1_G_T_1" android:translateX="16"
+ android:translateY="25">
+ <group android:name="_R_G_L_1_G" android:translateX="-10.917"
+ android:translateY="-9.583">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_N_3_T_1" android:translateX="16"
+ android:translateY="25">
+ <group android:name="_R_G_L_0_G_N_3_T_0" android:translateX="-10.917"
+ android:translateY="-9.583">
+ <group android:name="_R_G_L_0_G" android:translateX="9.917000000000002"
+ android:translateY="-12.75">
+ <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
+ android:strokeLineCap="round" android:strokeLineJoin="round"
+ android:strokeWidth="2" android:strokeAlpha="1"
+ android:pathData=" M-3 13.04 C-3,13.04 -3,9.04 -3,9.04 C-3,6.83 -1.03,5.04 0.91,5 C3.12,4.96 5,6.79 5,9 C5,9 5,13 5,13 "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_1_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="100"
+ android:startOffset="0"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.78 C9.71,11.78 8.72,10.79 8.72,9.58 C8.72,8.37 9.71,7.38 10.92,7.38 C12.13,7.38 13.12,8.37 13.12,9.58 C13.12,10.79 12.13,11.78 10.92,11.78c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="283"
+ android:startOffset="100"
+ android:valueFrom=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 11.78 C9.71,11.78 8.72,10.79 8.72,9.58 C8.72,8.37 9.71,7.38 10.92,7.38 C12.13,7.38 13.12,8.37 13.12,9.58 C13.12,10.79 12.13,11.78 10.92,11.78c "
+ android:valueTo=" M18.92 0.25 C18.92,0.25 2.92,0.25 2.92,0.25 C1.45,0.25 0.25,1.45 0.25,2.92 C0.25,2.92 0.25,16.25 0.25,16.25 C0.25,17.72 1.45,18.92 2.92,18.92 C2.92,18.92 18.92,18.92 18.92,18.92 C20.38,18.92 21.58,17.72 21.58,16.25 C21.58,16.25 21.58,2.92 21.58,2.92 C21.58,1.45 20.38,0.25 18.92,0.25c M10.92 12.25 C9.45,12.25 8.25,11.05 8.25,9.58 C8.25,8.12 9.45,6.92 10.92,6.92 C12.38,6.92 13.58,8.12 13.58,9.58 C13.58,11.05 12.38,12.25 10.92,12.25c "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="25" android:valueTo="23"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.32,0 0.803,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="23"
+ android:valueTo="26.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.223,0 0.761,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="26.5"
+ android:valueTo="25" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.311,0 0.633,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="67"
+ android:startOffset="0"
+ android:valueFrom="M-3 13.04 C-3,13.04 -3,9.04 -3,9.04 C-3,6.83 -1.03,5.04 0.91,5 C3.12,4.96 5,6.79 5,9 C5,9 5,13 5,13 "
+ android:valueTo="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.592,0 0.503,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="183"
+ android:startOffset="67"
+ android:valueFrom="M-3 6.73 C-3,5.62 -2.56,4.67 -1.84,4 C-1.11,3.32 -0.09,2.93 1.06,2.94 C3.27,2.96 5,4.54 5,6.75 C5,6.75 5,13 5,13 "
+ android:valueTo="M13 9 C13,7.9 12.55,6.9 11.83,6.17 C11.1,5.45 10.11,5 9,5 C6.79,5 5,6.79 5,9 C5,9 5,13 5,13 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.563,0 0.363,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_3_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="25" android:valueTo="23"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.32,0 0.803,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="23"
+ android:valueTo="26.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.223,0 0.761,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="26.5"
+ android:valueTo="25" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.311,0 0.633,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="717"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/anim/lock_unlock_rounded.xml b/packages/SystemUI/res/anim/lock_unlock_rounded.xml
new file mode 100644
index 000000000000..14a88a4aa77a
--- /dev/null
+++ b/packages/SystemUI/res/anim/lock_unlock_rounded.xml
@@ -0,0 +1,209 @@
+<!-- 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.
+-->
+<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:aapt="http://schemas.android.com/aapt">
+ <aapt:attr name="android:drawable">
+ <vector android:height="42dp" android:width="32dp" android:viewportHeight="42"
+ android:viewportWidth="32">
+ <group android:name="_R_G">
+ <group android:name="_R_G_L_2_G_T_1" android:translateX="16"
+ android:translateY="25">
+ <group android:name="_R_G_L_2_G" android:translateX="-14.667"
+ android:translateY="-12.667">
+ <path android:name="_R_G_L_2_G_D_0_P_0" android:strokeColor="#ffffff"
+ android:strokeLineCap="round" android:strokeLineJoin="round"
+ android:strokeWidth="1.5" android:strokeAlpha="1"
+ android:pathData=" M22.09 5 C22.09,5 6,5 6,5 C5.45,5 5,5.45 5,6 C5,6 5,19.33 5,19.33 C5,19.89 5.45,20.33 6,20.33 C6,20.33 23.33,20.33 23.33,20.33 C23.89,20.33 24.33,19.89 24.33,19.33 C24.33,19.33 24.33,6 24.33,6 C24.33,5.45 23.89,5 23.33,5 C23.33,5 22.09,5 22.09,5c "/>
+ </group>
+ </group>
+ <group android:name="_R_G_L_1_G_N_4_T_1" android:translateX="16"
+ android:translateY="25">
+ <group android:name="_R_G_L_1_G_N_4_T_0" android:translateX="-14.667"
+ android:translateY="-12.667">
+ <group android:name="_R_G_L_1_G" android:translateX="12.416"
+ android:translateY="10.417" android:pivotX="2.25"
+ android:pivotY="2.25" android:scaleX="1" android:scaleY="1">
+ <path android:name="_R_G_L_1_G_D_0_P_0" android:fillColor="#ffffff"
+ android:fillAlpha="1" android:fillType="nonZero"
+ android:pathData=" M2.25 0.25 C3.35,0.25 4.25,1.15 4.25,2.25 C4.25,3.35 3.35,4.25 2.25,4.25 C1.15,4.25 0.25,3.35 0.25,2.25 C0.25,1.15 1.15,0.25 2.25,0.25c "/>
+ </group>
+ </group>
+ </group>
+ <group android:name="_R_G_L_0_G_N_4_T_1" android:translateX="16"
+ android:translateY="25">
+ <group android:name="_R_G_L_0_G_N_4_T_0" android:translateX="-14.667"
+ android:translateY="-12.667">
+ <group android:name="_R_G_L_0_G" android:translateX="5.333"
+ android:translateY="-9.425999999999998">
+ <path android:name="_R_G_L_0_G_D_0_P_0" android:strokeColor="#ffffff"
+ android:strokeLineCap="round" android:strokeLineJoin="round"
+ android:strokeWidth="1.5" android:strokeAlpha="1"
+ android:pathData=" M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "/>
+ </group>
+ </group>
+ </group>
+ </group>
+ <group android:name="time_group"/>
+ </vector>
+ </aapt:attr>
+ <target android:name="_R_G_L_2_G_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="25"
+ android:valueTo="23.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="23.5"
+ android:valueTo="26" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="26"
+ android:valueTo="25" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="scaleX" android:duration="100"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="0.85"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.346,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="100"
+ android:startOffset="0" android:valueFrom="1" android:valueTo="0.85"
+ android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.346,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleX" android:duration="283"
+ android:startOffset="100" android:valueFrom="0.85"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.423,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="scaleY" android:duration="283"
+ android:startOffset="100" android:valueFrom="0.85"
+ android:valueTo="1" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.423,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_1_G_N_4_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="25"
+ android:valueTo="23.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="23.5"
+ android:valueTo="26" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="26"
+ android:valueTo="25" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_D_0_P_0">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="pathData" android:duration="67"
+ android:startOffset="0"
+ android:valueFrom="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.63,6.75 11.69,5 9.33,5.04 C6.98,5 5.04,6.75 5,8.94 C5,8.94 5,13.8 5,13.8 "
+ android:valueTo="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.658,0 0.317,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="pathData" android:duration="183"
+ android:startOffset="67"
+ android:valueFrom="M13.67 13.8 C13.67,13.8 13.69,5.06 13.69,5.06 C13.65,2.87 11.71,1.13 9.35,1.16 C7,1.13 5.06,2.87 5.02,5.06 C5.02,5.06 5,7.93 5,7.93 "
+ android:valueTo="M13.67 13.8 C13.67,13.8 13.67,8.94 13.67,8.94 C13.68,6.62 15.69,5.03 18.01,5.04 C20.46,5.04 22.32,6.89 22.34,8.85 C22.34,8.85 22.33,8.89 22.33,8.89 "
+ android:valueType="pathType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.679,0 0.175,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="_R_G_L_0_G_N_4_T_1">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="0" android:valueFrom="25"
+ android:valueTo="23.5" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="133"
+ android:startOffset="133" android:valueFrom="23.5"
+ android:valueTo="26" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ <objectAnimator android:propertyName="translateY" android:duration="100"
+ android:startOffset="267" android:valueFrom="26"
+ android:valueTo="25" android:valueType="floatType">
+ <aapt:attr name="android:interpolator">
+ <pathInterpolator android:pathData="M 0.0,0.0 c0.333,0 0.667,1 1.0,1.0"/>
+ </aapt:attr>
+ </objectAnimator>
+ </set>
+ </aapt:attr>
+ </target>
+ <target android:name="time_group">
+ <aapt:attr name="android:animation">
+ <set android:ordering="together">
+ <objectAnimator android:propertyName="translateX" android:duration="717"
+ android:startOffset="0" android:valueFrom="0" android:valueTo="1"
+ android:valueType="floatType"/>
+ </set>
+ </aapt:attr>
+ </target>
+</animated-vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/ic_info_outline.xml b/packages/SystemUI/res/drawable/ic_info_outline.xml
index a4a3e9aab239..44e09f6faa51 100644
--- a/packages/SystemUI/res/drawable/ic_info_outline.xml
+++ b/packages/SystemUI/res/drawable/ic_info_outline.xml
@@ -15,8 +15,8 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32dp"
- android:height="32dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/packages/SystemUI/res/drawable/ic_invert_colors.xml b/packages/SystemUI/res/drawable/ic_invert_colors.xml
index 77d491810ccc..37ea0800a51e 100644
--- a/packages/SystemUI/res/drawable/ic_invert_colors.xml
+++ b/packages/SystemUI/res/drawable/ic_invert_colors.xml
@@ -15,8 +15,8 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="48dp"
- android:height="48dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
index fbd92dead675..d2ee2839d701 100644
--- a/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -14,8 +14,8 @@ Copyright (C) 2017 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="64dp"
- android:height="64dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0"
android:tint="?android:attr/colorControlNormal" >
diff --git a/packages/SystemUI/res/drawable/ic_qs_no_sim.xml b/packages/SystemUI/res/drawable/ic_qs_no_sim.xml
index 22e12cc10405..6cabcaf4bcb4 100644
--- a/packages/SystemUI/res/drawable/ic_qs_no_sim.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_no_sim.xml
@@ -14,8 +14,8 @@ Copyright (C) 2017 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32dp"
- android:height="32dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/packages/SystemUI/res/drawable/ic_screenshot_delete.xml b/packages/SystemUI/res/drawable/ic_screenshot_delete.xml
index d60ee414888d..4cf578a92826 100644
--- a/packages/SystemUI/res/drawable/ic_screenshot_delete.xml
+++ b/packages/SystemUI/res/drawable/ic_screenshot_delete.xml
@@ -14,8 +14,8 @@ Copyright (C) 2015 The Android Open Source Project
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="32dp"
- android:height="32dp"
+ android:width="24dp"
+ android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 6e6c009dd18c..a549870ec780 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -40,8 +40,8 @@
<!-- Whether or not we show the number in the bar. -->
<bool name="config_statusBarShowNumber">false</bool>
- <!-- If the lock screen should be dismissed after biometric auth. -->
- <bool name="config_faceAuthDismissesKeyguard">false</bool>
+ <!-- For how long the lock screen can be on before the display turns off. -->
+ <integer name="config_lockScreenDisplayTimeout">10000</integer>
<!-- Vibrator pattern for camera gesture launch. -->
<integer-array translatable="false" name="config_cameraLaunchGestureVibePattern">
@@ -141,6 +141,9 @@
<!-- The number of milliseconds before the heads up notification auto-dismisses. -->
<integer name="heads_up_notification_decay">5000</integer>
+ <!-- The number of milliseconds before the heads up notification sent automatically by the system auto-dismisses. -->
+ <integer name="auto_heads_up_notification_decay">3000</integer>
+
<!-- The number of milliseconds after a heads up notification is pushed back
before the app can interrupt again. -->
<integer name="heads_up_default_snooze_length_ms">60000</integer>
@@ -153,10 +156,7 @@
<!-- The number of milliseconds before the ambient notification auto-dismisses. This will
override the default pulse length. -->
- <integer name="ambient_notification_decay">10000</integer>
-
- <!-- Minimum display time for a heads up notification, in milliseconds. -->
- <integer name="ambient_notification_minimum_time">2000</integer>
+ <integer name="heads_up_notification_decay_dozing">10000</integer>
<!-- The number of milliseconds to extend ambient pulse by when prompted (e.g. on touch) -->
<integer name="ambient_notification_extension_time">6000</integer>
@@ -200,25 +200,9 @@
<!-- Doze: duration to avoid false pickup gestures triggered by notification vibrations -->
<integer name="doze_pickup_vibration_threshold">2000</integer>
- <!-- Doze: can we assume the pickup sensor includes a proximity check?
- This is ignored if doze_pickup_subtype_performs_proximity_check is not empty.
- @deprecated: use doze_pickup_subtype_performs_proximity_check instead.-->
+ <!-- Doze: can we assume the pickup sensor includes a proximity check? -->
<bool name="doze_pickup_performs_proximity_check">false</bool>
- <!-- Doze: a list of pickup sensor subtypes that perform a proximity check before they trigger.
- If not empty, either * or !* must appear to specify the default.
- If empty, falls back to doze_pickup_performs_proximity_check.
-
- Examples: 1,2,3,!* -> subtypes 1,2 and 3 perform the check, all others don't.
- !1,!2,* -> subtypes 1 and 2 don't perform the check, all others do.
- !8,* -> subtype 8 does not perform the check, all others do
- 1,1,* -> illegal, every item may only appear once
- 1,!1,* -> illegal, no contradictions allowed
- 1,2 -> illegal, need either * or !*
- 1,,4a3 -> illegal, no empty or non-numeric terms allowed
- -->
- <string name="doze_pickup_subtype_performs_proximity_check"></string>
-
<!-- Type of a sensor that provides a low-power estimate of the desired display
brightness, suitable to listen to while the device is asleep (e.g. during
always-on display) -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index c5e4662f6d45..afe6d9c2552b 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -258,8 +258,8 @@
<!-- size at which Notification icons will be drawn on Ambient Display -->
<dimen name="status_bar_icon_drawing_size_dark">@*android:dimen/notification_header_icon_size_ambient</dimen>
- <!-- size of notification icons on AOD -->
- <dimen name="dark_shelf_icon_size">16dp</dimen>
+ <!-- size of notification icons when the notifications are hidden -->
+ <dimen name="hidden_shelf_icon_size">16dp</dimen>
<!-- opacity at which Notification icons will be drawn in the status bar -->
<item type="dimen" name="status_bar_icon_drawing_alpha">90%</item>
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index e97055f08e32..66f19495dfa6 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -94,6 +94,16 @@
<item type="id" name="top_roundess_animator_start_tag"/>
<item type="id" name="top_roundess_animator_end_tag"/>
+ <item type="id" name="keyguard_hun_animator_tag"/>
+ <item type="id" name="keyguard_hun_animator_start_tag"/>
+ <item type="id" name="keyguard_hun_animator_end_tag"/>
+
+ <item type="id" name="view_group_fade_helper_modified_views"/>
+ <item type="id" name="view_group_fade_helper_animator"/>
+ <item type="id" name="view_group_fade_helper_previous_value_tag"/>
+ <item type="id" name="view_group_fade_helper_restore_tag"/>
+ <item type="id" name="view_group_fade_helper_hardware_layer"/>
+
<!-- Accessibility actions for the notification menu -->
<item type="id" name="action_snooze_undo"/>
<item type="id" name="action_snooze_shorter"/>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 591af82ecb4e..7feacb469f81 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -303,6 +303,8 @@
<string name="biometric_dialog_face_icon_description_authenticated">Face authenticated</string>
<!-- Content description for the face icon when the user has been authenticated and the confirm button has been pressed [CHAR LIMIT=NONE] -->
<string name="biometric_dialog_face_icon_description_confirmed">Confirmed</string>
+ <!-- Message shown when a biometric is authenticated, waiting for the user to confirm authentication [CHAR LIMIT=40]-->
+ <string name="biometric_dialog_tap_confirm">Tap Confirm to complete</string>
<!-- Message shown when the system-provided fingerprint dialog is shown, asking for authentication -->
<string name="fingerprint_dialog_touch_sensor">Touch the fingerprint sensor</string>
@@ -953,8 +955,8 @@
<!-- Shows to explain the double tap interaction with notifications: After tapping a notification on Keyguard, this will explain users to tap again to launch a notification. [CHAR LIMIT=60] -->
<string name="notification_tap_again">Tap again to open</string>
- <!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] -->
- <string name="keyguard_unlock">Swipe up to unlock</string>
+ <!-- Message shown when lock screen is tapped or face authentication fails. [CHAR LIMIT=60] -->
+ <string name="keyguard_unlock">Swipe up to open</string>
<!-- Text on keyguard screen and in Quick Settings footer indicating that the device is enterprise-managed by a Device Owner [CHAR LIMIT=60] -->
<string name="do_disclosure_generic">This device is managed by your organization</string>
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
index a2abb4b1695c..506813beadf6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/ActivityManagerWrapper.java
@@ -307,28 +307,22 @@ public class ActivityManagerWrapper {
}
final ActivityOptions finalOptions = options;
- // Execute this from another thread such that we can do other things (like caching the
- // bitmap for the thumbnail) while AM is busy starting our activity.
- mBackgroundExecutor.submit(new Runnable() {
- @Override
- public void run() {
- boolean result = false;
- try {
- result = startActivityFromRecents(taskKey.id, finalOptions);
- } catch (Exception e) {
- // Fall through
- }
- final boolean finalResult = result;
- if (resultCallback != null) {
- resultCallbackHandler.post(new Runnable() {
- @Override
- public void run() {
- resultCallback.accept(finalResult);
- }
- });
+
+ boolean result = false;
+ try {
+ result = startActivityFromRecents(taskKey.id, finalOptions);
+ } catch (Exception e) {
+ // Fall through
+ }
+ final boolean finalResult = result;
+ if (resultCallback != null) {
+ resultCallbackHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ resultCallback.accept(finalResult);
}
- }
- });
+ });
+ }
}
/**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
index 3d9abafa0d73..c215d0fc13d6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListener.java
@@ -64,6 +64,14 @@ public abstract class TaskStackChangeListener {
onActivityLaunchOnSecondaryDisplayRerouted();
}
+ /**
+ * Called when contents are drawn for the first time on a display which can only contain one
+ * task.
+ *
+ * @param displayId the id of the display on which contents are drawn.
+ */
+ public void onSingleTaskDisplayDrawn(int displayId) { }
+
public void onTaskProfileLocked(int taskId, int userId) { }
public void onTaskCreated(int taskId, ComponentName componentName) { }
public void onTaskRemoved(int taskId) { }
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
index beb4f05d814c..d570a586f961 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskStackChangeListeners.java
@@ -196,12 +196,19 @@ public class TaskStackChangeListeners extends TaskStackListener {
}
@Override
- public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken) {
+ public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken)
+ throws RemoteException {
mHandler.obtainMessage(H.ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED, displayId, 0 /* unused */,
activityToken).sendToTarget();
}
@Override
+ public void onSingleTaskDisplayDrawn(int displayId) throws RemoteException {
+ mHandler.obtainMessage(H.ON_SINGLE_TASK_DISPLAY_DRAWN, displayId,
+ 0 /* unused */).sendToTarget();
+ }
+
+ @Override
public void onTaskDisplayChanged(int taskId, int newDisplayId) throws RemoteException {
mHandler.obtainMessage(H.ON_TASK_DISPLAY_CHANGED, taskId, newDisplayId).sendToTarget();
}
@@ -225,7 +232,8 @@ public class TaskStackChangeListeners extends TaskStackListener {
private static final int ON_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED = 16;
private static final int ON_SIZE_COMPAT_MODE_ACTIVITY_CHANGED = 17;
private static final int ON_BACK_PRESSED_ON_TASK_ROOT = 18;
- private static final int ON_TASK_DISPLAY_CHANGED = 19;
+ private static final int ON_SINGLE_TASK_DISPLAY_DRAWN = 19;
+ private static final int ON_TASK_DISPLAY_CHANGED = 20;
public H(Looper looper) {
@@ -362,6 +370,12 @@ public class TaskStackChangeListeners extends TaskStackListener {
}
break;
}
+ case ON_SINGLE_TASK_DISPLAY_DRAWN: {
+ for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
+ mTaskStackListeners.get(i).onSingleTaskDisplayDrawn(msg.arg1);
+ }
+ break;
+ }
case ON_TASK_DISPLAY_CHANGED: {
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
mTaskStackListeners.get(i).onTaskDisplayChanged(msg.arg1, msg.arg2);
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index 209074812d7a..11d093f22840 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -303,6 +303,11 @@ public class CarrierTextController {
}
} else {
subs = mKeyguardUpdateMonitor.getSubscriptionInfo(false);
+ if (subs == null) {
+ subs = new ArrayList<>();
+ } else {
+ filterMobileSubscriptionInSameGroup(subs);
+ }
}
return subs;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
index 2ff7266baecf..a4b6958498c8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardAbsKeyInputView.java
@@ -310,7 +310,9 @@ public abstract class KeyguardAbsKeyInputView extends LinearLayout
@Override
public void showMessage(CharSequence message, ColorStateList colorState) {
- mSecurityMessageDisplay.setNextMessageColor(colorState);
+ if (colorState != null) {
+ mSecurityMessageDisplay.setNextMessageColor(colorState);
+ }
mSecurityMessageDisplay.setMessage(message);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index b1cba53c4bca..2483192eb04e 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -3,13 +3,13 @@ package com.android.keyguard;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
import android.app.WallpaperManager;
import android.content.Context;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.os.Build;
+import android.transition.Fade;
import android.transition.Transition;
import android.transition.TransitionListenerAdapter;
import android.transition.TransitionManager;
@@ -34,6 +34,7 @@ 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;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -117,6 +118,11 @@ public class KeyguardClockSwitch extends RelativeLayout {
private float mDarkAmount;
/**
+ * Boolean value indicating if notifications are visible on lock screen.
+ */
+ private boolean mHasVisibleNotifications;
+
+ /**
* If the Keyguard Slice has a header (big center-aligned text.)
*/
private boolean mShowingHeader;
@@ -227,8 +233,13 @@ public class KeyguardClockSwitch extends RelativeLayout {
mClockPlugin = null;
}
if (plugin == null) {
- mClockView.setVisibility(View.VISIBLE);
- mClockViewBold.setVisibility(View.INVISIBLE);
+ if (mShowingHeader) {
+ mClockView.setVisibility(View.GONE);
+ mClockViewBold.setVisibility(View.VISIBLE);
+ } else {
+ mClockView.setVisibility(View.VISIBLE);
+ mClockViewBold.setVisibility(View.INVISIBLE);
+ }
mKeyguardStatusArea.setVisibility(View.VISIBLE);
return;
}
@@ -325,6 +336,24 @@ public class KeyguardClockSwitch extends RelativeLayout {
if (mClockPlugin != null) {
mClockPlugin.setDarkAmount(darkAmount);
}
+ updateBigClockAlpha();
+ }
+
+ /**
+ * Set whether or not the lock screen is showing notifications.
+ */
+ void setHasVisibleNotifications(boolean hasVisibleNotifications) {
+ if (hasVisibleNotifications == mHasVisibleNotifications) {
+ return;
+ }
+ mHasVisibleNotifications = hasVisibleNotifications;
+ if (mDarkAmount == 0f && mBigClockContainer != null) {
+ // Starting a fade transition since the visibility of the big clock will change.
+ TransitionManager.beginDelayedTransition(mBigClockContainer,
+ new Fade().setDuration(KeyguardSliceView.DEFAULT_ANIM_DURATION / 2).addTarget(
+ mBigClockContainer));
+ }
+ updateBigClockAlpha();
}
public Paint getPaint() {
@@ -401,15 +430,30 @@ public class KeyguardClockSwitch extends RelativeLayout {
}
}
+ private void updateBigClockAlpha() {
+ if (mBigClockContainer != null) {
+ final float alpha = mHasVisibleNotifications ? mDarkAmount : 1f;
+ mBigClockContainer.setAlpha(alpha);
+ if (alpha == 0f) {
+ mBigClockContainer.setVisibility(INVISIBLE);
+ } else if (mBigClockContainer.getVisibility() == INVISIBLE) {
+ mBigClockContainer.setVisibility(VISIBLE);
+ }
+ }
+ }
+
/**
* Sets if the keyguard slice is showing a center-aligned header. We need a smaller clock in
* these cases.
*/
void setKeyguardShowingHeader(boolean hasHeader) {
- if (mShowingHeader == hasHeader || hasCustomClock()) {
+ if (mShowingHeader == hasHeader) {
return;
}
mShowingHeader = hasHeader;
+ if (hasCustomClock()) {
+ return;
+ }
float smallFontSize = mContext.getResources().getDimensionPixelSize(
R.dimen.widget_small_font_size);
@@ -574,11 +618,16 @@ public class KeyguardClockSwitch extends RelativeLayout {
view.setScaleX(scale);
view.setScaleY(scale);
});
- animator.addListener(new AnimatorListenerAdapter() {
+ animator.addListener(new KeepAwakeAnimationListener(getContext()) {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
view.setVisibility(startVisibility);
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ super.onAnimationEnd(animation);
animation.removeListener(this);
}
});
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index d8086da277f2..55ddfc30d774 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -248,7 +248,8 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
@Override
public boolean disallowInterceptTouch(MotionEvent event) {
- return mLockPatternScreenBounds.contains((int) event.getRawX(), (int) event.getRawY());
+ return !mLockPatternView.isEmpty()
+ || mLockPatternScreenBounds.contains((int) event.getRawX(), (int) event.getRawY());
}
/** TODO: hook this up */
@@ -442,7 +443,9 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
@Override
public void showMessage(CharSequence message, ColorStateList colorState) {
- mSecurityMessageDisplay.setNextMessageColor(colorState);
+ if (colorState != null) {
+ mSecurityMessageDisplay.setNextMessageColor(colorState);
+ }
mSecurityMessageDisplay.setMessage(message);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 6cd971d25610..69630c4e90e8 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -46,6 +46,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.Dependency;
import com.android.systemui.SystemUIFactory;
+import com.android.systemui.statusbar.phone.UnlockMethodCache;
import com.android.systemui.util.InjectionInflationController;
public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSecurityView {
@@ -90,6 +91,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
private final SpringAnimation mSpringAnimation;
private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
private final KeyguardUpdateMonitor mUpdateMonitor;
+ private final UnlockMethodCache mUnlockMethodCache;
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
private float mLastTouchY = -1;
@@ -129,6 +131,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
mInjectionInflationController = new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent());
+ mUnlockMethodCache = UnlockMethodCache.getInstance(context);
mViewConfiguration = ViewConfiguration.get(context);
}
@@ -231,8 +234,10 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
}
if (action == MotionEvent.ACTION_UP) {
if (-getTranslationY() > TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
- MIN_DRAG_SIZE, getResources().getDisplayMetrics())) {
+ MIN_DRAG_SIZE, getResources().getDisplayMetrics())
+ && !mUpdateMonitor.isFaceDetectionRunning()) {
mUpdateMonitor.requestFaceAuth();
+ showMessage(null, null);
}
}
return true;
@@ -263,8 +268,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
*/
private void updateBiometricRetry() {
SecurityMode securityMode = getSecurityMode();
- int userId = KeyguardUpdateMonitor.getCurrentUser();
- mSwipeUpToRetry = mUpdateMonitor.isUnlockWithFacePossible(userId)
+ mSwipeUpToRetry = mUnlockMethodCache.isUnlockingWithFacePossible()
&& securityMode != SecurityMode.SimPin
&& securityMode != SecurityMode.SimPuk
&& securityMode != SecurityMode.None;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index a7fe607b0e87..37e89c095575 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -61,6 +61,7 @@ public class KeyguardStatusView extends GridLayout implements
private KeyguardClockSwitch mClockView;
private TextView mOwnerInfo;
private KeyguardSliceView mKeyguardSlice;
+ private View mNotificationIcons;
private Runnable mPendingMarqueeStart;
private Handler mHandler;
@@ -72,8 +73,8 @@ public class KeyguardStatusView extends GridLayout implements
* Bottom margin that defines the margin between bottom of smart space and top of notification
* icons on AOD.
*/
- private int mBottomMargin;
- private int mBottomMarginWithHeader;
+ private int mIconTopMargin;
+ private int mIconTopMarginWithHeader;
private boolean mShowingHeader;
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@@ -144,6 +145,13 @@ public class KeyguardStatusView extends GridLayout implements
return mClockView.hasCustomClock();
}
+ /**
+ * Set whether or not the lock screen is showing notifications.
+ */
+ public void setHasVisibleNotifications(boolean hasVisibleNotifications) {
+ mClockView.setHasVisibleNotifications(hasVisibleNotifications);
+ }
+
private void setEnableMarquee(boolean enabled) {
if (DEBUG) Log.v(TAG, "Schedule setEnableMarquee: " + (enabled ? "Enable" : "Disable"));
if (enabled) {
@@ -173,6 +181,7 @@ public class KeyguardStatusView extends GridLayout implements
super.onFinishInflate();
mStatusViewContainer = findViewById(R.id.status_view_container);
mLogoutView = findViewById(R.id.logout);
+ mNotificationIcons = findViewById(R.id.clock_notification_icon_container);
if (mLogoutView != null) {
mLogoutView.setOnClickListener(this::onLogoutClicked);
}
@@ -207,12 +216,14 @@ public class KeyguardStatusView extends GridLayout implements
return;
}
mShowingHeader = hasHeader;
- // Update bottom margin since header has appeared/disappeared.
- if (mStatusViewContainer != null) {
- MarginLayoutParams params = (MarginLayoutParams) mStatusViewContainer.getLayoutParams();
- params.setMargins(params.leftMargin, params.topMargin, params.rightMargin,
- hasHeader ? mBottomMarginWithHeader : mBottomMargin);
- mStatusViewContainer.setLayoutParams(params);
+ if (mNotificationIcons != null) {
+ // Update top margin since header has appeared/disappeared.
+ MarginLayoutParams params = (MarginLayoutParams) mNotificationIcons.getLayoutParams();
+ params.setMargins(params.leftMargin,
+ hasHeader ? mIconTopMarginWithHeader : mIconTopMargin,
+ params.rightMargin,
+ params.bottomMargin);
+ mNotificationIcons.setLayoutParams(params);
}
}
@@ -338,8 +349,8 @@ public class KeyguardStatusView extends GridLayout implements
}
private void loadBottomMargin() {
- mBottomMargin = getResources().getDimensionPixelSize(R.dimen.widget_vertical_padding);
- mBottomMarginWithHeader = getResources().getDimensionPixelSize(
+ mIconTopMargin = getResources().getDimensionPixelSize(R.dimen.widget_vertical_padding);
+ mIconTopMarginWithHeader = getResources().getDimensionPixelSize(
R.dimen.widget_vertical_padding_with_header);
}
@@ -412,6 +423,13 @@ public class KeyguardStatusView extends GridLayout implements
int expanded = mOwnerInfo.getBottom() + mOwnerInfo.getPaddingBottom();
int toRemove = (int) ((expanded - collapsed) * ratio);
setBottom(getMeasuredHeight() - toRemove);
+ if (mNotificationIcons != null) {
+ // We're using scrolling in order not to overload the translation which is used
+ // when appearing the icons
+ mNotificationIcons.setScrollY(toRemove);
+ }
+ } else if (mNotificationIcons != null){
+ mNotificationIcons.setScrollY(0);
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index 6a4dbc8d7228..05e14a779a17 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -28,6 +28,13 @@ import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
import static android.os.BatteryManager.EXTRA_PLUGGED;
import static android.os.BatteryManager.EXTRA_STATUS;
+import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
+
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
+import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
import android.annotation.AnyThread;
import android.annotation.MainThread;
@@ -70,6 +77,7 @@ import android.os.UserManager;
import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
+import android.telephony.PhoneStateListener;
import android.telephony.ServiceState;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
@@ -88,6 +96,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.WirelessUtils;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.google.android.collect.Lists;
@@ -111,6 +120,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private static final String TAG = "KeyguardUpdateMonitor";
private static final boolean DEBUG = KeyguardConstants.DEBUG;
private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
+ private static final boolean DEBUG_FACE = true;
private static final int LOW_BATTERY_THRESHOLD = 20;
private static final String ACTION_FACE_UNLOCK_STARTED
@@ -168,6 +178,9 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
*/
private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
+ private static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
+ public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
+
private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
@@ -179,6 +192,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
* Prudently disable lockscreen.
*/
public static final boolean CORE_APPS_ONLY;
+
static {
try {
CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
@@ -207,6 +221,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private boolean mHasLockscreenWallpaper;
private boolean mAssistantVisible;
private boolean mKeyguardOccluded;
+ private boolean mSecureCameraLaunched;
@VisibleForTesting
protected boolean mTelephonyCapable;
@@ -231,6 +246,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private List<SubscriptionInfo> mSubscriptionInfo;
private TrustManager mTrustManager;
private UserManager mUserManager;
+ private KeyguardBypassController mKeyguardBypassController;
private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
private LockPatternUtils mLockPatternUtils;
@@ -374,6 +390,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
};
+ private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
+ @Override
+ public void onActiveDataSubscriptionIdChanged(int subId) {
+ mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
+ }
+ };
+
private OnSubscriptionsChangedListener mSubscriptionListener =
new OnSubscriptionsChangedListener() {
@Override
@@ -423,7 +446,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private void handleSimSubscriptionInfoChanged() {
if (DEBUG_SIM_STATES) {
Log.v(TAG, "onSubscriptionInfoChanged()");
- List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
+ List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
if (sil != null) {
for (SubscriptionInfo subInfo : sil) {
Log.v(TAG, "SubInfo:" + subInfo);
@@ -475,7 +498,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
List<SubscriptionInfo> sil = mSubscriptionInfo;
if (sil == null || forceReload) {
- sil = mSubscriptionManager.getActiveSubscriptionInfoList();
+ sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
}
if (sil == null) {
// getActiveSubscriptionInfoList was null callers expect an empty list.
@@ -518,6 +541,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
/**
+ * Invoked when the secure camera is launched.
+ */
+ public void onCameraLaunched() {
+ mSecureCameraLaunched = true;
+ updateBiometricListeningState();
+ }
+
+ /**
* @return a cached version of DreamManager.isDreaming()
*/
public boolean isDreaming() {
@@ -570,7 +601,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
}
}
- handleFingerprintHelp(-1, mContext.getString(R.string.kg_fingerprint_not_recognized));
+ handleFingerprintHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
+ mContext.getString(R.string.kg_fingerprint_not_recognized));
}
private void handleFingerprintAcquired(int acquireInfo) {
@@ -646,8 +678,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
- mLockPatternUtils.requireStrongAuth(
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
+ mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
getCurrentUser());
}
@@ -722,13 +753,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
cb.onBiometricAuthFailed(BiometricSourceType.FACE);
}
}
- handleFaceHelp(-1, mContext.getString(R.string.kg_face_not_recognized));
+ handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
+ mContext.getString(R.string.kg_face_not_recognized));
}
private void handleFaceAcquired(int acquireInfo) {
if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
return;
}
+ if (DEBUG_FACE) Log.d(TAG, "Face acquired");
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -740,6 +773,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private void handleFaceAuthenticated(int authUserId) {
Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
try {
+ if (mGoingToSleep) {
+ Log.d(TAG, "Aborted successful auth because device is going to sleep.");
+ return;
+ }
final int userId;
try {
userId = ActivityManager.getService().getCurrentUser().id;
@@ -755,6 +792,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
return;
}
+ if (DEBUG_FACE) Log.d(TAG, "Face auth succeeded for user " + userId);
onFaceAuthenticated(userId);
} finally {
setFaceRunningState(BIOMETRIC_STATE_STOPPED);
@@ -763,6 +801,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
private void handleFaceHelp(int msgId, String helpString) {
+ if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -781,6 +820,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
};
private void handleFaceError(int msgId, String errString) {
+ if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
if (msgId == FaceManager.FACE_ERROR_CANCELED
&& mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
setFaceRunningState(BIOMETRIC_STATE_STOPPED);
@@ -798,11 +838,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
- mLockPatternUtils.requireStrongAuth(
- LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
+ mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
getCurrentUser());
}
+ // The face timeout message is not very actionable, let's ask the user to
+ // manually retry.
+ if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
+ errString = mContext.getString(R.string.keyguard_unlock);
+ }
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -913,8 +957,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
public boolean isUserInLockdown(int userId) {
- return mStrongAuthTracker.getStrongAuthForUser(userId)
- == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
+ return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId),
+ STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+ }
+
+ public boolean userNeedsStrongAuth() {
+ return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser())
+ != LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
+ }
+
+ private boolean containsFlag(int haystack, int needle) {
+ return (haystack & needle) != 0;
}
public boolean needsSlowUnlockTransition() {
@@ -1044,6 +1097,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
mHandler.sendMessage(
mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
+ } else if (TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
+ mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
} else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
action)) {
mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -1454,6 +1509,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
+ filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
@@ -1527,6 +1583,12 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
updateAirplaneModeState();
+
+ TelephonyManager telephony =
+ (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
+ if (telephony != null) {
+ telephony.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
+ }
}
private void updateAirplaneModeState() {
@@ -1624,12 +1686,34 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private boolean shouldListenForFace() {
final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
final int user = getCurrentUser();
+ final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
+ final boolean isLockOutOrLockDown =
+ containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_LOCKOUT)
+ || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
+ || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+ final boolean isEncryptedOrTimedOut =
+ containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
+ || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
+
+ boolean canBypass = mKeyguardBypassController != null
+ && mKeyguardBypassController.canBypass();
+ // There's no reason to ask the HAL for authentication when the user can dismiss the
+ // bouncer, unless we're bypassing and need to auto-dismiss the lock screen even when
+ // TrustAgents or biometrics are keeping the device unlocked.
+ boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
+
+ // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
+ // Lockout/lockdown modes shouldn't scan, since they are more explicit.
+ boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
+ && !isLockOutOrLockDown;
+
// Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
// instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
- && !mSwitchingUser && !getUserCanSkipBouncer(user) && !isFaceDisabled(user)
+ && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
&& !mKeyguardGoingAway && mFaceSettingEnabledForUser && !mLockIconPressed
- && mUserManager.isUserUnlocked(user) && mIsPrimaryUser;
+ && strongAuthAllowsScanning && mIsPrimaryUser
+ && !mSecureCameraLaunched;
}
/**
@@ -2077,6 +2161,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
checkIsHandlerThread();
Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
mKeyguardIsVisible = showing;
+
+ if (showing) {
+ mSecureCameraLaunched = false;
+ }
+
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -2195,6 +2284,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
sendUpdates(callback);
}
+ public void setKeyguardBypassController(KeyguardBypassController keyguardBypassController) {
+ mKeyguardBypassController = keyguardBypassController;
+ }
+
public boolean isSwitchingUser() {
return mSwitchingUser;
}
@@ -2285,6 +2378,13 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
mUserFaceAuthenticated.clear();
mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
+
+ for (int i = 0; i < mCallbacks.size(); i++) {
+ KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
+ if (cb != null) {
+ cb.onBiometricsCleared();
+ }
+ }
}
public boolean isSimPinVoiceSecure() {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
index 8696bb769bbd..0fef755b5aba 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitorCallback.java
@@ -314,4 +314,9 @@ public class KeyguardUpdateMonitorCallback {
*/
public void onLogoutEnabledChanged() { }
+ /**
+ * Called when authenticated biometrics are cleared.
+ */
+ public void onBiometricsCleared() { }
+
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
index 558ac4b564d1..9c5242ce1a3e 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/AnalogClockController.java
@@ -75,6 +75,11 @@ public class AnalogClockController implements ClockPlugin {
private TextClock mLockClock;
/**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
* Create a BubbleClockController instance.
*
* @param res Resources contains title and thumbnail.
@@ -162,17 +167,21 @@ public class AnalogClockController implements ClockPlugin {
public void setStyle(Style style) {}
@Override
- public void setTextColor(int color) { }
+ public void setTextColor(int color) {
+ updateColor();
+ }
@Override
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
- if (colorPalette == null || colorPalette.length == 0) {
- return;
- }
- final int length = colorPalette.length;
- mLockClock.setTextColor(colorPalette[Math.max(0, length - 2)]);
- mAnalogClock.setClockColors(colorPalette[Math.max(0, length - 5)],
- colorPalette[Math.max(0, length - 2)]);
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ mLockClock.setTextColor(secondary);
+ mAnalogClock.setClockColors(primary, secondary);
}
@Override
@@ -184,6 +193,7 @@ public class AnalogClockController implements ClockPlugin {
@Override
public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
mClockPosition.setDarkAmount(darkAmount);
mBigClockView.setDarkAmount(darkAmount);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
index bdf9dc4865b2..8e81327a9325 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/BubbleClockController.java
@@ -75,6 +75,11 @@ public class BubbleClockController implements ClockPlugin {
private TextClock mLockClock;
/**
+ * Helper to extract colors from wallpaper palette for clock face.
+ */
+ private final ClockPalette mPalette = new ClockPalette();
+
+ /**
* Create a BubbleClockController instance.
*
* @param res Resources contains title and thumbnail.
@@ -162,21 +167,26 @@ public class BubbleClockController implements ClockPlugin {
public void setStyle(Style style) {}
@Override
- public void setTextColor(int color) { }
+ public void setTextColor(int color) {
+ updateColor();
+ }
@Override
public void setColorPalette(boolean supportsDarkText, int[] colorPalette) {
- if (colorPalette == null || colorPalette.length == 0) {
- return;
- }
- final int length = colorPalette.length;
- final int color = colorPalette[Math.max(0, length - 3)];
- mLockClock.setTextColor(color);
- mAnalogClock.setClockColors(color, color);
+ mPalette.setColorPalette(supportsDarkText, colorPalette);
+ updateColor();
+ }
+
+ private void updateColor() {
+ final int primary = mPalette.getPrimaryColor();
+ final int secondary = mPalette.getSecondaryColor();
+ mLockClock.setTextColor(secondary);
+ mAnalogClock.setClockColors(primary, secondary);
}
@Override
public void setDarkAmount(float darkAmount) {
+ mPalette.setDarkAmount(darkAmount);
mClockPosition.setDarkAmount(darkAmount);
mView.setDarkAmount(darkAmount);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
index 19083459a87c..7485d336174c 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockLayout.java
@@ -94,7 +94,8 @@ public class ClockLayout extends FrameLayout {
getBurnInOffset(mBurnInPreventionOffsetX * 2, true) - mBurnInPreventionOffsetX,
mDarkAmount);
final float offsetY = MathUtils.lerp(0f,
- getBurnInOffset(mBurnInPreventionOffsetY * 2, false) - mBurnInPreventionOffsetY,
+ getBurnInOffset(mBurnInPreventionOffsetY * 2, false)
+ - 0.5f * mBurnInPreventionOffsetY,
mDarkAmount);
// Put the analog clock in the middle of the screen.
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
index 9f4c403ed787..9e2464ea4fbb 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockManager.java
@@ -240,9 +240,9 @@ public final class ClockManager {
}
private void reload() {
- mPreviewClocks.reload();
+ mPreviewClocks.reloadCurrentClock();
mListeners.forEach((listener, clocks) -> {
- clocks.reload();
+ clocks.reloadCurrentClock();
ClockPlugin clock = clocks.getCurrentClock();
if (clock instanceof DefaultClockController) {
listener.onClockChanged(null);
@@ -287,20 +287,13 @@ public final class ClockManager {
@Override
public void onPluginConnected(ClockPlugin plugin, Context pluginContext) {
addClockPlugin(plugin);
- reload();
- if (plugin == mCurrentClock) {
- ClockManager.this.reload();
- }
+ reloadIfNeeded(plugin);
}
@Override
public void onPluginDisconnected(ClockPlugin plugin) {
- boolean isCurrentClock = plugin == mCurrentClock;
removeClockPlugin(plugin);
- reload();
- if (isCurrentClock) {
- ClockManager.this.reload();
- }
+ reloadIfNeeded(plugin);
}
/**
@@ -347,10 +340,19 @@ public final class ClockManager {
}
}
+ private void reloadIfNeeded(ClockPlugin plugin) {
+ final boolean wasCurrentClock = plugin == mCurrentClock;
+ reloadCurrentClock();
+ final boolean isCurrentClock = plugin == mCurrentClock;
+ if (wasCurrentClock || isCurrentClock) {
+ ClockManager.this.reload();
+ }
+ }
+
/**
* Update the current clock.
*/
- void reload() {
+ void reloadCurrentClock() {
mCurrentClock = getClockPlugin();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt b/packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
new file mode 100644
index 000000000000..5c5493a0c200
--- /dev/null
+++ b/packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.keyguard.clock
+
+import android.graphics.Color
+import android.util.MathUtils
+
+private const val PRIMARY_INDEX = 5
+private const val SECONDARY_DARK_INDEX = 8
+private const val SECONDARY_LIGHT_INDEX = 2
+
+/**
+ * A helper class to extract colors from a clock face.
+ */
+class ClockPalette {
+
+ private var darkAmount: Float = 0f
+ private var accentPrimary: Int = Color.WHITE
+ private var accentSecondaryLight: Int = Color.WHITE
+ private var accentSecondaryDark: Int = Color.BLACK
+ private val lightHSV: FloatArray = FloatArray(3)
+ private val darkHSV: FloatArray = FloatArray(3)
+ private val hsv: FloatArray = FloatArray(3)
+
+ /** Returns a color from the palette as an RGB packed int. */
+ fun getPrimaryColor(): Int {
+ return accentPrimary
+ }
+
+ /** Returns either a light or dark color from the palette as an RGB packed int. */
+ fun getSecondaryColor(): Int {
+ Color.colorToHSV(accentSecondaryLight, lightHSV)
+ Color.colorToHSV(accentSecondaryDark, darkHSV)
+ for (i in 0..2) {
+ hsv[i] = MathUtils.lerp(darkHSV[i], lightHSV[i], darkAmount)
+ }
+ return Color.HSVToColor(hsv)
+ }
+
+ /** See {@link ClockPlugin#setColorPalette}. */
+ fun setColorPalette(supportsDarkText: Boolean, colorPalette: IntArray?) {
+ if (colorPalette == null || colorPalette.isEmpty()) {
+ accentPrimary = Color.WHITE
+ accentSecondaryLight = Color.WHITE
+ accentSecondaryDark = if (supportsDarkText) Color.BLACK else Color.WHITE
+ return
+ }
+ val length = colorPalette.size
+ accentPrimary = colorPalette[Math.max(0, length - PRIMARY_INDEX)]
+ accentSecondaryLight = colorPalette[Math.max(0, length - SECONDARY_LIGHT_INDEX)]
+ accentSecondaryDark = colorPalette[Math.max(0,
+ length - if (supportsDarkText) SECONDARY_DARK_INDEX else SECONDARY_LIGHT_INDEX)]
+ }
+
+ /** See {@link ClockPlugin#setDarkAmount}. */
+ fun setDarkAmount(darkAmount: Float) {
+ this.darkAmount = darkAmount
+ }
+}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java b/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java
index e1c658be4c26..096e94348429 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SettingsWrapper.java
@@ -15,21 +15,37 @@
*/
package com.android.keyguard.clock;
+import android.annotation.Nullable;
import android.content.ContentResolver;
import android.provider.Settings;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import org.json.JSONException;
+import org.json.JSONObject;
/**
* Wrapper around Settings used for testing.
*/
public class SettingsWrapper {
+ private static final String TAG = "ClockFaceSettings";
private static final String CUSTOM_CLOCK_FACE = Settings.Secure.LOCK_SCREEN_CUSTOM_CLOCK_FACE;
private static final String DOCKED_CLOCK_FACE = Settings.Secure.DOCKED_CLOCK_FACE;
+ private static final String CLOCK_FIELD = "clock";
- private ContentResolver mContentResolver;
+ private final ContentResolver mContentResolver;
+ private final Migration mMigration;
- public SettingsWrapper(ContentResolver contentResolver) {
+ SettingsWrapper(ContentResolver contentResolver) {
+ this(contentResolver, new Migrator(contentResolver));
+ }
+
+ @VisibleForTesting
+ SettingsWrapper(ContentResolver contentResolver, Migration migration) {
mContentResolver = contentResolver;
+ mMigration = migration;
}
/**
@@ -37,8 +53,10 @@ public class SettingsWrapper {
*
* @param userId ID of the user.
*/
- public String getLockScreenCustomClockFace(int userId) {
- return Settings.Secure.getStringForUser(mContentResolver, CUSTOM_CLOCK_FACE, userId);
+ String getLockScreenCustomClockFace(int userId) {
+ return decode(
+ Settings.Secure.getStringForUser(mContentResolver, CUSTOM_CLOCK_FACE, userId),
+ userId);
}
/**
@@ -46,7 +64,74 @@ public class SettingsWrapper {
*
* @param userId ID of the user.
*/
- public String getDockedClockFace(int userId) {
+ String getDockedClockFace(int userId) {
return Settings.Secure.getStringForUser(mContentResolver, DOCKED_CLOCK_FACE, userId);
}
+
+ /**
+ * Decodes the string stored in settings, which should be formatted as JSON.
+ * @param value String stored in settings. If value is not JSON, then the settings is
+ * overwritten with JSON containing the prior value.
+ * @return ID of the clock face to show on AOD and lock screen. If value is not JSON, the value
+ * is returned.
+ */
+ @VisibleForTesting
+ String decode(@Nullable String value, int userId) {
+ if (value == null) {
+ return value;
+ }
+ JSONObject json;
+ try {
+ json = new JSONObject(value);
+ } catch (JSONException ex) {
+ Log.e(TAG, "Settings value is not valid JSON", ex);
+ // The settings value isn't JSON since it didn't parse so migrate the value to JSON.
+ // TODO(b/135674383): Remove this migration path in the following release.
+ mMigration.migrate(value, userId);
+ return value;
+ }
+ try {
+ return json.getString(CLOCK_FIELD);
+ } catch (JSONException ex) {
+ Log.e(TAG, "JSON object does not contain clock field.", ex);
+ return null;
+ }
+ }
+
+ interface Migration {
+ void migrate(String value, int userId);
+ }
+
+ /**
+ * Implementation of {@link Migration} that writes valid JSON back to Settings.
+ */
+ private static final class Migrator implements Migration {
+
+ private final ContentResolver mContentResolver;
+
+ Migrator(ContentResolver contentResolver) {
+ mContentResolver = contentResolver;
+ }
+
+ /**
+ * Migrate settings values that don't parse by converting to JSON format.
+ *
+ * Values in settings must be JSON to be backed up and restored. To help users maintain
+ * their current settings, convert existing values into the JSON format.
+ *
+ * TODO(b/135674383): Remove this migration code in the following release.
+ */
+ @Override
+ public void migrate(String value, int userId) {
+ try {
+ JSONObject json = new JSONObject();
+ json.put(CLOCK_FIELD, value);
+ Settings.Secure.putStringForUser(mContentResolver, CUSTOM_CLOCK_FACE,
+ json.toString(),
+ userId);
+ } catch (JSONException ex) {
+ Log.e(TAG, "Failed migrating settings value to JSON format", ex);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
index 9b15dc6d5063..60ca945278f6 100644
--- a/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
+++ b/packages/SystemUI/src/com/android/keyguard/clock/SmallClockPosition.java
@@ -67,7 +67,8 @@ class SmallClockPosition {
*/
int getPreferredY() {
// On AOD, clock needs to appear below the status bar with enough room for pixel shifting
- int aodY = mStatusBarHeight + mKeyguardLockPadding + mBurnInOffsetY;
+ int aodY = mStatusBarHeight + mKeyguardLockHeight + 2 * mKeyguardLockPadding
+ + mBurnInOffsetY;
// On lock screen, clock needs to appear below the lock icon
int lockY = mStatusBarHeight + mKeyguardLockHeight + 2 * mKeyguardLockPadding;
return (int) MathUtils.lerp(lockY, aodY, mDarkAmount);
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 9f4a4e08bbfd..6c36bc98996b 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -53,7 +53,6 @@ import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.DevicePolicyManagerWrapper;
import com.android.systemui.shared.system.PackageManagerWrapper;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.NavigationBarController;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -267,7 +266,6 @@ public class Dependency extends SystemUI {
@Inject Lazy<VisualStabilityManager> mVisualStabilityManager;
@Inject Lazy<NotificationGutsManager> mNotificationGutsManager;
@Inject Lazy<NotificationMediaManager> mNotificationMediaManager;
- @Inject Lazy<AmbientPulseManager> mAmbientPulseManager;
@Inject Lazy<NotificationBlockingHelperManager> mNotificationBlockingHelperManager;
@Inject Lazy<NotificationRemoteInputManager> mNotificationRemoteInputManager;
@Inject Lazy<SmartReplyConstants> mSmartReplyConstants;
@@ -447,7 +445,6 @@ public class Dependency extends SystemUI {
mNotificationGroupAlertTransferHelper::get);
mProviders.put(NotificationMediaManager.class, mNotificationMediaManager::get);
mProviders.put(NotificationGutsManager.class, mNotificationGutsManager::get);
- mProviders.put(AmbientPulseManager.class, mAmbientPulseManager::get);
mProviders.put(NotificationBlockingHelperManager.class,
mNotificationBlockingHelperManager::get);
mProviders.put(NotificationRemoteInputManager.class,
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 73e57de3f915..f38b4f259c88 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -305,7 +305,7 @@ public class ScreenDecorations extends SystemUI implements Tunable,
mAssistHintBlocked = blocked;
if (mAssistHintVisible && mAssistHintBlocked) {
- setAssistHintVisible(false);
+ hideAssistHandles();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 61a0f72315ea..e89e6cb269f8 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -37,6 +37,7 @@ import android.util.TimingsTraceLog;
import com.android.systemui.plugins.OverlayPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.plugins.PluginManager;
+import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.util.NotificationChannels;
@@ -215,7 +216,8 @@ public class SystemUIApplication extends Application implements SysUiServiceProv
StatusBar statusBar = getComponent(StatusBar.class);
if (statusBar != null) {
plugin.setup(statusBar.getStatusBarWindow(),
- statusBar.getNavigationBarView(), new Callback(plugin));
+ statusBar.getNavigationBarView(), new Callback(plugin),
+ DozeParameters.getInstance(getBaseContext()));
}
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index d815d95f23d5..e87da3cbc170 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -22,6 +22,7 @@ import static com.android.systemui.Dependency.LEAK_REPORT_EMAIL_NAME;
import android.annotation.Nullable;
import android.app.AlarmManager;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
@@ -48,10 +49,13 @@ import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardEnvironmentImpl;
+import com.android.systemui.statusbar.phone.KeyguardLiftController;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -60,7 +64,9 @@ import com.android.systemui.statusbar.phone.ScrimState;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.UnlockMethodCache;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.util.AsyncSensorManager;
import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.util.leak.GarbageMonitor;
import com.android.systemui.volume.VolumeDialogComponent;
@@ -130,8 +136,8 @@ public class SystemUIFactory {
KeyguardBouncer.BouncerExpansionCallback expansionCallback) {
return new KeyguardBouncer(context, callback, lockPatternUtils, container,
dismissCallbackRegistry, FalsingManagerFactory.getInstance(context),
- expansionCallback, KeyguardUpdateMonitor.getInstance(context),
- new Handler(Looper.getMainLooper()));
+ expansionCallback, UnlockMethodCache.getInstance(context),
+ KeyguardUpdateMonitor.getInstance(context), new Handler(Looper.getMainLooper()));
}
public ScrimController createScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
@@ -144,8 +150,12 @@ public class SystemUIFactory {
}
public NotificationIconAreaController createNotificationIconAreaController(Context context,
- StatusBar statusBar, StatusBarStateController statusBarStateController) {
+ StatusBar statusBar,
+ NotificationWakeUpCoordinator wakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ StatusBarStateController statusBarStateController) {
return new NotificationIconAreaController(context, statusBar, statusBarStateController,
+ wakeUpCoordinator, keyguardBypassController,
Dependency.get(NotificationMediaManager.class));
}
@@ -207,6 +217,18 @@ public class SystemUIFactory {
@Singleton
@Provides
+ @Nullable
+ public KeyguardLiftController provideKeyguardLiftController(Context context,
+ StatusBarStateController statusBarStateController,
+ AsyncSensorManager asyncSensorManager) {
+ if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ return null;
+ }
+ return new KeyguardLiftController(context, statusBarStateController, asyncSensorManager);
+ }
+
+ @Singleton
+ @Provides
public NotificationListener provideNotificationListener(Context context) {
return new NotificationListener(context);
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index afb8e7421412..7a74dba27dce 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -61,6 +61,7 @@ public class AppOpsControllerImpl implements AppOpsController,
private H mBGHandler;
private final List<AppOpsController.Callback> mCallbacks = new ArrayList<>();
private final ArrayMap<Integer, Set<Callback>> mCallbacksByCode = new ArrayMap<>();
+ private boolean mListening;
@GuardedBy("mActiveItems")
private final List<AppOpItem> mActiveItems = new ArrayList<>();
@@ -93,6 +94,7 @@ public class AppOpsControllerImpl implements AppOpsController,
@VisibleForTesting
protected void setListening(boolean listening) {
+ mListening = listening;
if (listening) {
mAppOps.startWatchingActive(OPS, this);
mAppOps.startWatchingNoted(OPS, this);
@@ -279,6 +281,7 @@ public class AppOpsControllerImpl implements AppOpsController,
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("AppOpsController state:");
+ pw.println(" Listening: " + mListening);
pw.println(" Active Items:");
for (int i = 0; i < mActiveItems.size(); i++) {
final AppOpItem item = mActiveItems.get(i);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index 67fcd68339e2..97b6e7c58440 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -258,12 +258,8 @@ public class AssistManager implements ConfigurationChangedReceiver {
}
int phoneState = mPhoneStateMonitor.getPhoneState();
args.putInt(INVOCATION_PHONE_STATE_KEY, phoneState);
- args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.uptimeMillis());
- // Logs assistant start with invocation type.
- MetricsLogger.action(
- new LogMaker(MetricsEvent.ASSISTANT)
- .setType(MetricsEvent.TYPE_OPEN)
- .setSubtype(toLoggingSubType(invocationType, phoneState)));
+ args.putLong(INVOCATION_TIME_MS_KEY, SystemClock.elapsedRealtime());
+ logStartAssist(invocationType, phoneState);
startAssistInternal(args, assistComponent, isService);
}
@@ -449,7 +445,14 @@ public class AssistManager implements ConfigurationChangedReceiver {
return toLoggingSubType(invocationType, mPhoneStateMonitor.getPhoneState());
}
- private int toLoggingSubType(int invocationType, int phoneState) {
+ protected void logStartAssist(int invocationType, int phoneState) {
+ MetricsLogger.action(
+ new LogMaker(MetricsEvent.ASSISTANT)
+ .setType(MetricsEvent.TYPE_OPEN)
+ .setSubtype(toLoggingSubType(invocationType, phoneState)));
+ }
+
+ protected final int toLoggingSubType(int invocationType, int phoneState) {
// Note that this logic will break if the number of Assistant invocation types exceeds 7.
// There are currently 5 invocation types, but we will be migrating to the new logging
// framework in the next update.
diff --git a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
index 61395f158aea..b3f57afc0753 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/PhenotypeHelper.java
@@ -22,28 +22,28 @@ import androidx.annotation.Nullable;
import java.util.concurrent.Executor;
-class PhenotypeHelper {
+public class PhenotypeHelper {
- PhenotypeHelper() {}
+ public PhenotypeHelper() {}
- long getLong(String name, long defaultValue) {
+ public long getLong(String name, long defaultValue) {
return DeviceConfig.getLong(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
}
- int getInt(String name, int defaultValue) {
+ public int getInt(String name, int defaultValue) {
return DeviceConfig.getInt(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
}
@Nullable
- String getString(String name, @Nullable String defaultValue) {
+ public String getString(String name, @Nullable String defaultValue) {
return DeviceConfig.getString(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
}
- boolean getBoolean(String name, boolean defaultValue) {
+ public boolean getBoolean(String name, boolean defaultValue) {
return DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_SYSTEMUI, name, defaultValue);
}
- void addOnPropertiesChangedListener(
+ public void addOnPropertiesChangedListener(
Executor executor, DeviceConfig.OnPropertiesChangedListener listener) {
DeviceConfig.addOnPropertiesChangedListener(
DeviceConfig.NAMESPACE_SYSTEMUI, executor, listener);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
index 8ef7b6c564e9..43e7045511c5 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/InvocationLightsView.java
@@ -129,7 +129,7 @@ public class InvocationLightsView extends View
float arcLengthNormalized = cornerLengthNormalized * MINIMUM_CORNER_RATIO;
float arcOffsetNormalized = (cornerLengthNormalized - arcLengthNormalized) / 2f;
- float minLightLength = arcLengthNormalized / 2;
+ float minLightLength = 0;
float maxLightLength = mGuide.getRegionWidth(PerimeterPathGuide.Region.BOTTOM) / 4f;
float lightLength = MathUtils.lerp(minLightLength, maxLightLength, progress);
diff --git a/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java b/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java
index 8eea36892aa7..65a9fcc3a955 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/ui/PerimeterPathGuide.java
@@ -287,9 +287,12 @@ public class PerimeterPathGuide {
float accum = 0;
for (int i = 0; i < mRegions.length; i++) {
mRegions[i].normalizedLength = mRegions[i].absoluteLength / perimeterLength;
- accum += mRegions[i].normalizedLength;
- mRegions[i].endCoordinate = accum;
+ accum += mRegions[i].absoluteLength;
+ mRegions[i].endCoordinate = accum / perimeterLength;
}
+ // Ensure that the last coordinate is 1. Setting it explicitly to avoid floating point
+ // error.
+ mRegions[mRegions.length - 1].endCoordinate = 1f;
}
private CircularCornerPathRenderer.Corner getRotatedCorner(
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index 18b8a9c859b1..932e40c77af0 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -16,6 +16,8 @@
package com.android.systemui.biometrics;
+import static android.view.accessibility.AccessibilityEvent.CONTENT_CHANGE_TYPE_SUBTREE;
+
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.graphics.PixelFormat;
@@ -36,6 +38,8 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityManager;
import android.view.animation.Interpolator;
import android.widget.Button;
import android.widget.ImageView;
@@ -55,6 +59,7 @@ public abstract class BiometricDialogView extends LinearLayout {
private static final String KEY_TRY_AGAIN_VISIBILITY = "key_try_again_visibility";
private static final String KEY_CONFIRM_VISIBILITY = "key_confirm_visibility";
+ private static final String KEY_CONFIRM_ENABLED = "key_confirm_enabled";
private static final String KEY_STATE = "key_state";
private static final String KEY_ERROR_TEXT_VISIBILITY = "key_error_text_visibility";
private static final String KEY_ERROR_TEXT_STRING = "key_error_text_string";
@@ -72,6 +77,7 @@ public abstract class BiometricDialogView extends LinearLayout {
protected static final int STATE_PENDING_CONFIRMATION = 3;
protected static final int STATE_AUTHENTICATED = 4;
+ private final AccessibilityManager mAccessibilityManager;
private final IBinder mWindowToken = new Binder();
private final Interpolator mLinearOutSlowIn;
private final WindowManager mWindowManager;
@@ -150,6 +156,7 @@ public abstract class BiometricDialogView extends LinearLayout {
super(context);
mCallback = callback;
mLinearOutSlowIn = Interpolators.LINEAR_OUT_SLOW_IN;
+ mAccessibilityManager = mContext.getSystemService(AccessibilityManager.class);
mWindowManager = mContext.getSystemService(WindowManager.class);
mUserManager = mContext.getSystemService(UserManager.class);
mDevicePolicyManager = mContext.getSystemService(DevicePolicyManager.class);
@@ -226,6 +233,10 @@ public abstract class BiometricDialogView extends LinearLayout {
handleResetMessage();
updateState(STATE_AUTHENTICATING);
showTryAgainButton(false /* show */);
+
+ mPositiveButton.setVisibility(View.VISIBLE);
+ mPositiveButton.setEnabled(false);
+
mCallback.onTryAgainPressed();
});
@@ -237,6 +248,7 @@ public abstract class BiometricDialogView extends LinearLayout {
public void onSaveState(Bundle bundle) {
bundle.putInt(KEY_TRY_AGAIN_VISIBILITY, mTryAgainButton.getVisibility());
bundle.putInt(KEY_CONFIRM_VISIBILITY, mPositiveButton.getVisibility());
+ bundle.putBoolean(KEY_CONFIRM_ENABLED, mPositiveButton.isEnabled());
bundle.putInt(KEY_STATE, mState);
bundle.putInt(KEY_ERROR_TEXT_VISIBILITY, mErrorText.getVisibility());
bundle.putCharSequence(KEY_ERROR_TEXT_STRING, mErrorText.getText());
@@ -255,6 +267,7 @@ public abstract class BiometricDialogView extends LinearLayout {
mContext.getTheme());
image.setColorFilter(mDevicePolicyManager.getOrganizationColorForUser(mUserId),
PorterDuff.Mode.DARKEN);
+ backgroundView.setScaleType(ImageView.ScaleType.CENTER_CROP);
backgroundView.setImageDrawable(image);
} else {
backgroundView.setImageDrawable(null);
@@ -269,9 +282,15 @@ public abstract class BiometricDialogView extends LinearLayout {
if (mRestoredState == null) {
updateState(STATE_AUTHENTICATING);
- mErrorText.setText(getHintStringResourceId());
- mErrorText.setContentDescription(mContext.getString(getHintStringResourceId()));
- mErrorText.setVisibility(View.VISIBLE);
+ final int hint = getHintStringResourceId();
+ if (hint != 0) {
+ mErrorText.setText(hint);
+ mErrorText.setContentDescription(mContext.getString(hint));
+ mErrorText.setVisibility(View.VISIBLE);
+ } else {
+ mErrorText.setVisibility(View.INVISIBLE);
+ }
+ announceAccessibilityEvent();
} else {
updateState(mState);
}
@@ -284,6 +303,7 @@ public abstract class BiometricDialogView extends LinearLayout {
final CharSequence subtitleText = mBundle.getCharSequence(BiometricPrompt.KEY_SUBTITLE);
if (TextUtils.isEmpty(subtitleText)) {
mSubtitleText.setVisibility(View.GONE);
+ announceAccessibilityEvent();
} else {
mSubtitleText.setVisibility(View.VISIBLE);
mSubtitleText.setText(subtitleText);
@@ -293,6 +313,7 @@ public abstract class BiometricDialogView extends LinearLayout {
mBundle.getCharSequence(BiometricPrompt.KEY_DESCRIPTION);
if (TextUtils.isEmpty(descriptionText)) {
mDescriptionText.setVisibility(View.GONE);
+ announceAccessibilityEvent();
} else {
mDescriptionText.setVisibility(View.VISIBLE);
mDescriptionText.setText(descriptionText);
@@ -417,6 +438,7 @@ public abstract class BiometricDialogView extends LinearLayout {
mErrorText.setText(message);
mErrorText.setTextColor(mErrorColor);
mErrorText.setContentDescription(message);
+ mErrorText.setVisibility(View.VISIBLE);
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
BiometricPrompt.HIDE_DIALOG_DELAY);
}
@@ -450,13 +472,17 @@ public abstract class BiometricDialogView extends LinearLayout {
public void updateState(int newState) {
if (newState == STATE_PENDING_CONFIRMATION) {
mHandler.removeMessages(MSG_RESET_MESSAGE);
- mErrorText.setVisibility(View.INVISIBLE);
+ mErrorText.setTextColor(mTextColor);
+ mErrorText.setText(R.string.biometric_dialog_tap_confirm);
+ mErrorText.setVisibility(View.VISIBLE);
+ announceAccessibilityEvent();
mPositiveButton.setVisibility(View.VISIBLE);
mPositiveButton.setEnabled(true);
} else if (newState == STATE_AUTHENTICATED) {
mPositiveButton.setVisibility(View.GONE);
mNegativeButton.setVisibility(View.GONE);
mErrorText.setVisibility(View.INVISIBLE);
+ announceAccessibilityEvent();
}
if (newState == STATE_PENDING_CONFIRMATION || newState == STATE_AUTHENTICATED) {
@@ -475,14 +501,22 @@ public abstract class BiometricDialogView extends LinearLayout {
public void restoreState(Bundle bundle) {
mRestoredState = bundle;
- mTryAgainButton.setVisibility(bundle.getInt(KEY_TRY_AGAIN_VISIBILITY));
- mPositiveButton.setVisibility(bundle.getInt(KEY_CONFIRM_VISIBILITY));
+ final int tryAgainVisibility = bundle.getInt(KEY_TRY_AGAIN_VISIBILITY);
+ mTryAgainButton.setVisibility(tryAgainVisibility);
+ final int confirmVisibility = bundle.getInt(KEY_CONFIRM_VISIBILITY);
+ mPositiveButton.setVisibility(confirmVisibility);
+ final boolean confirmEnabled = bundle.getBoolean(KEY_CONFIRM_ENABLED);
+ mPositiveButton.setEnabled(confirmEnabled);
mState = bundle.getInt(KEY_STATE);
mErrorText.setText(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
mErrorText.setContentDescription(bundle.getCharSequence(KEY_ERROR_TEXT_STRING));
- mErrorText.setVisibility(bundle.getInt(KEY_ERROR_TEXT_VISIBILITY));
+ final int errorTextVisibility = bundle.getInt(KEY_ERROR_TEXT_VISIBILITY);
+ mErrorText.setVisibility(errorTextVisibility);
+ if (errorTextVisibility == View.INVISIBLE || tryAgainVisibility == View.INVISIBLE
+ || confirmVisibility == View.INVISIBLE) {
+ announceAccessibilityEvent();
+ }
mErrorText.setTextColor(bundle.getInt(KEY_ERROR_TEXT_COLOR));
-
if (bundle.getBoolean(KEY_ERROR_TEXT_IS_TEMPORARY)) {
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_RESET_MESSAGE),
BiometricPrompt.HIDE_DIALOG_DELAY);
@@ -505,4 +539,18 @@ public abstract class BiometricDialogView extends LinearLayout {
lp.token = mWindowToken;
return lp;
}
+
+ // Every time a view becomes invisible we need to announce an accessibility event.
+ // This is due to an issue in the framework, b/132298701 recommended this workaround.
+ protected void announceAccessibilityEvent() {
+ if (!mAccessibilityManager.isEnabled()) {
+ return;
+ }
+ AccessibilityEvent event = AccessibilityEvent.obtain();
+ event.setEventType(AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED);
+ event.setContentChangeTypes(CONTENT_CHANGE_TYPE_SUBTREE);
+ mDialog.sendAccessibilityEventUnchecked(event);
+ mDialog.notifySubtreeAccessibilityStateChanged(mDialog, mDialog,
+ CONTENT_CHANGE_TYPE_SUBTREE);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
index 8f26f1847779..729242e3144f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
@@ -149,6 +149,7 @@ public class FaceDialogView extends BiometricDialogView {
private final Runnable mErrorToIdleAnimationRunnable = () -> {
updateState(STATE_IDLE);
mErrorText.setVisibility(View.INVISIBLE);
+ announceAccessibilityEvent();
};
public FaceDialogView(Context context,
@@ -188,6 +189,7 @@ public class FaceDialogView extends BiometricDialogView {
mDialog.invalidateOutline();
mSize = newSize;
+ announceAccessibilityEvent();
} else if (mSize == SIZE_SMALL && newSize == SIZE_BIG) {
mSize = SIZE_GROWING;
@@ -287,14 +289,9 @@ public class FaceDialogView extends BiometricDialogView {
@Override
protected void handleResetMessage() {
- mErrorText.setText(getHintStringResourceId());
- mErrorText.setContentDescription(mContext.getString(getHintStringResourceId()));
mErrorText.setTextColor(mTextColor);
- if (getState() == STATE_AUTHENTICATING) {
- mErrorText.setVisibility(View.VISIBLE);
- } else {
- mErrorText.setVisibility(View.INVISIBLE);
- }
+ mErrorText.setVisibility(View.INVISIBLE);
+ announceAccessibilityEvent();
}
@Override
@@ -368,17 +365,19 @@ public class FaceDialogView extends BiometricDialogView {
mTryAgainButton.setVisibility(View.VISIBLE);
} else {
mTryAgainButton.setVisibility(View.GONE);
+ announceAccessibilityEvent();
}
}
if (show) {
mPositiveButton.setVisibility(View.GONE);
+ announceAccessibilityEvent();
}
}
@Override
protected int getHintStringResourceId() {
- return R.string.face_dialog_looking_for_face;
+ return 0;
}
@Override
@@ -403,7 +402,6 @@ public class FaceDialogView extends BiometricDialogView {
mHandler.removeCallbacks(mErrorToIdleAnimationRunnable);
if (mDialogAnimatedIn) {
mIconController.startPulsing();
- mErrorText.setVisibility(View.VISIBLE);
} else {
mIconController.showIcon(R.drawable.face_dialog_pulse_dark_to_light);
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
index f60e95e32600..5c6c39722900 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/Bubble.java
@@ -16,6 +16,8 @@
package com.android.systemui.bubbles;
+import static android.view.Display.INVALID_DISPLAY;
+
import static com.android.internal.annotations.VisibleForTesting.Visibility.PRIVATE;
import android.content.Context;
@@ -129,6 +131,20 @@ class Bubble {
mInflated = true;
}
+ /**
+ * Set visibility of bubble in the expanded state.
+ *
+ * @param visibility {@code true} if the expanded bubble should be visible on the screen.
+ *
+ * Note that this contents visibility doesn't affect visibility at {@link android.view.View},
+ * and setting {@code false} actually means rendering the expanded view in transparent.
+ */
+ void setContentVisibility(boolean visibility) {
+ if (expandedView != null) {
+ expandedView.setContentVisibility(visibility);
+ }
+ }
+
void setDismissed() {
entry.setBubbleDismissed(true);
// TODO: move this somewhere where it can be guaranteed not to run until safe from flicker
@@ -168,6 +184,13 @@ class Bubble {
}
/**
+ * @return the display id of the virtual display on which bubble contents is drawn.
+ */
+ int getDisplayId() {
+ return expandedView != null ? expandedView.getVirtualDisplayId() : INVALID_DISPLAY;
+ }
+
+ /**
* Should be invoked whenever a Bubble is accessed (selected while expanded).
*/
void markAsAccessedAt(long lastAccessedMillis) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 392183b554a9..a23c99ef01fe 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -672,17 +672,23 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
* status bar, otherwise returns {@link Display#INVALID_DISPLAY}.
*/
public int getExpandedDisplayId(Context context) {
+ final Bubble bubble = getExpandedBubble(context);
+ return bubble != null ? bubble.getDisplayId() : INVALID_DISPLAY;
+ }
+
+ @Nullable
+ private Bubble getExpandedBubble(Context context) {
if (mStackView == null) {
- return INVALID_DISPLAY;
+ return null;
}
- boolean defaultDisplay = context.getDisplay() != null
+ final boolean defaultDisplay = context.getDisplay() != null
&& context.getDisplay().getDisplayId() == DEFAULT_DISPLAY;
- Bubble b = mStackView.getExpandedBubble();
- if (defaultDisplay && b != null && isStackExpanded()
+ final Bubble expandedBubble = mStackView.getExpandedBubble();
+ if (defaultDisplay && expandedBubble != null && isStackExpanded()
&& !mStatusBarWindowController.getPanelExpanded()) {
- return b.expandedView.getVirtualDisplayId();
+ return expandedBubble;
}
- return INVALID_DISPLAY;
+ return null;
}
@VisibleForTesting
@@ -793,6 +799,14 @@ public class BubbleController implements ConfigurationController.ConfigurationLi
mBubbleData.setExpanded(false);
}
}
+
+ @Override
+ public void onSingleTaskDisplayDrawn(int displayId) {
+ final Bubble expandedBubble = getExpandedBubble(mContext);
+ if (expandedBubble != null && expandedBubble.getDisplayId() == displayId) {
+ expandedBubble.setContentVisibility(true);
+ }
+ }
}
private static boolean shouldAutoBubbleMessages(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
index cbe6c99bfb0b..923ca20b3925 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleExpandedView.java
@@ -182,6 +182,8 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
mActivityView = new ActivityView(mContext, null /* attrs */, 0 /* defStyle */,
true /* singleTaskInstance */);
+
+ setContentVisibility(false);
addView(mActivityView);
// Expanded stack layout, top to bottom:
@@ -236,6 +238,22 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
}
/**
+ * Set visibility of contents in the expanded state.
+ *
+ * @param visibility {@code true} if the contents should be visible on the screen.
+ *
+ * Note that this contents visibility doesn't affect visibility at {@link android.view.View},
+ * and setting {@code false} actually means rendering the contents in transparent.
+ */
+ void setContentVisibility(boolean visibility) {
+ final float alpha = visibility ? 1f : 0f;
+ mPointerView.setAlpha(alpha);
+ if (mActivityView != null) {
+ mActivityView.setAlpha(alpha);
+ }
+ }
+
+ /**
* Called by {@link BubbleStackView} when the insets for the expanded state should be updated.
* This should be done post-move and post-animation.
*/
@@ -307,6 +325,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
parent.removeView(mNotifRow);
}
addView(mNotifRow, 1 /* index */);
+ mPointerView.setAlpha(1f);
}
}
@@ -333,6 +352,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
removeView(mNotifRow);
mNotifRow = null;
}
+ setContentVisibility(false);
mActivityView.setVisibility(VISIBLE);
} else if (DEBUG_ENABLE_AUTO_BUBBLE) {
// Hide activity view if we had it previously
@@ -428,6 +448,7 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
mActivityView.onLocationChanged();
} else if (mNotifRow != null) {
applyRowState(mNotifRow);
+ mPointerView.setAlpha(1f);
}
updateHeight();
}
@@ -478,7 +499,6 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
view.setHeadsUp(false);
view.resetTranslation();
view.setOnKeyguard(false);
- view.setOnAmbient(false);
view.setClipBottomAmount(0);
view.setClipTopAmount(0);
view.setContentTransformationAmount(0, false);
@@ -494,7 +514,6 @@ public class BubbleExpandedView extends LinearLayout implements View.OnClickList
viewState.gone = false;
viewState.hidden = false;
viewState.dimmed = false;
- viewState.dark = false;
viewState.alpha = 1f;
viewState.notGoneIndex = -1;
viewState.xTranslation = 0;
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 771df2d86110..f87bcef5fde2 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -745,12 +745,16 @@ public class BubbleStackView extends FrameLayout {
}
final Bubble previouslySelected = mExpandedBubble;
mExpandedBubble = bubbleToSelect;
+
if (mIsExpanded) {
// Make the container of the expanded view transparent before removing the expanded view
// from it. Otherwise a punch hole created by {@link android.view.SurfaceView} in the
// expanded view becomes visible on the screen. See b/126856255
mExpandedViewContainer.setAlpha(0.0f);
mSurfaceSynchronizer.syncSurfaceAndRun(() -> {
+ if (previouslySelected != null) {
+ previouslySelected.setContentVisibility(false);
+ }
updateExpandedBubble();
updatePointerPosition();
requestUpdate();
@@ -779,6 +783,14 @@ public class BubbleStackView extends FrameLayout {
}
if (wasExpanded) {
// Collapse the stack
+ mExpandedViewContainer.setAlpha(0.0f);
+ // TODO: In order to prevent flicker, code below should be executed after the alpha
+ // value set on the mExpandedViewContainer is reflected on the screen. However, we
+ // cannot just postpone the execution like #setSelectedBubble(), since some of member
+ // variables referred by the code are overridden before the execution.
+ if (mExpandedBubble != null) {
+ mExpandedBubble.setContentVisibility(false);
+ }
animateExpansion(false /* expand */);
logBubbleEvent(mExpandedBubble, StatsLog.BUBBLE_UICHANGED__ACTION__COLLAPSED);
} else {
@@ -934,14 +946,10 @@ public class BubbleStackView extends FrameLayout {
if (shouldExpand) {
mExpandedViewContainer.setTranslationX(xStart);
mExpandedViewContainer.setTranslationY(yStart);
- mExpandedViewContainer.setAlpha(0f);
}
mExpandedViewXAnim.animateToFinalPosition(shouldExpand ? 0f : xStart);
mExpandedViewYAnim.animateToFinalPosition(shouldExpand ? yDest : yStart);
- mExpandedViewContainer.animate()
- .setDuration(100)
- .alpha(shouldExpand ? 1f : 0f);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
index 6f56a53c1c49..0e93f42a3554 100644
--- a/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
+++ b/packages/SystemUI/src/com/android/systemui/colorextraction/SysuiColorExtractor.java
@@ -67,12 +67,10 @@ public class SysuiColorExtractor extends ColorExtractor implements Dumpable,
mBackdropColors = new GradientColors();
mBackdropColors.setMainColor(Color.BLACK);
- if (wallpaperManager != null) {
- // Listen to all users instead of only the current one.
- wallpaperManager.removeOnColorsChangedListener(this);
- wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
- UserHandle.USER_ALL);
- }
+ // Listen to all users instead of only the current one.
+ wallpaperManager.removeOnColorsChangedListener(this);
+ wallpaperManager.addOnColorsChangedListener(this, null /* handler */,
+ UserHandle.USER_ALL);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
new file mode 100644
index 000000000000..e6a9e47be71c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeAuthRemover.java
@@ -0,0 +1,43 @@
+/*
+ * 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.doze;
+
+import android.content.Context;
+
+import com.android.keyguard.KeyguardUpdateMonitor;
+
+/**
+ * Controls removing Keyguard authorization when the phone goes to sleep.
+ */
+public class DozeAuthRemover implements DozeMachine.Part {
+
+ KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+
+ public DozeAuthRemover(Context context) {
+ mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context);
+ }
+
+ @Override
+ public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
+ if (newState == DozeMachine.State.DOZE || newState == DozeMachine.State.DOZE_AOD) {
+ int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+ if (mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(currentUser)) {
+ mKeyguardUpdateMonitor.clearBiometricRecognized();
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
index 3c6dc7317357..1d7e9eacbd2e 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeDockHandler.java
@@ -43,6 +43,7 @@ public class DozeDockHandler implements DozeMachine.Part {
private final DockManager mDockManager;
private int mDockState = DockManager.STATE_NONE;
+ private boolean mPulsePending;
public DozeDockHandler(Context context, DozeMachine machine, DozeHost dozeHost,
AmbientDisplayConfiguration config, Handler handler, DockManager dockManager) {
@@ -66,7 +67,8 @@ public class DozeDockHandler implements DozeMachine.Part {
}
// continue below
case DOZE:
- if (mDockState == DockManager.STATE_DOCKED) {
+ if (mDockState == DockManager.STATE_DOCKED && !mPulsePending) {
+ mPulsePending = true;
mHandler.post(() -> requestPulse(newState));
}
break;
@@ -79,11 +81,10 @@ public class DozeDockHandler implements DozeMachine.Part {
}
private void requestPulse(State dozeState) {
- if (mDozeHost.isPulsingBlocked() || !dozeState.canPulse()) {
- return;
+ if (!mDozeHost.isPulsingBlocked() && dozeState.canPulse()) {
+ mMachine.requestPulse(DozeLog.PULSE_REASON_DOCKING);
}
-
- mMachine.requestPulse(DozeLog.PULSE_REASON_DOCKING);
+ mPulsePending = false;
}
private void requestPulseOutNow(State dozeState) {
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
index 8694d2ad607c..fc3d1a52342f 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeFactory.java
@@ -71,7 +71,8 @@ public class DozeFactory {
createDozeScreenBrightness(context, wrappedService, sensorManager, host, params,
handler),
new DozeWallpaperState(context),
- new DozeDockHandler(context, machine, host, config, handler, dockManager)
+ new DozeDockHandler(context, machine, host, config, handler, dockManager),
+ new DozeAuthRemover(dozeService)
});
return machine;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
index 368451ad379d..5be097c457dc 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeScreenState.java
@@ -36,13 +36,13 @@ public class DozeScreenState implements DozeMachine.Part {
* Delay entering low power mode when animating to make sure that we'll have
* time to move all elements into their final positions while still at 60 fps.
*/
- private static final int ENTER_DOZE_DELAY = 6000;
+ private static final int ENTER_DOZE_DELAY = 4000;
/**
* Hide wallpaper earlier when entering low power mode. The gap between
* hiding the wallpaper and changing the display mode is necessary to hide
* the black frame that's inherent to hardware specs.
*/
- public static final int ENTER_DOZE_HIDE_WALLPAPER_DELAY = 4500;
+ public static final int ENTER_DOZE_HIDE_WALLPAPER_DELAY = 2500;
private final DozeMachine.Service mDozeService;
private final Handler mHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
index 5f52486b2bc6..cf04b7f192e4 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeSensors.java
@@ -76,6 +76,8 @@ public class DozeSensors {
private final ProxSensor mProxSensor;
private long mDebounceFrom;
private boolean mSettingRegistered;
+ private boolean mListening;
+ private boolean mPaused;
public DozeSensors(Context context, AlarmManager alarmManager, SensorManager sensorManager,
DozeParameters dozeParameters, AmbientDisplayConfiguration config, WakeLock wakeLock,
@@ -100,9 +102,12 @@ public class DozeSensors {
mPickupSensor = new TriggerSensor(
mSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE),
Settings.Secure.DOZE_PICK_UP_GESTURE,
+ true /* settingDef */,
config.dozePickupSensorAvailable(),
DozeLog.REASON_SENSOR_PICKUP, false /* touchCoords */,
- false /* touchscreen */),
+ false /* touchscreen */,
+ false /* ignoresSetting */,
+ mDozeParameters.getPickupPerformsProxCheck()),
new TriggerSensor(
findSensorWithType(config.doubleTapSensorType()),
Settings.Secure.DOZE_DOUBLE_TAP_GESTURE,
@@ -127,15 +132,15 @@ public class DozeSensors {
true /* touchscreen */),
new PluginSensor(
new SensorManagerPlugin.Sensor(TYPE_WAKE_DISPLAY),
- Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
+ Settings.Secure.DOZE_WAKE_DISPLAY_GESTURE,
mConfig.wakeScreenGestureAvailable() && alwaysOn,
DozeLog.REASON_SENSOR_WAKE_UP,
false /* reports touch coordinates */,
false /* touchscreen */),
new PluginSensor(
new SensorManagerPlugin.Sensor(TYPE_WAKE_LOCK_SCREEN),
- Settings.Secure.DOZE_WAKE_SCREEN_GESTURE,
- mConfig.wakeScreenGestureAvailable() && alwaysOn,
+ Settings.Secure.DOZE_WAKE_LOCK_SCREEN_GESTURE,
+ mConfig.wakeScreenGestureAvailable(),
DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
false /* reports touch coordinates */,
false /* touchscreen */, mConfig.getWakeLockScreenDebounce()),
@@ -170,11 +175,49 @@ public class DozeSensors {
return null;
}
+ /**
+ * If sensors should be registered and sending signals.
+ */
public void setListening(boolean listen) {
+ if (mListening == listen) {
+ return;
+ }
+ mListening = listen;
+ updateListening();
+ }
+
+ /**
+ * Unregister sensors, when listening, unless they are prox gated.
+ * @see #setListening(boolean)
+ */
+ public void setPaused(boolean paused) {
+ if (mPaused == paused) {
+ return;
+ }
+ mPaused = paused;
+ updateListening();
+ }
+
+ private void updateListening() {
+ boolean anyListening = false;
for (TriggerSensor s : mSensors) {
+ // We don't want to be listening while we're PAUSED (prox sensor is covered)
+ // except when the sensor is already gated by prox.
+ boolean listen = mListening && (!mPaused || s.performsProxCheck());
s.setListening(listen);
+ if (listen) {
+ anyListening = true;
+ }
+ }
+
+ if (!anyListening) {
+ mResolver.unregisterContentObserver(mSettingsObserver);
+ } else if (!mSettingRegistered) {
+ for (TriggerSensor s : mSensors) {
+ s.registerSettingsObserver(mSettingsObserver);
+ }
}
- registerSettingsObserverIfNeeded(listen);
+ mSettingRegistered = anyListening;
}
/** Set the listening state of only the sensors that require the touchscreen. */
@@ -236,17 +279,6 @@ public class DozeSensors {
return mProxSensor.mCurrentlyFar;
}
- private void registerSettingsObserverIfNeeded(boolean register) {
- if (!register) {
- mResolver.unregisterContentObserver(mSettingsObserver);
- } else if (!mSettingRegistered) {
- for (TriggerSensor s : mSensors) {
- s.registerSettingsObserver(mSettingsObserver);
- }
- }
- mSettingRegistered = register;
- }
-
private class ProxSensor implements SensorEventListener {
boolean mRequested;
@@ -334,10 +366,11 @@ public class DozeSensors {
final Sensor mSensor;
final boolean mConfigured;
final int mPulseReason;
- final String mSetting;
- final boolean mReportsTouchCoordinates;
- final boolean mSettingDefault;
- final boolean mRequiresTouchscreen;
+ private final String mSetting;
+ private final boolean mReportsTouchCoordinates;
+ private final boolean mSettingDefault;
+ private final boolean mRequiresTouchscreen;
+ private final boolean mSensorPerformsProxCheck;
protected boolean mRequested;
protected boolean mRegistered;
@@ -354,12 +387,14 @@ public class DozeSensors {
boolean configured, int pulseReason, boolean reportsTouchCoordinates,
boolean requiresTouchscreen) {
this(sensor, setting, settingDef, configured, pulseReason, reportsTouchCoordinates,
- requiresTouchscreen, false /* ignoresSetting */);
+ requiresTouchscreen, false /* ignoresSetting */,
+ false /* sensorPerformsProxCheck */);
}
private TriggerSensor(Sensor sensor, String setting, boolean settingDef,
boolean configured, int pulseReason, boolean reportsTouchCoordinates,
- boolean requiresTouchscreen, boolean ignoresSetting) {
+ boolean requiresTouchscreen, boolean ignoresSetting,
+ boolean sensorPerformsProxCheck) {
mSensor = sensor;
mSetting = setting;
mSettingDefault = settingDef;
@@ -368,6 +403,7 @@ public class DozeSensors {
mReportsTouchCoordinates = reportsTouchCoordinates;
mRequiresTouchscreen = requiresTouchscreen;
mIgnoresSetting = ignoresSetting;
+ mSensorPerformsProxCheck = sensorPerformsProxCheck;
}
public void setListening(boolean listen) {
@@ -427,14 +463,11 @@ public class DozeSensors {
DozeLog.traceSensor(mContext, mPulseReason);
mHandler.post(mWakeLock.wrap(() -> {
if (DEBUG) Log.d(TAG, "onTrigger: " + triggerEventToString(event));
- boolean sensorPerformsProxCheck = false;
if (mSensor != null && mSensor.getType() == Sensor.TYPE_PICK_UP_GESTURE) {
int subType = (int) event.values[0];
MetricsLogger.action(
mContext, MetricsProto.MetricsEvent.ACTION_AMBIENT_GESTURE,
subType);
- sensorPerformsProxCheck =
- mDozeParameters.getPickupSubtypePerformsProxCheck(subType);
}
mRegistered = false;
@@ -444,7 +477,7 @@ public class DozeSensors {
screenX = event.values[0];
screenY = event.values[1];
}
- mCallback.onSensorPulse(mPulseReason, sensorPerformsProxCheck, screenX, screenY,
+ mCallback.onSensorPulse(mPulseReason, mSensorPerformsProxCheck, screenX, screenY,
event.values);
if (!mRegistered) {
updateListener(); // reregister, this sensor only fires once
@@ -452,6 +485,15 @@ public class DozeSensors {
}));
}
+ /**
+ * If the sensor itself performs proximity checks, to avoid pocket dialing.
+ * Gated sensors don't need to be stopped when the {@link DozeMachine} is
+ * {@link DozeMachine.State#DOZE_AOD_PAUSED}.
+ */
+ public boolean performsProxCheck() {
+ return mSensorPerformsProxCheck;
+ }
+
public void registerSettingsObserver(ContentObserver settingsObserver) {
if (mConfigured && !TextUtils.isEmpty(mSetting)) {
mResolver.registerContentObserver(
@@ -543,7 +585,7 @@ public class DozeSensors {
mHandler.post(mWakeLock.wrap(() -> {
final long now = SystemClock.uptimeMillis();
if (now < mDebounceFrom + mDebounce) {
- if (DEBUG) Log.d(TAG, "onSensorEvent dropped: " + triggerEventToString(event));
+ Log.d(TAG, "onSensorEvent dropped: " + triggerEventToString(event));
return;
}
if (DEBUG) Log.d(TAG, "onSensorEvent: " + triggerEventToString(event));
diff --git a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
index a381e7b60f0a..97b08d5a12a6 100644
--- a/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
+++ b/packages/SystemUI/src/com/android/systemui/doze/DozeTriggers.java
@@ -107,9 +107,17 @@ public class DozeTriggers implements DozeMachine.Part {
}
private void onNotification() {
- if (DozeMachine.DEBUG) Log.d(TAG, "requestNotificationPulse");
+ if (DozeMachine.DEBUG) {
+ Log.d(TAG, "requestNotificationPulse");
+ }
+ if (!sWakeDisplaySensorState) {
+ Log.d(TAG, "Wake display false. Pulse denied.");
+ return;
+ }
mNotificationPulseTime = SystemClock.elapsedRealtime();
- if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) return;
+ if (!mConfig.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) {
+ return;
+ }
requestPulse(DozeLog.PULSE_REASON_NOTIFICATION, false /* performedProxCheck */);
DozeLog.traceNotificationPulse(mContext);
}
@@ -216,15 +224,21 @@ public class DozeTriggers implements DozeMachine.Part {
if (state == DozeMachine.State.DOZE_PULSING
|| state == DozeMachine.State.DOZE_PULSING_BRIGHT) {
boolean ignoreTouch = near;
- if (DEBUG) Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
+ if (DEBUG) {
+ Log.i(TAG, "Prox changed, ignore touch = " + ignoreTouch);
+ }
mDozeHost.onIgnoreTouchWhilePulsing(ignoreTouch);
}
if (far && (paused || pausing)) {
- if (DEBUG) Log.i(TAG, "Prox FAR, unpausing AOD");
+ if (DEBUG) {
+ Log.i(TAG, "Prox FAR, unpausing AOD");
+ }
mMachine.requestState(DozeMachine.State.DOZE_AOD);
} else if (near && aod) {
- if (DEBUG) Log.i(TAG, "Prox NEAR, pausing AOD");
+ if (DEBUG) {
+ Log.i(TAG, "Prox NEAR, pausing AOD");
+ }
mMachine.requestState(DozeMachine.State.DOZE_AOD_PAUSING);
}
}
@@ -282,6 +296,7 @@ public class DozeTriggers implements DozeMachine.Part {
case DOZE_AOD:
mDozeSensors.setProxListening(newState != DozeMachine.State.DOZE);
mDozeSensors.setListening(true);
+ mDozeSensors.setPaused(false);
if (newState == DozeMachine.State.DOZE_AOD && !sWakeDisplaySensorState) {
onWakeScreen(false, newState);
}
@@ -289,12 +304,13 @@ public class DozeTriggers implements DozeMachine.Part {
case DOZE_AOD_PAUSED:
case DOZE_AOD_PAUSING:
mDozeSensors.setProxListening(true);
- mDozeSensors.setListening(false);
+ mDozeSensors.setPaused(true);
break;
case DOZE_PULSING:
case DOZE_PULSING_BRIGHT:
mDozeSensors.setTouchscreenSensorsListening(false);
mDozeSensors.setProxListening(true);
+ mDozeSensors.setPaused(false);
break;
case DOZE_PULSE_DONE:
mDozeSensors.requestTemporaryDisable();
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
index 4065d5b5dd8d..1f3403b054c1 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsImpl.java
@@ -30,6 +30,7 @@ import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
import com.android.internal.colorextraction.drawable.ScrimDrawable;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.SysUiServiceProvider;
@@ -81,6 +82,7 @@ public class GlobalActionsImpl implements GlobalActions, CommandQueue.Callbacks
mGlobalActions.showDialog(mKeyguardMonitor.isShowing(),
mDeviceProvisionedController.isDeviceProvisioned(),
mPanelExtension.get());
+ KeyguardUpdateMonitor.getInstance(mContext).requestFaceAuth();
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 20477975a6dd..5136682bb292 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -52,6 +52,8 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.NextAlarmController;
import com.android.systemui.statusbar.policy.NextAlarmControllerImpl;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -102,8 +104,8 @@ public class KeyguardSliceProvider extends SliceProvider implements
private final Date mCurrentTime = new Date();
private final Handler mHandler;
private final AlarmManager.OnAlarmListener mUpdateNextAlarm = this::updateNextAlarm;
- private final HashSet<Integer> mMediaInvisibleStates;
private final Object mMediaToken = new Object();
+ private DozeParameters mDozeParameters;
@VisibleForTesting
protected SettableWakeLock mMediaWakeLock;
@VisibleForTesting
@@ -122,6 +124,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
private PendingIntent mPendingIntent;
protected NotificationMediaManager mMediaManager;
private StatusBarStateController mStatusBarStateController;
+ private KeyguardBypassController mKeyguardBypassController;
private CharSequence mMediaTitle;
private CharSequence mMediaArtist;
protected boolean mDozing;
@@ -182,11 +185,6 @@ public class KeyguardSliceProvider extends SliceProvider implements
mAlarmUri = Uri.parse(KEYGUARD_NEXT_ALARM_URI);
mDndUri = Uri.parse(KEYGUARD_DND_URI);
mMediaUri = Uri.parse(KEYGUARD_MEDIA_URI);
-
- mMediaInvisibleStates = new HashSet<>();
- mMediaInvisibleStates.add(PlaybackState.STATE_NONE);
- mMediaInvisibleStates.add(PlaybackState.STATE_STOPPED);
- mMediaInvisibleStates.add(PlaybackState.STATE_PAUSED);
}
/**
@@ -198,11 +196,15 @@ public class KeyguardSliceProvider extends SliceProvider implements
*/
public void initDependencies(
NotificationMediaManager mediaManager,
- StatusBarStateController statusBarStateController) {
+ StatusBarStateController statusBarStateController,
+ KeyguardBypassController keyguardBypassController,
+ DozeParameters dozeParameters) {
mMediaManager = mediaManager;
mMediaManager.addCallback(this);
mStatusBarStateController = statusBarStateController;
mStatusBarStateController.addCallback(this);
+ mKeyguardBypassController = keyguardBypassController;
+ mDozeParameters = dozeParameters;
}
@AnyThread
@@ -227,7 +229,9 @@ public class KeyguardSliceProvider extends SliceProvider implements
}
protected boolean needsMediaLocked() {
- return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && mDozing;
+ boolean keepWhenAwake = mKeyguardBypassController != null
+ && mKeyguardBypassController.getBypassEnabled() && mDozeParameters.getAlwaysOn();
+ return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || keepWhenAwake);
}
protected void addMediaLocked(ListBuilder listBuilder) {
@@ -452,7 +456,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
@Override
public void onMetadataOrStateChanged(MediaMetadata metadata, @PlaybackState.State int state) {
synchronized (this) {
- boolean nextVisible = !mMediaInvisibleStates.contains(state);
+ boolean nextVisible = NotificationMediaManager.isPlayingState(state);
mHandler.removeCallbacksAndMessages(mMediaToken);
if (mMediaIsVisible && !nextVisible) {
// We need to delay this event for a few millis when stopping to avoid jank in the
@@ -471,7 +475,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
}
private void updateMediaStateLocked(MediaMetadata metadata, @PlaybackState.State int state) {
- boolean nextVisible = !mMediaInvisibleStates.contains(state);
+ boolean nextVisible = NotificationMediaManager.isPlayingState(state);
CharSequence title = null;
if (metadata != null) {
title = metadata.getText(MediaMetadata.METADATA_KEY_TITLE);
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 9616f0a29021..4dcb9f94088c 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -61,6 +61,7 @@ import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
+import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManagerPolicyConstants;
import android.view.animation.Animation;
@@ -85,6 +86,7 @@ import com.android.systemui.SystemUIFactory;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.classifier.FalsingManagerFactory;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationPanelView;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -174,7 +176,7 @@ public class KeyguardViewMediator extends SystemUI {
/**
* The default amount of time we stay awake (used for all key input)
*/
- public static final int AWAKE_INTERVAL_DEFAULT_MS = 10000;
+ public static final int AWAKE_INTERVAL_BOUNCER_MS = 10000;
/**
* How long to wait after the screen turns off due to timeout before
@@ -1800,6 +1802,10 @@ public class KeyguardViewMediator extends SystemUI {
if (mStatusBarKeyguardViewManager.isUnlockWithWallpaper()) {
flags |= WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
}
+ if (mStatusBarKeyguardViewManager.shouldSubtleWindowAnimationsForUnlock()) {
+ flags |= WindowManagerPolicyConstants
+ .KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
+ }
mUpdateMonitor.setKeyguardGoingAway(true /* goingAway */);
@@ -2056,9 +2062,11 @@ public class KeyguardViewMediator extends SystemUI {
public StatusBarKeyguardViewManager registerStatusBar(StatusBar statusBar,
ViewGroup container, NotificationPanelView panelView,
- BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer) {
+ BiometricUnlockController biometricUnlockController, ViewGroup lockIconContainer,
+ View notificationContainer, KeyguardBypassController bypassController) {
mStatusBarKeyguardViewManager.registerStatusBar(statusBar, container, panelView,
- biometricUnlockController, mDismissCallbackRegistry, lockIconContainer);
+ biometricUnlockController, mDismissCallbackRegistry, lockIconContainer,
+ notificationContainer, bypassController);
return mStatusBarKeyguardViewManager;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index ec2feba8291b..41f66f7e2021 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -73,6 +73,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
private int mNumQuickTiles;
private float mLastPosition;
private QSTileHost mHost;
+ private boolean mShowCollapsedOnKeyguard;
public QSAnimator(QS qs, QuickQSPanel quickPanel, QSPanel panel) {
mQs = qs;
@@ -98,12 +99,32 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
public void setOnKeyguard(boolean onKeyguard) {
mOnKeyguard = onKeyguard;
- mQuickQsPanel.setVisibility(mOnKeyguard ? View.INVISIBLE : View.VISIBLE);
+ updateQQSVisibility();
if (mOnKeyguard) {
clearAnimationState();
}
}
+
+ /**
+ * Sets whether or not the keyguard is currently being shown with a collapsed header.
+ */
+ void setShowCollapsedOnKeyguard(boolean showCollapsedOnKeyguard) {
+ mShowCollapsedOnKeyguard = showCollapsedOnKeyguard;
+ updateQQSVisibility();
+ setCurrentPosition();
+ }
+
+
+ private void setCurrentPosition() {
+ setPosition(mLastPosition);
+ }
+
+ private void updateQQSVisibility() {
+ mQuickQsPanel.setVisibility(mOnKeyguard
+ && !mShowCollapsedOnKeyguard ? View.INVISIBLE : View.VISIBLE);
+ }
+
public void setHost(QSTileHost qsh) {
mHost = qsh;
qsh.addCallback(this);
@@ -322,7 +343,11 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
public void setPosition(float position) {
if (mFirstPageAnimator == null) return;
if (mOnKeyguard) {
- return;
+ if (mShowCollapsedOnKeyguard) {
+ position = 0;
+ } else {
+ position = 1;
+ }
}
mLastPosition = position;
if (mOnFirstPage && mAllowFancy) {
@@ -356,7 +381,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
@Override
public void onAnimationStarted() {
- mQuickQsPanel.setVisibility(mOnKeyguard ? View.INVISIBLE : View.VISIBLE);
+ updateQQSVisibility();
if (mOnFirstPage) {
final int N = mQuickQsViews.size();
for (int i = 0; i < N; i++) {
@@ -410,7 +435,7 @@ public class QSAnimator implements Callback, PageListener, Listener, OnLayoutCha
@Override
public void run() {
updateAnimators();
- setPosition(mLastPosition);
+ setCurrentPosition();
}
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 087a826844e2..0a3b43a78f13 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -40,8 +40,10 @@ import com.android.systemui.R;
import com.android.systemui.R.id;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.plugins.qs.QS;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.customize.QSCustomizer;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.phone.NotificationsQuickSettingsContainer;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
@@ -50,16 +52,17 @@ import com.android.systemui.util.LifecycleFragment;
import javax.inject.Inject;
-public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Callbacks {
+public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Callbacks,
+ StatusBarStateController.StateListener {
private static final String TAG = "QS";
private static final boolean DEBUG = false;
private static final String EXTRA_EXPANDED = "expanded";
private static final String EXTRA_LISTENING = "listening";
private final Rect mQsBounds = new Rect();
+ private final StatusBarStateController mStatusBarStateController;
private boolean mQsExpanded;
private boolean mHeaderAnimating;
- private boolean mKeyguardShowing;
private boolean mStackScrollerOverscrolling;
private long mDelay;
@@ -80,17 +83,27 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
private final InjectionInflationController mInjectionInflater;
private final QSTileHost mHost;
+ private boolean mShowCollapsedOnKeyguard;
+ private boolean mLastKeyguardAndExpanded;
+ /**
+ * The last received state from the controller. This should not be used directly to check if
+ * we're on keyguard but use {@link #isKeyguardShowing()} instead since that is more accurate
+ * during state transitions which often call into us.
+ */
+ private int mState;
@Inject
public QSFragment(RemoteInputQuickSettingsDisabler remoteInputQsDisabler,
InjectionInflationController injectionInflater,
Context context,
- QSTileHost qsTileHost) {
+ QSTileHost qsTileHost,
+ StatusBarStateController statusBarStateController) {
mRemoteInputQuickSettingsDisabler = remoteInputQsDisabler;
mInjectionInflater = injectionInflater;
SysUiServiceProvider.getComponent(context, CommandQueue.class)
.observe(getLifecycle(), this);
mHost = qsTileHost;
+ mStatusBarStateController = statusBarStateController;
}
@Override
@@ -126,11 +139,14 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
}
setHost(mHost);
+ mStatusBarStateController.addCallback(this);
+ onStateChanged(mStatusBarStateController.getState());
}
@Override
public void onDestroy() {
super.onDestroy();
+ mStatusBarStateController.removeCallback(this);
if (mListening) {
setListening(false);
}
@@ -235,20 +251,43 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
|| mHeaderAnimating;
mQSPanel.setExpanded(mQsExpanded);
mQSDetail.setExpanded(mQsExpanded);
- mHeader.setVisibility((mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
+ boolean keyguardShowing = isKeyguardShowing();
+ mHeader.setVisibility((mQsExpanded || !keyguardShowing || mHeaderAnimating
+ || mShowCollapsedOnKeyguard)
? View.VISIBLE
: View.INVISIBLE);
- mHeader.setExpanded((mKeyguardShowing && !mHeaderAnimating)
+ mHeader.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard)
|| (mQsExpanded && !mStackScrollerOverscrolling));
mFooter.setVisibility(
- !mQsDisabled && (mQsExpanded || !mKeyguardShowing || mHeaderAnimating)
+ !mQsDisabled && (mQsExpanded || !keyguardShowing || mHeaderAnimating
+ || mShowCollapsedOnKeyguard)
? View.VISIBLE
: View.INVISIBLE);
- mFooter.setExpanded((mKeyguardShowing && !mHeaderAnimating)
+ mFooter.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard)
|| (mQsExpanded && !mStackScrollerOverscrolling));
mQSPanel.setVisibility(!mQsDisabled && expandVisually ? View.VISIBLE : View.INVISIBLE);
}
+ private boolean isKeyguardShowing() {
+ // We want the freshest state here since otherwise we'll have some weirdness if earlier
+ // listeners trigger updates
+ return mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
+ }
+
+ @Override
+ public void setShowCollapsedOnKeyguard(boolean showCollapsedOnKeyguard) {
+ if (showCollapsedOnKeyguard != mShowCollapsedOnKeyguard) {
+ mShowCollapsedOnKeyguard = showCollapsedOnKeyguard;
+ updateQsState();
+ if (mQSAnimator != null) {
+ mQSAnimator.setShowCollapsedOnKeyguard(showCollapsedOnKeyguard);
+ }
+ if (!showCollapsedOnKeyguard && isKeyguardShowing()) {
+ setQsExpansion(mLastQSExpansion, 0);
+ }
+ }
+ }
+
public QSPanel getQsPanel() {
return mQSPanel;
}
@@ -280,10 +319,8 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
updateQsState();
}
- @Override
- public void setKeyguardShowing(boolean keyguardShowing) {
+ private void setKeyguardShowing(boolean keyguardShowing) {
if (DEBUG) Log.d(TAG, "setKeyguardShowing " + keyguardShowing);
- mKeyguardShowing = keyguardShowing;
mLastQSExpansion = -1;
if (mQSAnimator != null) {
@@ -321,16 +358,18 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
if (DEBUG) Log.d(TAG, "setQSExpansion " + expansion + " " + headerTranslation);
mContainer.setExpansion(expansion);
final float translationScaleY = expansion - 1;
- if (!mHeaderAnimating) {
+ boolean onKeyguardAndExpanded = isKeyguardShowing() && !mShowCollapsedOnKeyguard;
+ if (!mHeaderAnimating && !headerWillBeAnimating()) {
getView().setTranslationY(
- mKeyguardShowing
+ onKeyguardAndExpanded
? translationScaleY * mHeader.getHeight()
: headerTranslation);
}
- if (expansion == mLastQSExpansion) {
+ if (expansion == mLastQSExpansion && mLastKeyguardAndExpanded == onKeyguardAndExpanded) {
return;
}
mLastQSExpansion = expansion;
+ mLastKeyguardAndExpanded = onKeyguardAndExpanded;
boolean fullyExpanded = expansion == 1;
int heightDiff = mQSPanel.getBottom() - mHeader.getBottom() + mHeader.getPaddingBottom()
@@ -338,8 +377,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
float panelTranslationY = translationScaleY * heightDiff;
// Let the views animate their contents correctly by giving them the necessary context.
- mHeader.setExpansion(mKeyguardShowing, expansion, panelTranslationY);
- mFooter.setExpansion(mKeyguardShowing ? 1 : expansion);
+ mHeader.setExpansion(onKeyguardAndExpanded, expansion,
+ panelTranslationY);
+ mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
mQSPanel.getQsTileRevealController().setExpansion(expansion);
mQSPanel.getTileLayout().setExpansion(expansion);
mQSPanel.setTranslationY(translationScaleY * heightDiff);
@@ -361,12 +401,17 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
}
}
+ private boolean headerWillBeAnimating() {
+ return mState == StatusBarState.KEYGUARD && mShowCollapsedOnKeyguard
+ && !isKeyguardShowing();
+ }
+
@Override
public void animateHeaderSlidingIn(long delay) {
if (DEBUG) Log.d(TAG, "animateHeaderSlidingIn");
// If the QS is already expanded we don't need to slide in the header as it's already
// visible.
- if (!mQsExpanded) {
+ if (!mQsExpanded && getView().getTranslationY() != 0) {
mHeaderAnimating = true;
mDelay = delay;
getView().getViewTreeObserver().addOnPreDrawListener(mStartHeaderSlidingIn);
@@ -376,6 +421,9 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
@Override
public void animateHeaderSlidingOut() {
if (DEBUG) Log.d(TAG, "animateHeaderSlidingOut");
+ if (getView().getY() == -mHeader.getHeight()) {
+ return;
+ }
mHeaderAnimating = true;
getView().animate().y(-mHeader.getHeight())
.setStartDelay(0)
@@ -463,7 +511,6 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setListener(mAnimateHeaderSlidingInListener)
.start();
- getView().setY(-mHeader.getHeight());
return true;
}
};
@@ -476,4 +523,10 @@ public class QSFragment extends LifecycleFragment implements QS, CommandQueue.Ca
updateQsState();
}
};
+
+ @Override
+ public void onStateChanged(int newState) {
+ mState = newState;
+ setKeyguardShowing(newState == StatusBarState.KEYGUARD);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index d59e251563c7..a28b60dbe13c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -348,19 +348,19 @@ public class QuickStatusBarHeader extends RelativeLayout implements
/**
* Animates the inner contents based on the given expansion details.
*
- * @param isKeyguardShowing whether or not we're showing the keyguard (a.k.a. lockscreen)
+ * @param forceExpanded whether we should show the state expanded forcibly
* @param expansionFraction how much the QS panel is expanded/pulled out (up to 1f)
* @param panelTranslationY how much the panel has physically moved down vertically (required
* for keyguard animations only)
*/
- public void setExpansion(boolean isKeyguardShowing, float expansionFraction,
+ public void setExpansion(boolean forceExpanded, float expansionFraction,
float panelTranslationY) {
- final float keyguardExpansionFraction = isKeyguardShowing ? 1f : expansionFraction;
+ final float keyguardExpansionFraction = forceExpanded ? 1f : expansionFraction;
if (mStatusIconsAlphaAnimator != null) {
mStatusIconsAlphaAnimator.setPosition(keyguardExpansionFraction);
}
- if (isKeyguardShowing) {
+ if (forceExpanded) {
// If the keyguard is showing, we want to offset the text so that it comes in at the
// same time as the panel as it slides down.
mHeaderTextContainerView.setTranslationY(panelTranslationY);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index e5caf68c416e..19edc94a3871 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -119,7 +119,9 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
private boolean mIsEnabled;
private int mCurrentBoundedUserId = -1;
private float mNavBarButtonAlpha;
- private MotionEvent mStatusBarGestureDownEvent;
+ private boolean mInputFocusTransferStarted;
+ private float mInputFocusTransferStartY;
+ private long mInputFocusTransferStartMillis;
private float mWindowCornerRadius;
private boolean mSupportsRoundedCornersOnWindows;
private int mNavBarMode = NAV_BAR_MODE_3BUTTON;
@@ -164,6 +166,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
}
}
+ // TODO: change the method signature to use (boolean inputFocusTransferStarted)
@Override
public void onStatusBarMotionEvent(MotionEvent event) {
if (!verifyCaller("onStatusBarMotionEvent")) {
@@ -175,15 +178,19 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
mHandler.post(()->{
StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
if (bar != null) {
- bar.dispatchNotificationsPanelTouchEvent(event);
int action = event.getActionMasked();
if (action == ACTION_DOWN) {
- mStatusBarGestureDownEvent = MotionEvent.obtain(event);
+ mInputFocusTransferStarted = true;
+ mInputFocusTransferStartY = event.getY();
+ mInputFocusTransferStartMillis = event.getEventTime();
+ bar.onInputFocusTransfer(mInputFocusTransferStarted, 0 /* velocity */);
}
if (action == ACTION_UP || action == ACTION_CANCEL) {
- mStatusBarGestureDownEvent.recycle();
- mStatusBarGestureDownEvent = null;
+ mInputFocusTransferStarted = false;
+ bar.onInputFocusTransfer(mInputFocusTransferStarted,
+ (event.getY() - mInputFocusTransferStartY)
+ / (event.getEventTime() - mInputFocusTransferStartMillis));
}
event.recycle();
}
@@ -590,14 +597,12 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
}
public void cleanupAfterDeath() {
- if (mStatusBarGestureDownEvent != null) {
+ if (mInputFocusTransferStarted) {
mHandler.post(()-> {
StatusBar bar = SysUiServiceProvider.getComponent(mContext, StatusBar.class);
if (bar != null) {
- mStatusBarGestureDownEvent.setAction(MotionEvent.ACTION_CANCEL);
- bar.dispatchNotificationsPanelTouchEvent(mStatusBarGestureDownEvent);
- mStatusBarGestureDownEvent.recycle();
- mStatusBarGestureDownEvent = null;
+ mInputFocusTransferStarted = false;
+ bar.onInputFocusTransfer(false, 0 /* velocity */);
}
});
}
@@ -746,6 +751,8 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
try {
if (mOverviewProxy != null) {
mOverviewProxy.onAssistantVisibilityChanged(visibility);
+ } else {
+ Log.e(TAG_OPS, "Failed to get overview proxy for assistant visibility.");
}
} catch (RemoteException e) {
Log.e(TAG_OPS, "Failed to call onAssistantVisibilityChanged()", e);
@@ -780,6 +787,7 @@ public class OverviewProxyService implements CallbackController<OverviewProxyLis
pw.println(QuickStepContract.isBackGestureDisabled(mSysUiStateFlags));
pw.print(" assistantGestureDisabled=");
pw.println(QuickStepContract.isAssistantGestureDisabled(mSysUiStateFlags));
+ pw.print(" mInputFocusTransferStarted="); pw.println(mInputFocusTransferStarted);
}
public interface OverviewProxyListener {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
deleted file mode 100644
index 5f878cee12d6..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AmbientPulseManager.java
+++ /dev/null
@@ -1,162 +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.systemui.statusbar;
-
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
-
-import android.annotation.NonNull;
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.ArraySet;
-
-import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.R;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
-
-import javax.inject.Inject;
-import javax.inject.Singleton;
-
-/**
- * Manager which handles high priority notifications that should "pulse" in when the device is
- * dozing and/or in AOD. The pulse uses the notification's ambient view and pops in briefly
- * before automatically dismissing the alert.
- */
-@Singleton
-public class AmbientPulseManager extends AlertingNotificationManager {
-
- protected final ArraySet<OnAmbientChangedListener> mListeners = new ArraySet<>();
- @VisibleForTesting
- protected long mExtensionTime;
-
- @Inject
- public AmbientPulseManager(@NonNull final Context context) {
- Resources resources = context.getResources();
- mAutoDismissNotificationDecay = resources.getInteger(R.integer.ambient_notification_decay);
- mMinimumDisplayTime = resources.getInteger(R.integer.ambient_notification_minimum_time);
- mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
- }
-
- /**
- * Adds an OnAmbientChangedListener to observe events.
- */
- public void addListener(@NonNull OnAmbientChangedListener listener) {
- mListeners.add(listener);
- }
-
- /**
- * Removes the OnAmbientChangedListener from the observer list.
- */
- public void removeListener(@NonNull OnAmbientChangedListener listener) {
- mListeners.remove(listener);
- }
-
- /**
- * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts
- * longer.
- */
- public void extendPulse() {
- AmbientEntry topEntry = getTopEntry();
- if (topEntry == null) {
- return;
- }
- topEntry.extendPulse();
- }
-
- public @InflationFlag int getContentFlag() {
- return FLAG_CONTENT_VIEW_AMBIENT;
- }
-
- @Override
- protected void onAlertEntryAdded(AlertEntry alertEntry) {
- NotificationEntry entry = alertEntry.mEntry;
- entry.setAmbientPulsing(true);
- for (OnAmbientChangedListener listener : mListeners) {
- listener.onAmbientStateChanged(entry, true);
- }
- }
-
- @Override
- protected void onAlertEntryRemoved(AlertEntry alertEntry) {
- NotificationEntry entry = alertEntry.mEntry;
- entry.setAmbientPulsing(false);
- for (OnAmbientChangedListener listener : mListeners) {
- listener.onAmbientStateChanged(entry, false);
- }
- entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
- }
-
- @Override
- protected AlertEntry createAlertEntry() {
- return new AmbientEntry();
- }
-
- /**
- * Get the top pulsing entry. This should be the currently showing one if there are multiple.
- * @return the currently showing entry
- */
- private AmbientEntry getTopEntry() {
- if (mAlertEntries.isEmpty()) {
- return null;
- }
- AlertEntry topEntry = null;
- for (AlertEntry entry : mAlertEntries.values()) {
- if (topEntry == null || entry.compareTo(topEntry) < 0) {
- topEntry = entry;
- }
- }
- return (AmbientEntry) topEntry;
- }
-
- /**
- * Observer interface for any changes in the ambient entries.
- */
- public interface OnAmbientChangedListener {
- /**
- * Called when an entry starts or stops pulsing.
- * @param entry the entry that changed
- * @param isPulsing true if the entry is now pulsing, false otherwise
- */
- void onAmbientStateChanged(@NonNull NotificationEntry entry, boolean isPulsing);
- }
-
- private final class AmbientEntry extends AlertEntry {
- private boolean extended;
-
- /**
- * Extend the lifetime of the alertEntry so that it auto-removes later. Can only be
- * extended once.
- */
- private void extendPulse() {
- if (!extended) {
- extended = true;
- updateEntry(false);
- }
- }
-
- @Override
- public void reset() {
- super.reset();
- extended = false;
- }
-
- @Override
- protected long calculateFinishTime() {
- return super.calculateFinishTime() + (extended ? mExtensionTime : 0);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
index 04534ba06d7e..164215befe79 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/CrossFadeHelper.java
@@ -28,6 +28,10 @@ import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
public class CrossFadeHelper {
public static final long ANIMATION_DURATION_LENGTH = 210;
+ public static void fadeOut(final View view) {
+ fadeOut(view, null);
+ }
+
public static void fadeOut(final View view, final Runnable endRunnable) {
fadeOut(view, ANIMATION_DURATION_LENGTH, 0, endRunnable);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
index 3f1ff33437b9..4597b1656884 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/HeadsUpStatusBarView.java
@@ -43,7 +43,6 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
private static final String HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE =
"heads_up_status_bar_view_super_parcelable";
private static final String FIRST_LAYOUT = "first_layout";
- private static final String PUBLIC_MODE = "public_mode";
private static final String VISIBILITY = "visibility";
private static final String ALPHA = "alpha";
private int mAbsoluteStartPadding;
@@ -54,7 +53,6 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
private Rect mLayoutedIconRect = new Rect();
private int[] mTmpPosition = new int[2];
private boolean mFirstLayout = true;
- private boolean mPublicMode;
private int mMaxWidth;
private View mRootView;
private int mSysWinInset;
@@ -121,7 +119,6 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
bundle.putParcelable(HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE,
super.onSaveInstanceState());
bundle.putBoolean(FIRST_LAYOUT, mFirstLayout);
- bundle.putBoolean(PUBLIC_MODE, mPublicMode);
bundle.putInt(VISIBILITY, getVisibility());
bundle.putFloat(ALPHA, getAlpha());
@@ -139,7 +136,6 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
Parcelable superState = bundle.getParcelable(HEADS_UP_STATUS_BAR_VIEW_SUPER_PARCELABLE);
super.onRestoreInstanceState(superState);
mFirstLayout = bundle.getBoolean(FIRST_LAYOUT, true);
- mPublicMode = bundle.getBoolean(PUBLIC_MODE, false);
if (bundle.containsKey(VISIBILITY)) {
setVisibility(bundle.getInt(VISIBILITY));
}
@@ -166,11 +162,13 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
if (entry != null) {
mShowingEntry = entry;
CharSequence text = entry.headsUpStatusBarText;
- if (mPublicMode) {
+ if (entry.isSensitive()) {
text = entry.headsUpStatusBarTextPublic;
}
mTextView.setText(text);
- } else {
+ mShowingEntry.setOnSensitiveChangedListener(() -> setEntry(entry));
+ } else if (mShowingEntry != null){
+ mShowingEntry.setOnSensitiveChangedListener(null);
mShowingEntry = null;
}
}
@@ -273,10 +271,6 @@ public class HeadsUpStatusBarView extends AlphaOptimizedLinearLayout {
mTextView.setTextColor(DarkIconDispatcher.getTint(area, this, tint));
}
- public void setPublicMode(boolean publicMode) {
- mPublicMode = publicMode;
- }
-
public void setOnDrawingRectChangedListener(Runnable onDrawingRectChangedListener) {
mOnDrawingRectChangedListener = onDrawingRectChangedListener;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index ca12deb3904e..4be93df0e81a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -79,7 +79,9 @@ public class KeyguardIndicationController implements StateListener,
private static final int MSG_HIDE_TRANSIENT = 1;
private static final int MSG_CLEAR_BIOMETRIC_MSG = 2;
+ private static final int MSG_SWIPE_UP_TO_UNLOCK = 3;
private static final long TRANSIENT_BIOMETRIC_ERROR_TIMEOUT = 1300;
+ private static final float BOUNCE_ANIMATION_FINAL_Y = 0f;
private final Context mContext;
private final ShadeController mShadeController;
@@ -326,6 +328,7 @@ public class KeyguardIndicationController implements StateListener,
mTransientIndication = transientIndication;
mTransientTextColorState = textColorState;
mHandler.removeMessages(MSG_HIDE_TRANSIENT);
+ mHandler.removeMessages(MSG_SWIPE_UP_TO_UNLOCK);
if (mDozing && !TextUtils.isEmpty(mTransientIndication)) {
// Make sure this doesn't get stuck and burns in. Acquire wakelock until its cleared.
mWakeLock.setAcquired(true);
@@ -420,7 +423,6 @@ public class KeyguardIndicationController implements StateListener,
int animateDownDuration = mContext.getResources().getInteger(
R.integer.wired_charging_keyguard_text_animation_duration_down);
textView.animate().cancel();
- float translation = textView.getTranslationY();
ViewClippingUtil.setClippingDeactivated(textView, true, mClippingParams);
textView.animate()
.translationYBy(yTranslation)
@@ -436,7 +438,7 @@ public class KeyguardIndicationController implements StateListener,
@Override
public void onAnimationCancel(Animator animation) {
- textView.setTranslationY(translation);
+ textView.setTranslationY(BOUNCE_ANIMATION_FINAL_Y);
mCancelled = true;
}
@@ -450,15 +452,11 @@ public class KeyguardIndicationController implements StateListener,
textView.animate()
.setDuration(animateDownDuration)
.setInterpolator(Interpolators.BOUNCE)
- .translationY(translation)
+ .translationY(BOUNCE_ANIMATION_FINAL_Y)
.setListener(new AnimatorListenerAdapter() {
@Override
- public void onAnimationCancel(Animator animation) {
- textView.setTranslationY(translation);
- }
-
- @Override
public void onAnimationEnd(Animator animation) {
+ textView.setTranslationY(BOUNCE_ANIMATION_FINAL_Y);
ViewClippingUtil.setClippingDeactivated(textView, false,
mClippingParams);
}
@@ -553,10 +551,26 @@ public class KeyguardIndicationController implements StateListener,
hideTransientIndication();
} else if (msg.what == MSG_CLEAR_BIOMETRIC_MSG) {
mLockIcon.setTransientBiometricsError(false);
+ } else if (msg.what == MSG_SWIPE_UP_TO_UNLOCK) {
+ showSwipeUpToUnlock();
}
}
};
+ private void showSwipeUpToUnlock() {
+ if (mDozing) {
+ return;
+ }
+
+ String message = mContext.getString(R.string.keyguard_unlock);
+ if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
+ mStatusBarKeyguardViewManager.showBouncerMessage(message, mInitialTextColorState);
+ } else if (mKeyguardUpdateMonitor.isScreenOn()) {
+ showTransientIndication(message);
+ hideTransientIndicationDelayed(BaseKeyguardCallback.HIDE_DELAY_MS);
+ }
+ }
+
public void setDozing(boolean dozing) {
if (mDozing == dozing) {
return;
@@ -637,12 +651,20 @@ public class KeyguardIndicationController implements StateListener,
return;
}
animatePadlockError();
+ boolean showSwipeToUnlock =
+ msgId == KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
mStatusBarKeyguardViewManager.showBouncerMessage(helpString,
mInitialTextColorState);
} else if (updateMonitor.isScreenOn()) {
showTransientIndication(helpString);
- hideTransientIndicationDelayed(TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
+ if (!showSwipeToUnlock) {
+ hideTransientIndicationDelayed(TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
+ }
+ }
+ if (showSwipeToUnlock) {
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SWIPE_UP_TO_UNLOCK),
+ TRANSIENT_BIOMETRIC_ERROR_TIMEOUT);
}
}
@@ -732,13 +754,5 @@ public class KeyguardIndicationController implements StateListener,
updateIndication(false);
}
}
-
- @Override
- public void onKeyguardBouncerChanged(boolean bouncer) {
- if (mLockIcon == null) {
- return;
- }
- mLockIcon.setBouncerVisible(bouncer);
- }
- };
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
index 4b2d13121f6b..aaf48490d7b0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
@@ -25,6 +25,7 @@ import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
+import android.util.Log
import android.util.MathUtils
import com.android.internal.graphics.ColorUtils
import com.android.systemui.statusbar.notification.MediaNotificationProcessor
@@ -32,6 +33,7 @@ import com.android.systemui.statusbar.notification.MediaNotificationProcessor
import javax.inject.Inject
import javax.inject.Singleton
+private const val TAG = "MediaArtworkProcessor"
private const val COLOR_ALPHA = (255 * 0.7f).toInt()
private const val BLUR_RADIUS = 25f
private const val DOWNSAMPLE = 6
@@ -42,45 +44,54 @@ class MediaArtworkProcessor @Inject constructor() {
private val mTmpSize = Point()
private var mArtworkCache: Bitmap? = null
- fun processArtwork(context: Context, artwork: Bitmap): Bitmap {
+ fun processArtwork(context: Context, artwork: Bitmap): Bitmap? {
if (mArtworkCache != null) {
- return mArtworkCache!!
+ return mArtworkCache
}
-
- context.display.getSize(mTmpSize)
val renderScript = RenderScript.create(context)
- val rect = Rect(0, 0, artwork.width, artwork.height)
- MathUtils.fitRect(rect, Math.max(mTmpSize.x / DOWNSAMPLE, mTmpSize.y / DOWNSAMPLE))
- var inBitmap = Bitmap.createScaledBitmap(artwork, rect.width(), rect.height(),
- true /* filter */)
- // Render script blurs only support ARGB_8888, we need a conversion if we got a
- // different bitmap config.
- if (inBitmap.config != Bitmap.Config.ARGB_8888) {
- val oldIn = inBitmap
- inBitmap = oldIn.copy(Bitmap.Config.ARGB_8888, false /* isMutable */)
- oldIn.recycle()
- }
- val input = Allocation.createFromBitmap(renderScript, inBitmap,
- Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE)
- val outBitmap = Bitmap.createBitmap(inBitmap.width, inBitmap.height,
- Bitmap.Config.ARGB_8888)
- val output = Allocation.createFromBitmap(renderScript, outBitmap)
val blur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
- blur.setRadius(BLUR_RADIUS)
- blur.setInput(input)
- blur.forEach(output)
- output.copyTo(outBitmap)
+ var input: Allocation? = null
+ var output: Allocation? = null
+ var inBitmap: Bitmap? = null
+ try {
+ context.display.getSize(mTmpSize)
+ val rect = Rect(0, 0, artwork.width, artwork.height)
+ MathUtils.fitRect(rect, Math.max(mTmpSize.x / DOWNSAMPLE, mTmpSize.y / DOWNSAMPLE))
+ inBitmap = Bitmap.createScaledBitmap(artwork, rect.width(), rect.height(),
+ true /* filter */)
+ // Render script blurs only support ARGB_8888, we need a conversion if we got a
+ // different bitmap config.
+ if (inBitmap.config != Bitmap.Config.ARGB_8888) {
+ val oldIn = inBitmap
+ inBitmap = oldIn.copy(Bitmap.Config.ARGB_8888, false /* isMutable */)
+ oldIn.recycle()
+ }
+ val outBitmap = Bitmap.createBitmap(inBitmap.width, inBitmap.height,
+ Bitmap.Config.ARGB_8888)
- val swatch = MediaNotificationProcessor.findBackgroundSwatch(artwork)
+ input = Allocation.createFromBitmap(renderScript, inBitmap,
+ Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE)
+ output = Allocation.createFromBitmap(renderScript, outBitmap)
- input.destroy()
- output.destroy()
- inBitmap.recycle()
- blur.destroy()
+ blur.setRadius(BLUR_RADIUS)
+ blur.setInput(input)
+ blur.forEach(output)
+ output.copyTo(outBitmap)
- val canvas = Canvas(outBitmap)
- canvas.drawColor(ColorUtils.setAlphaComponent(swatch.rgb, COLOR_ALPHA))
- return outBitmap
+ val swatch = MediaNotificationProcessor.findBackgroundSwatch(artwork)
+
+ val canvas = Canvas(outBitmap)
+ canvas.drawColor(ColorUtils.setAlphaComponent(swatch.rgb, COLOR_ALPHA))
+ return outBitmap
+ } catch (ex: IllegalArgumentException) {
+ Log.e(TAG, "error while processing artwork", ex)
+ return null
+ } finally {
+ input?.destroy()
+ output?.destroy()
+ blur.destroy()
+ inBitmap?.recycle()
+ }
}
fun clearCache() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
index 6c36ab95f923..f001561754aa 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMediaManager.java
@@ -57,6 +57,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LockscreenWallpaper;
import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.ScrimState;
@@ -68,6 +69,7 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -89,6 +91,15 @@ public class NotificationMediaManager implements Dumpable {
= Dependency.get(StatusBarStateController.class);
private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
private final KeyguardMonitor mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
+ private final KeyguardBypassController mKeyguardBypassController;
+ private static final HashSet<Integer> PAUSED_MEDIA_STATES = new HashSet<>();
+ static {
+ PAUSED_MEDIA_STATES.add(PlaybackState.STATE_NONE);
+ PAUSED_MEDIA_STATES.add(PlaybackState.STATE_STOPPED);
+ PAUSED_MEDIA_STATES.add(PlaybackState.STATE_PAUSED);
+ PAUSED_MEDIA_STATES.add(PlaybackState.STATE_ERROR);
+ }
+
// Late binding
private NotificationEntryManager mEntryManager;
@@ -173,9 +184,11 @@ public class NotificationMediaManager implements Dumpable {
Lazy<ShadeController> shadeController,
Lazy<StatusBarWindowController> statusBarWindowController,
NotificationEntryManager notificationEntryManager,
- MediaArtworkProcessor mediaArtworkProcessor) {
+ MediaArtworkProcessor mediaArtworkProcessor,
+ KeyguardBypassController keyguardBypassController) {
mContext = context;
mMediaArtworkProcessor = mediaArtworkProcessor;
+ mKeyguardBypassController = keyguardBypassController;
mMediaListeners = new ArrayList<>();
mMediaSessionManager
= (MediaSessionManager) mContext.getSystemService(Context.MEDIA_SESSION_SERVICE);
@@ -203,6 +216,10 @@ public class NotificationMediaManager implements Dumpable {
mPropertiesChangedListener);
}
+ public static boolean isPlayingState(int state) {
+ return !PAUSED_MEDIA_STATES.contains(state);
+ }
+
public void setUpWithPresenter(NotificationPresenter presenter) {
mPresenter = presenter;
}
@@ -457,7 +474,7 @@ public class NotificationMediaManager implements Dumpable {
}
Bitmap artworkBitmap = null;
- if (mediaMetadata != null) {
+ if (mediaMetadata != null && !mKeyguardBypassController.getBypassEnabled()) {
artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
if (artworkBitmap == null) {
artworkBitmap = mediaMetadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 1440803f1524..70ee752dd8ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -52,6 +52,7 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -121,6 +122,7 @@ public class NotificationRemoteInputManager implements Dumpable {
protected final Context mContext;
private final UserManager mUserManager;
private final KeyguardManager mKeyguardManager;
+ private final StatusBarStateController mStatusBarStateController;
protected RemoteInputController mRemoteInputController;
protected NotificationLifetimeExtender.NotificationSafeToRemoveCallback
@@ -259,6 +261,7 @@ public class NotificationRemoteInputManager implements Dumpable {
SmartReplyController smartReplyController,
NotificationEntryManager notificationEntryManager,
Lazy<ShadeController> shadeController,
+ StatusBarStateController statusBarStateController,
@Named(MAIN_HANDLER_NAME) Handler mainHandler) {
mContext = context;
mLockscreenUserManager = lockscreenUserManager;
@@ -271,6 +274,7 @@ public class NotificationRemoteInputManager implements Dumpable {
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
addLifetimeExtenders();
mKeyguardManager = context.getSystemService(KeyguardManager.class);
+ mStatusBarStateController = statusBarStateController;
notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
@Override
@@ -380,7 +384,10 @@ public class NotificationRemoteInputManager implements Dumpable {
if (!mLockscreenUserManager.shouldAllowLockscreenRemoteInput()) {
final int userId = pendingIntent.getCreatorUserHandle().getIdentifier();
- if (mLockscreenUserManager.isLockscreenPublicMode(userId)) {
+ if (mLockscreenUserManager.isLockscreenPublicMode(userId)
+ || mStatusBarStateController.getState() == StatusBarState.KEYGUARD) {
+ // Even if we don't have security we should go through this flow, otherwise we won't
+ // go to the shade
mCallback.onLockedRemoteInput(row, view);
return true;
}
@@ -391,6 +398,11 @@ public class NotificationRemoteInputManager implements Dumpable {
}
}
+ if (!riv.isAttachedToWindow()) {
+ // the remoteInput isn't attached to the window anymore :/ Let's focus on the expanded
+ // one instead if it's available
+ riv = null;
+ }
if (riv == null) {
riv = findRemoteInputView(row.getPrivateLayout().getExpandedChild());
if (riv == null) {
@@ -405,6 +417,10 @@ public class NotificationRemoteInputManager implements Dumpable {
return true;
}
+ if (!riv.isAttachedToWindow()) {
+ // if we still didn't find a view that is attached, let's abort.
+ return false;
+ }
int width = view.getWidth();
if (view instanceof TextView) {
// Center the reveal on the text which might be off-center from the TextView
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 312ea473d9e6..4ccd0cd3353b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar;
import static com.android.systemui.Interpolators.FAST_OUT_SLOW_IN_REVERSE;
import static com.android.systemui.statusbar.phone.NotificationIconContainer.IconState.NO_VALUE;
+import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
import android.content.Context;
import android.content.res.Configuration;
@@ -48,8 +49,12 @@ import com.android.systemui.statusbar.notification.stack.AnimationProperties;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.notification.stack.ViewState;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationIconContainer;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* A notification shelf view that is placed inside the notification scroller. It manages the
* overflow icons that don't fit into the regular list anymore.
@@ -63,15 +68,13 @@ public class NotificationShelf extends ActivatableNotificationView implements
= SystemProperties.getBoolean("debug.icon_scroll_animations", true);
private static final int TAG_CONTINUOUS_CLIPPING = R.id.continuous_clipping_tag;
private static final String TAG = "NotificationShelf";
- private static final long SHELF_IN_TRANSLATION_DURATION = 200;
+ private final KeyguardBypassController mBypassController;
private NotificationIconContainer mShelfIcons;
private int[] mTmp = new int[2];
private boolean mHideBackground;
private int mIconAppearTopPadding;
- private int mShelfAppearTranslation;
- private float mDarkShelfPadding;
- private float mDarkShelfIconSize;
+ private float mHiddenShelfIconSize;
private int mStatusBarHeight;
private int mStatusBarPaddingStart;
private AmbientState mAmbientState;
@@ -96,8 +99,12 @@ public class NotificationShelf extends ActivatableNotificationView implements
private int mCutoutHeight;
private int mGapHeight;
- public NotificationShelf(Context context, AttributeSet attrs) {
+ @Inject
+ public NotificationShelf(@Named(VIEW_CONTEXT) Context context,
+ AttributeSet attrs,
+ KeyguardBypassController keyguardBypassController) {
super(context, attrs);
+ mBypassController = keyguardBypassController;
}
@Override
@@ -140,8 +147,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
mStatusBarHeight = res.getDimensionPixelOffset(R.dimen.status_bar_height);
mStatusBarPaddingStart = res.getDimensionPixelOffset(R.dimen.status_bar_padding_start);
mPaddingBetweenElements = res.getDimensionPixelSize(R.dimen.notification_divider_height);
- mShelfAppearTranslation = res.getDimensionPixelSize(R.dimen.shelf_appear_translation);
- mDarkShelfPadding = res.getDimensionPixelSize(R.dimen.widget_bottom_separator_padding);
ViewGroup.LayoutParams layoutParams = getLayoutParams();
layoutParams.height = res.getDimensionPixelOffset(R.dimen.notification_shelf_height);
@@ -152,7 +157,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
mScrollFastThreshold = res.getDimensionPixelOffset(R.dimen.scroll_fast_threshold);
mShowNotificationShelf = res.getBoolean(R.bool.config_showNotificationShelf);
mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
- mDarkShelfIconSize = res.getDimensionPixelOffset(R.dimen.dark_shelf_icon_size);
+ mHiddenShelfIconSize = res.getDimensionPixelOffset(R.dimen.hidden_shelf_icon_size);
mGapHeight = res.getDimensionPixelSize(R.dimen.qs_notification_padding);
if (!mShowNotificationShelf) {
@@ -167,33 +172,6 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
@Override
- public void setDark(boolean dark, boolean fade, long delay) {
- if (mDark == dark) return;
- super.setDark(dark, fade, delay);
- mShelfIcons.setDark(dark, fade, delay);
- updateInteractiveness();
- updateOutline();
- }
-
- /**
- * Alpha animation with translation played when this view is visible on AOD.
- */
- public void fadeInTranslating() {
- mShelfIcons.setTranslationY(-mShelfAppearTranslation);
- mShelfIcons.setAlpha(0);
- mShelfIcons.animate()
- .setInterpolator(Interpolators.DECELERATE_QUINT)
- .translationY(0)
- .setDuration(SHELF_IN_TRANSLATION_DURATION)
- .start();
- mShelfIcons.animate()
- .alpha(1)
- .setInterpolator(Interpolators.LINEAR)
- .setDuration(SHELF_IN_TRANSLATION_DURATION)
- .start();
- }
-
- @Override
protected View getContentView() {
return mShelfIcons;
}
@@ -219,11 +197,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
viewState.copyFrom(lastViewState);
viewState.height = getIntrinsicHeight();
- float awakenTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height,
+ viewState.yTranslation = Math.max(Math.min(viewEnd, maxShelfEnd) - viewState.height,
getFullyClosedTranslation());
- float yRatio = mAmbientState.hasPulsingNotifications() ?
- 0 : mAmbientState.getDarkAmount();
- viewState.yTranslation = awakenTranslation + mDarkShelfPadding * yRatio;
viewState.zTranslation = ambientState.getBaseZHeight();
// For the small display size, it's not enough to make the icon not covered by
// the top cutout so the denominator add the height of cutout.
@@ -344,7 +319,10 @@ public class NotificationShelf extends ActivatableNotificationView implements
colorTwoBefore = previousColor;
transitionAmount = inShelfAmount;
}
- if (isLastChild) {
+ // We don't want to modify the color if the notification is hun'd
+ boolean canModifyColor = mAmbientState.isShadeExpanded()
+ && !(mAmbientState.isOnKeyguard() && mBypassController.getBypassEnabled());
+ if (isLastChild && canModifyColor) {
if (colorOfViewBeforeLast == NO_COLOR) {
colorOfViewBeforeLast = ownColorUntinted;
}
@@ -452,7 +430,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
StatusBarIconView icon = row.getEntry().expandedIcon;
float shelfIconPosition = getTranslationY() + icon.getTop() + icon.getTranslationY();
- if (shelfIconPosition < maxTop && !mAmbientState.isFullyDark()) {
+ if (shelfIconPosition < maxTop && !mAmbientState.isFullyHidden()) {
int top = (int) (maxTop - shelfIconPosition);
Rect clipRect = new Rect(0, top, icon.getWidth(), Math.max(top, icon.getHeight()));
icon.setClipBounds(clipRect);
@@ -463,7 +441,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
private void updateContinuousClipping(final ExpandableNotificationRow row) {
StatusBarIconView icon = row.getEntry().expandedIcon;
- boolean needsContinuousClipping = ViewState.isAnimatingY(icon) && !mAmbientState.isDark();
+ boolean needsContinuousClipping = ViewState.isAnimatingY(icon) && !mAmbientState.isDozing();
boolean isContinuousClipping = icon.getTag(TAG_CONTINUOUS_CLIPPING) != null;
if (needsContinuousClipping && !isContinuousClipping) {
final ViewTreeObserver observer = icon.getViewTreeObserver();
@@ -512,8 +490,12 @@ public class NotificationShelf extends ActivatableNotificationView implements
float viewEnd = row.getTranslationY() + row.getActualHeight();
boolean isPinned = (row.isPinned() || row.isHeadsUpAnimatingAway())
&& !mAmbientState.isDozingAndNotPulsing(row);
- boolean shouldClipOwnTop = row.showingAmbientPulsing()
- || (mAmbientState.isPulseExpanding() && childIndex == 0);
+ boolean shouldClipOwnTop;
+ if (mAmbientState.isPulseExpanding()) {
+ shouldClipOwnTop = childIndex == 0;
+ } else {
+ shouldClipOwnTop = row.showingPulsing();
+ }
if (viewEnd > notificationClipEnd && !shouldClipOwnTop
&& (mAmbientState.isShadeExpanded() || !isPinned)) {
int clipBottomAmount = (int) (viewEnd - notificationClipEnd);
@@ -666,8 +648,8 @@ public class NotificationShelf extends ActivatableNotificationView implements
iconState.translateContent = false;
}
float transitionAmount;
- if (mAmbientState.isDarkAtAll() && !row.isInShelf()) {
- transitionAmount = mAmbientState.isFullyDark() ? 1 : 0;
+ if (mAmbientState.isHiddenAtAll() && !row.isInShelf()) {
+ transitionAmount = mAmbientState.isFullyHidden() ? 1 : 0;
} else if (isLastChild || !USE_ANIMATIONS_WHEN_OPENING || iconState.useFullTransitionAmount
|| iconState.useLinearTransitionAmount) {
transitionAmount = iconTransitionAmount;
@@ -682,7 +664,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
? fullTransitionAmount
: transitionAmount;
iconState.clampedAppearAmount = clampedAmount;
- float contentTransformationAmount = !row.isAboveShelf()
+ float contentTransformationAmount = !row.isAboveShelf() && !row.showingPulsing()
&& (isLastChild || iconState.translateContent)
? iconTransitionAmount
: 0.0f;
@@ -717,7 +699,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
notificationIconPosition += iconTopPadding;
float shelfIconPosition = getTranslationY() + icon.getTop();
- float iconSize = mDark ? mDarkShelfIconSize : mIconSize;
+ float iconSize = mAmbientState.isFullyHidden() ? mHiddenShelfIconSize : mIconSize;
shelfIconPosition += (icon.getHeight() - icon.getIconScale() * iconSize) / 2.0f;
float iconYTranslation = NotificationUtils.interpolate(
notificationIconPosition - shelfIconPosition,
@@ -752,7 +734,9 @@ public class NotificationShelf extends ActivatableNotificationView implements
iconState.scaleY = 1.0f;
iconState.hidden = false;
}
- if (row.isAboveShelf() || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
+ if (row.isAboveShelf()
+ || row.showingPulsing()
+ || (!row.isInShelf() && (isLastChild && row.areGutsExposed()
|| row.getTranslationZ() > mAmbientState.getBaseZHeight()))) {
iconState.hidden = true;
}
@@ -794,12 +778,12 @@ public class NotificationShelf extends ActivatableNotificationView implements
@Override
protected boolean needsOutline() {
- return !mHideBackground && !mDark && super.needsOutline();
+ return !mHideBackground && super.needsOutline();
}
@Override
protected boolean shouldHideBackground() {
- return super.shouldHideBackground() || mHideBackground || mDark;
+ return super.shouldHideBackground() || mHideBackground;
}
@Override
@@ -839,7 +823,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
private void setOpenedAmount(float openedAmount) {
mNoAnimationsInThisFrame = openedAmount == 1.0f && mOpenedAmount == 0.0f;
mOpenedAmount = openedAmount;
- if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDark()) {
+ if (!mAmbientState.isPanelFullWidth() || mAmbientState.isDozing()) {
// We don't do a transformation at all, lets just assume we are fully opened
openedAmount = 1.0f;
}
@@ -910,8 +894,7 @@ public class NotificationShelf extends ActivatableNotificationView implements
}
private void updateInteractiveness() {
- mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf
- && !mDark;
+ mInteractive = mStatusBarState == StatusBarState.KEYGUARD && mHasItemsInStableShelf;
setClickable(mInteractive);
setFocusable(mInteractive);
setImportantForAccessibility(mInteractive ? View.IMPORTANT_FOR_ACCESSIBILITY_YES
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 404920187351..22c91647d7f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -36,6 +36,7 @@ import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.util.Assert;
@@ -86,6 +87,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
private final boolean mAlwaysExpandNonGroupedNotification;
private final BubbleData mBubbleData;
private final DynamicPrivacyController mDynamicPrivacyController;
+ private final KeyguardBypassController mBypassController;
private NotificationPresenter mPresenter;
private NotificationListContainer mListContainer;
@@ -106,9 +108,11 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
NotificationEntryManager notificationEntryManager,
Lazy<ShadeController> shadeController,
BubbleData bubbleData,
+ KeyguardBypassController bypassController,
DynamicPrivacyController privacyController) {
mHandler = mainHandler;
mLockscreenUserManager = notificationLockscreenUserManager;
+ mBypassController = bypassController;
mGroupManager = groupManager;
mVisualStabilityManager = visualStabilityManager;
mStatusBarStateController = (SysuiStatusBarStateController) statusBarStateController;
@@ -168,7 +172,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
boolean deviceSensitive = devicePublic
&& !mLockscreenUserManager.userAllowsPrivateNotificationsInPublic(
currentUserId);
- ent.getRow().setSensitive(sensitive, deviceSensitive);
+ ent.setSensitive(sensitive, deviceSensitive);
ent.getRow().setNeedsRedaction(needsRedaction);
if (mGroupManager.isChildInGroupWithSummary(ent.notification)) {
NotificationEntry summary = mGroupManager.getGroupSummary(ent.notification);
@@ -362,7 +366,7 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
int visibleNotifications = 0;
boolean onKeyguard = mStatusBarStateController.getState() == StatusBarState.KEYGUARD;
int maxNotifications = -1;
- if (onKeyguard) {
+ if (onKeyguard && !mBypassController.getBypassEnabled()) {
maxNotifications = mPresenter.getMaxNotificationsWhileLocked(true /* recompute */);
}
mListContainer.setMaxDisplayedNotifications(maxNotifications);
@@ -390,7 +394,6 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
&& !row.isLowPriority()));
}
- entry.getRow().setOnAmbient(mShadeController.get().isDozing());
int userId = entry.notification.getUserId();
boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
entry.notification) && !entry.isRowRemoved();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
index a9d4fdeae397..986486ac14d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
@@ -25,6 +25,7 @@ import android.os.PowerManager
import android.os.PowerManager.WAKE_REASON_GESTURE
import android.os.SystemClock
import android.view.MotionEvent
+import android.view.VelocityTracker
import android.view.ViewConfiguration
import com.android.systemui.Gefingerpoken
@@ -35,8 +36,12 @@ import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
+import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.ShadeController
+import com.android.systemui.statusbar.policy.HeadsUpManager
import javax.inject.Inject
import javax.inject.Singleton
@@ -48,22 +53,46 @@ import kotlin.math.max
@Singleton
class PulseExpansionHandler @Inject
constructor(context: Context,
- private val mWakeUpCoordinator: NotificationWakeUpCoordinator) : Gefingerpoken {
+ private val wakeUpCoordinator: NotificationWakeUpCoordinator,
+ private val bypassController: KeyguardBypassController,
+ private val headsUpManager: HeadsUpManagerPhone,
+ private val roundnessManager: NotificationRoundnessManager) : Gefingerpoken {
companion object {
private val RUBBERBAND_FACTOR_STATIC = 0.25f
private val SPRING_BACK_ANIMATION_LENGTH_MS = 375
}
private val mPowerManager: PowerManager?
- private var mShadeController: ShadeController? = null
+ private lateinit var shadeController: ShadeController
private val mMinDragDistance: Int
private var mInitialTouchX: Float = 0.0f
private var mInitialTouchY: Float = 0.0f
var isExpanding: Boolean = false
+ private set(value) {
+ val changed = field != value
+ field = value
+ bypassController.isPulseExpanding = value
+ if (changed) {
+ if (value) {
+ val topEntry = headsUpManager.topEntry
+ topEntry?.let {
+ roundnessManager.setTrackingHeadsUp(it.row)
+ }
+ } else {
+ roundnessManager.setTrackingHeadsUp(null)
+ if (!leavingLockscreen) {
+ bypassController.maybePerformPendingUnlock()
+ pulseExpandAbortListener?.run()
+ }
+ }
+ headsUpManager.unpinAll(true /* userUnPinned */)
+ }
+ }
+ var leavingLockscreen: Boolean = false
private set
private val mTouchSlop: Float
- private var mExpansionCallback: ExpansionCallback? = null
- private lateinit var mStackScroller: NotificationStackScrollLayout
+ private lateinit var expansionCallback: ExpansionCallback
+ private lateinit var stackScroller: NotificationStackScrollLayout
private val mTemp2 = IntArray(2)
private var mDraggedFarEnough: Boolean = false
private var mStartingChild: ExpandableView? = null
@@ -74,9 +103,13 @@ constructor(context: Context,
private var mEmptyDragAmount: Float = 0.0f
private var mWakeUpHeight: Float = 0.0f
private var mReachedWakeUpHeight: Boolean = false
+ private var velocityTracker: VelocityTracker? = null
private val isFalseTouch: Boolean
get() = mFalsingManager.isFalseTouch
+ var qsExpanded: Boolean = false
+ var pulseExpandAbortListener: Runnable? = null
+ var bouncerShowing: Boolean = false
init {
mMinDragDistance = context.resources.getDimensionPixelSize(
@@ -91,9 +124,14 @@ constructor(context: Context,
}
private fun maybeStartExpansion(event: MotionEvent): Boolean {
- if (!mPulsing) {
+ if (!wakeUpCoordinator.canShowPulsingHuns || qsExpanded
+ || bouncerShowing) {
return false
}
+ if (velocityTracker == null) {
+ velocityTracker = VelocityTracker.obtain()
+ }
+ velocityTracker!!.addMovement(event)
val x = event.x
val y = event.y
@@ -101,6 +139,7 @@ constructor(context: Context,
MotionEvent.ACTION_DOWN -> {
mDraggedFarEnough = false
isExpanding = false
+ leavingLockscreen = false
mStartingChild = null
mInitialTouchY = y
mInitialTouchX = x
@@ -114,29 +153,52 @@ constructor(context: Context,
captureStartingChild(mInitialTouchX, mInitialTouchY)
mInitialTouchY = y
mInitialTouchX = x
- mWakeUpHeight = mWakeUpCoordinator.getWakeUpHeight()
+ mWakeUpHeight = wakeUpCoordinator.getWakeUpHeight()
mReachedWakeUpHeight = false
return true
}
}
+
+ MotionEvent.ACTION_UP -> {
+ recycleVelocityTracker();
+ }
+
+ MotionEvent.ACTION_CANCEL -> {
+ recycleVelocityTracker();
+ }
}
return false
}
+ private fun recycleVelocityTracker() {
+ velocityTracker?.recycle();
+ velocityTracker = null
+ }
+
override fun onTouchEvent(event: MotionEvent): Boolean {
if (!isExpanding) {
return maybeStartExpansion(event)
}
+ velocityTracker!!.addMovement(event)
val y = event.y
+ val moveDistance = y - mInitialTouchY
when (event.actionMasked) {
- MotionEvent.ACTION_MOVE -> updateExpansionHeight(y - mInitialTouchY)
- MotionEvent.ACTION_UP -> if (!mFalsingManager.isUnlockingDisabled && !isFalseTouch) {
- finishExpansion()
- } else {
+ MotionEvent.ACTION_MOVE -> updateExpansionHeight(moveDistance)
+ MotionEvent.ACTION_UP -> {
+ velocityTracker!!.computeCurrentVelocity(1000 /* units */)
+ val canExpand = moveDistance > 0 && velocityTracker!!.getYVelocity() > -1000
+ if (!mFalsingManager.isUnlockingDisabled && !isFalseTouch && canExpand) {
+ finishExpansion()
+ } else {
+ cancelExpansion()
+ }
+ recycleVelocityTracker()
+ }
+ MotionEvent.ACTION_CANCEL -> {
cancelExpansion()
+ recycleVelocityTracker()
}
- MotionEvent.ACTION_CANCEL -> cancelExpansion()
}
return isExpanding
}
@@ -147,12 +209,15 @@ constructor(context: Context,
setUserLocked(mStartingChild!!, false)
mStartingChild = null
}
+ if (shadeController.isDozing) {
+ isWakingToShadeLocked = true
+ wakeUpCoordinator.willWakeUp = true
+ mPowerManager!!.wakeUp(SystemClock.uptimeMillis(), WAKE_REASON_GESTURE,
+ "com.android.systemui:PULSEDRAG")
+ }
+ shadeController.goToLockedShade(mStartingChild)
+ leavingLockscreen = true;
isExpanding = false
- isWakingToShadeLocked = true
- mWakeUpCoordinator.willWakeUp = true
- mPowerManager!!.wakeUp(SystemClock.uptimeMillis(), WAKE_REASON_GESTURE,
- "com.android.systemui:PULSEDRAG")
- mShadeController!!.goToLockedShade(mStartingChild)
if (mStartingChild is ExpandableNotificationRow) {
val row = mStartingChild as ExpandableNotificationRow?
row!!.onExpandedByGesture(true /* userExpanded */)
@@ -172,17 +237,17 @@ constructor(context: Context,
expansionHeight = max(newHeight.toFloat(), expansionHeight)
} else {
val target = if (mReachedWakeUpHeight) mWakeUpHeight else 0.0f
- mWakeUpCoordinator.setNotificationsVisibleForExpansion(height > target,
+ wakeUpCoordinator.setNotificationsVisibleForExpansion(height > target,
true /* animate */,
true /* increaseSpeed */)
expansionHeight = max(mWakeUpHeight, expansionHeight)
}
- val emptyDragAmount = mWakeUpCoordinator.setPulseHeight(expansionHeight)
+ val emptyDragAmount = wakeUpCoordinator.setPulseHeight(expansionHeight)
setEmptyDragAmount(emptyDragAmount * RUBBERBAND_FACTOR_STATIC)
}
private fun captureStartingChild(x: Float, y: Float) {
- if (mStartingChild == null) {
+ if (mStartingChild == null && !bypassController.bypassEnabled) {
mStartingChild = findView(x, y)
if (mStartingChild != null) {
setUserLocked(mStartingChild!!, true)
@@ -192,7 +257,7 @@ constructor(context: Context,
private fun setEmptyDragAmount(amount: Float) {
mEmptyDragAmount = amount
- mExpansionCallback!!.setEmptyDragAmount(amount)
+ expansionCallback.setEmptyDragAmount(amount)
}
private fun reset(child: ExpandableView) {
@@ -227,6 +292,7 @@ constructor(context: Context,
}
private fun cancelExpansion() {
+ isExpanding = false
mFalsingManager.onExpansionFromPulseStopped()
if (mStartingChild != null) {
reset(mStartingChild!!)
@@ -234,30 +300,29 @@ constructor(context: Context,
} else {
resetClock()
}
- mWakeUpCoordinator.setNotificationsVisibleForExpansion(false /* visible */,
+ wakeUpCoordinator.setNotificationsVisibleForExpansion(false /* visible */,
true /* animate */,
false /* increaseSpeed */)
- isExpanding = false
}
private fun findView(x: Float, y: Float): ExpandableView? {
var totalX = x
var totalY = y
- mStackScroller.getLocationOnScreen(mTemp2)
+ stackScroller.getLocationOnScreen(mTemp2)
totalX += mTemp2[0].toFloat()
totalY += mTemp2[1].toFloat()
- val childAtRawPosition = mStackScroller.getChildAtRawPosition(totalX, totalY)
+ val childAtRawPosition = stackScroller.getChildAtRawPosition(totalX, totalY)
return if (childAtRawPosition != null && childAtRawPosition.isContentExpandable) {
childAtRawPosition
} else null
}
- fun setUp(notificationStackScroller: NotificationStackScrollLayout,
- expansionCallback: ExpansionCallback,
- shadeController: ShadeController) {
- mExpansionCallback = expansionCallback
- mShadeController = shadeController
- mStackScroller = notificationStackScroller
+ fun setUp(stackScroller: NotificationStackScrollLayout,
+ expansionCallback: ExpansionCallback,
+ shadeController: ShadeController) {
+ this.expansionCallback = expansionCallback
+ this.shadeController = shadeController
+ this.stackScroller = stackScroller
}
fun setPulsing(pulsing: Boolean) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 6552fe671794..f4af9ae21b75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -112,7 +112,7 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
};
private boolean mAlwaysScaleIcon;
- private int mStatusBarIconDrawingSizeDark = 1;
+ private int mStatusBarIconDrawingSizeIncreased = 1;
private int mStatusBarIconDrawingSize = 1;
private int mStatusBarIconSize = 1;
private StatusBarIcon mIcon;
@@ -139,7 +139,7 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
private int mDrawableColor;
private int mIconColor;
private int mDecorColor;
- private float mDarkAmount;
+ private float mDozeAmount;
private ValueAnimator mColorAnimator;
private int mCurrentSetColor = NO_COLOR;
private int mAnimationStartColor = NO_COLOR;
@@ -158,6 +158,7 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
private Runnable mLayoutRunnable;
private boolean mDismissed;
private Runnable mOnDismissListener;
+ private boolean mIncreasedSize;
public StatusBarIconView(Context context, String slot, StatusBarNotification sbn) {
this(context, slot, sbn, false);
@@ -196,12 +197,10 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
private void updateIconScaleForNotifications() {
- final float imageBounds = NotificationUtils.interpolate(
- mStatusBarIconDrawingSize,
- mStatusBarIconDrawingSizeDark,
- mDarkAmount);
+ final float imageBounds = mIncreasedSize ?
+ mStatusBarIconDrawingSizeIncreased : mStatusBarIconDrawingSize;
final int outerBounds = mStatusBarIconSize;
- mIconScale = (float)imageBounds / (float)outerBounds;
+ mIconScale = imageBounds / (float)outerBounds;
updatePivot();
}
@@ -225,8 +224,8 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
}
- public float getIconScaleFullyDark() {
- return (float) mStatusBarIconDrawingSizeDark / mStatusBarIconDrawingSize;
+ public float getIconScaleIncreased() {
+ return (float) mStatusBarIconDrawingSizeIncreased / mStatusBarIconDrawingSize;
}
public float getIconScale() {
@@ -256,7 +255,7 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
Resources res = getResources();
mStaticDotRadius = res.getDimensionPixelSize(R.dimen.overflow_dot_radius);
mStatusBarIconSize = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
- mStatusBarIconDrawingSizeDark =
+ mStatusBarIconDrawingSizeIncreased =
res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size_dark);
mStatusBarIconDrawingSize =
res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
@@ -584,7 +583,7 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
}
private void updateDecorColor() {
- int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDarkAmount);
+ int color = NotificationUtils.interpolateColors(mDecorColor, Color.WHITE, mDozeAmount);
if (mDotPaint.getColor() != color) {
mDotPaint.setColor(color);
@@ -618,13 +617,13 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
mMatrixColorFilter = new ColorMatrixColorFilter(mMatrix);
}
int color = NotificationUtils.interpolateColors(
- mCurrentSetColor, Color.WHITE, mDarkAmount);
- updateTintMatrix(mMatrix, color, DARK_ALPHA_BOOST * mDarkAmount);
+ mCurrentSetColor, Color.WHITE, mDozeAmount);
+ updateTintMatrix(mMatrix, color, DARK_ALPHA_BOOST * mDozeAmount);
mMatrixColorFilter.setColorMatrixArray(mMatrix);
setColorFilter(null); // setColorFilter only invalidates if the instance changed.
setColorFilter(mMatrixColorFilter);
} else {
- mDozer.updateGrayscale(this, mDarkAmount);
+ mDozer.updateGrayscale(this, mDozeAmount);
}
}
@@ -855,19 +854,18 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
mOnVisibilityChangedListener = listener;
}
- public void setDark(boolean dark, boolean fade, long delay) {
- mDozer.setIntensityDark(f -> {
- mDarkAmount = f;
- maybeUpdateIconScaleDimens();
+ public void setDozing(boolean dozing, boolean fade, long delay) {
+ mDozer.setDozing(f -> {
+ mDozeAmount = f;
updateDecorColor();
updateIconColor();
updateAllowAnimation();
- }, dark, fade, delay, this);
+ }, dozing, fade, delay, this);
}
private void updateAllowAnimation() {
- if (mDarkAmount == 0 || mDarkAmount == 1) {
- setAllowAnimation(mDarkAmount == 0);
+ if (mDozeAmount == 0 || mDozeAmount == 1) {
+ setAllowAnimation(mDozeAmount == 0);
}
}
@@ -949,6 +947,11 @@ public class StatusBarIconView extends AnimatedImageView implements StatusIconDi
return mBlocked;
}
+ public void setIncreasedSize(boolean increasedSize) {
+ mIncreasedSize = increasedSize;
+ maybeUpdateIconScaleDimens();
+ }
+
public interface OnVisibilityChangedListener {
void onVisibilityChanged(int newVisibility);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index eb386dcdbf46..f0eeb046bc44 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -20,6 +20,7 @@ import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.text.format.DateFormat;
import android.util.FloatProperty;
+import android.view.View;
import android.view.animation.Interpolator;
import com.android.internal.annotations.GuardedBy;
@@ -77,6 +78,16 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
private HistoricalState[] mHistoricalRecords = new HistoricalState[HISTORY_SIZE];
/**
+ * Current SystemUiVisibility
+ */
+ private int mSystemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE;
+
+ /**
+ * If the device is currently pulsing (AOD2).
+ */
+ private boolean mPulsing;
+
+ /**
* If the device is currently dozing or not.
*/
private boolean mIsDozing;
@@ -292,6 +303,30 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
return mKeyguardRequested;
}
+ @Override
+ public void setSystemUiVisibility(int visibility) {
+ if (mSystemUiVisibility != visibility) {
+ mSystemUiVisibility = visibility;
+ synchronized (mListeners) {
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.mListener.onSystemUiVisibilityChanged(mSystemUiVisibility);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void setPulsing(boolean pulsing) {
+ if (mPulsing != pulsing) {
+ mPulsing = pulsing;
+ synchronized (mListeners) {
+ for (RankedListener rl : new ArrayList<>(mListeners)) {
+ rl.mListener.onPulsingChanged(pulsing);
+ }
+ }
+ }
+ }
+
/**
* Returns String readable state of status bar from {@link StatusBarState}
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
index dc5e1e913b4c..2ad979ab64e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SysuiStatusBarStateController.java
@@ -111,6 +111,16 @@ public interface SysuiStatusBarStateController extends StatusBarStateController
boolean isKeyguardRequested();
/**
+ * Set systemui visibility
+ */
+ void setSystemUiVisibility(int visibility);
+
+ /**
+ * Set pulsing
+ */
+ void setPulsing(boolean visibility);
+
+ /**
* Listener with rankings SbStateListenerRank that have dependencies so must be updated
* in a certain order
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt
new file mode 100644
index 000000000000..ea474ced7632
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.notification
+
+import android.content.Context
+import android.media.MediaMetadata
+import android.provider.Settings
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationMediaManager
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.tuner.TunerService
+import javax.inject.Inject
+import javax.inject.Singleton
+
+/**
+ * A class that automatically creates heads up for important notification when bypassing the
+ * lockscreen
+ */
+@Singleton
+class BypassHeadsUpNotifier @Inject constructor(
+ private val context: Context,
+ private val bypassController: KeyguardBypassController,
+ private val statusBarStateController: StatusBarStateController,
+ private val headsUpManager: HeadsUpManagerPhone,
+ private val mediaManager: NotificationMediaManager,
+ tunerService: TunerService) : StatusBarStateController.StateListener,
+ NotificationMediaManager.MediaListener {
+
+ private lateinit var entryManager: NotificationEntryManager
+ private var currentMediaEntry: NotificationEntry? = null
+ private var enabled = true
+
+ var fullyAwake = false
+ set(value) {
+ field = value
+ if (value) {
+ updateAutoHeadsUp(currentMediaEntry)
+ }
+ }
+
+ init {
+ statusBarStateController.addCallback(this)
+ tunerService.addTunable(
+ TunerService.Tunable { _, _ ->
+ enabled = Settings.Secure.getIntForUser(
+ context.contentResolver,
+ Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING,
+ 1 /* default */,
+ KeyguardUpdateMonitor.getCurrentUser()) != 0
+ }, Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING)
+ }
+
+ fun setUp(entryManager: NotificationEntryManager) {
+ this.entryManager = entryManager
+ mediaManager.addCallback(this)
+ }
+
+ override fun onMetadataOrStateChanged(metadata: MediaMetadata?, state: Int) {
+ val previous = currentMediaEntry
+ var newEntry = entryManager.notificationData.get(mediaManager.mediaNotificationKey)
+ if (!NotificationMediaManager.isPlayingState(state)) {
+ newEntry = null
+ }
+ if (newEntry?.isSensitive == true) {
+ newEntry = null
+ }
+ currentMediaEntry = newEntry
+ updateAutoHeadsUp(previous)
+ updateAutoHeadsUp(currentMediaEntry)
+ }
+
+ private fun updateAutoHeadsUp(entry: NotificationEntry?) {
+ entry?.let {
+ val autoHeadsUp = it == currentMediaEntry && canAutoHeadsUp()
+ it.isAutoHeadsUp = autoHeadsUp
+ if (autoHeadsUp) {
+ headsUpManager.showNotification(it)
+ }
+ }
+ }
+
+ override fun onStatePostChange() {
+ updateAutoHeadsUp(currentMediaEntry)
+ }
+
+ private fun canAutoHeadsUp() : Boolean {
+ if (!enabled) {
+ return false
+ }
+ if (!bypassController.bypassEnabled) {
+ return false
+ }
+ if (statusBarStateController.state != StatusBarState.KEYGUARD) {
+ return false
+ }
+ if (!fullyAwake) {
+ return false
+ }
+ return true
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
index f6d3cdfddb31..d71d40781f2e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationAlertingManager.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.FORCE_REMOTE_INPUT_HISTORY;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
import android.app.Notification;
@@ -25,8 +24,6 @@ import android.service.notification.StatusBarNotification;
import android.util.Log;
import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.statusbar.AlertingNotificationManager;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -45,7 +42,6 @@ public class NotificationAlertingManager {
private static final String TAG = "NotifAlertManager";
- private final AmbientPulseManager mAmbientPulseManager;
private final NotificationRemoteInputManager mRemoteInputManager;
private final VisualStabilityManager mVisualStabilityManager;
private final Lazy<ShadeController> mShadeController;
@@ -57,13 +53,11 @@ public class NotificationAlertingManager {
@Inject
public NotificationAlertingManager(
NotificationEntryManager notificationEntryManager,
- AmbientPulseManager ambientPulseManager,
NotificationRemoteInputManager remoteInputManager,
VisualStabilityManager visualStabilityManager,
Lazy<ShadeController> shadeController,
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
NotificationListener notificationListener) {
- mAmbientPulseManager = ambientPulseManager;
mRemoteInputManager = remoteInputManager;
mVisualStabilityManager = visualStabilityManager;
mShadeController = shadeController;
@@ -108,44 +102,31 @@ public class NotificationAlertingManager {
// If it does and we no longer need to heads up, we should free the view.
if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) {
mHeadsUpManager.showNotification(entry);
- // Mark as seen immediately
- setNotificationShown(entry.notification);
+ if (!mShadeController.get().isDozing()) {
+ // Mark as seen immediately
+ setNotificationShown(entry.notification);
+ }
} else {
entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_HEADS_UP);
}
}
- if ((inflatedFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
- if (mNotificationInterruptionStateProvider.shouldPulse(entry)) {
- mAmbientPulseManager.showNotification(entry);
- } else {
- entry.freeContentViewWhenSafe(FLAG_CONTENT_VIEW_AMBIENT);
- }
- }
}
private void updateAlertState(NotificationEntry entry) {
boolean alertAgain = alertAgain(entry, entry.notification.getNotification());
- AlertingNotificationManager alertManager;
boolean shouldAlert;
- if (mShadeController.get().isDozing()) {
- alertManager = mAmbientPulseManager;
- shouldAlert = mNotificationInterruptionStateProvider.shouldPulse(entry);
- } else {
- alertManager = mHeadsUpManager;
- shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
- }
- final boolean wasAlerting = alertManager.isAlerting(entry.key);
+ shouldAlert = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
+ final boolean wasAlerting = mHeadsUpManager.isAlerting(entry.key);
if (wasAlerting) {
- if (!shouldAlert) {
+ if (shouldAlert) {
+ mHeadsUpManager.updateNotification(entry.key, alertAgain);
+ } else if (!mHeadsUpManager.isEntryAutoHeadsUpped(entry.key)) {
// We don't want this to be interrupting anymore, let's remove it
- alertManager.removeNotification(entry.key,
- false /* ignoreEarliestRemovalTime */);
- } else {
- alertManager.updateNotification(entry.key, alertAgain);
+ mHeadsUpManager.removeNotification(entry.key, false /* removeImmediately */);
}
} else if (shouldAlert && alertAgain) {
// This notification was updated to be alerting, show it!
- alertManager.showNotification(entry);
+ mHeadsUpManager.showNotification(entry);
}
}
@@ -171,7 +152,7 @@ public class NotificationAlertingManager {
}
private void stopAlerting(final String key) {
- // Attempt to remove notifications from their alert managers (heads up, ambient pulse).
+ // Attempt to remove notifications from their alert manager.
// Though the remove itself may fail, it lets the manager know to remove as soon as
// possible.
if (mHeadsUpManager.isAlerting(key)) {
@@ -185,8 +166,5 @@ public class NotificationAlertingManager {
|| !mVisualStabilityManager.isReorderingAllowed();
mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
}
- if (mAmbientPulseManager.isAlerting(key)) {
- mAmbientPulseManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
index ef042bab7625..63bb73ab7f13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationDozeHelper.java
@@ -79,10 +79,11 @@ public class NotificationDozeHelper {
animator.start();
}
- public void setIntensityDark(Consumer<Float> listener, boolean dark,
+ public void setDozing(Consumer<Float> listener, boolean dozing,
boolean animate, long delay, View view) {
if (animate) {
- startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dark, delay,
+ startIntensityAnimation(a -> listener.accept((Float) a.getAnimatedValue()), dozing,
+ delay,
new AnimatorListenerAdapter() {
@Override
@@ -100,7 +101,7 @@ public class NotificationDozeHelper {
if (animator != null) {
animator.cancel();
}
- listener.accept(dark ? 1f : 0f);
+ listener.accept(dozing ? 1f : 0f);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
index 1aa6bc9ae5f9..dfc64508cadf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryListener.java
@@ -24,6 +24,8 @@ import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
+import androidx.annotation.NonNull;
+
/**
* Listener interface for changes sent by NotificationEntryManager.
*/
@@ -45,7 +47,7 @@ public interface NotificationEntryListener {
/**
* Called when a new entry is created.
*/
- default void onNotificationAdded(NotificationEntry entry) {
+ default void onNotificationAdded(@NonNull NotificationEntry entry) {
}
/**
@@ -61,7 +63,7 @@ public interface NotificationEntryListener {
/**
* Called when a notification was updated, after any filtering of notifications have occurred.
*/
- default void onPostEntryUpdated(NotificationEntry entry) {
+ default void onPostEntryUpdated(@NonNull NotificationEntry entry) {
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
index 926d4b6a79b3..5bab0ef39326 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationInterruptionStateProvider.java
@@ -39,6 +39,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationPresenter;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -186,14 +187,15 @@ public class NotificationInterruptionStateProvider {
* @return true if the entry should heads up, false otherwise
*/
public boolean shouldHeadsUp(NotificationEntry entry) {
- StatusBarNotification sbn = entry.notification;
-
- if (getShadeController().isDozing()) {
- if (DEBUG) {
- Log.d(TAG, "No heads up: device is dozing: " + sbn.getKey());
- }
- return false;
+ if (mStatusBarStateController.isDozing()) {
+ return shouldHeadsUpWhenDozing(entry);
+ } else {
+ return shouldHeadsUpWhenAwake(entry);
}
+ }
+
+ private boolean shouldHeadsUpWhenAwake(NotificationEntry entry) {
+ StatusBarNotification sbn = entry.notification;
boolean inShade = mStatusBarStateController.getState() == SHADE;
if (entry.isBubble() && inShade) {
@@ -251,7 +253,7 @@ public class NotificationInterruptionStateProvider {
* @param entry the entry to check
* @return true if the entry should ambient pulse, false otherwise
*/
- public boolean shouldPulse(NotificationEntry entry) {
+ private boolean shouldHeadsUpWhenDozing(NotificationEntry entry) {
StatusBarNotification sbn = entry.notification;
if (!mAmbientDisplayConfiguration.pulseOnNotificationEnabled(UserHandle.USER_CURRENT)) {
@@ -261,13 +263,6 @@ public class NotificationInterruptionStateProvider {
return false;
}
- if (!getShadeController().isDozing()) {
- if (DEBUG) {
- Log.d(TAG, "No pulsing: not dozing: " + sbn.getKey());
- }
- return false;
- }
-
if (!canAlertCommon(entry)) {
if (DEBUG) {
Log.d(TAG, "No pulsing: notification shouldn't alert: " + sbn.getKey());
@@ -288,24 +283,14 @@ public class NotificationInterruptionStateProvider {
}
return false;
}
-
- Bundle extras = sbn.getNotification().extras;
- CharSequence title = extras.getCharSequence(Notification.EXTRA_TITLE);
- CharSequence text = extras.getCharSequence(Notification.EXTRA_TEXT);
- if (TextUtils.isEmpty(title) && TextUtils.isEmpty(text)) {
- if (DEBUG) {
- Log.d(TAG, "No pulsing: title and text are empty: " + sbn.getKey());
- }
- return false;
- }
-
- return true;
+ return true;
}
/**
- * Common checks between heads up alerting and ambient pulse alerting. See
+ * Common checks between regular heads up and when pulsing. See
* {@link #shouldHeadsUp(NotificationEntry)} and
- * {@link #shouldPulse(NotificationEntry)}. Notifications that fail any of these checks
+ * {@link #shouldHeadsUpWhenDozing(NotificationEntry)}. Notifications that fail any of these
+ * checks
* should not alert at all.
*
* @param entry the entry to check
@@ -389,6 +374,19 @@ public class NotificationInterruptionStateProvider {
return mPresenter;
}
+ /**
+ * When an entry was added, should we launch its fullscreen intent? Examples are Alarms or
+ * incoming calls.
+ *
+ * @param entry the entry that was added
+ * @return {@code true} if we should launch the full screen intent
+ */
+ public boolean shouldLaunchFullScreenIntentWhenAdded(NotificationEntry entry) {
+ return entry.notification.getNotification().fullScreenIntent != null
+ && (!shouldHeadsUp(entry)
+ || mStatusBarStateController.getState() == StatusBarState.KEYGUARD);
+ }
+
/** A component which can suppress heads-up notifications due to the overall state of the UI. */
public interface HeadsUpSuppressor {
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 7c193b19654b..6a3816c50330 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -21,12 +21,15 @@ import android.content.Context
import android.util.FloatProperty
import com.android.systemui.Interpolators
import com.android.systemui.plugins.statusbar.StatusBarStateController
-import com.android.systemui.statusbar.AmbientPulseManager
-import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
import com.android.systemui.statusbar.notification.stack.StackStateAnimator
import com.android.systemui.statusbar.phone.DozeParameters
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
+import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
import javax.inject.Inject
import javax.inject.Singleton
@@ -34,9 +37,10 @@ import javax.inject.Singleton
@Singleton
class NotificationWakeUpCoordinator @Inject constructor(
private val mContext: Context,
- private val mAmbientPulseManager: AmbientPulseManager,
- private val mStatusBarStateController: StatusBarStateController)
- : AmbientPulseManager.OnAmbientChangedListener, StatusBarStateController.StateListener {
+ private val mHeadsUpManagerPhone: HeadsUpManagerPhone,
+ private val statusBarStateController: StatusBarStateController,
+ private val bypassController: KeyguardBypassController)
+ : OnHeadsUpChangedListener, StatusBarStateController.StateListener {
private val mNotificationVisibility
= object : FloatProperty<NotificationWakeUpCoordinator>("notificationVisibility") {
@@ -57,12 +61,18 @@ class NotificationWakeUpCoordinator @Inject constructor(
private var mNotificationVisibleAmount = 0.0f
private var mNotificationsVisible = false
private var mNotificationsVisibleForExpansion = false
- private var mDarkAnimator: ObjectAnimator? = null
+ private var mVisibilityAnimator: ObjectAnimator? = null
private var mVisibilityAmount = 0.0f
private var mLinearVisibilityAmount = 0.0f
private var mWakingUp = false
private val mEntrySetToClearWhenFinished = mutableSetOf<NotificationEntry>()
- private val mDozeParameters: DozeParameters;
+ private val mDozeParameters: DozeParameters
+ private var pulseExpanding: Boolean = false
+ private val wakeUpListeners = arrayListOf<WakeUpListener>()
+ private var state: Int = StatusBarState.KEYGUARD
+
+ var fullyAwake: Boolean = false
+
var willWakeUp = false
set(value) {
if (!value || mDozeAmount != 0.0f) {
@@ -70,6 +80,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
+ lateinit var iconAreaController : NotificationIconAreaController
var pulsing: Boolean = false
set(value) {
field = value
@@ -82,17 +93,52 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
+ var notificationsFullyHidden: Boolean = false
+ private set(value) {
+ if (field != value) {
+ field = value
+ for (listener in wakeUpListeners) {
+ listener.onFullyHiddenChanged(value)
+ }
+ }
+ }
+
+ /**
+ * True if we can show pulsing heads up notifications
+ */
+ var canShowPulsingHuns: Boolean = false
+ private set
+ get() {
+ var canShow = pulsing
+ if (bypassController.bypassEnabled) {
+ // We also allow pulsing on the lock screen!
+ canShow = canShow || (mWakingUp || willWakeUp || fullyAwake)
+ && statusBarStateController.state == StatusBarState.KEYGUARD
+ }
+ return canShow
+ }
init {
- mAmbientPulseManager.addListener(this)
- mStatusBarStateController.addCallback(this)
+ mHeadsUpManagerPhone.addListener(this)
+ statusBarStateController.addCallback(this)
mDozeParameters = DozeParameters.getInstance(mContext)
}
fun setStackScroller(stackScroller: NotificationStackScrollLayout) {
mStackScroller = stackScroller
+ pulseExpanding = stackScroller.isPulseExpanding
+ stackScroller.setOnPulseHeightChangedListener {
+ val nowExpanding = isPulseExpanding()
+ val changed = nowExpanding != pulseExpanding
+ pulseExpanding = nowExpanding
+ for (listener in wakeUpListeners) {
+ listener.onPulseExpansionChanged(changed)
+ }
+ }
}
+ fun isPulseExpanding(): Boolean = mStackScroller.isPulseExpanding
+
/**
* @param visible should notifications be visible
* @param animate should this change be animated
@@ -106,13 +152,23 @@ class NotificationWakeUpCoordinator @Inject constructor(
// If we stopped expanding and we're still visible because we had a pulse that hasn't
// times out, let's release them all to make sure were not stuck in a state where
// notifications are visible
- mAmbientPulseManager.releaseAllImmediately()
+ mHeadsUpManagerPhone.releaseAllImmediately()
}
}
+ fun addListener(listener: WakeUpListener) {
+ wakeUpListeners.add(listener);
+ }
+
+ fun removeFullyHiddenChangedListener(listener: WakeUpListener) {
+ wakeUpListeners.remove(listener);
+ }
+
private fun updateNotificationVisibility(animate: Boolean, increaseSpeed: Boolean) {
- var visible = (mNotificationsVisibleForExpansion || mAmbientPulseManager.hasNotifications())
- && pulsing;
+ // TODO: handle Lockscreen wakeup for bypass when we're not pulsing anymore
+ var visible = mNotificationsVisibleForExpansion || mHeadsUpManagerPhone.hasNotifications()
+ visible = visible && canShowPulsingHuns
+
if (!visible && mNotificationsVisible && (mWakingUp || willWakeUp) && mDozeAmount != 0.0f) {
// let's not make notifications invisible while waking up, otherwise the animation
// is strange
@@ -127,7 +183,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
return
}
mNotificationsVisible = visible
- mDarkAnimator?.cancel();
+ mVisibilityAnimator?.cancel();
if (animate) {
notifyAnimationStart(visible)
startVisibilityAnimation(increaseSpeed)
@@ -137,22 +193,55 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
override fun onDozeAmountChanged(linear: Float, eased: Float) {
+ if (updateDozeAmountIfBypass()) {
+ return
+ }
if (linear != 1.0f && linear != 0.0f
&& (mLinearDozeAmount == 0.0f || mLinearDozeAmount == 1.0f)) {
// Let's notify the scroller that an animation started
notifyAnimationStart(mLinearDozeAmount == 1.0f)
}
+ setDozeAmount(linear, eased)
+ }
+
+ fun setDozeAmount(linear: Float, eased: Float) {
+ val changed = linear != mLinearDozeAmount
mLinearDozeAmount = linear
mDozeAmount = eased
mStackScroller.setDozeAmount(mDozeAmount)
- updateDarkAmount()
- if (linear == 0.0f) {
+ updateHideAmount()
+ if (changed && linear == 0.0f) {
setNotificationsVisible(visible = false, animate = false, increaseSpeed = false);
setNotificationsVisibleForExpansion(visible = false, animate = false,
increaseSpeed = false)
}
}
+ override fun onStateChanged(newState: Int) {
+ updateDozeAmountIfBypass();
+ if (bypassController.bypassEnabled &&
+ newState == StatusBarState.KEYGUARD && state == StatusBarState.SHADE_LOCKED
+ && (!statusBarStateController.isDozing || shouldAnimateVisibility())) {
+ // We're leaving shade locked. Let's animate the notifications away
+ setNotificationsVisible(visible = true, increaseSpeed = false, animate = false)
+ setNotificationsVisible(visible = false, increaseSpeed = false, animate = true)
+ }
+ this.state = newState
+ }
+
+ private fun updateDozeAmountIfBypass(): Boolean {
+ if (bypassController.bypassEnabled) {
+ var amount = 1.0f;
+ if (statusBarStateController.state == StatusBarState.SHADE
+ || statusBarStateController.state == StatusBarState.SHADE_LOCKED) {
+ amount = 0.0f;
+ }
+ setDozeAmount(amount, amount)
+ return true
+ }
+ return false
+ }
+
private fun startVisibilityAnimation(increaseSpeed: Boolean) {
if (mNotificationVisibleAmount == 0f || mNotificationVisibleAmount == 1f) {
mVisibilityInterpolator = if (mNotificationsVisible)
@@ -161,15 +250,15 @@ class NotificationWakeUpCoordinator @Inject constructor(
Interpolators.FAST_OUT_SLOW_IN_REVERSE
}
val target = if (mNotificationsVisible) 1.0f else 0.0f
- val darkAnimator = ObjectAnimator.ofFloat(this, mNotificationVisibility, target)
- darkAnimator.setInterpolator(Interpolators.LINEAR)
+ val visibilityAnimator = ObjectAnimator.ofFloat(this, mNotificationVisibility, target)
+ visibilityAnimator.setInterpolator(Interpolators.LINEAR)
var duration = StackStateAnimator.ANIMATION_DURATION_WAKEUP.toLong()
if (increaseSpeed) {
duration = (duration.toFloat() / 1.5F).toLong();
}
- darkAnimator.setDuration(duration)
- darkAnimator.start()
- mDarkAnimator = darkAnimator
+ visibilityAnimator.setDuration(duration)
+ visibilityAnimator.start()
+ mVisibilityAnimator = visibilityAnimator
}
private fun setVisibilityAmount(visibilityAmount: Float) {
@@ -177,28 +266,29 @@ class NotificationWakeUpCoordinator @Inject constructor(
mVisibilityAmount = mVisibilityInterpolator.getInterpolation(
visibilityAmount)
handleAnimationFinished();
- updateDarkAmount()
+ updateHideAmount()
}
private fun handleAnimationFinished() {
if (mLinearDozeAmount == 0.0f || mLinearVisibilityAmount == 0.0f) {
- mEntrySetToClearWhenFinished.forEach { it.setAmbientGoingAway(false) }
+ mEntrySetToClearWhenFinished.forEach { it.setHeadsUpAnimatingAway(false) }
mEntrySetToClearWhenFinished.clear()
}
}
fun getWakeUpHeight() : Float {
- return mStackScroller.pulseHeight
+ return mStackScroller.wakeUpHeight
}
- private fun updateDarkAmount() {
+ private fun updateHideAmount() {
val linearAmount = Math.min(1.0f - mLinearVisibilityAmount, mLinearDozeAmount)
val amount = Math.min(1.0f - mVisibilityAmount, mDozeAmount)
- mStackScroller.setDarkAmount(linearAmount, amount)
+ mStackScroller.setHideAmount(linearAmount, amount)
+ notificationsFullyHidden = linearAmount == 1.0f;
}
private fun notifyAnimationStart(awake: Boolean) {
- mStackScroller.notifyDarkAnimationStart(!awake)
+ mStackScroller.notifyHideAnimationStart(!awake)
}
override fun onDozingChanged(isDozing: Boolean) {
@@ -207,39 +297,60 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
+ /**
+ * Set the height how tall notifications are pulsing. This is only set whenever we are expanding
+ * from a pulse and determines how much the notifications are expanded.
+ */
fun setPulseHeight(height: Float): Float {
- return mStackScroller.setPulseHeight(height)
+ val overflow = mStackScroller.setPulseHeight(height)
+ // no overflow for the bypass experience
+ return if (bypassController.bypassEnabled) 0.0f else overflow
}
fun setWakingUp(wakingUp: Boolean) {
willWakeUp = false
mWakingUp = wakingUp
- if (wakingUp && mNotificationsVisible && !mNotificationsVisibleForExpansion) {
+ if (wakingUp && mNotificationsVisible && !mNotificationsVisibleForExpansion
+ && !bypassController.bypassEnabled) {
// We're waking up while pulsing, let's make sure the animation looks nice
mStackScroller.wakeUpFromPulse();
}
}
- override fun onAmbientStateChanged(entry: NotificationEntry, isPulsing: Boolean) {
+ override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
var animate = shouldAnimateVisibility()
- if (!isPulsing) {
+ if (!isHeadsUp) {
if (mLinearDozeAmount != 0.0f && mLinearVisibilityAmount != 0.0f) {
if (entry.isRowDismissed) {
// if we animate, we see the shelf briefly visible. Instead we fully animate
// the notification and its background out
animate = false
} else if (!mWakingUp && !willWakeUp){
- entry.setAmbientGoingAway(true)
+ // TODO: look that this is done properly and not by anyone else
+ entry.setHeadsUpAnimatingAway(true)
mEntrySetToClearWhenFinished.add(entry)
}
}
} else if (mEntrySetToClearWhenFinished.contains(entry)) {
mEntrySetToClearWhenFinished.remove(entry)
- entry.setAmbientGoingAway(false)
+ entry.setHeadsUpAnimatingAway(false)
}
updateNotificationVisibility(animate, increaseSpeed = false)
}
private fun shouldAnimateVisibility() =
mDozeParameters.getAlwaysOn() && !mDozeParameters.getDisplayNeedsBlanking()
+
+ interface WakeUpListener {
+ /**
+ * Called whenever the notifications are fully hidden or shown
+ */
+ @JvmDefault fun onFullyHiddenChanged(isFullyHidden: Boolean) {}
+
+ /**
+ * Called whenever the pulseExpansion changes
+ * @param expandingChanged if the user has started or stopped expanding
+ */
+ @JvmDefault fun onPulseExpansionChanged(expandingChanged: Boolean) {}
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
index aacb22ddaa90..fe565529db32 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/PropertyAnimator.java
@@ -115,7 +115,20 @@ public class PropertyAnimator {
view.setTag(animationEndTag, newEndValue);
}
- public static <T extends View> boolean isAnimating(T view, AnimatableProperty property) {
- return view.getTag(property.getAnimatorTag()) != null;
+ public static <T extends View> void applyImmediately(T view, AnimatableProperty property,
+ float newValue) {
+ cancelAnimation(view, property);
+ property.getProperty().set(view, newValue);
+ }
+
+ public static void cancelAnimation(View view, AnimatableProperty property) {
+ ValueAnimator animator = (ValueAnimator) view.getTag(property.getAnimatorTag());
+ if (animator != null) {
+ animator.cancel();
+ }
+ }
+
+ public static boolean isAnimating(View view, AnimatableProperty property) {
+ return view.getTag(property.getAnimatorTag()) != null;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
new file mode 100644
index 000000000000..847d1ccddddf
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
@@ -0,0 +1,147 @@
+/*
+ * 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
+
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ValueAnimator
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.Interpolators
+import com.android.systemui.R
+
+/**
+ * Class to help with fading of view groups without fading one subview
+ */
+class ViewGroupFadeHelper {
+ companion object {
+ private val visibilityIncluder = {
+ view: View -> view.visibility == View.VISIBLE
+ }
+
+ /**
+ * Fade out all views of a root except a single child. This will iterate over all children
+ * of the view and make sure that the animation works smoothly.
+ * @param root the view root to fade the children away
+ * @param excludedView which view should remain
+ * @param duration the duration of the animation
+ */
+ @JvmStatic
+ fun fadeOutAllChildrenExcept(root: ViewGroup, excludedView: View, duration: Long,
+ endRunnable: Runnable?) {
+ // starting from the view going up, we are adding the siblings of the child to the set
+ // of views that need to be faded.
+ val viewsToFadeOut = gatherViews(root, excludedView, visibilityIncluder)
+
+ // Applying the right layertypes for the animation
+ for (viewToFade in viewsToFadeOut) {
+ if (viewToFade.hasOverlappingRendering
+ && viewToFade.layerType == View.LAYER_TYPE_NONE) {
+ viewToFade.setLayerType(View.LAYER_TYPE_HARDWARE, null)
+ viewToFade.setTag(R.id.view_group_fade_helper_hardware_layer, true)
+ }
+ }
+
+ val animator = ValueAnimator.ofFloat(1.0f, 0.0f).apply {
+ this.duration = duration
+ interpolator = Interpolators.ALPHA_OUT
+ addUpdateListener { animation ->
+ val previousSetAlpha = root.getTag(
+ R.id.view_group_fade_helper_previous_value_tag) as Float?
+ val newAlpha = animation.animatedValue as Float
+ for (viewToFade in viewsToFadeOut) {
+ if (viewToFade.alpha != previousSetAlpha) {
+ // A value was set that wasn't set from our view, let's store it and restore
+ // it at the end
+ viewToFade.setTag(R.id.view_group_fade_helper_restore_tag, viewToFade.alpha)
+ }
+ viewToFade.alpha = newAlpha
+ }
+ root.setTag(R.id.view_group_fade_helper_previous_value_tag, newAlpha)
+ }
+ addListener(object : AnimatorListenerAdapter() {
+ override fun onAnimationEnd(animation: Animator?) {
+ endRunnable?.run()
+ }
+ })
+ start()
+ }
+ root.setTag(R.id.view_group_fade_helper_modified_views, viewsToFadeOut)
+ root.setTag(R.id.view_group_fade_helper_animator, animator)
+ }
+
+ private fun gatherViews(root: ViewGroup, excludedView: View,
+ shouldInclude: (View) -> Boolean): MutableSet<View> {
+ val viewsToFadeOut = mutableSetOf<View>()
+ var parent = excludedView.parent as ViewGroup?
+ var viewContainingExcludedView = excludedView;
+ while (parent != null) {
+ for (i in 0 until parent.childCount) {
+ val child = parent.getChildAt(i)
+ if (shouldInclude.invoke(child) && viewContainingExcludedView != child) {
+ viewsToFadeOut.add(child)
+ }
+ }
+ if (parent == root) {
+ break;
+ }
+ viewContainingExcludedView = parent
+ parent = parent.parent as ViewGroup?
+ }
+ return viewsToFadeOut
+ }
+
+ /**
+ * Reset all view alphas for views previously transformed away.
+ */
+ @JvmStatic
+ fun reset(root: ViewGroup) {
+ @Suppress("UNCHECKED_CAST")
+ val modifiedViews = root.getTag(R.id.view_group_fade_helper_modified_views)
+ as MutableSet<View>?
+ val animator = root.getTag(R.id.view_group_fade_helper_animator) as Animator?
+ if (modifiedViews == null || animator == null) {
+ // nothing to restore
+ return
+ }
+ animator.cancel()
+ val lastSetValue = root.getTag(
+ R.id.view_group_fade_helper_previous_value_tag) as Float?
+ for (viewToFade in modifiedViews) {
+ val restoreAlpha = viewToFade.getTag(
+ R.id.view_group_fade_helper_restore_tag) as Float?
+ if (restoreAlpha == null) {
+ continue
+ }
+ if (lastSetValue == viewToFade.alpha) {
+ // it was modified after the transition!
+ viewToFade.alpha = restoreAlpha
+ }
+ val needsLayerReset = viewToFade.getTag(
+ R.id.view_group_fade_helper_hardware_layer) as Boolean?
+ if (needsLayerReset == true) {
+ viewToFade.setLayerType(View.LAYER_TYPE_NONE, null)
+ viewToFade.setTag(R.id.view_group_fade_helper_hardware_layer, null)
+ }
+ viewToFade.setTag(R.id.view_group_fade_helper_restore_tag, null)
+ }
+ root.setTag(R.id.view_group_fade_helper_modified_views, null)
+ root.setTag(R.id.view_group_fade_helper_previous_value_tag, null)
+ root.setTag(R.id.view_group_fade_helper_animator, null)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
index 64b2f048ce2e..fca520fe0521 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
@@ -114,8 +114,6 @@ public class NotificationData {
} else if (isHeadsUp) {
// Provide consistent ranking with headsUpManager
return mHeadsUpManager.compare(a, b);
- } else if (a.getRow().showingAmbientPulsing() != b.getRow().showingAmbientPulsing()) {
- return a.getRow().showingAmbientPulsing() ? -1 : 1;
} else if (aMedia != bMedia) {
// Upsort current media notification.
return aMedia ? -1 : 1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index 92c261c4cad7..b19d2ca29c96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -96,6 +96,7 @@ public final class NotificationEntry {
public StatusBarIconView icon;
public StatusBarIconView expandedIcon;
public StatusBarIconView centeredIcon;
+ public StatusBarIconView aodIcon;
private boolean interruption;
public boolean autoRedacted; // whether the redacted notification was generated by us
public int targetSdk;
@@ -172,6 +173,9 @@ public final class NotificationEntry {
* the lock screen/status bar and in the top section in the shade.
*/
private boolean mHighPriority;
+ private boolean mSensitive = true;
+ private Runnable mOnSensitiveChangedListener;
+ private boolean mAutoHeadsUp;
public NotificationEntry(StatusBarNotification n) {
this(n, null);
@@ -336,6 +340,12 @@ public final class NotificationEntry {
sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
expandedIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ // Construct the expanded icon.
+ aodIcon = new StatusBarIconView(context,
+ sbn.getPackageName() + "/0x" + Integer.toHexString(sbn.getId()), sbn);
+ aodIcon.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
+ aodIcon.setIncreasedSize(true);
+
final StatusBarIcon ic = new StatusBarIcon(
sbn.getUser(),
sbn.getPackageName(),
@@ -344,10 +354,11 @@ public final class NotificationEntry {
n.number,
StatusBarIconView.contentDescForNotification(context, n));
- if (!icon.set(ic) || !expandedIcon.set(ic)) {
+ if (!icon.set(ic) || !expandedIcon.set(ic) || !aodIcon.set(ic)) {
icon = null;
expandedIcon = null;
centeredIcon = null;
+ aodIcon = null;
throw new InflationException("Couldn't create icon: " + ic);
}
expandedIcon.setVisibility(View.INVISIBLE);
@@ -380,6 +391,10 @@ public final class NotificationEntry {
if (centeredIcon != null) {
centeredIcon.setTag(key, tag);
}
+
+ if (aodIcon != null) {
+ aodIcon.setTag(key, tag);
+ }
}
/**
@@ -403,7 +418,8 @@ public final class NotificationEntry {
StatusBarIconView.contentDescForNotification(context, n));
icon.setNotification(sbn);
expandedIcon.setNotification(sbn);
- if (!icon.set(ic) || !expandedIcon.set(ic)) {
+ aodIcon.setNotification(sbn);
+ if (!icon.set(ic) || !expandedIcon.set(ic) || !aodIcon.set(ic)) {
throw new InflationException("Couldn't update icon: " + ic);
}
@@ -615,10 +631,6 @@ public final class NotificationEntry {
if (row != null) row.freeContentViewWhenSafe(inflationFlag);
}
- public void setAmbientPulsing(boolean pulsing) {
- if (row != null) row.setAmbientPulsing(pulsing);
- }
-
public boolean rowExists() {
return row != null;
}
@@ -647,23 +659,37 @@ public final class NotificationEntry {
if (row != null) row.setPinned(pinned);
}
- public boolean isRowAnimatingAway() {
- return row != null && row.isHeadsUpAnimatingAway();
- }
-
public boolean isRowHeadsUp() {
return row != null && row.isHeadsUp();
}
+ public boolean showingPulsing() {
+ return row != null && row.showingPulsing();
+ }
+
public void setHeadsUp(boolean shouldHeadsUp) {
if (row != null) row.setHeadsUp(shouldHeadsUp);
}
+ public void setHeadsUpAnimatingAway(boolean animatingAway) {
+ if (row != null) row.setHeadsUpAnimatingAway(animatingAway);
+ }
- public void setAmbientGoingAway(boolean goingAway) {
- if (row != null) row.setAmbientGoingAway(goingAway);
+ /**
+ * Set that this notification was automatically heads upped. This happens for example when
+ * the user bypasses the lockscreen and media is playing.
+ */
+ public void setAutoHeadsUp(boolean autoHeadsUp) {
+ mAutoHeadsUp = autoHeadsUp;
}
+ /**
+ * @return if this notification was automatically heads upped. This happens for example when
+ * * the user bypasses the lockscreen and media is playing.
+ */
+ public boolean isAutoHeadsUp() {
+ return mAutoHeadsUp;
+ }
public boolean mustStayOnScreen() {
return row != null && row.mustStayOnScreen();
@@ -850,6 +876,30 @@ public final class NotificationEntry {
return Objects.equals(n.category, category);
}
+ /**
+ * Set this notification to be sensitive.
+ *
+ * @param sensitive true if the content of this notification is sensitive right now
+ * @param deviceSensitive true if the device in general is sensitive right now
+ */
+ public void setSensitive(boolean sensitive, boolean deviceSensitive) {
+ getRow().setSensitive(sensitive, deviceSensitive);
+ if (sensitive != mSensitive) {
+ mSensitive = sensitive;
+ if (mOnSensitiveChangedListener != null) {
+ mOnSensitiveChangedListener.run();
+ }
+ }
+ }
+
+ public boolean isSensitive() {
+ return mSensitive;
+ }
+
+ public void setOnSensitiveChangedListener(Runnable listener) {
+ mOnSensitiveChangedListener = listener;
+ }
+
/** Information about a suggestion that is being edited. */
public static class EditedSuggestionInfo {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
index d3e5af8c729e..247c31fc80a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationRowBinderImpl.java
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.notification.collection;
import static com.android.internal.util.Preconditions.checkNotNull;
import static com.android.systemui.statusbar.NotificationRemoteInputManager.ENABLE_REMOTE_INPUT;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
import android.annotation.Nullable;
@@ -34,6 +33,7 @@ import com.android.internal.util.NotificationMessagingUtil;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.UiOffloadThread;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -47,6 +47,7 @@ import com.android.systemui.statusbar.notification.row.NotificationContentInflat
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -69,6 +70,8 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
private final ExpandableNotificationRow.ExpansionLogger mExpansionLogger =
this::logNotificationExpansion;
private final boolean mAllowLongPress;
+ private final KeyguardBypassController mKeyguardBypassController;
+ private final StatusBarStateController mStatusBarStateController;
private NotificationRemoteInputManager mRemoteInputManager;
private NotificationPresenter mPresenter;
@@ -80,10 +83,14 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
private NotificationClicker mNotificationClicker;
private final NotificationLogger mNotificationLogger = Dependency.get(NotificationLogger.class);
- public NotificationRowBinderImpl(Context context, boolean allowLongPress) {
+ public NotificationRowBinderImpl(Context context, boolean allowLongPress,
+ KeyguardBypassController keyguardBypassController,
+ StatusBarStateController statusBarStateController) {
mContext = context;
mMessagingUtil = new NotificationMessagingUtil(context);
mAllowLongPress = allowLongPress;
+ mKeyguardBypassController = keyguardBypassController;
+ mStatusBarStateController = statusBarStateController;
}
private NotificationRemoteInputManager getRemoteInputManager() {
@@ -144,6 +151,8 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
StatusBarNotification sbn, ExpandableNotificationRow row,
Runnable onDismissRunnable) {
row.setExpansionLogger(mExpansionLogger, entry.notification.getKey());
+ row.setBypassController(mKeyguardBypassController);
+ row.setStatusBarStateController(mStatusBarStateController);
row.setGroupManager(mGroupManager);
row.setHeadsUpManager(mHeadsUpManager);
row.setOnExpandClickListener(mPresenter);
@@ -249,9 +258,6 @@ public class NotificationRowBinderImpl implements NotificationRowBinder {
if (mNotificationInterruptionStateProvider.shouldHeadsUp(entry)) {
row.updateInflationFlag(FLAG_CONTENT_VIEW_HEADS_UP, true /* shouldInflate */);
}
- if (mNotificationInterruptionStateProvider.shouldPulse(entry)) {
- row.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true /* shouldInflate */);
- }
row.setNeedsRedaction(
Dependency.get(NotificationLockscreenUserManager.class).needsRedaction(entry));
row.inflateViews();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index 94f7e651d73d..81275fda57e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -101,7 +101,7 @@ public class NotificationLogger implements StateListener {
// Tracks notifications currently visible in mNotificationStackScroller and
// emits visibility events via NoMan on changes.
- protected final Runnable mVisibilityReporter = new Runnable() {
+ protected Runnable mVisibilityReporter = new Runnable() {
private final ArraySet<NotificationVisibility> mTmpNewlyVisibleNotifications =
new ArraySet<>();
private final ArraySet<NotificationVisibility> mTmpCurrentlyVisibleNotifications =
@@ -407,6 +407,11 @@ public class NotificationLogger implements StateListener {
mExpansionStateLogger.onExpansionChanged(key, isUserAction, isExpanded, location);
}
+ @VisibleForTesting
+ public void setVisibilityReporter(Runnable visibilityReporter) {
+ mVisibilityReporter = visibilityReporter;
+ }
+
/**
* A listener that is notified when some child locations might have changed.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
index 94face2581b3..dca152fbe37a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationView.java
@@ -52,7 +52,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private static final int BACKGROUND_ANIMATION_LENGTH_MS = 220;
private static final int ACTIVATE_ANIMATION_LENGTH = 220;
- private static final long DARK_ANIMATION_LENGTH = StackStateAnimator.ANIMATION_DURATION_WAKEUP;
/**
* The amount of width, which is kept in the end when performing a disappear animation (also
@@ -85,11 +84,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private static final float VERTICAL_ANIMATION_START = 1.0f;
/**
- * Scale for the background to animate from when exiting dark mode.
- */
- private static final float DARK_EXIT_SCALE_START = 0.93f;
-
- /**
* A sentinel value when no color should be used. Can be used with {@link #setTintColor(int)}
* or {@link #setOverrideTintColor(int, float)}.
*/
@@ -105,7 +99,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
private final DoubleTapHelper mDoubleTapHelper;
private boolean mDimmed;
- protected boolean mDark;
protected int mBgTint = NO_COLOR;
private float mBgAlpha = 1f;
@@ -440,16 +433,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
return true;
}
- public void setDark(boolean dark, boolean fade, long delay) {
- super.setDark(dark, fade, delay);
- if (mDark == dark) {
- return;
- }
- mDark = dark;
- updateBackground();
- updateBackgroundTint(false);
- }
-
private void updateOutlineAlpha() {
float alpha = NotificationStackScrollLayout.BACKGROUND_ALPHA_DIMMED;
alpha = (alpha + (1.0f - alpha) * mNormalBackgroundVisibilityAmount);
@@ -542,10 +525,6 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
* used and the background color not at all.
*/
public void setOverrideTintColor(int color, float overrideAmount) {
- if (mDark) {
- color = NO_COLOR;
- overrideAmount = 0;
- }
mOverrideTint = color;
mOverrideAmount = overrideAmount;
int newColor = calculateBgColor();
@@ -1057,6 +1036,14 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
return false;
}
+ public boolean isHeadsUp() {
+ return false;
+ }
+
+ public int getHeadsUpHeightWithoutHeader() {
+ return getHeight();
+ }
+
public interface OnActivatedListener {
void onActivated(ActivatableNotificationView view);
void onActivationReset(ActivatableNotificationView view);
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 d625b318487d..a8327f63dcf7 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
@@ -17,11 +17,9 @@
package com.android.systemui.statusbar.notification.row;
import static com.android.systemui.statusbar.notification.ActivityLaunchAnimator.ExpandAnimationParameters;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_PUBLIC;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationCallback;
-import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
@@ -81,6 +79,7 @@ import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.MenuItem;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.RemoteInputController;
@@ -98,6 +97,7 @@ 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.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -127,14 +127,16 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private static final long RECENTLY_ALERTED_THRESHOLD_MS = TimeUnit.SECONDS.toMillis(30);
private boolean mUpdateBackgroundOnUpdate;
private boolean mNotificationTranslationFinished = false;
-
/**
* Listener for when {@link ExpandableNotificationRow} is laid out.
*/
public interface LayoutListener {
void onLayout();
+
}
+ private StatusBarStateController mStatusbarStateController;
+ private KeyguardBypassController mBypassController;
private LayoutListener mLayoutListener;
private final NotificationContentInflater mNotificationInflater;
private int mIconTransformContentShift;
@@ -187,11 +189,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
*/
private boolean mOnKeyguard;
- /**
- * Whether or not the row is currently on the doze screen.
- */
- private boolean mOnAmbient;
-
private Animator mTranslateAnim;
private ArrayList<View> mTranslateableViews;
private NotificationContentView mPublicLayout;
@@ -211,17 +208,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private boolean mIsHeadsUp;
/**
- * Whether or not the notification is using the ambient display view and is pulsing. This
- * occurs when a high priority notification alerts while the phone is dozing or is on AOD.
- */
- private boolean mIsAmbientPulsing;
-
- /**
- * Happens when the notification was pulsing before and goes away to ensure smooth animations.
- */
- private boolean mAmbientGoingAway;
-
- /**
* Whether or not the notification should be redacted on the lock screen, i.e has sensitive
* content which should be redacted on the lock screen.
*/
@@ -341,7 +327,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private SystemNotificationAsyncTask mSystemNotificationAsyncTask =
new SystemNotificationAsyncTask();
- private int mStatusBarState = -1;
/**
* Returns whether the given {@code statusBarNotification} is a system notification.
@@ -487,12 +472,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_HEADSUP,
freeViewRunnable);
break;
- case FLAG_CONTENT_VIEW_AMBIENT:
- getPrivateLayout().performWhenContentInactive(VISIBLE_TYPE_AMBIENT,
- freeViewRunnable);
- getPublicLayout().performWhenContentInactive(VISIBLE_TYPE_AMBIENT,
- freeViewRunnable);
- break;
case FLAG_CONTENT_VIEW_PUBLIC:
getPublicLayout().performWhenContentInactive(VISIBLE_TYPE_CONTRACTED,
freeViewRunnable);
@@ -648,7 +627,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
if (!getShowingLayout().isDimmable()) {
return false;
}
- if (showingAmbientPulsing()) {
+ if (showingPulsing()) {
return false;
}
return super.isDimmable();
@@ -698,7 +677,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
if (headsUpWrapper != null) {
headsUpHeight = Math.max(headsUpHeight, headsUpWrapper.getMinLayoutHeight());
}
- layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight, headsUpHeight);
+ layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight);
}
public StatusBarNotification getStatusBarNotification() {
@@ -709,6 +688,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mEntry;
}
+ @Override
public boolean isHeadsUp() {
return mIsHeadsUp;
}
@@ -734,14 +714,18 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
@Override
- public boolean showingAmbientPulsing() {
- return mIsAmbientPulsing || mAmbientGoingAway;
+ public boolean showingPulsing() {
+ return isHeadsUpState() && (isDozing() || (mOnKeyguard && isBypassEnabled()));
}
- public void setAmbientPulsing(boolean isAmbientPulsing) {
- mIsAmbientPulsing = isAmbientPulsing;
+ /**
+ * @return if the view is in heads up state, i.e either still heads upped or it's disappearing.
+ */
+ public boolean isHeadsUpState() {
+ return mIsHeadsUp || mHeadsupDisappearRunning;
}
+
public void setGroupManager(NotificationGroupManager groupManager) {
mGroupManager = groupManager;
mPrivateLayout.setGroupManager(groupManager);
@@ -1660,6 +1644,14 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
initDimens();
}
+ public void setBypassController(KeyguardBypassController bypassController) {
+ mBypassController = bypassController;
+ }
+
+ public void setStatusBarStateController(StatusBarStateController statusBarStateController) {
+ mStatusbarStateController = statusBarStateController;
+ }
+
private void initDimens() {
mNotificationMinHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_min_height_legacy);
@@ -2050,23 +2042,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return false;
}
- @Override
- public void setDark(boolean dark, boolean fade, long delay) {
- if (mDark == dark) {
- return;
- }
- super.setDark(dark, fade, delay);
- if (!mIsAmbientPulsing) {
- // Only fade the showing view of the pulsing notification.
- fade = false;
- }
- final NotificationContentView showing = getShowingLayout();
- if (showing != null) {
- showing.setDark(dark, fade, delay);
- }
- updateShelfIconColor();
- }
-
public void applyExpandAnimationParams(ExpandAnimationParameters params) {
if (params == null) {
return;
@@ -2180,7 +2155,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
*/
@Override
public boolean isSoundEffectsEnabled() {
- final boolean mute = mDark && mSecureStateProvider != null &&
+ final boolean mute = mStatusbarStateController != null
+ && mStatusbarStateController.isDozing()
+ && mSecureStateProvider != null &&
!mSecureStateProvider.getAsBoolean();
return !mute && super.isSoundEffectsEnabled();
}
@@ -2345,9 +2322,9 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return mPrivateLayout.getMinHeight();
} else if (mSensitive && mHideSensitiveForIntrinsicHeight) {
return getMinHeight();
- } else if (mIsSummaryWithChildren && !mOnKeyguard) {
+ } else if (mIsSummaryWithChildren) {
return mChildrenContainer.getIntrinsicHeight();
- } else if (isHeadsUpAllowed() && (mIsHeadsUp || mHeadsupDisappearRunning)) {
+ } else if (canShowHeadsUp() && isHeadsUpState()) {
if (isPinned() || mHeadsupDisappearRunning) {
return getPinnedHeadsUpHeight(true /* atLeastMinHeight */);
} else if (isExpanded()) {
@@ -2362,22 +2339,27 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
}
- private boolean isHeadsUpAllowed() {
- return !mOnKeyguard && !mOnAmbient;
+ /**
+ * @return {@code true} if the notification can show it's heads up layout. This is mostly true
+ * except for legacy use cases.
+ */
+ public boolean canShowHeadsUp() {
+ if (mOnKeyguard && !isDozing() && !isBypassEnabled()) {
+ return false;
+ }
+ return true;
}
- private boolean isShownAsBubble() {
- return mEntry.isBubble() && !mEntry.showInShadeWhenBubble() && !mEntry.isBubbleDismissed();
+ private boolean isBypassEnabled() {
+ return mBypassController == null || mBypassController.getBypassEnabled();
}
- /**
- * Set the current status bar state.
- * @param state should be from {@link com.android.systemui.statusbar.StatusBarState}.
- */
- public void setStatusBarState(int state) {
- if (mStatusBarState != state) {
- mStatusBarState = state;
- }
+ private boolean isDozing() {
+ return mStatusbarStateController != null && mStatusbarStateController.isDozing();
+ }
+
+ private boolean isShownAsBubble() {
+ return mEntry.isBubble() && !mEntry.showInShadeWhenBubble() && !mEntry.isBubbleDismissed();
}
@Override
@@ -2563,7 +2545,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
showingLayout.updateBackgroundColor(animated);
mPrivateLayout.updateExpandButtons(isExpandable());
updateShelfIconColor();
- showingLayout.setDark(isDark(), false /* animate */, 0 /* delay */);
mShowingPublicInitialized = true;
}
@@ -2656,7 +2637,7 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
private int getHeadsUpHeight() {
- return getShowingLayout().getHeadsUpHeight();
+ return getShowingLayout().getHeadsUpHeight(false /* forceNoHeader */);
}
public boolean areGutsExposed() {
@@ -2717,6 +2698,8 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
l.setAlpha(1.0f);
l.setLayerType(LAYER_TYPE_NONE, null);
}
+ } else {
+ setHeadsUpAnimatingAway(false);
}
}
@@ -2773,12 +2756,12 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
public int getMinHeight(boolean ignoreTemporaryStates) {
if (!ignoreTemporaryStates && mGuts != null && mGuts.isExposed()) {
return mGuts.getIntrinsicHeight();
- } else if (!ignoreTemporaryStates && isHeadsUpAllowed() && mIsHeadsUp
+ } else if (!ignoreTemporaryStates && canShowHeadsUp() && mIsHeadsUp
&& mHeadsUpManager.isTrackingHeadsUp()) {
return getPinnedHeadsUpHeight(false /* atLeastMinHeight */);
} else if (mIsSummaryWithChildren && !isGroupExpanded() && !shouldShowPublic()) {
return mChildrenContainer.getMinHeight();
- } else if (!ignoreTemporaryStates && isHeadsUpAllowed() && mIsHeadsUp) {
+ } else if (!ignoreTemporaryStates && canShowHeadsUp() && mIsHeadsUp) {
return getHeadsUpHeight();
}
NotificationContentView showingLayout = getShowingLayout();
@@ -2794,6 +2777,17 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
@Override
+ public int getHeadsUpHeightWithoutHeader() {
+ if (!canShowHeadsUp() || !mIsHeadsUp) {
+ return getCollapsedHeight();
+ }
+ if (mIsSummaryWithChildren && !shouldShowPublic()) {
+ return mChildrenContainer.getCollapsedHeightWithoutHeader();
+ }
+ return getShowingLayout().getHeadsUpHeight(true /* forceNoHeader */);
+ }
+
+ @Override
public void setClipTopAmount(int clipTopAmount) {
super.setClipTopAmount(clipTopAmount);
for (NotificationContentView l : mLayouts) {
@@ -3050,18 +3044,11 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
@Override
public boolean isAboveShelf() {
- return showingAmbientPulsing() || (!isOnKeyguard()
+ return (canShowHeadsUp()
&& (mIsPinned || mHeadsupDisappearRunning || (mIsHeadsUp && mAboveShelf)
|| mExpandAnimationRunning || mChildIsExpanding));
}
- public void setOnAmbient(boolean onAmbient) {
- if (onAmbient != mOnAmbient) {
- mOnAmbient = onAmbient;
- notifyHeightChanged(false /* needsAnimation */);
- }
- }
-
@Override
public boolean topAmountNeedsClipping() {
if (isGroupExpanded()) {
@@ -3125,10 +3112,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
return getCurrentBottomRoundness() == 0.0f && getCurrentTopRoundness() == 0.0f;
}
- public boolean isOnAmbient() {
- return mOnAmbient;
- }
-
//TODO: this logic can't depend on layout if we are recycling!
public boolean isMediaRow() {
return getExpandedContentView() != null
@@ -3206,10 +3189,6 @@ public class ExpandableNotificationRow extends ActivatableNotificationView
}
}
- public void setAmbientGoingAway(boolean goingAway) {
- mAmbientGoingAway = goingAway;
- }
-
/**
* Returns the Smart Suggestions backing the smart suggestion buttons in the notification.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index cac41da52120..a0fef0068b05 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -49,7 +49,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
protected int mClipBottomAmount;
protected int mMinimumHeightForClipping = 0;
protected float mExtraWidthForClipping = 0;
- private boolean mDark;
private ArrayList<View> mMatchParentViews = new ArrayList<View>();
private static Rect mClipRect = new Rect();
private boolean mWillBeGone;
@@ -212,21 +211,6 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
public void setDimmed(boolean dimmed, boolean fade) {
}
- /**
- * Sets the notification as dark. The default implementation does nothing.
- *
- * @param dark Whether the notification should be dark.
- * @param fade Whether an animation should be played to change the state.
- * @param delay If fading, the delay of the animation.
- */
- public void setDark(boolean dark, boolean fade, long delay) {
- mDark = dark;
- }
-
- public boolean isDark() {
- return mDark;
- }
-
public boolean isRemoved() {
return false;
}
@@ -527,7 +511,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable {
public void setHeadsUpIsVisible() {
}
- public boolean showingAmbientPulsing() {
+ public boolean showingPulsing() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index 396cd73f9a22..d057a1d2f20b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.notification.row;
-import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_CONTRACTED;
import static com.android.systemui.statusbar.notification.row.NotificationContentView.VISIBLE_TYPE_HEADSUP;
@@ -51,12 +50,6 @@ import com.android.systemui.util.Assert;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
-import java.util.concurrent.Executor;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.ThreadFactory;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicInteger;
/**
* A utility that inflates the right kind of contentView based on the state
@@ -72,7 +65,6 @@ public class NotificationContentInflater {
FLAG_CONTENT_VIEW_CONTRACTED,
FLAG_CONTENT_VIEW_EXPANDED,
FLAG_CONTENT_VIEW_HEADS_UP,
- FLAG_CONTENT_VIEW_AMBIENT,
FLAG_CONTENT_VIEW_PUBLIC,
FLAG_CONTENT_VIEW_ALL})
public @interface InflationFlag {}
@@ -93,17 +85,11 @@ public class NotificationContentInflater {
public static final int FLAG_CONTENT_VIEW_HEADS_UP = 1 << 2;
/**
- * The ambient view. Seen when a high priority notification is received and the phone
- * is dozing.
- */
- public static final int FLAG_CONTENT_VIEW_AMBIENT = 1 << 3;
-
- /**
* The public view. This is a version of the contracted view that hides sensitive
* information and is used on the lock screen if we determine that the notification's
* content should be hidden.
*/
- public static final int FLAG_CONTENT_VIEW_PUBLIC = 1 << 4;
+ public static final int FLAG_CONTENT_VIEW_PUBLIC = 1 << 3;
public static final int FLAG_CONTENT_VIEW_ALL = ~0;
@@ -128,7 +114,6 @@ public class NotificationContentInflater {
private RemoteViews.OnClickHandler mRemoteViewClickHandler;
private boolean mIsChildInGroup;
private InflationCallback mCallback;
- private boolean mRedactAmbient;
private boolean mInflateSynchronously = false;
private final ArrayMap<Integer, RemoteViews> mCachedContentViews = new ArrayMap<>();
@@ -169,21 +154,18 @@ public class NotificationContentInflater {
/**
* Update whether or not the notification is redacted on the lock screen. If the notification
- * is now redacted, we should inflate the public contracted view and public ambient view to
- * now show on the lock screen.
+ * is now redacted, we should inflate the public contracted view to now show on the lock screen.
*
* @param needsRedaction true if the notification should now be redacted on the lock screen
*/
public void updateNeedsRedaction(boolean needsRedaction) {
- mRedactAmbient = needsRedaction;
if (mRow.getEntry() == null) {
return;
}
- int flags = FLAG_CONTENT_VIEW_AMBIENT;
if (needsRedaction) {
- flags |= FLAG_CONTENT_VIEW_PUBLIC;
+ int flags = FLAG_CONTENT_VIEW_PUBLIC;
+ inflateNotificationViews(flags);
}
- inflateNotificationViews(flags);
}
/**
@@ -263,7 +245,6 @@ public class NotificationContentInflater {
mIsChildInGroup,
mUsesIncreasedHeight,
mUsesIncreasedHeadsUpHeight,
- mRedactAmbient,
mCallback,
mRemoteViewClickHandler);
if (mInflateSynchronously) {
@@ -281,7 +262,7 @@ public class NotificationContentInflater {
Context packageContext) {
InflationProgress result = createRemoteViews(reInflateFlags, builder, mIsLowPriority,
mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
- mRedactAmbient, packageContext);
+ packageContext);
result = inflateSmartReplyViews(result, reInflateFlags, mRow.getEntry(),
mRow.getContext(), mRow.getHeadsUpManager(),
mRow.getExistingSmartRepliesAndActions());
@@ -291,7 +272,6 @@ public class NotificationContentInflater {
reInflateFlags,
mCachedContentViews,
mRow,
- mRedactAmbient,
mRemoteViewClickHandler,
null);
return result;
@@ -316,21 +296,6 @@ public class NotificationContentInflater {
mRow.getPrivateLayout().setHeadsUpInflatedSmartReplies(null);
}
break;
- case FLAG_CONTENT_VIEW_AMBIENT:
- boolean privateSafeToRemove = mRow.getPrivateLayout().isContentViewInactive(
- VISIBLE_TYPE_AMBIENT);
- boolean publicSafeToRemove = mRow.getPublicLayout().isContentViewInactive(
- VISIBLE_TYPE_AMBIENT);
- if (privateSafeToRemove) {
- mRow.getPrivateLayout().setAmbientChild(null);
- }
- if (publicSafeToRemove) {
- mRow.getPublicLayout().setAmbientChild(null);
- }
- if (privateSafeToRemove && publicSafeToRemove) {
- mCachedContentViews.remove(FLAG_CONTENT_VIEW_AMBIENT);
- }
- break;
case FLAG_CONTENT_VIEW_PUBLIC:
if (mRow.getPublicLayout().isContentViewInactive(VISIBLE_TYPE_CONTRACTED)) {
mRow.getPublicLayout().setContractedChild(null);
@@ -366,7 +331,7 @@ public class NotificationContentInflater {
private static InflationProgress createRemoteViews(@InflationFlag int reInflateFlags,
Notification.Builder builder, boolean isLowPriority, boolean isChildInGroup,
- boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight, boolean redactAmbient,
+ boolean usesIncreasedHeight, boolean usesIncreasedHeadsUpHeight,
Context packageContext) {
InflationProgress result = new InflationProgress();
isLowPriority = isLowPriority && !isChildInGroup;
@@ -387,10 +352,6 @@ public class NotificationContentInflater {
result.newPublicView = builder.makePublicContentView();
}
- if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
- result.newAmbientView = redactAmbient ? builder.makePublicAmbientNotification()
- : builder.makeAmbientNotification();
- }
result.packageContext = packageContext;
result.headsUpStatusBarText = builder.getHeadsUpStatusBarText(false /* showingPublic */);
result.headsUpStatusBarTextPublic = builder.getHeadsUpStatusBarText(
@@ -404,7 +365,6 @@ public class NotificationContentInflater {
@InflationFlag int reInflateFlags,
ArrayMap<Integer, RemoteViews> cachedContentViews,
ExpandableNotificationRow row,
- boolean redactAmbient,
RemoteViews.OnClickHandler remoteViewClickHandler,
@Nullable InflationCallback callback) {
NotificationContentView privateLayout = row.getPrivateLayout();
@@ -428,7 +388,7 @@ public class NotificationContentInflater {
}
};
applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews,
- row, redactAmbient, isNewView, remoteViewClickHandler, callback, privateLayout,
+ row, isNewView, remoteViewClickHandler, callback, privateLayout,
privateLayout.getContractedChild(), privateLayout.getVisibleWrapper(
NotificationContentView.VISIBLE_TYPE_CONTRACTED),
runningInflations, applyCallback);
@@ -452,7 +412,7 @@ public class NotificationContentInflater {
}
};
applyRemoteView(inflateSynchronously, result, reInflateFlags, flag,
- cachedContentViews, row, redactAmbient, isNewView, remoteViewClickHandler,
+ cachedContentViews, row, isNewView, remoteViewClickHandler,
callback, privateLayout, privateLayout.getExpandedChild(),
privateLayout.getVisibleWrapper(
NotificationContentView.VISIBLE_TYPE_EXPANDED), runningInflations,
@@ -478,7 +438,7 @@ public class NotificationContentInflater {
}
};
applyRemoteView(inflateSynchronously, result, reInflateFlags, flag,
- cachedContentViews, row, redactAmbient, isNewView, remoteViewClickHandler,
+ cachedContentViews, row, isNewView, remoteViewClickHandler,
callback, privateLayout, privateLayout.getHeadsUpChild(),
privateLayout.getVisibleWrapper(
VISIBLE_TYPE_HEADSUP), runningInflations,
@@ -503,39 +463,14 @@ public class NotificationContentInflater {
}
};
applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews,
- row, redactAmbient, isNewView, remoteViewClickHandler, callback,
+ row, isNewView, remoteViewClickHandler, callback,
publicLayout, publicLayout.getContractedChild(),
publicLayout.getVisibleWrapper(NotificationContentView.VISIBLE_TYPE_CONTRACTED),
runningInflations, applyCallback);
}
- flag = FLAG_CONTENT_VIEW_AMBIENT;
- if ((reInflateFlags & flag) != 0) {
- NotificationContentView newParent = redactAmbient ? publicLayout : privateLayout;
- boolean isNewView = (!canReapplyAmbient(row, redactAmbient)
- || !canReapplyRemoteView(result.newAmbientView,
- cachedContentViews.get(FLAG_CONTENT_VIEW_AMBIENT)));
- ApplyCallback applyCallback = new ApplyCallback() {
- @Override
- public void setResultView(View v) {
- result.inflatedAmbientView = v;
- }
-
- @Override
- public RemoteViews getRemoteView() {
- return result.newAmbientView;
- }
- };
- applyRemoteView(inflateSynchronously, result, reInflateFlags, flag, cachedContentViews,
- row, redactAmbient, isNewView, remoteViewClickHandler, callback,
- newParent, newParent.getAmbientChild(), newParent.getVisibleWrapper(
- NotificationContentView.VISIBLE_TYPE_AMBIENT), runningInflations,
- applyCallback);
- }
-
// Let's try to finish, maybe nobody is even inflating anything
- finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations, callback, row,
- redactAmbient);
+ finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations, callback, row);
CancellationSignal cancellationSignal = new CancellationSignal();
cancellationSignal.setOnCancelListener(
() -> runningInflations.values().forEach(CancellationSignal::cancel));
@@ -550,7 +485,6 @@ public class NotificationContentInflater {
@InflationFlag int inflationId,
final ArrayMap<Integer, RemoteViews> cachedContentViews,
final ExpandableNotificationRow row,
- final boolean redactAmbient,
boolean isNewView,
RemoteViews.OnClickHandler remoteViewClickHandler,
@Nullable final InflationCallback callback,
@@ -603,7 +537,7 @@ public class NotificationContentInflater {
}
runningInflations.remove(inflationId);
finishIfDone(result, reInflateFlags, cachedContentViews, runningInflations,
- callback, row, redactAmbient);
+ callback, row);
}
@Override
@@ -670,8 +604,7 @@ public class NotificationContentInflater {
private static boolean finishIfDone(InflationProgress result,
@InflationFlag int reInflateFlags, ArrayMap<Integer, RemoteViews> cachedContentViews,
HashMap<Integer, CancellationSignal> runningInflations,
- @Nullable InflationCallback endListener, ExpandableNotificationRow row,
- boolean redactAmbient) {
+ @Nullable InflationCallback endListener, ExpandableNotificationRow row) {
Assert.isMainThread();
NotificationEntry entry = row.getEntry();
NotificationContentView privateLayout = row.getPrivateLayout();
@@ -735,19 +668,6 @@ public class NotificationContentInflater {
}
}
- if ((reInflateFlags & FLAG_CONTENT_VIEW_AMBIENT) != 0) {
- if (result.inflatedAmbientView != null) {
- NotificationContentView newParent = redactAmbient
- ? publicLayout : privateLayout;
- NotificationContentView otherParent = !redactAmbient
- ? publicLayout : privateLayout;
- newParent.setAmbientChild(result.inflatedAmbientView);
- otherParent.setAmbientChild(null);
- cachedContentViews.put(FLAG_CONTENT_VIEW_AMBIENT, result.newAmbientView);
- } else if (cachedContentViews.get(FLAG_CONTENT_VIEW_AMBIENT) != null) {
- cachedContentViews.put(FLAG_CONTENT_VIEW_AMBIENT, result.newAmbientView);
- }
- }
entry.headsUpStatusBarText = result.headsUpStatusBarText;
entry.headsUpStatusBarTextPublic = result.headsUpStatusBarTextPublic;
if (endListener != null) {
@@ -827,12 +747,6 @@ public class NotificationContentInflater {
mInflateSynchronously = inflateSynchronously;
}
- private static boolean canReapplyAmbient(ExpandableNotificationRow row, boolean redactAmbient) {
- NotificationContentView ambientView = redactAmbient ? row.getPublicLayout()
- : row.getPrivateLayout();
- return ambientView.getAmbientChild() != null;
- }
-
public static class AsyncInflationTask extends AsyncTask<Void, Void, InflationProgress>
implements InflationCallback, InflationTask {
@@ -844,7 +758,6 @@ public class NotificationContentInflater {
private final boolean mUsesIncreasedHeight;
private final InflationCallback mCallback;
private final boolean mUsesIncreasedHeadsUpHeight;
- private final boolean mRedactAmbient;
private @InflationFlag int mReInflateFlags;
private final ArrayMap<Integer, RemoteViews> mCachedContentViews;
private ExpandableNotificationRow mRow;
@@ -862,7 +775,6 @@ public class NotificationContentInflater {
boolean isChildInGroup,
boolean usesIncreasedHeight,
boolean usesIncreasedHeadsUpHeight,
- boolean redactAmbient,
InflationCallback callback,
RemoteViews.OnClickHandler remoteViewClickHandler) {
mRow = row;
@@ -875,7 +787,6 @@ public class NotificationContentInflater {
mIsChildInGroup = isChildInGroup;
mUsesIncreasedHeight = usesIncreasedHeight;
mUsesIncreasedHeadsUpHeight = usesIncreasedHeadsUpHeight;
- mRedactAmbient = redactAmbient;
mRemoteViewClickHandler = remoteViewClickHandler;
mCallback = callback;
NotificationEntry entry = row.getEntry();
@@ -903,9 +814,8 @@ public class NotificationContentInflater {
processor.processNotification(notification, recoveredBuilder);
}
InflationProgress inflationProgress = createRemoteViews(mReInflateFlags,
- recoveredBuilder, mIsLowPriority,
- mIsChildInGroup, mUsesIncreasedHeight, mUsesIncreasedHeadsUpHeight,
- mRedactAmbient, packageContext);
+ recoveredBuilder, mIsLowPriority, mIsChildInGroup, mUsesIncreasedHeight,
+ mUsesIncreasedHeadsUpHeight, packageContext);
return inflateSmartReplyViews(inflationProgress, mReInflateFlags, mRow.getEntry(),
mRow.getContext(), mRow.getHeadsUpManager(),
mRow.getExistingSmartRepliesAndActions());
@@ -919,7 +829,7 @@ public class NotificationContentInflater {
protected void onPostExecute(InflationProgress result) {
if (mError == null) {
mCancellationSignal = apply(mInflateSynchronously, result, mReInflateFlags,
- mCachedContentViews, mRow, mRedactAmbient, mRemoteViewClickHandler, this);
+ mCachedContentViews, mRow, mRemoteViewClickHandler, this);
} else {
handleError(mError);
}
@@ -974,7 +884,6 @@ public class NotificationContentInflater {
private RemoteViews newContentView;
private RemoteViews newHeadsUpView;
private RemoteViews newExpandedView;
- private RemoteViews newAmbientView;
private RemoteViews newPublicView;
@VisibleForTesting
@@ -983,7 +892,6 @@ public class NotificationContentInflater {
private View inflatedContentView;
private View inflatedHeadsUpView;
private View inflatedExpandedView;
- private View inflatedAmbientView;
private View inflatedPublicView;
private CharSequence headsUpStatusBarText;
private CharSequence headsUpStatusBarTextPublic;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 354ed2d00d32..90f63249846e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -71,7 +71,6 @@ public class NotificationContentView extends FrameLayout {
public static final int VISIBLE_TYPE_EXPANDED = 1;
public static final int VISIBLE_TYPE_HEADSUP = 2;
private static final int VISIBLE_TYPE_SINGLELINE = 3;
- public static final int VISIBLE_TYPE_AMBIENT = 4;
public static final int UNDEFINED = -1;
private final Rect mClipBounds = new Rect();
@@ -82,7 +81,6 @@ public class NotificationContentView extends FrameLayout {
private View mExpandedChild;
private View mHeadsUpChild;
private HybridNotificationView mSingleLineView;
- private View mAmbientChild;
private RemoteInputView mExpandedRemoteInput;
private RemoteInputView mHeadsUpRemoteInput;
@@ -98,12 +96,10 @@ public class NotificationContentView extends FrameLayout {
private NotificationViewWrapper mContractedWrapper;
private NotificationViewWrapper mExpandedWrapper;
private NotificationViewWrapper mHeadsUpWrapper;
- private NotificationViewWrapper mAmbientWrapper;
private HybridGroupManager mHybridGroupManager;
private int mClipTopAmount;
private int mContentHeight;
private int mVisibleType = VISIBLE_TYPE_CONTRACTED;
- private boolean mDark;
private boolean mAnimate;
private boolean mIsHeadsUp;
private boolean mLegacy;
@@ -111,7 +107,6 @@ public class NotificationContentView extends FrameLayout {
private int mSmallHeight;
private int mHeadsUpHeight;
private int mNotificationMaxHeight;
- private int mNotificationAmbientHeight;
private StatusBarNotification mStatusBarNotification;
private NotificationGroupManager mGroupManager;
private RemoteInputController mRemoteInputController;
@@ -166,7 +161,6 @@ public class NotificationContentView extends FrameLayout {
private int mUnrestrictedContentHeight;
private MediaTransferManager mMediaTransferManager;
-
public NotificationContentView(Context context, AttributeSet attrs) {
super(context, attrs);
mHybridGroupManager = new HybridGroupManager(getContext(), this);
@@ -183,12 +177,10 @@ public class NotificationContentView extends FrameLayout {
com.android.internal.R.dimen.notification_content_margin_end);
}
- public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight,
- int ambientHeight) {
+ public void setHeights(int smallHeight, int headsUpMaxHeight, int maxHeight) {
mSmallHeight = smallHeight;
mHeadsUpHeight = headsUpMaxHeight;
mNotificationMaxHeight = maxHeight;
- mNotificationAmbientHeight = ambientHeight;
}
@Override
@@ -286,20 +278,6 @@ public class NotificationContentView extends FrameLayout {
MeasureSpec.makeMeasureSpec(mNotificationMaxHeight, MeasureSpec.AT_MOST));
maxChildHeight = Math.max(maxChildHeight, mSingleLineView.getMeasuredHeight());
}
- if (mAmbientChild != null) {
- int size = mNotificationAmbientHeight;
- ViewGroup.LayoutParams layoutParams = mAmbientChild.getLayoutParams();
- boolean useExactly = false;
- if (layoutParams.height >= 0) {
- // An actual height is set
- size = Math.min(size, layoutParams.height);
- useExactly = true;
- }
- mAmbientChild.measure(widthMeasureSpec,
- MeasureSpec.makeMeasureSpec(size, useExactly ? MeasureSpec.EXACTLY
- : MeasureSpec.AT_MOST));
- maxChildHeight = Math.max(maxChildHeight, mAmbientChild.getMeasuredHeight());
- }
int ownHeight = Math.min(maxChildHeight, maxSize);
setMeasuredDimension(width, ownHeight);
}
@@ -394,10 +372,6 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpChild;
}
- public View getAmbientChild() {
- return mAmbientChild;
- }
-
/**
* Sets the contracted view. Child may be null to remove the content view.
*
@@ -432,9 +406,6 @@ public class NotificationContentView extends FrameLayout {
if (child == mHeadsUpChild) {
return mHeadsUpWrapper;
}
- if (child == mAmbientChild) {
- return mAmbientWrapper;
- }
return null;
}
@@ -514,33 +485,6 @@ public class NotificationContentView extends FrameLayout {
mContainingNotification);
}
- /**
- * Sets the ambient view. Child may be null to remove the content view.
- *
- * @param child ambient content view to set
- */
- public void setAmbientChild(@Nullable View child) {
- if (mAmbientChild != null) {
- mAmbientChild.animate().cancel();
- removeView(mAmbientChild);
- }
- if (child == null) {
- mAmbientChild = null;
- mAmbientWrapper = null;
- if (mTransformationStartVisibleType == VISIBLE_TYPE_AMBIENT) {
- mTransformationStartVisibleType = UNDEFINED;
- }
- if (mVisibleType == VISIBLE_TYPE_AMBIENT) {
- selectLayout(false /* animate */, true /* force */);
- }
- return;
- }
- addView(child);
- mAmbientChild = child;
- mAmbientWrapper = NotificationViewWrapper.wrap(getContext(), child,
- mContainingNotification);
- }
-
@Override
public void onViewAdded(View child) {
super.onViewAdded(child);
@@ -645,7 +589,7 @@ public class NotificationContentView extends FrameLayout {
isTransitioningFromTo(VISIBLE_TYPE_EXPANDED, VISIBLE_TYPE_HEADSUP);
boolean pinned = !isVisibleOrTransitioning(VISIBLE_TYPE_CONTRACTED)
&& (mIsHeadsUp || mHeadsUpAnimatingAway)
- && !mContainingNotification.isOnKeyguard();
+ && mContainingNotification.canShowHeadsUp();
if (transitioningBetweenHunAndExpanded || pinned) {
return Math.min(getViewHeight(VISIBLE_TYPE_HEADSUP),
getViewHeight(VISIBLE_TYPE_EXPANDED));
@@ -659,9 +603,7 @@ public class NotificationContentView extends FrameLayout {
}
int hint;
- if (mAmbientChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_AMBIENT)) {
- hint = mAmbientChild.getHeight();
- } else if (mHeadsUpChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_HEADSUP)) {
+ if (mHeadsUpChild != null && isVisibleOrTransitioning(VISIBLE_TYPE_HEADSUP)) {
hint = getViewHeight(VISIBLE_TYPE_HEADSUP);
} else if (mExpandedChild != null) {
hint = getViewHeight(VISIBLE_TYPE_EXPANDED);
@@ -761,9 +703,7 @@ public class NotificationContentView extends FrameLayout {
if (mExpandedChild != null) {
return getViewHeight(VISIBLE_TYPE_EXPANDED)
+ getExtraRemoteInputHeight(mExpandedRemoteInput);
- } else if (mContainingNotification.isOnAmbient() && getShowingAmbientView() != null) {
- return getShowingAmbientView().getHeight();
- } else if (mIsHeadsUp && mHeadsUpChild != null && !mContainingNotification.isOnKeyguard()) {
+ } else if (mIsHeadsUp && mHeadsUpChild != null && mContainingNotification.canShowHeadsUp()) {
return getViewHeight(VISIBLE_TYPE_HEADSUP)
+ getExtraRemoteInputHeight(mHeadsUpRemoteInput);
} else if (mContractedChild != null) {
@@ -773,11 +713,15 @@ public class NotificationContentView extends FrameLayout {
}
private int getViewHeight(int visibleType) {
+ return getViewHeight(visibleType, false /* forceNoHeader */);
+ }
+
+ private int getViewHeight(int visibleType, boolean forceNoHeader) {
View view = getViewForVisibleType(visibleType);
int height = view.getHeight();
NotificationViewWrapper viewWrapper = getWrapperForView(view);
if (viewWrapper != null) {
- height += viewWrapper.getHeaderTranslation();
+ height += viewWrapper.getHeaderTranslation(forceNoHeader);
}
return height;
}
@@ -787,9 +731,7 @@ public class NotificationContentView extends FrameLayout {
}
public int getMinHeight(boolean likeGroupExpanded) {
- if (mContainingNotification.isOnAmbient() && getShowingAmbientView() != null) {
- return getShowingAmbientView().getHeight();
- } else if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
+ if (likeGroupExpanded || !mIsChildInGroup || isGroupExpanded()) {
return mContractedChild != null
? getViewHeight(VISIBLE_TYPE_CONTRACTED) : mMinContractedHeight;
} else {
@@ -797,15 +739,6 @@ public class NotificationContentView extends FrameLayout {
}
}
- public View getShowingAmbientView() {
- View v = mIsChildInGroup ? mSingleLineView : mAmbientChild;
- if (v != null) {
- return v;
- } else {
- return mContractedChild;
- }
- }
-
private boolean isGroupExpanded() {
return mGroupManager.isGroupExpanded(mStatusBarNotification);
}
@@ -887,7 +820,6 @@ public class NotificationContentView extends FrameLayout {
forceUpdateVisibility(VISIBLE_TYPE_EXPANDED, mExpandedChild, mExpandedWrapper);
forceUpdateVisibility(VISIBLE_TYPE_HEADSUP, mHeadsUpChild, mHeadsUpWrapper);
forceUpdateVisibility(VISIBLE_TYPE_SINGLELINE, mSingleLineView, mSingleLineView);
- forceUpdateVisibility(VISIBLE_TYPE_AMBIENT, mAmbientChild, mAmbientWrapper);
fireExpandedVisibleListenerIfVisible();
// forceUpdateVisibilities cancels outstanding animations without updating the
// mAnimationStartVisibleType. Do so here instead.
@@ -963,8 +895,6 @@ public class NotificationContentView extends FrameLayout {
mHeadsUpChild, mHeadsUpWrapper);
updateViewVisibility(visibleType, VISIBLE_TYPE_SINGLELINE,
mSingleLineView, mSingleLineView);
- updateViewVisibility(visibleType, VISIBLE_TYPE_AMBIENT,
- mAmbientChild, mAmbientWrapper);
fireExpandedVisibleListenerIfVisible();
// updateViewVisibilities cancels outstanding animations without updating the
// mAnimationStartVisibleType. Do so here instead.
@@ -1025,8 +955,6 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpWrapper;
case VISIBLE_TYPE_SINGLELINE:
return mSingleLineView;
- case VISIBLE_TYPE_AMBIENT:
- return mAmbientWrapper;
default:
return mContractedWrapper;
}
@@ -1044,8 +972,6 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpChild;
case VISIBLE_TYPE_SINGLELINE:
return mSingleLineView;
- case VISIBLE_TYPE_AMBIENT:
- return mAmbientChild;
default:
return mContractedChild;
}
@@ -1059,8 +985,6 @@ public class NotificationContentView extends FrameLayout {
return mHeadsUpWrapper;
case VISIBLE_TYPE_CONTRACTED:
return mContractedWrapper;
- case VISIBLE_TYPE_AMBIENT:
- return mAmbientWrapper;
default:
return null;
}
@@ -1100,26 +1024,23 @@ public class NotificationContentView extends FrameLayout {
if (!noExpandedChild && viewHeight == getViewHeight(VISIBLE_TYPE_EXPANDED)) {
return VISIBLE_TYPE_EXPANDED;
}
- boolean onAmbient = mContainingNotification.isOnAmbient();
if (!mUserExpanding && mIsChildInGroup && !isGroupExpanded()) {
return VISIBLE_TYPE_SINGLELINE;
}
if ((mIsHeadsUp || mHeadsUpAnimatingAway) && mHeadsUpChild != null
- && !mContainingNotification.isOnKeyguard()) {
+ && mContainingNotification.canShowHeadsUp()) {
if (viewHeight <= getViewHeight(VISIBLE_TYPE_HEADSUP) || noExpandedChild) {
return VISIBLE_TYPE_HEADSUP;
} else {
return VISIBLE_TYPE_EXPANDED;
}
} else {
- int collapsedType = onAmbient && mAmbientChild != null ? VISIBLE_TYPE_AMBIENT :
- VISIBLE_TYPE_CONTRACTED;
if (noExpandedChild || (mContractedChild != null
- && viewHeight <= getViewHeight(collapsedType)
+ && viewHeight <= getViewHeight(VISIBLE_TYPE_CONTRACTED)
&& (!mIsChildInGroup || isGroupExpanded()
|| !mContainingNotification.isExpanded(true /* allowOnKeyguard */)))) {
- return collapsedType;
+ return VISIBLE_TYPE_CONTRACTED;
} else {
return VISIBLE_TYPE_EXPANDED;
}
@@ -1130,14 +1051,6 @@ public class NotificationContentView extends FrameLayout {
return mIsContentExpandable;
}
- public void setDark(boolean dark, boolean fade, long delay) {
- if (mContractedChild == null) {
- return;
- }
- mDark = dark;
- selectLayout(!dark && fade /* animate */, false /* force */);
- }
-
public void setHeadsUp(boolean headsUp) {
mIsHeadsUp = headsUp;
selectLayout(false /* animate */, true /* force */);
@@ -1180,9 +1093,6 @@ public class NotificationContentView extends FrameLayout {
if (mHeadsUpChild != null) {
mHeadsUpWrapper.setIsChildInGroup(mIsChildInGroup);
}
- if (mAmbientChild != null) {
- mAmbientWrapper.setIsChildInGroup(mIsChildInGroup);
- }
updateAllSingleLineViews();
}
@@ -1201,14 +1111,10 @@ public class NotificationContentView extends FrameLayout {
if (mHeadsUpChild != null) {
mHeadsUpWrapper.onContentUpdated(row);
}
- if (mAmbientChild != null) {
- mAmbientWrapper.onContentUpdated(row);
- }
applyRemoteInputAndSmartReply(entry);
applyMediaTransfer(entry);
updateLegacy();
mForceSelectNextLayout = true;
- setDark(mDark, false /* animate */, 0 /* delay */);
mPreviousExpandedRemoteInputIntent = null;
mPreviousHeadsUpRemoteInputIntent = null;
}
@@ -1514,7 +1420,7 @@ public class NotificationContentView extends FrameLayout {
// if the expanded child has the same height as the collapsed one we hide it.
if (mExpandedChild != null && mExpandedChild.getHeight() != 0) {
if ((!mIsHeadsUp && !mHeadsUpAnimatingAway)
- || mHeadsUpChild == null || mContainingNotification.isOnKeyguard()) {
+ || mHeadsUpChild == null || !mContainingNotification.canShowHeadsUp()) {
if (mExpandedChild.getHeight() <= mContractedChild.getHeight()) {
expandable = false;
}
@@ -1545,9 +1451,6 @@ public class NotificationContentView extends FrameLayout {
if (header == null && mHeadsUpChild != null) {
header = mHeadsUpWrapper.getNotificationHeader();
}
- if (header == null && mAmbientChild != null) {
- header = mAmbientWrapper.getNotificationHeader();
- }
return header;
}
@@ -1849,14 +1752,15 @@ public class NotificationContentView extends FrameLayout {
return getViewHeight(viewType) + getExtraRemoteInputHeight(mExpandedRemoteInput);
}
- public int getHeadsUpHeight() {
+ public int getHeadsUpHeight(boolean forceNoHeader) {
int viewType = VISIBLE_TYPE_HEADSUP;
if (mHeadsUpChild == null) {
viewType = VISIBLE_TYPE_CONTRACTED;
}
// The headsUp remote input quickly switches to the expanded one, so lets also include that
// one
- return getViewHeight(viewType) + getExtraRemoteInputHeight(mHeadsUpRemoteInput)
+ return getViewHeight(viewType, forceNoHeader)
+ + getExtraRemoteInputHeight(mHeadsUpRemoteInput)
+ getExtraRemoteInputHeight(mExpandedRemoteInput);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index b5a8aadf651f..8f7671a5dd96 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -419,9 +419,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
}
final ExpandableNotificationRow row = (ExpandableNotificationRow) view;
- if (row.isDark()) {
- return false;
- }
view.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
if (row.areGutsExposed()) {
closeAndSaveGuts(false /* removeLeavebehind */, false /* force */,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
index d911e1a05029..b4ccb567504a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationMenuRow.java
@@ -346,8 +346,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
if (mShouldShowMenu
&& !NotificationStackScrollLayout.isPinnedHeadsUp(getParent())
&& !mParent.areGutsExposed()
- && !mParent.isDark()
- && !mParent.showingAmbientPulsing()
+ && !mParent.showingPulsing()
&& (mCheckForDrag == null || !mHandler.hasCallbacks(mCheckForDrag))) {
// Only show the menu if we're not a heads up view and guts aren't exposed.
mCheckForDrag = new CheckForDrag();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
index 7ebdb93daf23..97d84433dafe 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationTemplateViewWrapper.java
@@ -51,7 +51,7 @@ import com.android.systemui.statusbar.notification.row.HybridNotificationView;
*/
public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapper {
- private final int mTranslationForHeader;
+ private final int mFullHeaderTranslation;
protected ImageView mPicture;
private ProgressBar mProgressBar;
private TextView mTitle;
@@ -135,7 +135,7 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
}
}, TRANSFORMING_VIEW_TEXT);
- mTranslationForHeader = ctx.getResources().getDimensionPixelSize(
+ mFullHeaderTranslation = ctx.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.notification_content_margin)
- ctx.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.notification_content_margin_top);
@@ -340,20 +340,20 @@ public class NotificationTemplateViewWrapper extends NotificationHeaderViewWrapp
// We also need to compensate for any header translation, since we're always at the end.
mActionsContainer.setTranslationY(constrainedContentHeight - mView.getHeight()
- - getHeaderTranslation());
+ - getHeaderTranslation(false /* forceNoHeader */));
}
}
@Override
- public int getHeaderTranslation() {
- return (int) mHeaderTranslation;
+ public int getHeaderTranslation(boolean forceNoHeader) {
+ return forceNoHeader ? mFullHeaderTranslation : (int) mHeaderTranslation;
}
@Override
public void setHeaderVisibleAmount(float headerVisibleAmount) {
super.setHeaderVisibleAmount(headerVisibleAmount);
mNotificationHeader.setAlpha(headerVisibleAmount);
- mHeaderTranslation = (1.0f - headerVisibleAmount) * mTranslationForHeader;
+ mHeaderTranslation = (1.0f - headerVisibleAmount) * mFullHeaderTranslation;
mView.setTranslationY(mHeaderTranslation);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
index 3808702176a9..47906a7058a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationViewWrapper.java
@@ -224,7 +224,7 @@ public abstract class NotificationViewWrapper implements TransformableView {
return null;
}
- public int getHeaderTranslation() {
+ public int getHeaderTranslation(boolean forceNoHeader) {
return 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
index 78dc9a0a731c..f3d068a9d610 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AmbientState.java
@@ -24,7 +24,6 @@ import android.view.View;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -32,6 +31,7 @@ import com.android.systemui.statusbar.notification.row.ActivatableNotificationVi
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.ArrayList;
@@ -52,9 +52,8 @@ public class AmbientState {
private float mOverScrollTopAmount;
private float mOverScrollBottomAmount;
private int mSpeedBumpIndex = -1;
- private boolean mDark;
+ private boolean mDozing;
private boolean mHideSensitive;
- private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
private float mStackTranslation;
private int mLayoutHeight;
private int mTopPadding;
@@ -79,15 +78,19 @@ public class AmbientState {
private int mIntrinsicPadding;
private int mExpandAnimationTopChange;
private ExpandableNotificationRow mExpandingNotification;
- private float mDarkAmount;
+ private float mHideAmount;
private boolean mAppearing;
private float mPulseHeight = MAX_PULSE_HEIGHT;
private float mDozeAmount = 0.0f;
+ private HeadsUpManager mHeadUpManager;
+ private Runnable mOnPulseHeightChangedListener;
public AmbientState(
Context context,
- @NonNull SectionProvider sectionProvider) {
+ @NonNull SectionProvider sectionProvider,
+ HeadsUpManager headsUpManager) {
mSectionProvider = sectionProvider;
+ mHeadUpManager = headsUpManager;
reload(context);
}
@@ -180,23 +183,23 @@ public class AmbientState {
mDimmed = dimmed;
}
- /** In dark mode, we draw as little as possible, assuming a black background */
- public void setDark(boolean dark) {
- mDark = dark;
+ /** While dozing, we draw as little as possible, assuming a black background */
+ public void setDozing(boolean dozing) {
+ mDozing = dozing;
}
- /** Dark ratio of the status bar **/
- public void setDarkAmount(float darkAmount) {
- if (darkAmount == 1.0f && mDarkAmount != darkAmount) {
- // Whenever we are fully dark, let's reset the pulseHeight again
- mPulseHeight = MAX_PULSE_HEIGHT;
+ /** Hide ratio of the status bar **/
+ public void setHideAmount(float hidemount) {
+ if (hidemount == 1.0f && mHideAmount != hidemount) {
+ // Whenever we are fully hidden, let's reset the pulseHeight again
+ setPulseHeight(MAX_PULSE_HEIGHT);
}
- mDarkAmount = darkAmount;
+ mHideAmount = hidemount;
}
- /** Returns the dark ratio of the status bar */
- public float getDarkAmount() {
- return mDarkAmount;
+ /** Returns the hide ratio of the status bar */
+ public float getHideAmount() {
+ return mHideAmount;
}
public void setHideSensitive(boolean hideSensitive) {
@@ -217,8 +220,8 @@ public class AmbientState {
return mDimmed && !(isPulseExpanding() && mDozeAmount == 1.0f);
}
- public boolean isDark() {
- return mDark;
+ public boolean isDozing() {
+ return mDozing;
}
public boolean isHideSensitive() {
@@ -295,7 +298,7 @@ public class AmbientState {
}
public boolean isPulseExpanding() {
- return mPulseHeight != MAX_PULSE_HEIGHT && mDozeAmount != 0.0f && mDarkAmount != 1.0f;
+ return mPulseHeight != MAX_PULSE_HEIGHT && mDozeAmount != 0.0f && mHideAmount != 1.0f;
}
public boolean isShadeExpanded() {
@@ -389,8 +392,7 @@ public class AmbientState {
}
public boolean hasPulsingNotifications() {
- return mPulsing && mAmbientPulseManager != null
- && mAmbientPulseManager.hasNotifications();
+ return mPulsing && mHeadUpManager != null && mHeadUpManager.hasNotifications();
}
public void setPulsing(boolean hasPulsing) {
@@ -405,10 +407,10 @@ public class AmbientState {
}
public boolean isPulsing(NotificationEntry entry) {
- if (!mPulsing || mAmbientPulseManager == null) {
+ if (!mPulsing || mHeadUpManager == null) {
return false;
}
- return mAmbientPulseManager.isAlerting(entry.key);
+ return mHeadUpManager.isAlerting(entry.key);
}
public boolean isPanelTracking() {
@@ -461,7 +463,7 @@ public class AmbientState {
* @return whether a row is dozing and not pulsing right now
*/
public boolean isDozingAndNotPulsing(ExpandableNotificationRow row) {
- return isDark() && !isPulsing(row.getEntry());
+ return isDozing() && !isPulsing(row.getEntry());
}
public void setExpandAnimationTopChange(int expandAnimationTopChange) {
@@ -481,14 +483,15 @@ public class AmbientState {
}
/**
- * @return {@code true } when shade is completely dark: in AOD or ambient display.
+ * @return {@code true } when shade is completely hidden: in AOD, ambient display or when
+ * bypassing.
*/
- public boolean isFullyDark() {
- return mDarkAmount == 1;
+ public boolean isFullyHidden() {
+ return mHideAmount == 1;
}
- public boolean isDarkAtAll() {
- return mDarkAmount != 0;
+ public boolean isHiddenAtAll() {
+ return mHideAmount != 0;
}
public void setAppearing(boolean appearing) {
@@ -500,7 +503,20 @@ public class AmbientState {
}
public void setPulseHeight(float height) {
- mPulseHeight = height;
+ if (height != mPulseHeight) {
+ mPulseHeight = height;
+ if (mOnPulseHeightChangedListener != null) {
+ mOnPulseHeightChangedListener.run();
+ }
+ }
+ }
+
+ public float getPulseHeight() {
+ if (mPulseHeight == MAX_PULSE_HEIGHT) {
+ // If we're not pulse expanding, the height should be 0
+ return 0;
+ }
+ return mPulseHeight;
}
public void setDozeAmount(float dozeAmount) {
@@ -508,7 +524,7 @@ public class AmbientState {
mDozeAmount = dozeAmount;
if (dozeAmount == 0.0f || dozeAmount == 1.0f) {
// We woke all the way up, let's reset the pulse height
- mPulseHeight = MAX_PULSE_HEIGHT;
+ setPulseHeight(MAX_PULSE_HEIGHT);
}
}
}
@@ -520,4 +536,12 @@ public class AmbientState {
public boolean isFullyAwake() {
return mDozeAmount == 0.0f;
}
+
+ public void setOnPulseHeightChangedListener(Runnable onPulseHeightChangedListener) {
+ mOnPulseHeightChangedListener = onPulseHeightChangedListener;
+ }
+
+ public Runnable getOnPulseHeightChangedListener() {
+ return mOnPulseHeightChangedListener;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
index a471d8784c54..6cd229037462 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/AnimationFilter.java
@@ -36,7 +36,6 @@ public class AnimationFilter {
boolean animateHeight;
boolean animateTopInset;
boolean animateDimmed;
- boolean animateDark;
boolean animateHideSensitive;
boolean hasDelays;
boolean hasGoToFullShadeEvent;
@@ -89,11 +88,6 @@ public class AnimationFilter {
return this;
}
- public AnimationFilter animateDark() {
- animateDark = true;
- return this;
- }
-
public AnimationFilter animateHideSensitive() {
animateHideSensitive = true;
return this;
@@ -145,7 +139,6 @@ public class AnimationFilter {
animateHeight |= filter.animateHeight;
animateTopInset |= filter.animateTopInset;
animateDimmed |= filter.animateDimmed;
- animateDark |= filter.animateDark;
animateHideSensitive |= filter.animateHideSensitive;
hasDelays |= filter.hasDelays;
mAnimatedProperties.addAll(filter.mAnimatedProperties);
@@ -160,7 +153,6 @@ public class AnimationFilter {
animateHeight = false;
animateTopInset = false;
animateDimmed = false;
- animateDark = false;
animateHideSensitive = false;
hasDelays = false;
hasGoToFullShadeEvent = false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
index f28e556229ce..72ef7f9572a4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ExpandableViewState.java
@@ -85,7 +85,6 @@ public class ExpandableViewState extends ViewState {
public int height;
public boolean dimmed;
- public boolean dark;
public boolean hideSensitive;
public boolean belowSpeedBump;
public boolean inShelf;
@@ -121,7 +120,6 @@ public class ExpandableViewState extends ViewState {
ExpandableViewState svs = (ExpandableViewState) viewState;
height = svs.height;
dimmed = svs.dimmed;
- dark = svs.dark;
hideSensitive = svs.hideSensitive;
belowSpeedBump = svs.belowSpeedBump;
clipTopAmount = svs.clipTopAmount;
@@ -158,9 +156,6 @@ public class ExpandableViewState extends ViewState {
// apply below shelf speed bump
expandableView.setBelowSpeedBump(this.belowSpeedBump);
- // apply dark
- expandableView.setDark(this.dark, false /* animate */, 0 /* delay */);
-
// apply clipping
float oldClipTopAmount = expandableView.getClipTopAmount();
if (oldClipTopAmount != this.clipTopAmount) {
@@ -209,9 +204,6 @@ public class ExpandableViewState extends ViewState {
expandableView.setHideSensitive(this.hideSensitive, animationFilter.animateHideSensitive,
properties.delay, properties.duration);
- // start dark animation
- expandableView.setDark(this.dark, animationFilter.animateDark, properties.delay);
-
if (properties.wasAdded(child) && !hidden) {
expandableView.performAddAnimation(properties.delay, properties.duration,
false /* isHeadsUpAppear */);
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 6632ae63d944..45f7b3a5bb2a 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
@@ -567,7 +567,6 @@ public class NotificationChildrenContainer extends ViewGroup {
? parentState.zTranslation
: 0;
childState.dimmed = parentState.dimmed;
- childState.dark = parentState.dark;
childState.hideSensitive = parentState.hideSensitive;
childState.belowSpeedBump = parentState.belowSpeedBump;
childState.clipTopAmount = 0;
@@ -662,8 +661,10 @@ public class NotificationChildrenContainer extends ViewGroup {
&& !showingAsLowPriority()) {
return NUMBER_OF_CHILDREN_WHEN_CHILDREN_EXPANDED;
}
- if (mIsLowPriority || !mContainingNotification.isOnKeyguard()
- && (mContainingNotification.isExpanded() || mContainingNotification.isHeadsUp())) {
+ if (mIsLowPriority
+ || (!mContainingNotification.isOnKeyguard() && mContainingNotification.isExpanded())
+ || (mContainingNotification.isHeadsUpState()
+ && mContainingNotification.canShowHeadsUp())) {
return NUMBER_OF_CHILDREN_WHEN_SYSTEM_EXPANDED;
}
return NUMBER_OF_CHILDREN_WHEN_COLLAPSED;
@@ -1066,6 +1067,11 @@ public class NotificationChildrenContainer extends ViewGroup {
false /* likeHighPriority */);
}
+ public int getCollapsedHeightWithoutHeader() {
+ return getMinHeight(getMaxAllowedVisibleChildren(true /* forceCollapsed */),
+ false /* likeHighPriority */, 0);
+ }
+
/**
* Get the minimum Height for this group.
*
@@ -1073,10 +1079,22 @@ public class NotificationChildrenContainer extends ViewGroup {
* @param likeHighPriority if the height should be calculated as if it were not low priority
*/
private int getMinHeight(int maxAllowedVisibleChildren, boolean likeHighPriority) {
+ return getMinHeight(maxAllowedVisibleChildren, likeHighPriority, mCurrentHeaderTranslation);
+ }
+
+ /**
+ * Get the minimum Height for this group.
+ *
+ * @param maxAllowedVisibleChildren the number of children that should be visible
+ * @param likeHighPriority if the height should be calculated as if it were not low priority
+ * @param headerTranslation the translation amount of the header
+ */
+ private int getMinHeight(int maxAllowedVisibleChildren, boolean likeHighPriority,
+ int headerTranslation) {
if (!likeHighPriority && showingAsLowPriority()) {
return mNotificationHeaderLowPriority.getHeight();
}
- int minExpandHeight = mNotificationHeaderMargin + mCurrentHeaderTranslation;
+ int minExpandHeight = mNotificationHeaderMargin + headerTranslation;
int visibleChildren = 0;
boolean firstChild = true;
int childCount = mChildren.size();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index c5ab9f6049c6..422184699952 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -18,11 +18,14 @@ package com.android.systemui.statusbar.notification.stack;
import static com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout.NUM_SECTIONS;
-import com.android.systemui.statusbar.AmbientPulseManager;
+
+import android.util.MathUtils;
+
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import java.util.HashSet;
@@ -34,27 +37,26 @@ import javax.inject.Singleton;
* A class that manages the roundness for notification views
*/
@Singleton
-class NotificationRoundnessManager implements OnHeadsUpChangedListener,
- AmbientPulseManager.OnAmbientChangedListener {
+public class NotificationRoundnessManager implements OnHeadsUpChangedListener {
private final ActivatableNotificationView[] mFirstInSectionViews;
private final ActivatableNotificationView[] mLastInSectionViews;
private final ActivatableNotificationView[] mTmpFirstInSectionViews;
private final ActivatableNotificationView[] mTmpLastInSectionViews;
+ private final KeyguardBypassController mBypassController;
private boolean mExpanded;
private HashSet<ExpandableView> mAnimatedChildren;
private Runnable mRoundingChangedCallback;
private ExpandableNotificationRow mTrackedHeadsUp;
- private ActivatableNotificationView mTrackedAmbient;
private float mAppearFraction;
@Inject
- NotificationRoundnessManager(AmbientPulseManager ambientPulseManager) {
+ NotificationRoundnessManager(KeyguardBypassController keyguardBypassController) {
mFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
mLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
mTmpFirstInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
mTmpLastInSectionViews = new ActivatableNotificationView[NUM_SECTIONS];
- ambientPulseManager.addListener(this);
+ mBypassController = keyguardBypassController;
}
@Override
@@ -73,14 +75,8 @@ class NotificationRoundnessManager implements OnHeadsUpChangedListener,
}
@Override
- public void onAmbientStateChanged(NotificationEntry entry, boolean isPulsing) {
- ActivatableNotificationView row = entry.getRow();
- if (isPulsing) {
- mTrackedAmbient = row;
- } else if (mTrackedAmbient == row) {
- mTrackedAmbient = null;
- }
- updateView(row, false /* animate */);
+ public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
+ updateView(entry.getRow(), false /* animate */);
}
private void updateView(ActivatableNotificationView view, boolean animate) {
@@ -140,12 +136,12 @@ class NotificationRoundnessManager implements OnHeadsUpChangedListener,
if (isLastInSection(view, true /* include last section */) && !top) {
return 1.0f;
}
- if (view == mTrackedHeadsUp && mAppearFraction <= 0.0f) {
+ if (view == mTrackedHeadsUp) {
// If we're pushing up on a headsup the appear fraction is < 0 and it needs to still be
// rounded.
- return 1.0f;
+ return MathUtils.saturate(1.0f - mAppearFraction);
}
- if (view == mTrackedAmbient) {
+ if (view.showingPulsing() && !mBypassController.getBypassEnabled()) {
return 1.0f;
}
return 0.0f;
@@ -242,6 +238,10 @@ class NotificationRoundnessManager implements OnHeadsUpChangedListener,
}
public void setTrackingHeadsUp(ExpandableNotificationRow row) {
+ ExpandableNotificationRow previous = mTrackedHeadsUp;
mTrackedHeadsUp = row;
+ if (previous != null) {
+ updateView(previous, true /* animate */);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
index cbcfdd4b2ea7..f39ed2e89432 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSection.java
@@ -254,7 +254,7 @@ class NotificationSection {
newTop = (int) Math.ceil(firstView.getTranslationY());
}
top = Math.max(newTop, top);
- if (firstView.showingAmbientPulsing()) {
+ if (firstView.showingPulsing()) {
// If we're pulsing, the notification can actually go below!
bottom = Math.max(bottom, finalTranslationY
+ ExpandableViewState.getFinalActualHeight(firstView));
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 8fe34180203f..9e3d74b138fa 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
@@ -96,7 +96,6 @@ import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin.OnMenuEv
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.DragDownHelper.DragDownCallback;
import com.android.systemui.statusbar.EmptyShadeView;
@@ -125,10 +124,10 @@ import com.android.systemui.statusbar.notification.row.NotificationGuts;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.NotificationSnooze;
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
-import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.HeadsUpAppearanceController;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
import com.android.systemui.statusbar.phone.HeadsUpTouchHelper;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.LockscreenGestureLogger;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager.OnGroupChangeListener;
@@ -180,7 +179,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* gap is drawn between them). In this case we don't want to round their corners.
*/
private static final int DISTANCE_BETWEEN_ADJACENT_SECTIONS_PX = 1;
- private final AmbientPulseManager mAmbientPulseManager;
+ private final KeyguardBypassController mKeyguardBypassController;
private ExpandHelper mExpandHelper;
private final NotificationSwipeHelper mSwipeHelper;
@@ -267,8 +266,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private boolean mTopPaddingNeedsAnimation;
private boolean mDimmedNeedsAnimation;
private boolean mHideSensitiveNeedsAnimation;
- private boolean mDarkNeedsAnimation;
- private int mDarkAnimationOriginIndex;
private boolean mActivateNeedsAnimation;
private boolean mGoToFullShadeNeedsAnimation;
private boolean mIsExpanded = true;
@@ -409,9 +406,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private final ViewOutlineProvider mOutlineProvider = new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- if (mAmbientState.isDarkAtAll()) {
- float xProgress = mDarkXInterpolator.getInterpolation(
- (1 - mLinearDarkAmount) * mBackgroundXFactor);
+ if (mAmbientState.isHiddenAtAll()) {
+ float xProgress = mHideXInterpolator.getInterpolation(
+ (1 - mLinearHideAmount) * mBackgroundXFactor);
outline.setRoundRect(mBackgroundAnimationRect,
MathUtils.lerp(mCornerRadius / 2.0f, mCornerRadius,
xProgress));
@@ -427,14 +424,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private View mForcedScroll;
/**
- * @see #setDarkAmount(float, float)
+ * @see #setHideAmount(float, float)
*/
- private float mInterpolatedDarkAmount = 0f;
+ private float mInterpolatedHideAmount = 0f;
/**
- * @see #setDarkAmount(float, float)
+ * @see #setHideAmount(float, float)
*/
- private float mLinearDarkAmount = 0f;
+ private float mLinearHideAmount = 0f;
/**
* How fast the background scales in the X direction as a factor of the Y expansion.
@@ -469,12 +466,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private int mCornerRadius;
private int mSidePaddings;
private final Rect mBackgroundAnimationRect = new Rect();
- private int mAntiBurnInOffsetX;
private ArrayList<BiConsumer<Float, Float>> mExpandedHeightListeners = new ArrayList<>();
private int mHeadsUpInset;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
private NotificationIconAreaController mIconAreaController;
- private float mHorizontalPanelTranslation;
private final NotificationLockscreenUserManager mLockscreenUserManager =
Dependency.get(NotificationLockscreenUserManager.class);
private final Rect mTmpRect = new Rect();
@@ -495,17 +490,16 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
Dependency.get(VisualStabilityManager.class);
protected boolean mClearAllEnabled;
- private Interpolator mDarkXInterpolator = Interpolators.FAST_OUT_SLOW_IN;
+ private Interpolator mHideXInterpolator = Interpolators.FAST_OUT_SLOW_IN;
private NotificationPanelView mNotificationPanel;
private final ShadeController mShadeController = Dependency.get(ShadeController.class);
private final NotificationGutsManager
mNotificationGutsManager = Dependency.get(NotificationGutsManager.class);
private final NotificationSectionsManager mSectionsManager;
- /**
- * If the {@link NotificationShelf} should be visible when dark.
- */
private boolean mAnimateBottomOnLayout;
+ private float mLastSentAppear;
+ private float mLastSentExpandedHeight;
@Inject
public NotificationStackScrollLayout(
@@ -513,11 +507,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
AttributeSet attrs,
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowLongPress,
NotificationRoundnessManager notificationRoundnessManager,
- AmbientPulseManager ambientPulseManager,
DynamicPrivacyController dynamicPrivacyController,
ConfigurationController configurationController,
ActivityStarter activityStarter,
- StatusBarStateController statusBarStateController) {
+ StatusBarStateController statusBarStateController,
+ HeadsUpManagerPhone headsUpManager,
+ KeyguardBypassController keyguardBypassController) {
super(context, attrs, 0, 0);
Resources res = getResources();
@@ -526,8 +521,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
for (int i = 0; i < NUM_SECTIONS; i++) {
mSections[i] = new NotificationSection(this);
}
+ mRoundnessManager = notificationRoundnessManager;
- mAmbientPulseManager = ambientPulseManager;
+ mHeadsUpManager = headsUpManager;
+ mHeadsUpManager.addListener(mRoundnessManager);
+ mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
+ mKeyguardBypassController = keyguardBypassController;
mSectionsManager =
new NotificationSectionsManager(
@@ -543,8 +542,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
clearNotifications(ROWS_GENTLE, closeShade);
});
- mAmbientState = new AmbientState(context, mSectionsManager);
- mRoundnessManager = notificationRoundnessManager;
+ mAmbientState = new AmbientState(context, mSectionsManager, mHeadsUpManager);
mBgColor = context.getColor(R.color.notification_shade_background_color);
int minHeight = res.getDimensionPixelSize(R.dimen.notification_min_height);
int maxHeight = res.getDimensionPixelSize(R.dimen.notification_max_height);
@@ -563,17 +561,18 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
res.getBoolean(R.bool.config_fadeNotificationsOnDismiss);
mRoundnessManager.setAnimatedChildren(mChildrenToAddAnimated);
mRoundnessManager.setOnRoundingChangedCallback(this::invalidate);
- addOnExpandedHeightListener(mRoundnessManager::setExpanded);
+ addOnExpandedHeightChangedListener(mRoundnessManager::setExpanded);
setOutlineProvider(mOutlineProvider);
// Blocking helper manager wants to know the expanded state, update as well.
NotificationBlockingHelperManager blockingHelperManager =
Dependency.get(NotificationBlockingHelperManager.class);
- addOnExpandedHeightListener((height, unused) -> {
+ addOnExpandedHeightChangedListener((height, unused) -> {
blockingHelperManager.setNotificationShadeExpanded(height);
});
- updateWillNotDraw();
+ boolean willDraw = mShouldDrawNotificationBackground || DEBUG;
+ setWillNotDraw(!willDraw);
mBackgroundPaint.setAntiAlias(true);
if (DEBUG) {
mDebugPaint = new Paint();
@@ -632,10 +631,14 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
/**
* @return the height at which we will wake up when pulsing
*/
- public float getPulseHeight() {
+ public float getWakeUpHeight() {
ActivatableNotificationView firstChild = getFirstChildWithBackground();
if (firstChild != null) {
- return firstChild.getCollapsedHeight();
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ return firstChild.getHeadsUpHeightWithoutHeader();
+ } else {
+ return firstChild.getCollapsedHeight();
+ }
}
return 0f;
}
@@ -762,7 +765,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
if (mShouldDrawNotificationBackground
&& (mSections[0].getCurrentBounds().top
< mSections[NUM_SECTIONS - 1].getCurrentBounds().bottom
- || mAmbientState.isDark())) {
+ || mAmbientState.isDozing())) {
drawBackground(canvas);
} else if (mInHeadsUpPinnedMode || mHeadsUpAnimatingAway) {
drawHeadsUpBackground(canvas);
@@ -796,7 +799,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
canvas.drawLine(0, y, getWidth(), y, mDebugPaint);
}
canvas.drawText(Integer.toString(getMaxNegativeScrollAmount()), getWidth() - 100,
- getIntrinsicPadding() + 30, mDebugPaint);
+ getTopPadding() + 30, mDebugPaint);
canvas.drawText(Integer.toString(getMaxPositiveScrollAmount()), getWidth() - 100,
getHeight() - 30, mDebugPaint);
}
@@ -808,17 +811,17 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
int lockScreenRight = getWidth() - mSidePaddings;
int lockScreenTop = mSections[0].getCurrentBounds().top;
int lockScreenBottom = mSections[NUM_SECTIONS - 1].getCurrentBounds().bottom;
- int darkLeft = getWidth() / 2;
- int darkTop = mTopPadding;
+ int hiddenLeft = getWidth() / 2;
+ int hiddenTop = mTopPadding;
- float yProgress = 1 - mInterpolatedDarkAmount;
- float xProgress = mDarkXInterpolator.getInterpolation(
- (1 - mLinearDarkAmount) * mBackgroundXFactor);
+ float yProgress = 1 - mInterpolatedHideAmount;
+ float xProgress = mHideXInterpolator.getInterpolation(
+ (1 - mLinearHideAmount) * mBackgroundXFactor);
- int left = (int) MathUtils.lerp(darkLeft, lockScreenLeft, xProgress);
- int right = (int) MathUtils.lerp(darkLeft, lockScreenRight, xProgress);
- int top = (int) MathUtils.lerp(darkTop, lockScreenTop, yProgress);
- int bottom = (int) MathUtils.lerp(darkTop, lockScreenBottom, yProgress);
+ int left = (int) MathUtils.lerp(hiddenLeft, lockScreenLeft, xProgress);
+ int right = (int) MathUtils.lerp(hiddenLeft, lockScreenRight, xProgress);
+ int top = (int) MathUtils.lerp(hiddenTop, lockScreenTop, yProgress);
+ int bottom = (int) MathUtils.lerp(hiddenTop, lockScreenBottom, yProgress);
mBackgroundAnimationRect.set(
left,
top,
@@ -834,7 +837,13 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
break;
}
}
- if (!mAmbientState.isDark() || anySectionHasVisibleChild) {
+ boolean shouldDrawBackground;
+ if (mKeyguardBypassController.getBypassEnabled() && onKeyguard()) {
+ shouldDrawBackground = isPulseExpanding();
+ } else {
+ shouldDrawBackground = !mAmbientState.isDozing() || anySectionHasVisibleChild;
+ }
+ if (shouldDrawBackground) {
drawBackgroundRects(canvas, left, right, top, backgroundTopAnimationOffset);
}
@@ -934,7 +943,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
// Interpolate between semi-transparent notification panel background color
// and white AOD separator.
float colorInterpolation = MathUtils.smoothStep(0.4f /* start */, 1f /* end */,
- mLinearDarkAmount);
+ mLinearHideAmount);
int color = ColorUtils.blendARGB(mBgColor, Color.WHITE, colorInterpolation);
if (mCachedBackgroundColor != color) {
@@ -988,6 +997,10 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
+ public boolean isPulseExpanding() {
+ return mAmbientState.isPulseExpanding();
+ }
+
@Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
@@ -1303,7 +1316,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
stackHeight = (int) height;
}
} else {
- appearFraction = getAppearFraction(height);
+ appearFraction = calculateAppearFraction(height);
if (appearFraction >= 0) {
translationY = NotificationUtils.interpolate(getExpandTranslationStart(), 0,
appearFraction);
@@ -1326,9 +1339,26 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
requestChildrenUpdate();
}
setStackTranslation(translationY);
- for (int i = 0; i < mExpandedHeightListeners.size(); i++) {
- BiConsumer<Float, Float> listener = mExpandedHeightListeners.get(i);
- listener.accept(mExpandedHeight, appearFraction);
+ notifyAppearChangedListeners();
+ }
+
+ private void notifyAppearChangedListeners() {
+ float appear;
+ float expandAmount;
+ if (mKeyguardBypassController.getBypassEnabled() && onKeyguard()) {
+ appear = calculateAppearFractionBypass();
+ expandAmount = getPulseHeight();
+ } else {
+ appear = MathUtils.saturate(calculateAppearFraction(mExpandedHeight));
+ expandAmount = mExpandedHeight;
+ }
+ if (appear != mLastSentAppear || expandAmount != mLastSentExpandedHeight) {
+ mLastSentAppear = appear;
+ mLastSentExpandedHeight = expandAmount;
+ for (int i = 0; i < mExpandedHeightListeners.size(); i++) {
+ BiConsumer<Float, Float> listener = mExpandedHeightListeners.get(i);
+ listener.accept(expandAmount, appear);
+ }
}
}
@@ -1355,11 +1385,12 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mIsClipped = clipped;
}
- if (!mAmbientPulseManager.hasNotifications() && mAmbientState.isFullyDark()) {
- setClipBounds(null);
- } else if (mAmbientState.isDarkAtAll()) {
+ if (mAmbientState.isHiddenAtAll()) {
clipToOutline = true;
invalidateOutline();
+ if (isFullyHidden()) {
+ setClipBounds(null);
+ }
} else if (clipped) {
setClipBounds(mRequestedClipBounds);
} else {
@@ -1423,7 +1454,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
int notGoneChildCount = getNotGoneChildCount();
if (mEmptyShadeView.getVisibility() == GONE && notGoneChildCount != 0) {
if (isHeadsUpTransition()
- || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDark())) {
+ || (mHeadsUpManager.hasPinnedHeadsUp() && !mAmbientState.isDozing())) {
appearPosition = getTopHeadsUpPinnedHeight();
} else {
appearPosition = 0;
@@ -1449,7 +1480,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* @return the fraction of the appear animation that has been performed
*/
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- public float getAppearFraction(float height) {
+ public float calculateAppearFraction(float height) {
float appearEndPosition = getAppearEndPosition();
float appearStartPosition = getAppearStartPosition();
return (height - appearStartPosition)
@@ -2388,7 +2419,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
mIntrinsicContentHeight = height;
- mContentHeight = height + mTopPadding + mBottomMargin;
+ // The topPadding can be bigger than the regular padding when qs is expanded, in that
+ // state the maxPanelHeight and the contentHeight should be bigger
+ mContentHeight = height + Math.max(mIntrinsicPadding, mTopPadding) + mBottomMargin;
updateScrollability();
clampScrollPosition();
mAmbientState.setLayoutMaxHeight(mContentHeight);
@@ -2426,7 +2459,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private void updateBackground() {
// No need to update the background color if it's not being drawn.
- if (!mShouldDrawNotificationBackground || mAmbientState.isFullyDark()) {
+ if (!mShouldDrawNotificationBackground) {
return;
}
@@ -2518,12 +2551,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
int minTopPosition = 0;
NotificationSection lastSection = getLastVisibleSection();
- if (mStatusBarState != StatusBarState.KEYGUARD) {
+ boolean onKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
+ if (!onKeyguard) {
minTopPosition = (int) (mTopPadding + mStackTranslation);
} else if (lastSection == null) {
minTopPosition = mTopPadding;
}
- boolean shiftPulsingWithFirst = mAmbientPulseManager.getAllEntries().count() <= 1;
+ boolean shiftPulsingWithFirst = mHeadsUpManager.getAllEntries().count() <= 1
+ && (mAmbientState.isDozing()
+ || (mKeyguardBypassController.getBypassEnabled() && onKeyguard));
for (NotificationSection section : mSections) {
int minBottomPosition = minTopPosition;
if (section == lastSection) {
@@ -2768,12 +2804,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
*
* @param qsHeight the top padding imposed by the quick settings panel
* @param animate whether to animate the change
- * @param ignoreIntrinsicPadding if true, {@link #getIntrinsicPadding()} is ignored and
- * {@code qsHeight} is the final top padding
*/
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- public void updateTopPadding(float qsHeight, boolean animate,
- boolean ignoreIntrinsicPadding) {
+ public void updateTopPadding(float qsHeight, boolean animate) {
int topPadding = (int) qsHeight;
int minStackHeight = getLayoutMinHeight();
if (topPadding + minStackHeight > getHeight()) {
@@ -2781,8 +2814,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
} else {
mTopPaddingOverflow = 0;
}
- setTopPadding(ignoreIntrinsicPadding ? topPadding : clampPadding(topPadding),
- animate);
+ setTopPadding(topPadding, animate && !mKeyguardBypassController.getBypassEnabled());
setExpandedHeight(mExpandedHeight);
}
@@ -3218,7 +3250,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private void updateNotificationAnimationStates() {
boolean running = mAnimationsEnabled || hasPulsingNotifications();
mShelf.setAnimationsEnabled(running);
- mIconAreaController.setAnimationsEnabled(running);
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -3278,7 +3309,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
@Override
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {
- if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress) {
+ if (mIsExpanded && mAnimationsEnabled && !mChangePositionInProgress && !isFullyHidden()) {
// Generate Animations
mChildrenToAddAnimated.add(child);
if (fromMoreCard) {
@@ -3286,7 +3317,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
mNeedsAnimation = true;
}
- if (isHeadsUp(child) && mAnimationsEnabled && !mChangePositionInProgress) {
+ if (isHeadsUp(child) && mAnimationsEnabled && !mChangePositionInProgress
+ && !isFullyHidden()) {
mAddedHeadsUpChildren.add(child);
mChildrenToAddAnimated.remove(child);
}
@@ -3359,7 +3391,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
generateActivateEvent();
generateDimmedEvent();
generateHideSensitiveEvent();
- generateDarkEvent();
generateGoToFullShadeEvent();
generateViewResizeEvent();
generateGroupExpansionEvent();
@@ -3371,10 +3402,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
for (Pair<ExpandableNotificationRow, Boolean> eventPair : mHeadsUpChangeAnimations) {
ExpandableNotificationRow row = eventPair.first;
boolean isHeadsUp = eventPair.second;
+ if (isHeadsUp != row.isHeadsUp()) {
+ // For cases where we have a heads up showing and appearing again we shouldn't
+ // do the animations at all.
+ continue;
+ }
int type = AnimationEvent.ANIMATION_TYPE_HEADS_UP_OTHER;
boolean onBottom = false;
boolean pinnedAndClosed = row.isPinned() && !mIsExpanded;
- if (!mIsExpanded && !isHeadsUp) {
+ boolean performDisappearAnimation = !mIsExpanded
+ // Only animate if we still have pinned heads up, otherwise we just have the
+ // regular collapse animation of the lock screen
+ || (mKeyguardBypassController.getBypassEnabled() && onKeyguard()
+ && mHeadsUpManager.hasPinnedHeadsUp());
+ if (performDisappearAnimation && !isHeadsUp) {
type = row.wasJustClicked()
? AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK
: AnimationEvent.ANIMATION_TYPE_HEADS_UP_DISAPPEAR;
@@ -3524,7 +3565,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private void generateTopPaddingEvent() {
if (mTopPaddingNeedsAnimation) {
AnimationEvent event;
- if (mAmbientState.isDark()) {
+ if (mAmbientState.isDozing()) {
event = new AnimationEvent(null /* view */,
AnimationEvent.ANIMATION_TYPE_TOP_PADDING_CHANGED,
KeyguardSliceView.DEFAULT_ANIM_DURATION);
@@ -3574,20 +3615,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private void generateDarkEvent() {
- if (mDarkNeedsAnimation) {
- AnimationEvent ev = new AnimationEvent(null,
- AnimationEvent.ANIMATION_TYPE_DARK,
- new AnimationFilter()
- .animateDark()
- .animateY(mShelf));
- ev.darkAnimationOriginIndex = mDarkAnimationOriginIndex;
- mAnimationEvents.add(ev);
- }
- mDarkNeedsAnimation = false;
- }
-
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
private void generateGoToFullShadeEvent() {
if (mGoToFullShadeNeedsAnimation) {
mAnimationEvents.add(
@@ -4689,14 +4716,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
return mIntrinsicPadding;
}
- /**
- * @return the y position of the first notification
- */
- @ShadeViewRefactor(RefactorComponent.COORDINATOR)
- public float getNotificationsTopY() {
- return mTopPadding + getStackTranslation();
- }
-
@Override
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public boolean shouldDelayChildPressedState() {
@@ -4704,126 +4723,68 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
/**
- * See {@link AmbientState#setDark}.
+ * See {@link AmbientState#setDozing}.
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setDark(boolean dark, boolean animate, @Nullable PointF touchWakeUpScreenLocation) {
- if (mAmbientState.isDark() == dark) {
+ public void setDozing(boolean dozing, boolean animate,
+ @Nullable PointF touchWakeUpScreenLocation) {
+ if (mAmbientState.isDozing() == dozing) {
return;
}
- mAmbientState.setDark(dark);
- if (animate && mAnimationsEnabled) {
- mDarkNeedsAnimation = true;
- mDarkAnimationOriginIndex = findDarkAnimationOriginIndex(touchWakeUpScreenLocation);
- mNeedsAnimation = true;
- } else {
- setDarkAmount(dark ? 1f : 0f);
- updateBackground();
- }
+ mAmbientState.setDozing(dozing);
requestChildrenUpdate();
- updateWillNotDraw();
notifyHeightChangeListener(mShelf);
}
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void updatePanelTranslation() {
- setTranslationX(mHorizontalPanelTranslation + mAntiBurnInOffsetX * mInterpolatedDarkAmount);
- }
-
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setHorizontalPanelTranslation(float verticalPanelTranslation) {
- mHorizontalPanelTranslation = verticalPanelTranslation;
- updatePanelTranslation();
- }
-
- /**
- * Updates whether or not this Layout will perform its own custom drawing (i.e. whether or
- * not {@link #onDraw(Canvas)} is called). This method should be called whenever the
- * {@link #mAmbientState}'s dark mode is toggled.
- */
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void updateWillNotDraw() {
- boolean willDraw = mShouldDrawNotificationBackground || DEBUG;
- setWillNotDraw(!willDraw);
- }
-
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- private void setDarkAmount(float darkAmount) {
- setDarkAmount(darkAmount, darkAmount);
- }
-
/**
- * Sets the current dark amount.
+ * Sets the current hide amount.
*
- * @param linearDarkAmount The dark amount that follows linear interpoloation in the
+ * @param linearHideAmount The hide amount that follows linear interpoloation in the
* animation,
* i.e. animates from 0 to 1 or vice-versa in a linear manner.
- * @param interpolatedDarkAmount The dark amount that follows the actual interpolation of the
+ * @param interpolatedHideAmount The hide amount that follows the actual interpolation of the
* animation curve.
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setDarkAmount(float linearDarkAmount, float interpolatedDarkAmount) {
- mLinearDarkAmount = linearDarkAmount;
- mInterpolatedDarkAmount = interpolatedDarkAmount;
- boolean wasFullyDark = mAmbientState.isFullyDark();
- boolean wasDarkAtAll = mAmbientState.isDarkAtAll();
- mAmbientState.setDarkAmount(interpolatedDarkAmount);
- boolean nowFullyDark = mAmbientState.isFullyDark();
- boolean nowDarkAtAll = mAmbientState.isDarkAtAll();
- if (nowFullyDark != wasFullyDark) {
- updateContentHeight();
- if (nowFullyDark) {
- updateDarkShelfVisibility();
- }
- }
- if (!wasDarkAtAll && nowDarkAtAll) {
+ public void setHideAmount(float linearHideAmount, float interpolatedHideAmount) {
+ mLinearHideAmount = linearHideAmount;
+ mInterpolatedHideAmount = interpolatedHideAmount;
+ boolean wasFullyHidden = mAmbientState.isFullyHidden();
+ boolean wasHiddenAtAll = mAmbientState.isHiddenAtAll();
+ mAmbientState.setHideAmount(interpolatedHideAmount);
+ boolean nowFullyHidden = mAmbientState.isFullyHidden();
+ boolean nowHiddenAtAll = mAmbientState.isHiddenAtAll();
+ if (nowFullyHidden != wasFullyHidden) {
+ updateVisibility();
+ }
+ if (!wasHiddenAtAll && nowHiddenAtAll) {
resetExposedMenuView(true /* animate */, true /* animate */);
}
- if (nowFullyDark != wasFullyDark || wasDarkAtAll != nowDarkAtAll) {
+ if (nowFullyHidden != wasFullyHidden || wasHiddenAtAll != nowHiddenAtAll) {
invalidateOutline();
}
updateAlgorithmHeightAndPadding();
updateBackgroundDimming();
- updatePanelTranslation();
requestChildrenUpdate();
}
- private void updateDarkShelfVisibility() {
- DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
- if (dozeParameters.shouldControlScreenOff()) {
- mShelf.fadeInTranslating();
- }
- updateClipping();
+ private void updateVisibility() {
+ boolean shouldShow = !mAmbientState.isFullyHidden() || !onKeyguard();
+ setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- public void notifyDarkAnimationStart(boolean dark) {
- // We only swap the scaling factor if we're fully dark or fully awake to avoid
+ public void notifyHideAnimationStart(boolean hide) {
+ // We only swap the scaling factor if we're fully hidden or fully awake to avoid
// interpolation issues when playing with the power button.
- if (mInterpolatedDarkAmount == 0 || mInterpolatedDarkAmount == 1) {
- mBackgroundXFactor = dark ? 1.8f : 1.5f;
- mDarkXInterpolator = dark
+ if (mInterpolatedHideAmount == 0 || mInterpolatedHideAmount == 1) {
+ mBackgroundXFactor = hide ? 1.8f : 1.5f;
+ mHideXInterpolator = hide
? Interpolators.FAST_OUT_SLOW_IN_REVERSE
: Interpolators.FAST_OUT_SLOW_IN;
}
}
- @ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
- private int findDarkAnimationOriginIndex(@Nullable PointF screenLocation) {
- if (screenLocation == null || screenLocation.y < mTopPadding) {
- return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
- }
- if (screenLocation.y > getBottomMostNotificationBottom()) {
- return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_BELOW;
- }
- View child = getClosestChildAtRawPosition(screenLocation.x, screenLocation.y);
- if (child != null) {
- return getNotGoneIndex(child);
- } else {
- return AnimationEvent.DARK_ANIMATION_ORIGIN_INDEX_ABOVE;
- }
- }
-
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
private int getNotGoneIndex(View child) {
int count = getChildCount();
@@ -5076,13 +5037,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mAnimationFinishedRunnables.add(runnable);
}
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
- mHeadsUpManager = headsUpManager;
- mHeadsUpManager.addListener(mRoundnessManager);
- mHeadsUpManager.setAnimationStateHandler(this::setHeadsUpGoingAwayAnimationsAllowed);
- }
-
public void generateHeadsUpAnimation(NotificationEntry entry, boolean isHeadsUp) {
ExpandableNotificationRow row = entry.getHeadsUpAnimationView();
generateHeadsUpAnimation(row, isHeadsUp);
@@ -5309,7 +5263,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
boolean publicMode = mLockscreenUserManager.isAnyProfilePublicMode();
if (mHeadsUpAppearanceController != null) {
- mHeadsUpAppearanceController.setPublicMode(publicMode);
+ mHeadsUpAppearanceController.onStateChanged();
}
SysuiStatusBarStateController state = (SysuiStatusBarStateController)
@@ -5327,6 +5281,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
onUpdateRowStates();
mEntryManager.updateNotifications();
+ updateVisibility();
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
@@ -5365,12 +5320,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void setAntiBurnInOffsetX(int antiBurnInOffsetX) {
- mAntiBurnInOffsetX = antiBurnInOffsetX;
- updatePanelTranslation();
- }
-
- @ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(String.format("[%s: pulsing=%s qsCustomizerShowing=%s visibility=%s"
+ " alpha:%f scrollY:%d maxTopPadding:%d showShelfOnly=%s"
@@ -5423,18 +5372,18 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public boolean isFullyDark() {
- return mAmbientState.isFullyDark();
+ public boolean isFullyHidden() {
+ return mAmbientState.isFullyHidden();
}
/**
- * Add a listener whenever the expanded height changes. The first value passed as an argument
- * is the expanded height and the second one is the appearFraction.
+ * Add a listener whenever the expanded height changes. The first value passed as an
+ * argument is the expanded height and the second one is the appearFraction.
*
* @param listener the listener to notify.
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void addOnExpandedHeightListener(BiConsumer<Float, Float> listener) {
+ public void addOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
mExpandedHeightListeners.add(listener);
}
@@ -5442,7 +5391,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
* Stop a listener from listening to the expandedHeight.
*/
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- public void removeOnExpandedHeightListener(BiConsumer<Float, Float> listener) {
+ public void removeOnExpandedHeightChangedListener(BiConsumer<Float, Float> listener) {
mExpandedHeightListeners.remove(listener);
}
@@ -5663,12 +5612,19 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
*/
public float setPulseHeight(float height) {
mAmbientState.setPulseHeight(height);
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ notifyAppearChangedListeners();
+ }
requestChildrenUpdate();
return Math.max(0, height - mAmbientState.getInnerHeight(true /* ignorePulseHeight */));
}
+ public float getPulseHeight() {
+ return mAmbientState.getPulseHeight();
+ }
+
/**
- * Set the amount how much we're dozing. This is different from how dark the shade is, when
+ * Set the amount how much we're dozing. This is different from how hidden the shade is, when
* the notification is pulsing.
*/
public void setDozeAmount(float dozeAmount) {
@@ -5678,7 +5634,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
public void wakeUpFromPulse() {
- setPulseHeight(getPulseHeight());
+ setPulseHeight(getWakeUpHeight());
// Let's place the hidden views at the end of the pulsing notification to make sure we have
// a smooth animation
boolean firstVisibleView = true;
@@ -5714,6 +5670,20 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
}
+ public void setOnPulseHeightChangedListener(Runnable listener) {
+ mAmbientState.setOnPulseHeightChangedListener(listener);
+ }
+
+ public float calculateAppearFractionBypass() {
+ float pulseHeight = getPulseHeight();
+ float wakeUpHeight = getWakeUpHeight();
+ float dragDownAmount = pulseHeight - wakeUpHeight;
+
+ // The total distance required to fully reveal the header
+ float totalDistance = getIntrinsicPadding();
+ return MathUtils.smoothStep(0, totalDistance, dragDownAmount);
+ }
+
/**
* A listener that is notified when the empty space below the notifications is clicked on
*/
@@ -5887,9 +5857,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
.animateY()
.animateZ(),
- // ANIMATION_TYPE_DARK
- null, // Unused
-
// ANIMATION_TYPE_GO_TO_FULL_SHADE
new AnimationFilter()
.animateHeight()
@@ -5951,7 +5918,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
// ANIMATION_TYPE_EVERYTHING
new AnimationFilter()
.animateAlpha()
- .animateDark()
.animateDimmed()
.animateHideSensitive()
.animateHeight()
@@ -5983,9 +5949,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
// ANIMATION_TYPE_CHANGE_POSITION
StackStateAnimator.ANIMATION_DURATION_STANDARD,
- // ANIMATION_TYPE_DARK
- StackStateAnimator.ANIMATION_DURATION_WAKEUP,
-
// ANIMATION_TYPE_GO_TO_FULL_SHADE
StackStateAnimator.ANIMATION_DURATION_GO_TO_FULL_SHADE,
@@ -6021,19 +5984,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
static final int ANIMATION_TYPE_ACTIVATED_CHILD = 4;
static final int ANIMATION_TYPE_DIMMED = 5;
static final int ANIMATION_TYPE_CHANGE_POSITION = 6;
- static final int ANIMATION_TYPE_DARK = 7;
- static final int ANIMATION_TYPE_GO_TO_FULL_SHADE = 8;
- static final int ANIMATION_TYPE_HIDE_SENSITIVE = 9;
- static final int ANIMATION_TYPE_VIEW_RESIZE = 10;
- static final int ANIMATION_TYPE_GROUP_EXPANSION_CHANGED = 11;
- static final int ANIMATION_TYPE_HEADS_UP_APPEAR = 12;
- static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR = 13;
- static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK = 14;
- static final int ANIMATION_TYPE_HEADS_UP_OTHER = 15;
- static final int ANIMATION_TYPE_EVERYTHING = 16;
-
- static final int DARK_ANIMATION_ORIGIN_INDEX_ABOVE = -1;
- static final int DARK_ANIMATION_ORIGIN_INDEX_BELOW = -2;
+ static final int ANIMATION_TYPE_GO_TO_FULL_SHADE = 7;
+ static final int ANIMATION_TYPE_HIDE_SENSITIVE = 8;
+ static final int ANIMATION_TYPE_VIEW_RESIZE = 9;
+ static final int ANIMATION_TYPE_GROUP_EXPANSION_CHANGED = 10;
+ static final int ANIMATION_TYPE_HEADS_UP_APPEAR = 11;
+ static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR = 12;
+ static final int ANIMATION_TYPE_HEADS_UP_DISAPPEAR_CLICK = 13;
+ static final int ANIMATION_TYPE_HEADS_UP_OTHER = 14;
+ static final int ANIMATION_TYPE_EVERYTHING = 15;
final long eventStartTime;
final ExpandableView mChangingView;
@@ -6041,7 +6000,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
final AnimationFilter filter;
final long length;
View viewAfterChangingView;
- int darkAnimationOriginIndex;
boolean headsUpFromBottom;
AnimationEvent(ExpandableView view, int type) {
@@ -6296,6 +6254,15 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mAmbientState.onDragFinished(animView);
updateContinuousShadowDrawing();
updateContinuousBackgroundDrawing();
+ if (animView instanceof ExpandableNotificationRow) {
+ ExpandableNotificationRow row = (ExpandableNotificationRow) animView;
+ if (row.isPinned() && !canChildBeDismissed(row)
+ && row.getStatusBarNotification().getNotification().fullScreenIntent
+ == null) {
+ mHeadsUpManager.removeNotification(row.getStatusBarNotification().getKey(),
+ true /* removeImmediately */);
+ }
+ }
}
@Override
@@ -6346,7 +6313,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
(int) (dragLengthY / mDisplayMetrics.density),
0 /* velocityDp - N/A */);
- if (!mAmbientState.isDark() || startingChild != null) {
+ if (!mAmbientState.isDozing() || startingChild != null) {
// We have notifications, go to locked shade.
mShadeController.goToLockedShade(startingChild);
if (startingChild instanceof ExpandableNotificationRow) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 60061c6a9ad2..35ba801c75ba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -213,7 +213,6 @@ public class StackScrollAlgorithm {
private void updateDimmedActivatedHideSensitive(AmbientState ambientState,
StackScrollAlgorithmState algorithmState) {
boolean dimmed = ambientState.isDimmed();
- boolean dark = ambientState.isFullyDark();
boolean hideSensitive = ambientState.isHideSensitive();
View activatedChild = ambientState.getActivatedChild();
int childCount = algorithmState.visibleChildren.size();
@@ -221,7 +220,6 @@ public class StackScrollAlgorithm {
ExpandableView child = algorithmState.visibleChildren.get(i);
ExpandableViewState childViewState = child.getViewState();
childViewState.dimmed = dimmed;
- childViewState.dark = dark;
childViewState.hideSensitive = hideSensitive;
boolean isActivatedChild = activatedChild == child;
if (dimmed && isActivatedChild) {
@@ -255,7 +253,7 @@ public class StackScrollAlgorithm {
state.paddingMap.clear();
int notGoneIndex = 0;
ExpandableView lastView = null;
- int firstHiddenIndex = ambientState.isDark()
+ int firstHiddenIndex = ambientState.isDozing()
? (ambientState.hasPulsingNotifications() ? 1 : 0)
: childCount;
@@ -501,7 +499,7 @@ public class StackScrollAlgorithm {
continue;
}
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- if (!row.showingAmbientPulsing() || (i == 0 && ambientState.isPulseExpanding())) {
+ if (!row.showingPulsing() || (i == 0 && ambientState.isPulseExpanding())) {
continue;
}
ExpandableViewState viewState = row.getViewState();
@@ -530,7 +528,8 @@ public class StackScrollAlgorithm {
boolean isTopEntry = topHeadsUpEntry == row;
float unmodifiedEndLocation = childState.yTranslation + childState.height;
if (mIsExpanded) {
- if (row.mustStayOnScreen() && !childState.headsUpIsVisible) {
+ if (row.mustStayOnScreen() && !childState.headsUpIsVisible
+ && !row.showingPulsing()) {
// Ensure that the heads up is always visible even when scrolled off
clampHunToTop(ambientState, row, childState);
if (i == 0 && row.isAboveShelf()) {
@@ -547,12 +546,12 @@ public class StackScrollAlgorithm {
ExpandableViewState topState =
topHeadsUpEntry == null ? null : topHeadsUpEntry.getViewState();
if (topState != null && !isTopEntry && (!mIsExpanded
- || unmodifiedEndLocation < topState.yTranslation + topState.height)) {
+ || unmodifiedEndLocation > topState.yTranslation + topState.height)) {
// Ensure that a headsUp doesn't vertically extend further than the heads-up at
// the top most z-position
childState.height = row.getIntrinsicHeight();
- childState.yTranslation = topState.yTranslation + topState.height
- - childState.height;
+ childState.yTranslation = Math.min(topState.yTranslation + topState.height
+ - childState.height, childState.yTranslation);
}
// heads up notification show and this row is the top entry of heads up
@@ -667,7 +666,7 @@ public class StackScrollAlgorithm {
}
childViewState.zTranslation = baseZ
+ childrenOnTop * zDistanceBetweenElements;
- } else if (i == 0 && child.isAboveShelf()) {
+ } else if (i == 0 && (child.isAboveShelf() || child.showingPulsing())) {
// In case this is a new view that has never been measured before, we don't want to
// elevate if we are currently expanded more then the notification
int shelfHeight = ambientState.getShelf() == null ? 0 :
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
index a6f4ca54ba91..0996ff27e9a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateAnimator.java
@@ -28,6 +28,7 @@ import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.StatusBarIconView;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -174,8 +175,7 @@ public class StackStateAnimator {
|| viewState.zTranslation != child.getTranslationZ()
|| viewState.alpha != child.getAlpha()
|| viewState.height != child.getActualHeight()
- || viewState.clipTopAmount != child.getClipTopAmount()
- || viewState.dark != child.isDark())) {
+ || viewState.clipTopAmount != child.getClipTopAmount())) {
mAnimationProperties.delay = mCurrentAdditionalDelay
+ calculateChildAnimationDelay(viewState, animationStaggerCount);
}
@@ -452,7 +452,11 @@ public class StackStateAnimator {
if (row.isDismissed()) {
needsAnimation = false;
}
- StatusBarIconView icon = row.getEntry().icon;
+ NotificationEntry entry = row.getEntry();
+ StatusBarIconView icon = entry.icon;
+ if (entry.centeredIcon != null && entry.centeredIcon.getParent() != null) {
+ icon = entry.centeredIcon;
+ }
if (icon.getParent() != null) {
icon.getLocationOnScreen(mTmpLocation);
float iconPosition = mTmpLocation[0] - icon.getTranslationX()
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 4d4818d51414..05d26b0a6a17 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.IntDef;
import android.content.Context;
import android.hardware.biometrics.BiometricSourceType;
import android.metrics.LogMaker;
@@ -23,7 +24,6 @@ import android.os.Handler;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Trace;
-import android.provider.Settings;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -34,14 +34,14 @@ import com.android.keyguard.KeyguardConstants;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.Dependency;
-import com.android.systemui.R;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.tuner.TunerService;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
/**
* Controller which coordinates all the biometric unlocking actions with the UI.
@@ -53,6 +53,20 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
private static final long BIOMETRIC_WAKELOCK_TIMEOUT_MS = 15 * 1000;
private static final String BIOMETRIC_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
+ @IntDef(prefix = { "MODE_" }, value = {
+ MODE_NONE,
+ MODE_WAKE_AND_UNLOCK,
+ MODE_WAKE_AND_UNLOCK_PULSING,
+ MODE_SHOW_BOUNCER,
+ MODE_ONLY_WAKE,
+ MODE_UNLOCK_COLLAPSING,
+ MODE_UNLOCK_FADING,
+ MODE_DISMISS_BOUNCER,
+ MODE_WAKE_AND_UNLOCK_FROM_DREAM
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface WakeAndUnlockMode {}
+
/**
* Mode in which we don't need to wake up the device when we authenticate.
*/
@@ -84,38 +98,33 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
/**
* Mode in which fingerprint unlocks the device.
*/
- public static final int MODE_UNLOCK = 5;
-
- /**
- * Mode in which fingerprint brings up the bouncer because fingerprint unlocking is currently
- * not allowed.
- */
- public static final int MODE_DISMISS_BOUNCER = 6;
+ public static final int MODE_UNLOCK_COLLAPSING = 5;
/**
* Mode in which fingerprint wakes and unlocks the device from a dream.
*/
- public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 7;
+ public static final int MODE_WAKE_AND_UNLOCK_FROM_DREAM = 6;
/**
- * How much faster we collapse the lockscreen when authenticating with biometric.
+ * Faster mode of dismissing the lock screen when we cross fade to an app
+ * (used for keyguard bypass.)
*/
- private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
+ public static final int MODE_UNLOCK_FADING = 7;
/**
- * If face unlock dismisses the lock screen or keeps user on keyguard by default on this device.
+ * When bouncer is visible and will be dismissed.
*/
- private final boolean mFaceDismissesKeyguardByDefault;
+ public static final int MODE_DISMISS_BOUNCER = 8;
/**
- * If face unlock dismisses the lock screen or keeps user on keyguard for the current user.
+ * How much faster we collapse the lockscreen when authenticating with biometric.
*/
- @VisibleForTesting
- protected boolean mFaceDismissesKeyguard;
+ private static final float BIOMETRIC_COLLAPSE_SPEEDUP_FACTOR = 1.1f;
private final NotificationMediaManager mMediaManager;
private final PowerManager mPowerManager;
private final Handler mHandler;
+ private final KeyguardBypassController mKeyguardBypassController;
private PowerManager.WakeLock mWakeLock;
private final KeyguardUpdateMonitor mUpdateMonitor;
private final UnlockMethodCache mUnlockMethodCache;
@@ -133,16 +142,6 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
private boolean mPendingShowBouncer;
private boolean mHasScreenTurnedOnSinceAuthenticating;
- private final TunerService.Tunable mFaceDismissedKeyguardTunable = new TunerService.Tunable() {
- @Override
- public void onTuningChanged(String key, String newValue) {
- int defaultValue = mFaceDismissesKeyguardByDefault ? 1 : 0;
- mFaceDismissesKeyguard = Settings.Secure.getIntForUser(mContext.getContentResolver(),
- Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
- defaultValue, KeyguardUpdateMonitor.getCurrentUser()) != 0;
- }
- };
-
private final MetricsLogger mMetricsLogger = Dependency.get(MetricsLogger.class);
public BiometricUnlockController(Context context,
@@ -152,12 +151,12 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
StatusBar statusBar,
UnlockMethodCache unlockMethodCache, Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- TunerService tunerService) {
+ KeyguardBypassController keyguardBypassController) {
this(context, dozeScrimController, keyguardViewMediator, scrimController, statusBar,
- unlockMethodCache, handler, keyguardUpdateMonitor, tunerService,
+ unlockMethodCache, handler, keyguardUpdateMonitor,
context.getResources()
.getInteger(com.android.internal.R.integer.config_wakeUpDelayDoze),
- context.getResources().getBoolean(R.bool.config_faceAuthDismissesKeyguard));
+ keyguardBypassController);
}
@VisibleForTesting
@@ -168,9 +167,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
StatusBar statusBar,
UnlockMethodCache unlockMethodCache, Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- TunerService tunerService,
int wakeUpDelay,
- boolean faceDismissesKeyguard) {
+ KeyguardBypassController keyguardBypassController) {
mContext = context;
mPowerManager = context.getSystemService(PowerManager.class);
mUpdateMonitor = keyguardUpdateMonitor;
@@ -186,9 +184,8 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
mUnlockMethodCache = unlockMethodCache;
mHandler = handler;
mWakeUpDelay = wakeUpDelay;
- mFaceDismissesKeyguardByDefault = faceDismissesKeyguard;
- tunerService.addTunable(mFaceDismissedKeyguardTunable,
- Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD);
+ mKeyguardBypassController = keyguardBypassController;
+ mKeyguardBypassController.setUnlockController(this);
}
public void setStatusBarKeyguardViewManager(
@@ -260,11 +257,18 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
}
mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
.setType(MetricsEvent.TYPE_SUCCESS).setSubtype(toSubtype(biometricSourceType)));
+ boolean unlockAllowed = mKeyguardBypassController.onBiometricAuthenticated(
+ biometricSourceType);
+ if (unlockAllowed) {
+ startWakeAndUnlock(biometricSourceType);
+ }
+ }
+
+ public void startWakeAndUnlock(BiometricSourceType biometricSourceType) {
startWakeAndUnlock(calculateMode(biometricSourceType));
}
- public void startWakeAndUnlock(int mode) {
- // TODO(b/62444020): remove when this bug is fixed
+ public void startWakeAndUnlock(@WakeAndUnlockMode int mode) {
Log.v(TAG, "startWakeAndUnlock(" + mode + ")");
boolean wasDeviceInteractive = mUpdateMonitor.isDeviceInteractive();
mMode = mode;
@@ -296,19 +300,20 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
Trace.endSection();
};
- if (!delayWakeUp) {
+ if (!delayWakeUp && mMode != MODE_NONE) {
wakeUp.run();
}
switch (mMode) {
case MODE_DISMISS_BOUNCER:
- Trace.beginSection("MODE_DISMISS");
+ case MODE_UNLOCK_FADING:
+ Trace.beginSection("MODE_DISMISS_BOUNCER or MODE_UNLOCK_FADING");
mStatusBarKeyguardViewManager.notifyKeyguardAuthenticated(
false /* strongAuth */);
Trace.endSection();
break;
- case MODE_UNLOCK:
+ case MODE_UNLOCK_COLLAPSING:
case MODE_SHOW_BOUNCER:
- Trace.beginSection("MODE_UNLOCK or MODE_SHOW_BOUNCER");
+ Trace.beginSection("MODE_UNLOCK_COLLAPSING or MODE_SHOW_BOUNCER");
if (!wasDeviceInteractive) {
mPendingShowBouncer = true;
} else {
@@ -388,33 +393,38 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
return mMode;
}
- private int calculateMode(BiometricSourceType biometricSourceType) {
+ private @WakeAndUnlockMode int calculateMode(BiometricSourceType biometricSourceType) {
+ if (biometricSourceType == BiometricSourceType.FACE
+ || biometricSourceType == BiometricSourceType.IRIS) {
+ return calculateModeForPassiveAuth();
+ } else {
+ return calculateModeForFingerprint();
+ }
+ }
+
+ private @WakeAndUnlockMode int calculateModeForFingerprint() {
boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
boolean deviceDreaming = mUpdateMonitor.isDreaming();
- boolean faceStayingOnKeyguard = biometricSourceType == BiometricSourceType.FACE
- && !mFaceDismissesKeyguard;
if (!mUpdateMonitor.isDeviceInteractive()) {
if (!mStatusBarKeyguardViewManager.isShowing()) {
return MODE_ONLY_WAKE;
} else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
- return faceStayingOnKeyguard ? MODE_NONE : MODE_WAKE_AND_UNLOCK_PULSING;
+ return MODE_WAKE_AND_UNLOCK_PULSING;
} else if (unlockingAllowed || !mUnlockMethodCache.isMethodSecure()) {
return MODE_WAKE_AND_UNLOCK;
} else {
return MODE_SHOW_BOUNCER;
}
}
- if (unlockingAllowed && deviceDreaming && !faceStayingOnKeyguard) {
+ if (unlockingAllowed && deviceDreaming) {
return MODE_WAKE_AND_UNLOCK_FROM_DREAM;
}
if (mStatusBarKeyguardViewManager.isShowing()) {
- if ((mStatusBarKeyguardViewManager.isBouncerShowing()
- || mStatusBarKeyguardViewManager.isBouncerPartiallyVisible())
- && unlockingAllowed) {
+ if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
return MODE_DISMISS_BOUNCER;
} else if (unlockingAllowed) {
- return faceStayingOnKeyguard ? MODE_ONLY_WAKE : MODE_UNLOCK;
+ return MODE_UNLOCK_COLLAPSING;
} else if (!mStatusBarKeyguardViewManager.isBouncerShowing()) {
return MODE_SHOW_BOUNCER;
}
@@ -422,6 +432,49 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
return MODE_NONE;
}
+ private @WakeAndUnlockMode int calculateModeForPassiveAuth() {
+ boolean unlockingAllowed = mUpdateMonitor.isUnlockingWithBiometricAllowed();
+ boolean deviceDreaming = mUpdateMonitor.isDreaming();
+ boolean bypass = mKeyguardBypassController.getBypassEnabled();
+
+ if (!mUpdateMonitor.isDeviceInteractive()) {
+ if (!mStatusBarKeyguardViewManager.isShowing()) {
+ return bypass ? MODE_WAKE_AND_UNLOCK : MODE_ONLY_WAKE;
+ } else if (mDozeScrimController.isPulsing() && unlockingAllowed) {
+ // Let's not wake-up to lock screen when not bypassing, otherwise the notification
+ // would move as the user tried to tap it.
+ return bypass ? MODE_WAKE_AND_UNLOCK_PULSING : MODE_NONE;
+ } else {
+ if (!(mDozeScrimController.isPulsing() && !unlockingAllowed)) {
+ Log.wtf(TAG, "Face somehow arrived when the device was not interactive");
+ }
+ if (bypass) {
+ // Wake-up fading out nicely
+ return MODE_WAKE_AND_UNLOCK_PULSING;
+ } else {
+ // We could theoretically return MODE_NONE, but this means that the device
+ // would be not interactive, unlocked, and the user would not see the device
+ // state.
+ return MODE_ONLY_WAKE;
+ }
+ }
+ }
+ if (unlockingAllowed && deviceDreaming) {
+ return bypass ? MODE_WAKE_AND_UNLOCK_FROM_DREAM : MODE_ONLY_WAKE;
+ }
+ if (mStatusBarKeyguardViewManager.isShowing()) {
+ if (mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing() && unlockingAllowed) {
+ return bypass && !mKeyguardBypassController.canPlaySubtleWindowAnimations()
+ ? MODE_UNLOCK_COLLAPSING : MODE_UNLOCK_FADING;
+ } else if (unlockingAllowed) {
+ return bypass ? MODE_UNLOCK_FADING : MODE_NONE;
+ } else {
+ return bypass ? MODE_SHOW_BOUNCER : MODE_NONE;
+ }
+ }
+ return MODE_NONE;
+ }
+
@Override
public void onBiometricAuthFailed(BiometricSourceType biometricSourceType) {
mMetricsLogger.write(new LogMaker(MetricsEvent.BIOMETRIC_AUTH)
@@ -508,7 +561,7 @@ public class BiometricUnlockController extends KeyguardUpdateMonitorCallback {
* on or off.
*/
public boolean isBiometricUnlock() {
- return isWakeAndUnlock() || mMode == MODE_UNLOCK;
+ return isWakeAndUnlock() || mMode == MODE_UNLOCK_COLLAPSING || mMode == MODE_UNLOCK_FADING;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
index 58f457ed6e3a..d655b2fef411 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -35,6 +35,7 @@ import com.android.systemui.R;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
import com.android.systemui.statusbar.policy.EncryptionHelper;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -201,20 +202,21 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
}
protected int adjustDisableFlags(int state) {
+ boolean headsUpVisible = mStatusBarComponent.headsUpShouldBeVisible();
+ if (headsUpVisible) {
+ state |= DISABLE_CLOCK;
+ }
+
if (!mKeyguardMonitor.isLaunchTransitionFadingAway()
&& !mKeyguardMonitor.isKeyguardFadingAway()
- && shouldHideNotificationIcons()) {
+ && shouldHideNotificationIcons()
+ && !(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+ && headsUpVisible)) {
state |= DISABLE_NOTIFICATION_ICONS;
state |= DISABLE_SYSTEM_INFO;
state |= DISABLE_CLOCK;
}
- // In landscape, the heads up show but shouldHideNotificationIcons() return false
- // because the visual icon is in notification icon area rather than heads up's space.
- // whether the notification icon show or not, clock should hide when heads up show.
- if (mStatusBarComponent.isHeadsUpShouldBeVisible()) {
- state |= DISABLE_CLOCK;
- }
if (mNetworkController != null && EncryptionHelper.IS_DATA_ENCRYPTED) {
if (mNetworkController.hasEmergencyCryptKeeperText()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index a17e04259fe3..10b48e71005d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -22,9 +22,7 @@ import android.os.PowerManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings;
-import android.text.TextUtils;
import android.util.MathUtils;
-import android.util.SparseBooleanArray;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
@@ -35,15 +33,17 @@ import com.android.systemui.tuner.TunerService;
import java.io.PrintWriter;
-public class DozeParameters implements TunerService.Tunable {
+/**
+ * Retrieve doze information
+ */
+public class DozeParameters implements TunerService.Tunable,
+ com.android.systemui.plugins.statusbar.DozeParameters {
private static final int MAX_DURATION = 60 * 1000;
- public static final String DOZE_SENSORS_WAKE_UP_FULLY = "doze_sensors_wake_up_fully";
public static final boolean FORCE_NO_BLANKING =
SystemProperties.getBoolean("debug.force_no_blanking", false);
public static final boolean FORCE_BLANKING =
SystemProperties.getBoolean("debug.force_blanking", false);
- private static IntInOutMatcher sPickupSubtypePerformsProxMatcher;
private static DozeParameters sInstance;
private final Context mContext;
@@ -88,20 +88,6 @@ public class DozeParameters implements TunerService.Tunable {
pw.print(" getVibrateOnPickup(): "); pw.println(getVibrateOnPickup());
pw.print(" getProxCheckBeforePulse(): "); pw.println(getProxCheckBeforePulse());
pw.print(" getPickupVibrationThreshold(): "); pw.println(getPickupVibrationThreshold());
- pw.print(" getPickupSubtypePerformsProxCheck(): ");pw.println(
- dumpPickupSubtypePerformsProxCheck());
- }
-
- private String dumpPickupSubtypePerformsProxCheck() {
- // Refresh sPickupSubtypePerformsProxMatcher
- getPickupSubtypePerformsProxCheck(0);
-
- if (sPickupSubtypePerformsProxMatcher == null) {
- return "fallback: " + mContext.getResources().getBoolean(
- R.bool.doze_pickup_performs_proximity_check);
- } else {
- return "spec: " + sPickupSubtypePerformsProxMatcher.mSpec;
- }
}
public boolean getDisplayStateSupported() {
@@ -221,21 +207,8 @@ public class DozeParameters implements TunerService.Tunable {
return SystemProperties.get(propName, mContext.getString(resId));
}
- public boolean getPickupSubtypePerformsProxCheck(int subType) {
- String spec = getString("doze.pickup.proxcheck",
- R.string.doze_pickup_subtype_performs_proximity_check);
-
- if (TextUtils.isEmpty(spec)) {
- // Fall back to non-subtype based property.
- return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check);
- }
-
- if (sPickupSubtypePerformsProxMatcher == null
- || !TextUtils.equals(spec, sPickupSubtypePerformsProxMatcher.mSpec)) {
- sPickupSubtypePerformsProxMatcher = new IntInOutMatcher(spec);
- }
-
- return sPickupSubtypePerformsProxMatcher.isIn(subType);
+ public boolean getPickupPerformsProxCheck() {
+ return mContext.getResources().getBoolean(R.bool.doze_pickup_performs_proximity_check);
}
public int getPulseVisibleDurationExtended() {
@@ -254,81 +227,4 @@ public class DozeParameters implements TunerService.Tunable {
public AlwaysOnDisplayPolicy getPolicy() {
return mAlwaysOnPolicy;
}
-
- /**
- * Parses a spec of the form `1,2,3,!5,*`. The resulting object will match numbers that are
- * listed, will not match numbers that are listed with a ! prefix, and will match / not match
- * unlisted numbers depending on whether * or !* is present.
- *
- * * -> match any numbers that are not explicitly listed
- * !* -> don't match any numbers that are not explicitly listed
- * 2 -> match 2
- * !3 -> don't match 3
- *
- * It is illegal to specify:
- * - an empty spec
- * - a spec containing that are empty, or a lone !
- * - a spec for anything other than numbers or *
- * - multiple terms for the same number / multiple *s
- */
- public static class IntInOutMatcher {
- private static final String WILDCARD = "*";
- private static final char OUT_PREFIX = '!';
-
- private final SparseBooleanArray mIsIn;
- private final boolean mDefaultIsIn;
- final String mSpec;
-
- public IntInOutMatcher(String spec) {
- if (TextUtils.isEmpty(spec)) {
- throw new IllegalArgumentException("Spec must not be empty");
- }
-
- boolean defaultIsIn = false;
- boolean foundWildcard = false;
-
- mSpec = spec;
- mIsIn = new SparseBooleanArray();
-
- for (String itemPrefixed : spec.split(",", -1)) {
- if (itemPrefixed.length() == 0) {
- throw new IllegalArgumentException(
- "Illegal spec, must not have zero-length items: `" + spec + "`");
- }
- boolean isIn = itemPrefixed.charAt(0) != OUT_PREFIX;
- String item = isIn ? itemPrefixed : itemPrefixed.substring(1);
-
- if (itemPrefixed.length() == 0) {
- throw new IllegalArgumentException(
- "Illegal spec, must not have zero-length items: `" + spec + "`");
- }
-
- if (WILDCARD.equals(item)) {
- if (foundWildcard) {
- throw new IllegalArgumentException("Illegal spec, `" + WILDCARD +
- "` must not appear multiple times in `" + spec + "`");
- }
- defaultIsIn = isIn;
- foundWildcard = true;
- } else {
- int key = Integer.parseInt(item);
- if (mIsIn.indexOfKey(key) >= 0) {
- throw new IllegalArgumentException("Illegal spec, `" + key +
- "` must not appear multiple times in `" + spec + "`");
- }
- mIsIn.put(key, isIn);
- }
- }
-
- if (!foundWildcard) {
- throw new IllegalArgumentException("Illegal spec, must specify either * or !*");
- }
-
- mDefaultIsIn = defaultIsIn;
- }
-
- public boolean isIn(int value) {
- return (mIsIn.get(value, mDefaultIsIn));
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index a2438552e8af..60e381a776d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -149,6 +149,14 @@ public class DozeScrimController implements StateListener {
mHandler.removeCallbacks(mPulseOut);
}
+ /**
+ * When pulsing, cancel any timeouts that would take you out of the pulsing state.
+ */
+ public void cancelPendingPulseTimeout() {
+ mHandler.removeCallbacks(mPulseOut);
+ mHandler.removeCallbacks(mPulseOutExtended);
+ }
+
private void cancelPulsing() {
if (mPulseCallback != null) {
if (DEBUG) Log.d(TAG, "Cancel pulsing");
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 66903fa531e0..46dd5e62ddda 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.SysUiServiceProvider.getComponent;
+
import android.graphics.Point;
import android.graphics.Rect;
import android.view.DisplayCutout;
@@ -27,11 +29,16 @@ import com.android.internal.widget.ViewClippingUtil;
import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import com.android.systemui.statusbar.policy.KeyguardMonitor;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import java.util.function.BiConsumer;
@@ -56,13 +63,16 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
private final Consumer<ExpandableNotificationRow>
mSetTrackingHeadsUp = this::setTrackingHeadsUp;
private final Runnable mUpdatePanelTranslation = this::updatePanelTranslation;
- private final BiConsumer<Float, Float> mSetExpandedHeight = this::setExpandedHeight;
+ private final BiConsumer<Float, Float> mSetExpandedHeight = this::setAppearFraction;
+ private final KeyguardBypassController mBypassController;
+ private final StatusBarStateController mStatusBarStateController;
+ private final CommandQueue mCommandQueue;
@VisibleForTesting
float mExpandedHeight;
@VisibleForTesting
boolean mIsExpanded;
@VisibleForTesting
- float mExpandFraction;
+ float mAppearFraction;
private ExpandableNotificationRow mTrackedChild;
private boolean mShown;
private final View.OnLayoutChangeListener mStackScrollLayoutChangeListener =
@@ -77,13 +87,17 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
};
private boolean mAnimationsEnabled = true;
Point mPoint;
+ private KeyguardMonitor mKeyguardMonitor;
public HeadsUpAppearanceController(
NotificationIconAreaController notificationIconAreaController,
HeadsUpManagerPhone headsUpManager,
- View statusbarView) {
- this(notificationIconAreaController, headsUpManager,
+ View statusbarView,
+ SysuiStatusBarStateController statusBarStateController,
+ KeyguardBypassController keyguardBypassController) {
+ this(notificationIconAreaController, headsUpManager, statusBarStateController,
+ keyguardBypassController,
statusbarView.findViewById(R.id.heads_up_status_bar_view),
statusbarView.findViewById(R.id.notification_stack_scroller),
statusbarView.findViewById(R.id.notification_panel),
@@ -96,6 +110,8 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
public HeadsUpAppearanceController(
NotificationIconAreaController notificationIconAreaController,
HeadsUpManagerPhone headsUpManager,
+ StatusBarStateController stateController,
+ KeyguardBypassController bypassController,
HeadsUpStatusBarView headsUpStatusBarView,
NotificationStackScrollLayout stackScroller,
NotificationPanelView panelView,
@@ -114,7 +130,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
panelView.addTrackingHeadsUpListener(mSetTrackingHeadsUp);
panelView.addVerticalTranslationListener(mUpdatePanelTranslation);
panelView.setHeadsUpAppearanceController(this);
- mStackScroller.addOnExpandedHeightListener(mSetExpandedHeight);
+ mStackScroller.addOnExpandedHeightChangedListener(mSetExpandedHeight);
mStackScroller.addOnLayoutChangeListener(mStackScrollLayoutChangeListener);
mStackScroller.setHeadsUpAppearanceController(this);
mClockView = clockView;
@@ -135,6 +151,10 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
mHeadsUpStatusBarView.removeOnLayoutChangeListener(this);
}
});
+ mBypassController = bypassController;
+ mStatusBarStateController = stateController;
+ mCommandQueue = getComponent(headsUpStatusBarView.getContext(), CommandQueue.class);
+ mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
}
@@ -144,7 +164,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
mPanelView.removeTrackingHeadsUpListener(mSetTrackingHeadsUp);
mPanelView.removeVerticalTranslationListener(mUpdatePanelTranslation);
mPanelView.setHeadsUpAppearanceController(null);
- mStackScroller.removeOnExpandedHeightListener(mSetExpandedHeight);
+ mStackScroller.removeOnExpandedHeightChangedListener(mSetExpandedHeight);
mStackScroller.removeOnLayoutChangeListener(mStackScrollLayoutChangeListener);
mDarkIconDispatcher.removeDarkReceiver(this);
}
@@ -219,7 +239,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
private void updateTopEntry() {
NotificationEntry newEntry = null;
- if (!mIsExpanded && mHeadsUpManager.hasPinnedHeadsUp()) {
+ if (shouldBeVisible()) {
newEntry = mHeadsUpManager.getTopEntry();
}
NotificationEntry previousEntry = mHeadsUpStatusBarView.getShowingEntry();
@@ -342,7 +362,13 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
* @return if the heads up status bar view should be shown
*/
public boolean shouldBeVisible() {
- return !mIsExpanded && mHeadsUpManager.hasPinnedHeadsUp();
+ boolean canShow = !mIsExpanded;
+ if (mBypassController.getBypassEnabled() &&
+ (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+ || mKeyguardMonitor.isKeyguardGoingAway())) {
+ canShow = true;
+ }
+ return canShow && mHeadsUpManager.hasPinnedHeadsUp();
}
@Override
@@ -351,12 +377,24 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
updateHeader(entry);
}
- public void setExpandedHeight(float expandedHeight, float appearFraction) {
- boolean changedHeight = expandedHeight != mExpandedHeight;
+ @Override
+ public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
+ if (mStatusBarStateController.getState() != StatusBarState.SHADE) {
+ // Show the status bar icons when the pinned mode changes
+ mCommandQueue.recomputeDisableFlags(
+ mHeadsUpStatusBarView.getContext().getDisplayId(), false);
+ }
+ }
+
+ public void setAppearFraction(float expandedHeight, float appearFraction) {
+ boolean changed = expandedHeight != mExpandedHeight;
mExpandedHeight = expandedHeight;
- mExpandFraction = appearFraction;
+ mAppearFraction = appearFraction;
boolean isExpanded = expandedHeight > 0;
- if (changedHeight) {
+ // We only notify if the expandedHeight changed and not on the appearFraction, since
+ // otherwise we may run into an infinite loop where the panel and this are constantly
+ // updating themselves over just a small fraction
+ if (changed) {
updateHeadsUpHeaders();
}
if (isExpanded != mIsExpanded) {
@@ -389,8 +427,9 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
public void updateHeader(NotificationEntry entry) {
ExpandableNotificationRow row = entry.getRow();
float headerVisibleAmount = 1.0f;
- if (row.isPinned() || row.isHeadsUpAnimatingAway() || row == mTrackedChild) {
- headerVisibleAmount = mExpandFraction;
+ if (row.isPinned() || row.isHeadsUpAnimatingAway() || row == mTrackedChild
+ || row.showingPulsing()) {
+ headerVisibleAmount = mAppearFraction;
}
row.setHeaderVisibleAmount(headerVisibleAmount);
}
@@ -400,8 +439,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
mHeadsUpStatusBarView.onDarkChanged(area, darkIntensity, tint);
}
- public void setPublicMode(boolean publicMode) {
- mHeadsUpStatusBarView.setPublicMode(publicMode);
+ public void onStateChanged() {
updateTopEntry();
}
@@ -410,7 +448,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
mTrackedChild = oldController.mTrackedChild;
mExpandedHeight = oldController.mExpandedHeight;
mIsExpanded = oldController.mIsExpanded;
- mExpandFraction = oldController.mExpandFraction;
+ mAppearFraction = oldController.mAppearFraction;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index a0cda693822f..c44f953615e3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -31,7 +31,7 @@ import android.view.ViewTreeObserver;
import androidx.collection.ArraySet;
-import com.android.systemui.Dependency;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.ScreenDecorations;
@@ -50,18 +50,29 @@ import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Stack;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
/**
* A implementation of HeadsUpManager for phone and car.
*/
+@Singleton
public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
VisualStabilityManager.Callback, OnHeadsUpChangedListener,
ConfigurationController.ConfigurationListener, StateListener {
private static final String TAG = "HeadsUpManagerPhone";
- private final View mStatusBarWindowView;
- private final NotificationGroupManager mGroupManager;
- private final VisualStabilityManager mVisualStabilityManager;
- private final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+ @VisibleForTesting
+ final int mExtensionTime;
+ private final StatusBarStateController mStatusBarStateController;
+ private final KeyguardBypassController mBypassController;
+ private final int mAutoHeadsUpNotificationDecay;
+ private View mStatusBarWindowView;
+ private NotificationGroupManager mGroupManager;
+ private VisualStabilityManager mVisualStabilityManager;
+ private StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
+ @VisibleForTesting
+ int mAutoDismissNotificationDecayDozing;
private boolean mReleaseOnExpandFinish;
private int mStatusBarHeight;
@@ -70,6 +81,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
private boolean mTrackingHeadsUp;
private HashSet<String> mSwipedOutKeys = new HashSet<>();
private HashSet<NotificationEntry> mEntriesToRemoveAfterExpand = new HashSet<>();
+ private HashSet<String> mKeysToRemoveWhenLeavingKeyguard = new HashSet<>();
private ArraySet<NotificationEntry> mEntriesToRemoveWhenReorderingAllowed
= new ArraySet<>();
private boolean mIsExpanded;
@@ -101,21 +113,35 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
///////////////////////////////////////////////////////////////////////////////////////////////
// Constructor:
+ @Inject
public HeadsUpManagerPhone(@NonNull final Context context,
- @NonNull View statusBarWindowView,
- @NonNull NotificationGroupManager groupManager,
- @NonNull StatusBar bar,
- @NonNull VisualStabilityManager visualStabilityManager) {
+ StatusBarStateController statusBarStateController,
+ KeyguardBypassController bypassController) {
super(context);
+ Resources resources = mContext.getResources();
+ mAutoDismissNotificationDecayDozing = resources.getInteger(
+ R.integer.heads_up_notification_decay_dozing);
+ mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
+ mAutoHeadsUpNotificationDecay = resources.getInteger(
+ R.integer.auto_heads_up_notification_decay);
+ mStatusBarStateController = statusBarStateController;
+ mStatusBarStateController.addCallback(this);
+ mBypassController = bypassController;
+ initResources();
+ }
+
+
+ public void setUp(@NonNull View statusBarWindowView,
+ @NonNull NotificationGroupManager groupManager,
+ @NonNull StatusBar bar,
+ @NonNull VisualStabilityManager visualStabilityManager) {
mStatusBarWindowView = statusBarWindowView;
- mStatusBarTouchableRegionManager = new StatusBarTouchableRegionManager(context, this, bar,
+ mStatusBarTouchableRegionManager = new StatusBarTouchableRegionManager(mContext, this, bar,
statusBarWindowView);
mGroupManager = groupManager;
mVisualStabilityManager = visualStabilityManager;
- initResources();
-
addListener(new OnHeadsUpChangedListener() {
@Override
public void onHeadsUpPinnedModeChanged(boolean hasPinnedNotification) {
@@ -125,7 +151,6 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
mStatusBarTouchableRegionManager.updateTouchableRegion();
}
});
- Dependency.get(StatusBarStateController.class).addCallback(this);
}
public void setAnimationStateHandler(AnimationStateHandler handler) {
@@ -209,7 +234,36 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
@Override
public void onStateChanged(int newState) {
+ boolean wasKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
+ boolean isKeyguard = newState == StatusBarState.KEYGUARD;
mStatusBarState = newState;
+ if (wasKeyguard && !isKeyguard && mKeysToRemoveWhenLeavingKeyguard.size() != 0) {
+ String[] keys = mKeysToRemoveWhenLeavingKeyguard.toArray(new String[0]);
+ for (String key : keys) {
+ removeAlertEntry(key);
+ }
+ mKeysToRemoveWhenLeavingKeyguard.clear();
+ }
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ if (!isDozing) {
+ // Let's make sure all huns we got while dozing time out within the normal timeout
+ // duration. Otherwise they could get stuck for a very long time
+ for (AlertEntry entry : mAlertEntries.values()) {
+ entry.updateEntry(true /* updatePostTime */);
+ }
+ }
+ }
+
+ @Override
+ public boolean isEntryAutoHeadsUpped(String key) {
+ HeadsUpEntryPhone headsUpEntryPhone = getHeadsUpEntryPhone(key);
+ if (headsUpEntryPhone == null) {
+ return false;
+ }
+ return headsUpEntryPhone.isAutoHeadsUp();
}
/**
@@ -261,6 +315,18 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
}
}
+ /**
+ * Extends the lifetime of the currently showing pulsing notification so that the pulse lasts
+ * longer.
+ */
+ public void extendHeadsUp() {
+ HeadsUpEntryPhone topEntry = getTopHeadsUpEntryPhone();
+ if (topEntry == null) {
+ return;
+ }
+ topEntry.extendPulse();
+ }
+
///////////////////////////////////////////////////////////////////////////////////////////////
// HeadsUpManager public methods overrides:
@@ -375,14 +441,18 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
@Override
protected void onAlertEntryRemoved(AlertEntry alertEntry) {
+ mKeysToRemoveWhenLeavingKeyguard.remove(alertEntry.mEntry.key);
super.onAlertEntryRemoved(alertEntry);
mEntryPool.release((HeadsUpEntryPhone) alertEntry);
}
@Override
protected boolean shouldHeadsUpBecomePinned(NotificationEntry entry) {
- return mStatusBarState != StatusBarState.KEYGUARD && !mIsExpanded
- || super.shouldHeadsUpBecomePinned(entry);
+ boolean pin = mStatusBarState == StatusBarState.SHADE && !mIsExpanded;
+ if (mBypassController.getBypassEnabled()) {
+ pin |= mStatusBarState == StatusBarState.KEYGUARD;
+ }
+ return pin || super.shouldHeadsUpBecomePinned(entry);
}
@Override
@@ -426,6 +496,17 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
private boolean mMenuShownPinned;
+ /**
+ * If the time this entry has been on was extended
+ */
+ private boolean extended;
+
+ /**
+ * Was this entry received while on keyguard
+ */
+ private boolean mIsAutoHeadsUp;
+
+
@Override
protected boolean isSticky() {
return super.isSticky() || mMenuShownPinned;
@@ -433,14 +514,19 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
public void setEntry(@NonNull final NotificationEntry entry) {
Runnable removeHeadsUpRunnable = () -> {
- if (!mVisualStabilityManager.isReorderingAllowed()) {
+ if (!mVisualStabilityManager.isReorderingAllowed()
+ // We don't want to allow reordering while pulsing, but headsup need to
+ // time out anyway
+ && !entry.showingPulsing()) {
mEntriesToRemoveWhenReorderingAllowed.add(entry);
mVisualStabilityManager.addReorderingAllowedCallback(
HeadsUpManagerPhone.this);
- } else if (!mTrackingHeadsUp) {
- removeAlertEntry(entry.key);
- } else {
+ } else if (mTrackingHeadsUp) {
mEntriesToRemoveAfterExpand.add(entry);
+ } else if (mIsAutoHeadsUp && mStatusBarState == StatusBarState.KEYGUARD) {
+ mKeysToRemoveWhenLeavingKeyguard.add(entry.key);
+ } else {
+ removeAlertEntry(entry.key);
}
};
@@ -449,6 +535,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
@Override
public void updateEntry(boolean updatePostTime) {
+ mIsAutoHeadsUp = mEntry.isAutoHeadsUp();
super.updateEntry(updatePostTime);
if (mEntriesToRemoveAfterExpand.contains(mEntry)) {
@@ -457,6 +544,7 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
if (mEntriesToRemoveWhenReorderingAllowed.contains(mEntry)) {
mEntriesToRemoveWhenReorderingAllowed.remove(mEntry);
}
+ mKeysToRemoveWhenLeavingKeyguard.remove(mEntry.key);
}
@Override
@@ -490,6 +578,47 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
public void reset() {
super.reset();
mMenuShownPinned = false;
+ extended = false;
+ mIsAutoHeadsUp = false;
+ }
+
+ private void extendPulse() {
+ if (!extended) {
+ extended = true;
+ updateEntry(false);
+ }
+ }
+
+ @Override
+ public int compareTo(AlertEntry alertEntry) {
+ HeadsUpEntryPhone headsUpEntry = (HeadsUpEntryPhone) alertEntry;
+ boolean autoShown = isAutoHeadsUp();
+ boolean otherAutoShown = headsUpEntry.isAutoHeadsUp();
+ if (autoShown && !otherAutoShown) {
+ return 1;
+ } else if (!autoShown && otherAutoShown) {
+ return -1;
+ }
+ return super.compareTo(alertEntry);
+ }
+
+ @Override
+ protected long calculateFinishTime() {
+ return mPostTime + getDecayDuration() + (extended ? mExtensionTime : 0);
+ }
+
+ private int getDecayDuration() {
+ if (mStatusBarStateController.isDozing()) {
+ return mAutoDismissNotificationDecayDozing;
+ } else if (isAutoHeadsUp()) {
+ return getRecommendedHeadsUpTimeoutMs(mAutoHeadsUpNotificationDecay);
+ } else {
+ return getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
+ }
+ }
+
+ private boolean isAutoHeadsUp() {
+ return mIsAutoHeadsUp;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index 0b994ff46f29..21a22eccf509 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -54,7 +54,7 @@ import java.io.PrintWriter;
public class KeyguardBouncer {
private static final String TAG = "KeyguardBouncer";
- static final long BOUNCER_FACE_DELAY = 800;
+ static final long BOUNCER_FACE_DELAY = 1200;
static final float ALPHA_EXPANSION_THRESHOLD = 0.95f;
static final float EXPANSION_HIDDEN = 1f;
static final float EXPANSION_VISIBLE = 0f;
@@ -68,6 +68,7 @@ public class KeyguardBouncer {
private final Handler mHandler;
private final BouncerExpansionCallback mExpansionCallback;
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final UnlockMethodCache mUnlockMethodCache;
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@Override
@@ -95,7 +96,7 @@ public class KeyguardBouncer {
public KeyguardBouncer(Context context, ViewMediatorCallback callback,
LockPatternUtils lockPatternUtils, ViewGroup container,
DismissCallbackRegistry dismissCallbackRegistry, FalsingManager falsingManager,
- BouncerExpansionCallback expansionCallback,
+ BouncerExpansionCallback expansionCallback, UnlockMethodCache unlockMethodCache,
KeyguardUpdateMonitor keyguardUpdateMonitor, Handler handler) {
mContext = context;
mCallback = callback;
@@ -106,6 +107,7 @@ public class KeyguardBouncer {
mDismissCallbackRegistry = dismissCallbackRegistry;
mExpansionCallback = expansionCallback;
mHandler = handler;
+ mUnlockMethodCache = unlockMethodCache;
mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
}
@@ -168,7 +170,8 @@ public class KeyguardBouncer {
// Split up the work over multiple frames.
DejankUtils.removeCallbacks(mResetRunnable);
- if (mKeyguardUpdateMonitor.isFaceDetectionRunning()) {
+ if (mUnlockMethodCache.isUnlockingWithFacePossible() && !needsFullscreenBouncer()
+ && !mKeyguardUpdateMonitor.userNeedsStrongAuth()) {
mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
} else {
DejankUtils.postAfterTraversal(mShowRunnable);
@@ -342,9 +345,11 @@ public class KeyguardBouncer {
&& mExpansion == EXPANSION_VISIBLE && !isAnimatingAway();
}
- public boolean isPartiallyVisible() {
- return (mShowingSoon || (mRoot != null && mRoot.getVisibility() == View.VISIBLE))
- && mExpansion != EXPANSION_HIDDEN && !isAnimatingAway();
+ /**
+ * {@link #show(boolean)} was called but we're not showing yet.
+ */
+ public boolean willShowSoon() {
+ return mShowingSoon;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
new file mode 100644
index 000000000000..d7deedce3c2f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -0,0 +1,158 @@
+/*
+ * 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.phone
+
+import android.content.Context
+import android.content.pm.PackageManager
+import android.hardware.biometrics.BiometricSourceType
+import android.hardware.face.FaceManager
+import android.provider.Settings
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
+import com.android.systemui.statusbar.StatusBarState
+import com.android.systemui.tuner.TunerService
+import javax.inject.Inject
+import javax.inject.Singleton
+
+@Singleton
+class KeyguardBypassController {
+
+ private val unlockMethodCache: UnlockMethodCache
+ private val statusBarStateController: StatusBarStateController
+
+ /**
+ * The pending unlock type which is set if the bypass was blocked when it happened.
+ */
+ private var pendingUnlockType: BiometricSourceType? = null
+
+ lateinit var unlockController: BiometricUnlockController
+ var isPulseExpanding = false
+
+ /**
+ * If face unlock dismisses the lock screen or keeps user on keyguard for the current user.
+ */
+ var bypassEnabled: Boolean = false
+ get() = field && unlockMethodCache.isUnlockingWithFacePossible
+ private set
+
+ var bouncerShowing: Boolean = false
+ var launchingAffordance: Boolean = false
+ var qSExpanded = false
+ set(value) {
+ val changed = field != value
+ field = value
+ if (changed && !value) {
+ maybePerformPendingUnlock()
+ }
+ }
+
+ @Inject
+ constructor(context: Context, tunerService: TunerService,
+ statusBarStateController: StatusBarStateController,
+ lockscreenUserManager: NotificationLockscreenUserManager) {
+ unlockMethodCache = UnlockMethodCache.getInstance(context)
+ this.statusBarStateController = statusBarStateController
+ statusBarStateController.addCallback(object : StatusBarStateController.StateListener {
+ override fun onStateChanged(newState: Int) {
+ if (newState != StatusBarState.KEYGUARD) {
+ pendingUnlockType = null;
+ }
+ }
+ })
+ if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ return
+ }
+ val faceManager = context.getSystemService(FaceManager::class.java)
+ if (faceManager?.isHardwareDetected != true) {
+ return
+ }
+
+ val dismissByDefault = if (context.resources.getBoolean(
+ com.android.internal.R.bool.config_faceAuthDismissesKeyguard)) 1 else 0
+ tunerService.addTunable(
+ object : TunerService.Tunable {
+ override fun onTuningChanged(key: String?, newValue: String?) {
+ bypassEnabled = Settings.Secure.getIntForUser(
+ context.contentResolver,
+ Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD,
+ dismissByDefault,
+ KeyguardUpdateMonitor.getCurrentUser()) != 0
+ }
+ }, Settings.Secure.FACE_UNLOCK_DISMISSES_KEYGUARD)
+ lockscreenUserManager.addUserChangedListener { pendingUnlockType = null }
+ }
+
+ /**
+ * Notify that the biometric unlock has happened.
+ *
+ * @return false if we can not wake and unlock right now
+ */
+ fun onBiometricAuthenticated(biometricSourceType: BiometricSourceType): Boolean {
+ if (bypassEnabled) {
+ val can = canBypass()
+ if (!can && (isPulseExpanding || qSExpanded)) {
+ pendingUnlockType = biometricSourceType
+ }
+ return can
+ }
+ return true
+ }
+
+ fun maybePerformPendingUnlock() {
+ if (pendingUnlockType != null) {
+ if (onBiometricAuthenticated(pendingUnlockType!!)) {
+ unlockController.startWakeAndUnlock(pendingUnlockType)
+ pendingUnlockType = null
+ }
+ }
+ }
+
+ /**
+ * If keyguard can be dismissed because of bypass.
+ */
+ fun canBypass(): Boolean {
+ if (bypassEnabled) {
+ return when {
+ bouncerShowing -> true
+ statusBarStateController.state != StatusBarState.KEYGUARD -> false
+ launchingAffordance -> false
+ isPulseExpanding || qSExpanded -> false
+ else -> true
+ }
+ }
+ return false
+ }
+
+ /**
+ * If shorter animations should be played when unlocking.
+ */
+ fun canPlaySubtleWindowAnimations(): Boolean {
+ if (bypassEnabled) {
+ return when {
+ statusBarStateController.state != StatusBarState.KEYGUARD -> false
+ qSExpanded -> false
+ else -> true
+ }
+ }
+ return false
+ }
+
+ fun onStartedGoingToSleep() {
+ pendingUnlockType = null
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
index bc2d00f53186..179375e31dd3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java
@@ -112,6 +112,17 @@ public class KeyguardClockPositionAlgorithm {
private float mEmptyDragAmount;
/**
+ * Setting if bypass is enabled. If true the clock should always be positioned like it's dark
+ * and other minor adjustments.
+ */
+ private boolean mBypassEnabled;
+
+ /**
+ * The stackscroller padding when unlocked
+ */
+ private int mUnlockedStackScrollerPadding;
+
+ /**
* Refreshes the dimension values.
*/
public void loadDimens(Resources res) {
@@ -132,7 +143,8 @@ public class KeyguardClockPositionAlgorithm {
public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight,
float panelExpansion, int parentHeight, int keyguardStatusHeight, int clockPreferredY,
- boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount) {
+ boolean hasCustomClock, boolean hasVisibleNotifs, float dark, float emptyDragAmount,
+ boolean bypassEnabled, int unlockedStackScrollerPadding) {
mMinTopMargin = minTopMargin + mContainerTopPadding;
mMaxShadeBottom = maxShadeBottom;
mNotificationStackHeight = notificationStackHeight;
@@ -144,18 +156,24 @@ public class KeyguardClockPositionAlgorithm {
mHasVisibleNotifs = hasVisibleNotifs;
mDarkAmount = dark;
mEmptyDragAmount = emptyDragAmount;
+ mBypassEnabled = bypassEnabled;
+ mUnlockedStackScrollerPadding = unlockedStackScrollerPadding;
}
public void run(Result result) {
- final int y = getClockY();
+ final int y = getClockY(mPanelExpansion);
result.clockY = y;
result.clockAlpha = getClockAlpha(y);
- result.stackScrollerPadding = y + mKeyguardStatusHeight;
+ result.stackScrollerPadding = mBypassEnabled ? mUnlockedStackScrollerPadding
+ : y + mKeyguardStatusHeight;
+ result.stackScrollerPaddingExpanded = mBypassEnabled ? mUnlockedStackScrollerPadding
+ : getClockY(1.0f) + mKeyguardStatusHeight;
result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount);
}
public float getMinStackScrollerPadding() {
- return mMinTopMargin + mKeyguardStatusHeight + mClockNotificationsMargin;
+ return mBypassEnabled ? mUnlockedStackScrollerPadding
+ : mMinTopMargin + mKeyguardStatusHeight + mClockNotificationsMargin;
}
private int getMaxClockY() {
@@ -167,7 +185,7 @@ public class KeyguardClockPositionAlgorithm {
}
private int getExpandedPreferredClockY() {
- return (mHasCustomClock && !mHasVisibleNotifs) ? getPreferredClockY()
+ return (mHasCustomClock && (!mHasVisibleNotifs || mBypassEnabled)) ? getPreferredClockY()
: getExpandedClockPosition();
}
@@ -195,7 +213,7 @@ public class KeyguardClockPositionAlgorithm {
return (int) y;
}
- private int getClockY() {
+ private int getClockY(float panelExpansion) {
// Dark: Align the bottom edge of the clock at about half of the screen:
float clockYDark = (mHasCustomClock ? getPreferredClockY() : getMaxClockY())
+ burnInPreventionOffsetY();
@@ -205,11 +223,12 @@ public class KeyguardClockPositionAlgorithm {
float clockYBouncer = -mKeyguardStatusHeight;
// Move clock up while collapsing the shade
- float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(mPanelExpansion);
+ float shadeExpansion = Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(panelExpansion);
float clockY = MathUtils.lerp(clockYBouncer, clockYRegular, shadeExpansion);
clockYDark = MathUtils.lerp(clockYBouncer, clockYDark, shadeExpansion);
- return (int) (MathUtils.lerp(clockY, clockYDark, mDarkAmount) + mEmptyDragAmount);
+ float darkAmount = mBypassEnabled && !mHasCustomClock ? 1.0f : mDarkAmount;
+ return (int) (MathUtils.lerp(clockY, clockYDark, darkAmount) + mEmptyDragAmount);
}
/**
@@ -257,5 +276,10 @@ public class KeyguardClockPositionAlgorithm {
* The top padding of the stack scroller, in pixels.
*/
public int stackScrollerPadding;
+
+ /**
+ * The top padding of the stack scroller, in pixels when fully expanded.
+ */
+ public int stackScrollerPaddingExpanded;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
index 6111178bbac9..b11329ad0135 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissHandler.java
@@ -24,6 +24,7 @@ public interface KeyguardDismissHandler {
/**
* Executes an action that requres the screen to be unlocked, showing the keyguard if
* necessary. Does not close the notification shade (in case it was open).
+ * @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
*/
- void executeWhenUnlocked(OnDismissAction action);
+ void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
index e541e14b3d91..834d2a5ae4a0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
@@ -37,7 +37,7 @@ public class KeyguardDismissUtil implements KeyguardDismissHandler {
public KeyguardDismissUtil() {
}
- /** Sets the actual {@link DismissHandler} implementation. */
+ /** Sets the actual {@link KeyguardDismissHandler} implementation. */
public void setDismissHandler(KeyguardDismissHandler dismissHandler) {
mDismissHandler = dismissHandler;
}
@@ -46,15 +46,17 @@ public class KeyguardDismissUtil implements KeyguardDismissHandler {
* Executes an action that requires the screen to be unlocked.
*
* <p>Must be called after {@link #setDismissHandler}.
+ *
+ * @param requiresShadeOpen does the shade need to be forced open when hiding the keyguard?
*/
@Override
- public void executeWhenUnlocked(OnDismissAction action) {
+ public void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
KeyguardDismissHandler dismissHandler = mDismissHandler;
if (dismissHandler == null) {
Log.wtf(TAG, "KeyguardDismissHandler not set.");
action.onDismiss();
return;
}
- dismissHandler.executeWhenUnlocked(action);
+ dismissHandler.executeWhenUnlocked(action, requiresShadeOpen);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
new file mode 100644
index 000000000000..f4635d1270a8
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
@@ -0,0 +1,84 @@
+/*
+ * 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.phone
+
+import android.content.Context
+import android.hardware.Sensor
+import android.hardware.TriggerEvent
+import android.hardware.TriggerEventListener
+import com.android.keyguard.KeyguardUpdateMonitor
+import com.android.keyguard.KeyguardUpdateMonitorCallback
+import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.util.Assert
+import com.android.systemui.util.AsyncSensorManager
+
+class KeyguardLiftController constructor(
+ context: Context,
+ private val statusBarStateController: StatusBarStateController,
+ private val asyncSensorManager: AsyncSensorManager
+) : StatusBarStateController.StateListener, KeyguardUpdateMonitorCallback() {
+
+ private val keyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(context)
+ private val pickupSensor = asyncSensorManager.getDefaultSensor(Sensor.TYPE_PICK_UP_GESTURE)
+ private var isListening = false
+ private var bouncerVisible = false
+
+ init {
+ statusBarStateController.addCallback(this)
+ keyguardUpdateMonitor.registerCallback(this)
+ updateListeningState()
+ }
+
+ private val listener: TriggerEventListener = object : TriggerEventListener() {
+ override fun onTrigger(event: TriggerEvent?) {
+ Assert.isMainThread()
+ // Not listening anymore since trigger events unregister themselves
+ isListening = false
+ updateListeningState()
+ keyguardUpdateMonitor.requestFaceAuth()
+ }
+ }
+
+ override fun onDozingChanged(isDozing: Boolean) {
+ updateListeningState()
+ }
+
+ override fun onKeyguardBouncerChanged(bouncer: Boolean) {
+ bouncerVisible = bouncer
+ updateListeningState()
+ }
+
+ override fun onKeyguardVisibilityChanged(showing: Boolean) {
+ updateListeningState()
+ }
+
+ private fun updateListeningState() {
+ val onKeyguard = keyguardUpdateMonitor.isKeyguardVisible &&
+ !statusBarStateController.isDozing
+
+ val shouldListen = onKeyguard || bouncerVisible
+ if (shouldListen != isListening) {
+ isListening = shouldListen
+
+ if (shouldListen) {
+ asyncSensorManager.requestTriggerSensor(listener, pickupSensor)
+ } else {
+ asyncSensorManager.cancelTriggerSensor(listener, pickupSensor)
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 3d0c9e88ac9e..49afae7415ae 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -16,9 +16,9 @@
package com.android.systemui.statusbar.phone;
-import static com.android.systemui.Dependency.MAIN_HANDLER_NAME;
import static com.android.systemui.util.InjectionInflationController.VIEW_CONTEXT;
+import android.annotation.IntDef;
import android.content.Context;
import android.content.res.ColorStateList;
import android.content.res.Configuration;
@@ -28,10 +28,12 @@ import android.graphics.drawable.Animatable2;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.hardware.biometrics.BiometricSourceType;
-import android.os.Handler;
import android.os.Trace;
+import android.provider.Settings;
+import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityNodeInfo;
import androidx.annotation.Nullable;
@@ -40,16 +42,23 @@ import com.android.internal.graphics.ColorUtils;
import com.android.internal.telephony.IccCardConstants;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.KeyguardAffordanceView;
+import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.phone.ScrimController.ScrimVisibility;
import com.android.systemui.statusbar.policy.AccessibilityController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
import javax.inject.Inject;
import javax.inject.Named;
@@ -58,7 +67,9 @@ import javax.inject.Named;
*/
public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChangedListener,
StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
- UnlockMethodCache.OnUnlockMethodChangedListener {
+ UnlockMethodCache.OnUnlockMethodChangedListener,
+ NotificationWakeUpCoordinator.WakeUpListener, ViewTreeObserver.OnPreDrawListener,
+ OnHeadsUpChangedListener {
private static final int STATE_LOCKED = 0;
private static final int STATE_LOCK_OPEN = 1;
@@ -70,35 +81,49 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final AccessibilityController mAccessibilityController;
private final DockManager mDockManager;
- private final Handler mMainHandler;
private final KeyguardMonitor mKeyguardMonitor;
+ private final KeyguardBypassController mBypassController;
+ private final NotificationWakeUpCoordinator mWakeUpCoordinator;
+ private final HeadsUpManagerPhone mHeadsUpManager;
private int mLastState = 0;
+ private boolean mForceUpdate;
private boolean mTransientBiometricsError;
private boolean mIsFaceUnlockState;
private boolean mSimLocked;
private int mDensity;
private boolean mPulsing;
private boolean mDozing;
- private boolean mBouncerVisible;
private boolean mDocked;
- private boolean mLastDozing;
- private boolean mLastPulsing;
- private boolean mLastBouncerVisible;
+ private boolean mBlockUpdates;
private int mIconColor;
private float mDozeAmount;
- private int mIconRes;
- private boolean mWasPulsingOnThisFrame;
+ private boolean mBouncerShowingScrimmed;
private boolean mWakeAndUnlockRunning;
private boolean mKeyguardShowing;
private boolean mShowingLaunchAffordance;
+ private boolean mUpdatePending;
private final KeyguardMonitor.Callback mKeyguardMonitorCallback =
new KeyguardMonitor.Callback() {
@Override
public void onKeyguardShowingChanged() {
+ boolean force = false;
+ boolean wasShowing = mKeyguardShowing;
mKeyguardShowing = mKeyguardMonitor.isShowing();
- update(false /* force */);
+ if (!wasShowing && mKeyguardShowing && mBlockUpdates) {
+ mBlockUpdates = false;
+ force = true;
+ }
+ update(force);
+ }
+
+ @Override
+ public void onKeyguardFadingAwayChanged() {
+ if (!mKeyguardMonitor.isKeyguardFadingAway() && mBlockUpdates) {
+ mBlockUpdates = false;
+ update(true /* force */);
+ }
}
};
private final DockManager.DockEventListener mDockEventListener =
@@ -109,7 +134,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
|| event == DockManager.STATE_DOCKED_HIDE;
if (docked != mDocked) {
mDocked = docked;
- update(true /* force */);
+ update();
}
}
};
@@ -119,9 +144,8 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
@Override
public void onSimStateChanged(int subId, int slotId,
IccCardConstants.State simState) {
- boolean oldSimLocked = mSimLocked;
mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
- update(oldSimLocked != mSimLocked);
+ update();
}
@Override
@@ -146,9 +170,11 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
StatusBarStateController statusBarStateController,
ConfigurationController configurationController,
AccessibilityController accessibilityController,
+ KeyguardBypassController bypassController,
+ NotificationWakeUpCoordinator wakeUpCoordinator,
KeyguardMonitor keyguardMonitor,
@Nullable DockManager dockManager,
- @Named(MAIN_HANDLER_NAME) Handler mainHandler) {
+ HeadsUpManagerPhone headsUpManager) {
super(context, attrs);
mContext = context;
mUnlockMethodCache = UnlockMethodCache.getInstance(context);
@@ -156,9 +182,11 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
mAccessibilityController = accessibilityController;
mConfigurationController = configurationController;
mStatusBarStateController = statusBarStateController;
+ mBypassController = bypassController;
+ mWakeUpCoordinator = wakeUpCoordinator;
mKeyguardMonitor = keyguardMonitor;
mDockManager = dockManager;
- mMainHandler = mainHandler;
+ mHeadsUpManager = headsUpManager;
}
@Override
@@ -169,11 +197,13 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
mKeyguardMonitor.addCallback(mKeyguardMonitorCallback);
mKeyguardUpdateMonitor.registerCallback(mUpdateMonitorCallback);
mUnlockMethodCache.addListener(this);
+ mWakeUpCoordinator.addListener(this);
mSimLocked = mKeyguardUpdateMonitor.isSimPinSecure();
if (mDockManager != null) {
mDockManager.addListener(mDockEventListener);
}
onThemeChanged();
+ update();
}
@Override
@@ -183,6 +213,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
mConfigurationController.removeCallback(this);
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
mKeyguardMonitor.removeCallback(mKeyguardMonitorCallback);
+ mWakeUpCoordinator.removeFullyHiddenChangedListener(this);
mUnlockMethodCache.removeListener(this);
if (mDockManager != null) {
mDockManager.removeListener(mDockEventListener);
@@ -226,59 +257,100 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
}
public void update(boolean force) {
+ if (force) {
+ mForceUpdate = true;
+ }
+ if (!mUpdatePending) {
+ mUpdatePending = true;
+ getViewTreeObserver().addOnPreDrawListener(this);
+ }
+ }
+
+ @Override
+ public boolean onPreDraw() {
+ mUpdatePending = false;
+ getViewTreeObserver().removeOnPreDrawListener(this);
+
int state = getState();
+ int lastState = mLastState;
mIsFaceUnlockState = state == STATE_SCANNING_FACE;
- if (state != mLastState || mLastDozing != mDozing || mLastPulsing != mPulsing
- || mLastBouncerVisible != mBouncerVisible || force) {
- int iconAnimRes = getAnimationResForTransition(mLastState, state, mLastPulsing,
- mPulsing, mLastDozing, mDozing, mBouncerVisible);
- boolean isAnim = iconAnimRes != -1;
-
- int iconRes = isAnim ? iconAnimRes : getIconForState(state);
- if (iconRes != mIconRes) {
- mIconRes = iconRes;
-
- Drawable icon = mContext.getDrawable(iconRes);
- final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
- ? (AnimatedVectorDrawable) icon
- : null;
- setImageDrawable(icon, false);
- if (mIsFaceUnlockState) {
- announceForAccessibility(getContext().getString(
- R.string.accessibility_scanning_face));
- }
+ mLastState = state;
- if (animation != null && isAnim) {
- animation.forceAnimationOnUI();
- animation.clearAnimationCallbacks();
- animation.registerAnimationCallback(new Animatable2.AnimationCallback() {
- @Override
- public void onAnimationEnd(Drawable drawable) {
- if (getDrawable() == animation && state == getState()
- && doesAnimationLoop(iconAnimRes)) {
- animation.start();
- } else {
- Trace.endAsyncSection("LockIcon#Animation", state);
- }
- }
- });
- Trace.beginAsyncSection("LockIcon#Animation", state);
- animation.start();
- }
+ boolean shouldUpdate = lastState != state || mForceUpdate;
+ if (mBlockUpdates && canBlockUpdates()) {
+ shouldUpdate = false;
+ }
+ if (shouldUpdate) {
+ mForceUpdate = false;
+ @LockAnimIndex final int lockAnimIndex = getAnimationIndexForTransition(lastState,
+ state, mPulsing, mDozing);
+ boolean isAnim = lockAnimIndex != -1;
+ int iconRes = isAnim ? getThemedAnimationResId(lockAnimIndex) : getIconForState(state);
+
+ Drawable icon = mContext.getDrawable(iconRes);
+ final AnimatedVectorDrawable animation = icon instanceof AnimatedVectorDrawable
+ ? (AnimatedVectorDrawable) icon
+ : null;
+ setImageDrawable(icon, false);
+ if (mIsFaceUnlockState) {
+ announceForAccessibility(getContext().getString(
+ R.string.accessibility_scanning_face));
}
- updateDarkTint();
- mLastState = state;
- mLastDozing = mDozing;
- mLastPulsing = mPulsing;
- mLastBouncerVisible = mBouncerVisible;
+ if (animation != null && isAnim) {
+ animation.forceAnimationOnUI();
+ animation.clearAnimationCallbacks();
+ animation.registerAnimationCallback(new Animatable2.AnimationCallback() {
+ @Override
+ public void onAnimationEnd(Drawable drawable) {
+ if (getDrawable() == animation && state == getState()
+ && doesAnimationLoop(lockAnimIndex)) {
+ animation.start();
+ } else {
+ Trace.endAsyncSection("LockIcon#Animation", state);
+ }
+ }
+ });
+ Trace.beginAsyncSection("LockIcon#Animation", state);
+ animation.start();
+ }
}
+ updateDarkTint();
boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked);
boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning
|| mShowingLaunchAffordance;
- setVisibility(invisible ? INVISIBLE : VISIBLE);
+ if (mBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) {
+ if (mHeadsUpManager.isHeadsUpGoingAway()
+ || mHeadsUpManager.hasPinnedHeadsUp()
+ || (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+ && !mWakeUpCoordinator.getNotificationsFullyHidden())) {
+ invisible = true;
+ }
+ }
+ boolean wasInvisible = getVisibility() == INVISIBLE;
+ if (invisible != wasInvisible) {
+ setVisibility(invisible ? INVISIBLE : VISIBLE);
+ animate().cancel();
+ if (!invisible) {
+ setScaleX(0);
+ setScaleY(0);
+ animate()
+ .setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN)
+ .scaleX(1)
+ .scaleY(1)
+ .withLayer()
+ .setDuration(233)
+ .start();
+ }
+ }
updateClickability();
+
+ return true;
+ }
+
+ private boolean canBlockUpdates() {
+ return mKeyguardShowing || mKeyguardMonitor.isKeyguardFadingAway();
}
private void updateClickability() {
@@ -335,46 +407,97 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
return iconRes;
}
- private boolean doesAnimationLoop(int resourceId) {
- return resourceId == com.android.internal.R.anim.lock_scanning;
+ private boolean doesAnimationLoop(@LockAnimIndex int lockAnimIndex) {
+ return lockAnimIndex == SCANNING;
}
- private int getAnimationResForTransition(int oldState, int newState,
- boolean wasPulsing, boolean pulsing, boolean wasDozing, boolean dozing,
- boolean bouncerVisible) {
+ private static int getAnimationIndexForTransition(int oldState, int newState, boolean pulsing,
+ boolean dozing) {
// Never animate when screen is off
- if (dozing && !pulsing && !mWasPulsingOnThisFrame) {
+ if (dozing && !pulsing) {
return -1;
}
- boolean isError = oldState != STATE_BIOMETRICS_ERROR && newState == STATE_BIOMETRICS_ERROR;
- boolean justUnlocked = oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN;
- boolean justLocked = oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED;
- boolean nowPulsing = !wasPulsing && pulsing;
- boolean turningOn = wasDozing && !dozing && !mWasPulsingOnThisFrame;
-
- if (isError) {
- return com.android.internal.R.anim.lock_to_error;
- } else if (justUnlocked) {
- return com.android.internal.R.anim.lock_unlock;
- } else if (justLocked) {
- return com.android.internal.R.anim.lock_lock;
- } else if (newState == STATE_SCANNING_FACE && bouncerVisible) {
- return com.android.internal.R.anim.lock_scanning;
- } else if ((nowPulsing || turningOn) && newState != STATE_LOCK_OPEN) {
- return com.android.internal.R.anim.lock_in;
+ if (newState == STATE_BIOMETRICS_ERROR) {
+ return ERROR;
+ } else if (oldState != STATE_LOCK_OPEN && newState == STATE_LOCK_OPEN) {
+ return UNLOCK;
+ } else if (oldState == STATE_LOCK_OPEN && newState == STATE_LOCKED) {
+ return LOCK;
+ } else if (newState == STATE_SCANNING_FACE) {
+ return SCANNING;
}
return -1;
}
+ @Override
+ public void onFullyHiddenChanged(boolean isFullyHidden) {
+ if (mBypassController.getBypassEnabled()) {
+ update();
+ }
+ }
+
+ public void setBouncerShowingScrimmed(boolean bouncerShowing) {
+ mBouncerShowingScrimmed = bouncerShowing;
+ if (mBypassController.getBypassEnabled()) {
+ update();
+ }
+ }
+
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({ERROR, UNLOCK, LOCK, SCANNING})
+ @interface LockAnimIndex {}
+ private static final int ERROR = 0, UNLOCK = 1, LOCK = 2, SCANNING = 3;
+ private static final int[][] LOCK_ANIM_RES_IDS = new int[][] {
+ {
+ R.anim.lock_to_error,
+ R.anim.lock_unlock,
+ R.anim.lock_lock,
+ R.anim.lock_scanning
+ },
+ {
+ R.anim.lock_to_error_circular,
+ R.anim.lock_unlock_circular,
+ R.anim.lock_lock_circular,
+ R.anim.lock_scanning_circular
+ },
+ {
+ R.anim.lock_to_error_filled,
+ R.anim.lock_unlock_filled,
+ R.anim.lock_lock_filled,
+ R.anim.lock_scanning_filled
+ },
+ {
+ R.anim.lock_to_error_rounded,
+ R.anim.lock_unlock_rounded,
+ R.anim.lock_lock_rounded,
+ R.anim.lock_scanning_rounded
+ },
+ };
+
+ private int getThemedAnimationResId(@LockAnimIndex int lockAnimIndex) {
+ final String setting = TextUtils.emptyIfNull(
+ Settings.Secure.getString(getContext().getContentResolver(),
+ Settings.Secure.THEME_CUSTOMIZATION_OVERLAY_PACKAGES));
+ if (setting.contains("com.android.theme.icon_pack.circular.android")) {
+ return LOCK_ANIM_RES_IDS[1][lockAnimIndex];
+ } else if (setting.contains("com.android.theme.icon_pack.filled.android")) {
+ return LOCK_ANIM_RES_IDS[2][lockAnimIndex];
+ } else if (setting.contains("com.android.theme.icon_pack.rounded.android")) {
+ return LOCK_ANIM_RES_IDS[3][lockAnimIndex];
+ }
+ return LOCK_ANIM_RES_IDS[0][lockAnimIndex];
+ }
+
private int getState() {
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
- if (mTransientBiometricsError) {
- return STATE_BIOMETRICS_ERROR;
- } else if ((mUnlockMethodCache.canSkipBouncer() || !mKeyguardShowing) && !mSimLocked) {
+ if ((mUnlockMethodCache.canSkipBouncer() || !mKeyguardShowing
+ || mKeyguardMonitor.isKeyguardGoingAway()) && !mSimLocked) {
return STATE_LOCK_OPEN;
- } else if (updateMonitor.isFaceDetectionRunning()) {
+ } else if (mTransientBiometricsError) {
+ return STATE_BIOMETRICS_ERROR;
+ } else if (updateMonitor.isFaceDetectionRunning() && !mPulsing) {
return STATE_SCANNING_FACE;
} else {
return STATE_LOCKED;
@@ -393,12 +516,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
*/
public void setPulsing(boolean pulsing) {
mPulsing = pulsing;
- if (!mPulsing) {
- mWasPulsingOnThisFrame = true;
- mMainHandler.post(() -> {
- mWasPulsingOnThisFrame = false;
- });
- }
update();
}
@@ -416,17 +533,6 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
setImageTintList(ColorStateList.valueOf(color));
}
- /**
- * If bouncer is visible or not.
- */
- public void setBouncerVisible(boolean bouncerVisible) {
- if (mBouncerVisible == bouncerVisible) {
- return;
- }
- mBouncerVisible = bouncerVisible;
- update();
- }
-
@Override
public void onDensityOrFontScaleChanged() {
ViewGroup.LayoutParams lp = getLayoutParams();
@@ -453,11 +559,17 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
/**
* 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.
+ * @param wakeAndUnlock are we wake and unlocking
+ * @param isUnlock are we currently unlocking
*/
- public void onBiometricAuthModeChanged(boolean wakeAndUnlock) {
+ public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
if (wakeAndUnlock) {
mWakeAndUnlockRunning = true;
}
+ if (isUnlock && mBypassController.getBypassEnabled() && canBlockUpdates()) {
+ // We don't want the icon to change while we are unlocking
+ mBlockUpdates = true;
+ }
update();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 776cd4d71c94..22e3edb2bbd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -627,7 +627,7 @@ public class NavigationBarView extends FrameLayout implements
if (mOverviewProxyService.isEnabled()) {
// Force disable recents when not in legacy mode
disableRecent |= !QuickStepContract.isLegacyMode(mNavBarMode);
- if (pinningActive) {
+ if (pinningActive && !QuickStepContract.isGesturalMode(mNavBarMode)) {
disableBack = disableHome = false;
}
} else if (pinningActive) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
index 4dbd8545efb9..4d69f77e744d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
@@ -28,8 +28,6 @@ import com.android.systemui.Dependency;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.AlertingNotificationManager;
-import com.android.systemui.statusbar.AmbientPulseManager;
-import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener;
import com.android.systemui.statusbar.InflationTask;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -48,13 +46,13 @@ import javax.inject.Inject;
import javax.inject.Singleton;
/**
- * A helper class dealing with the alert interactions between {@link NotificationGroupManager},
- * {@link HeadsUpManager}, {@link AmbientPulseManager}. In particular, this class deals with keeping
+ * A helper class dealing with the alert interactions between {@link NotificationGroupManager} and
+ * {@link HeadsUpManager}. In particular, this class deals with keeping
* the correct notification in a group alerting based off the group suppression.
*/
@Singleton
public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedListener,
- OnAmbientChangedListener, StateListener {
+ StateListener {
private static final long ALERT_TRANSFER_TIMEOUT = 300;
@@ -70,8 +68,6 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
private final ArrayMap<String, PendingAlertInfo> mPendingAlerts = new ArrayMap<>();
private HeadsUpManager mHeadsUpManager;
- private final AmbientPulseManager mAmbientPulseManager =
- Dependency.get(AmbientPulseManager.class);
private final NotificationGroupManager mGroupManager =
Dependency.get(NotificationGroupManager.class);
@@ -144,10 +140,9 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
@Override
public void onGroupSuppressionChanged(NotificationGroup group, boolean suppressed) {
- AlertingNotificationManager alertManager = getActiveAlertManager();
if (suppressed) {
- if (alertManager.isAlerting(group.summary.key)) {
- handleSuppressedSummaryAlerted(group.summary, alertManager);
+ if (mHeadsUpManager.isAlerting(group.summary.key)) {
+ handleSuppressedSummaryAlerted(group.summary, mHeadsUpManager);
}
} else {
// Group summary can be null if we are no longer suppressed because the summary was
@@ -160,8 +155,8 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
// Group is no longer suppressed. We should check if we need to transfer the alert
// back to the summary now that it's no longer suppressed.
if (groupAlertEntry.mAlertSummaryOnNextAddition) {
- if (!alertManager.isAlerting(group.summary.key)) {
- alertNotificationWhenPossible(group.summary, alertManager);
+ if (!mHeadsUpManager.isAlerting(group.summary.key)) {
+ alertNotificationWhenPossible(group.summary, mHeadsUpManager);
}
groupAlertEntry.mAlertSummaryOnNextAddition = false;
} else {
@@ -172,11 +167,6 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
};
@Override
- public void onAmbientStateChanged(NotificationEntry entry, boolean isAmbient) {
- onAlertStateChanged(entry, isAmbient, mAmbientPulseManager);
- }
-
- @Override
public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
onAlertStateChanged(entry, isHeadsUp, mHeadsUpManager);
}
@@ -208,11 +198,10 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
PendingAlertInfo alertInfo = mPendingAlerts.remove(entry.key);
if (alertInfo != null) {
if (alertInfo.isStillValid()) {
- alertNotificationWhenPossible(entry, getActiveAlertManager());
+ alertNotificationWhenPossible(entry, mHeadsUpManager);
} else {
// The transfer is no longer valid. Free the content.
- entry.getRow().freeContentViewWhenSafe(
- alertInfo.mAlertManager.getContentFlag());
+ entry.getRow().freeContentViewWhenSafe(mHeadsUpManager.getContentFlag());
}
}
}
@@ -354,7 +343,6 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
if (SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime
< ALERT_TRANSFER_TIMEOUT) {
NotificationEntry summary = groupAlertEntry.mGroup.summary;
- AlertingNotificationManager alertManager = getActiveAlertManager();
if (!onlySummaryAlerts(summary)) {
return;
@@ -369,9 +357,9 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
boolean releasedChild = false;
for (int i = 0; i < children.size(); i++) {
NotificationEntry entry = children.get(i);
- if (onlySummaryAlerts(entry) && alertManager.isAlerting(entry.key)) {
+ if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.key)) {
releasedChild = true;
- alertManager.removeNotification(entry.key, true /* releaseImmediately */);
+ mHeadsUpManager.removeNotification(entry.key, true /* releaseImmediately */);
}
if (mPendingAlerts.containsKey(entry.key)) {
// This is the child that would've been removed if it was inflated.
@@ -379,10 +367,10 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
mPendingAlerts.get(entry.key).mAbortOnInflation = true;
}
}
- if (releasedChild && !alertManager.isAlerting(summary.key)) {
+ if (releasedChild && !mHeadsUpManager.isAlerting(summary.key)) {
boolean notifyImmediately = (numChildren - numPendingChildren) > 1;
if (notifyImmediately) {
- alertNotificationWhenPossible(summary, alertManager);
+ alertNotificationWhenPossible(summary, mHeadsUpManager);
} else {
// Should wait until the pending child inflates before alerting.
groupAlertEntry.mAlertSummaryOnNextAddition = true;
@@ -403,7 +391,7 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
@NonNull AlertingNotificationManager alertManager) {
@InflationFlag int contentFlag = alertManager.getContentFlag();
if (!entry.getRow().isInflationFlagSet(contentFlag)) {
- mPendingAlerts.put(entry.key, new PendingAlertInfo(entry, alertManager));
+ mPendingAlerts.put(entry.key, new PendingAlertInfo(entry));
entry.getRow().updateInflationFlag(contentFlag, true /* shouldInflate */);
entry.getRow().inflateViews();
return;
@@ -415,10 +403,6 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
}
}
- private AlertingNotificationManager getActiveAlertManager() {
- return mIsDozing ? mAmbientPulseManager : mHeadsUpManager;
- }
-
private boolean onlySummaryAlerts(NotificationEntry entry) {
return entry.notification.getNotification().getGroupAlertBehavior()
== Notification.GROUP_ALERT_SUMMARY;
@@ -429,10 +413,6 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
* inflation completes.
*/
private class PendingAlertInfo {
- /**
- * The alert manager when the transfer is initiated.
- */
- final AlertingNotificationManager mAlertManager;
/**
* The original notification when the transfer is initiated. This is used to determine if
@@ -450,10 +430,9 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
*/
boolean mAbortOnInflation;
- PendingAlertInfo(NotificationEntry entry, AlertingNotificationManager alertManager) {
+ PendingAlertInfo(NotificationEntry entry) {
mOriginalNotification = entry.notification;
mEntry = entry;
- mAlertManager = alertManager;
}
/**
@@ -466,10 +445,6 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
// Notification is aborted due to the transfer being explicitly cancelled
return false;
}
- if (mAlertManager != getActiveAlertManager()) {
- // Alert manager has changed
- return false;
- }
if (mEntry.notification.getGroupKey() != mOriginalNotification.getGroupKey()) {
// Groups have changed
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index cc8af3ba64fc..0bbfbefb7883 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -24,8 +24,6 @@ import android.util.Log;
import com.android.systemui.Dependency;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.AmbientPulseManager;
-import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -46,8 +44,7 @@ import javax.inject.Singleton;
* A class to handle notifications and their corresponding groups.
*/
@Singleton
-public class NotificationGroupManager implements OnHeadsUpChangedListener,
- OnAmbientChangedListener, StateListener {
+public class NotificationGroupManager implements OnHeadsUpChangedListener, StateListener {
private static final String TAG = "NotificationGroupManager";
private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
@@ -55,12 +52,11 @@ public class NotificationGroupManager implements OnHeadsUpChangedListener,
private int mBarState = -1;
private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
private HeadsUpManager mHeadsUpManager;
- private AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
private boolean mIsUpdatingUnchangedGroup;
@Inject
- public NotificationGroupManager() {
- Dependency.get(StatusBarStateController.class).addCallback(this);
+ public NotificationGroupManager(StatusBarStateController statusBarStateController) {
+ statusBarStateController.addCallback(this);
}
/**
@@ -439,23 +435,6 @@ public class NotificationGroupManager implements OnHeadsUpChangedListener,
}
@Override
- public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
- }
-
- @Override
- public void onHeadsUpPinned(NotificationEntry entry) {
- }
-
- @Override
- public void onHeadsUpUnPinned(NotificationEntry entry) {
- }
-
- @Override
- public void onAmbientStateChanged(NotificationEntry entry, boolean isAmbient) {
- onAlertStateChanged(entry, isAmbient);
- }
-
- @Override
public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
onAlertStateChanged(entry, isHeadsUp);
}
@@ -485,7 +464,7 @@ public class NotificationGroupManager implements OnHeadsUpChangedListener,
if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) {
return false;
}
- if (!mHeadsUpManager.isAlerting(entry.key) && !mAmbientPulseManager.isAlerting(entry.key)) {
+ if (!mHeadsUpManager.isAlerting(entry.key)) {
return false;
}
return (sbn.getNotification().fullScreenIntent != null
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index f52becaf7b00..d2159ca15b24 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -4,6 +4,7 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
+import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -12,23 +13,26 @@ import android.widget.FrameLayout;
import androidx.annotation.NonNull;
import androidx.collection.ArrayMap;
-import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.internal.util.ContrastColorUtil;
+import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
+import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.StatusBarIconView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.tuner.TunerService;
import java.util.ArrayList;
import java.util.Objects;
@@ -39,16 +43,22 @@ import java.util.function.Function;
* normally reserved for notifications.
*/
public class NotificationIconAreaController implements DarkReceiver,
- StatusBarStateController.StateListener {
+ StatusBarStateController.StateListener,
+ NotificationWakeUpCoordinator.WakeUpListener {
public static final String HIGH_PRIORITY = "high_priority";
+ private static final long AOD_ICONS_APPEAR_DURATION = 200;
private final ContrastColorUtil mContrastColorUtil;
private final NotificationEntryManager mEntryManager;
private final Runnable mUpdateStatusBarIcons = this::updateStatusBarIcons;
private final StatusBarStateController mStatusBarStateController;
private final NotificationMediaManager mMediaManager;
+ private final NotificationWakeUpCoordinator mWakeUpCoordinator;
+ private final KeyguardBypassController mBypassController;
+ private final DozeParameters mDozeParameters;
+ private boolean mShowSilentOnLockscreen = true;
private int mIconSize;
private int mIconHPadding;
private int mIconTint = Color.WHITE;
@@ -60,20 +70,22 @@ public class NotificationIconAreaController implements DarkReceiver,
private NotificationIconContainer mShelfIcons;
protected View mCenteredIconArea;
private NotificationIconContainer mCenteredIcon;
+ private NotificationIconContainer mAodIcons;
private StatusBarIconView mCenteredIconView;
private final Rect mTintArea = new Rect();
private ViewGroup mNotificationScrollLayout;
private Context mContext;
- private boolean mFullyDark;
- private boolean mAnimationsEnabled;
+ private int mAodIconAppearTranslation;
- /**
- * Ratio representing being awake or in ambient mode, where 1 is dark and 0 awake.
- */
- private float mDarkAmount;
+ private boolean mAnimationsEnabled;
+ private int mAodIconTint;
+ private boolean mFullyHidden;
+ private boolean mAodIconsVisible;
public NotificationIconAreaController(Context context, StatusBar statusBar,
StatusBarStateController statusBarStateController,
+ NotificationWakeUpCoordinator wakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
NotificationMediaManager notificationMediaManager) {
mStatusBar = statusBar;
mContrastColorUtil = ContrastColorUtil.getInstance(context);
@@ -82,8 +94,18 @@ public class NotificationIconAreaController implements DarkReceiver,
mStatusBarStateController = statusBarStateController;
mStatusBarStateController.addCallback(this);
mMediaManager = notificationMediaManager;
+ mDozeParameters = DozeParameters.getInstance(mContext);
+ mWakeUpCoordinator = wakeUpCoordinator;
+ wakeUpCoordinator.addListener(this);
+ mBypassController = keyguardBypassController;
initializeNotificationAreaViews(context);
+ reloadAodColor();
+
+ TunerService tunerService = Dependency.get(TunerService.class);
+ tunerService.addTunable((key, newValue) -> {
+ mShowSilentOnLockscreen = "1".equals(newValue);
+ }, Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS);
}
protected View inflateIconArea(LayoutInflater inflater) {
@@ -104,6 +126,24 @@ public class NotificationIconAreaController implements DarkReceiver,
mCenteredIconArea = layoutInflater.inflate(R.layout.center_icon_area, null);
mCenteredIcon = mCenteredIconArea.findViewById(R.id.centeredIcon);
+
+ initAodIcons();
+ }
+
+ public void initAodIcons() {
+ boolean changed = mAodIcons != null;
+ if (changed) {
+ mAodIcons.setAnimationsEnabled(false);
+ mAodIcons.removeAllViews();
+ }
+ mAodIcons = mStatusBar.getStatusBarWindow().findViewById(
+ R.id.clock_notification_icon_container);
+ mAodIcons.setOnLockScreen(true);
+ updateAodIconsVisibility(false /* animate */);
+ updateAnimations();
+ if (changed) {
+ updateAodNotificationIcons();
+ }
}
public void setupShelf(NotificationShelf shelf) {
@@ -126,6 +166,10 @@ public class NotificationIconAreaController implements DarkReceiver,
View child = mCenteredIcon.getChildAt(i);
child.setLayoutParams(params);
}
+ for (int i = 0; i < mAodIcons.getChildCount(); i++) {
+ View child = mAodIcons.getChildAt(i);
+ child.setLayoutParams(params);
+ }
}
@NonNull
@@ -138,6 +182,8 @@ public class NotificationIconAreaController implements DarkReceiver,
Resources res = context.getResources();
mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size);
mIconHPadding = res.getDimensionPixelSize(R.dimen.status_bar_icon_padding);
+ mAodIconAppearTranslation = res.getDimensionPixelSize(
+ R.dimen.shelf_appear_translation);
}
/**
@@ -193,11 +239,16 @@ public class NotificationIconAreaController implements DarkReceiver,
protected boolean shouldShowNotificationIcon(NotificationEntry entry,
boolean showAmbient, boolean showLowPriority, boolean hideDismissed,
- boolean hideRepliedMessages, boolean hideCurrentMedia, boolean hideCenteredIcon) {
+ boolean hideRepliedMessages, boolean hideCurrentMedia, boolean hideCenteredIcon,
+ boolean hidePulsing, boolean onlyShowCenteredIcon) {
- final boolean isCenteredNotificationIcon = entry.centeredIcon != null
+ final boolean isCenteredNotificationIcon = mCenteredIconView != null
+ && entry.centeredIcon != null
&& Objects.equals(entry.centeredIcon, mCenteredIconView);
- if (hideCenteredIcon == isCenteredNotificationIcon) {
+ if (onlyShowCenteredIcon) {
+ return isCenteredNotificationIcon;
+ }
+ if (hideCenteredIcon && isCenteredNotificationIcon && !entry.isRowHeadsUp()) {
return false;
}
if (mEntryManager.getNotificationData().isAmbient(entry.key) && !showAmbient) {
@@ -222,7 +273,10 @@ public class NotificationIconAreaController implements DarkReceiver,
return false;
}
// showAmbient == show in shade but not shelf
- if ((!showAmbient || mFullyDark) && entry.shouldSuppressStatusBar()) {
+ if (!showAmbient && entry.shouldSuppressStatusBar()) {
+ return false;
+ }
+ if (hidePulsing && entry.showingPulsing()) {
return false;
}
return true;
@@ -235,6 +289,7 @@ public class NotificationIconAreaController implements DarkReceiver,
updateStatusBarIcons();
updateShelfIcons();
updateCenterIcon();
+ updateAodNotificationIcons();
applyNotificationIconsTint();
}
@@ -244,9 +299,11 @@ public class NotificationIconAreaController implements DarkReceiver,
true /* showAmbient */,
true /* showLowPriority */,
false /* hideDismissed */,
- mFullyDark /* hideRepliedMessages */,
- mFullyDark /* hideCurrentMedia */,
- true /* hide centered icon */);
+ false /* hideRepliedMessages */,
+ false /* hideCurrentMedia */,
+ false /* hide centered icon */,
+ false /* hidePulsing */,
+ false /* onlyShowCenteredIcon */);
}
public void updateStatusBarIcons() {
@@ -256,7 +313,9 @@ public class NotificationIconAreaController implements DarkReceiver,
true /* hideDismissed */,
true /* hideRepliedMessages */,
false /* hideCurrentMedia */,
- true /* hide centered icon */);
+ true /* hide centered icon */,
+ false /* hidePulsing */,
+ false /* onlyShowCenteredIcon */);
}
private void updateCenterIcon() {
@@ -265,27 +324,22 @@ public class NotificationIconAreaController implements DarkReceiver,
true /* showLowPriority */,
false /* hideDismissed */,
false /* hideRepliedMessages */,
- mFullyDark /* hideCurrentMedia */,
- false /* hide centered icon */);
- }
-
- /**
- * If icons of the status bar should animate when they are added or removed.
- */
- public void setAnimationsEnabled(boolean enabled) {
- mAnimationsEnabled = enabled;
- updateAnimations();
- }
-
- @Override
- public void onStateChanged(int newState) {
- updateAnimations();
+ false /* hideCurrentMedia */,
+ false /* hide centered icon */,
+ false /* hidePulsing */,
+ true/* onlyShowCenteredIcon */);
}
- private void updateAnimations() {
- boolean inShade = mStatusBarStateController.getState() == StatusBarState.SHADE;
- mCenteredIcon.setAnimationsEnabled(mAnimationsEnabled && inShade);
- mNotificationIcons.setAnimationsEnabled(mAnimationsEnabled && inShade);
+ public void updateAodNotificationIcons() {
+ updateIconsForLayout(entry -> entry.aodIcon, mAodIcons,
+ false /* showAmbient */,
+ mShowSilentOnLockscreen /* showLowPriority */,
+ true /* hideDismissed */,
+ true /* hideRepliedMessages */,
+ true /* hideCurrentMedia */,
+ true /* hide centered icon */,
+ mBypassController.getBypassEnabled() /* hidePulsing */,
+ false /* onlyShowCenteredIcon */);
}
/**
@@ -296,11 +350,12 @@ public class NotificationIconAreaController implements DarkReceiver,
* @param showAmbient should ambient notification icons be shown
* @param hideDismissed should dismissed icons be hidden
* @param hideRepliedMessages should messages that have been replied to be hidden
+ * @param hidePulsing should pulsing notifications be hidden
*/
private void updateIconsForLayout(Function<NotificationEntry, StatusBarIconView> function,
NotificationIconContainer hostLayout, boolean showAmbient, boolean showLowPriority,
boolean hideDismissed, boolean hideRepliedMessages, boolean hideCurrentMedia,
- boolean hideCenteredIcon) {
+ boolean hideCenteredIcon, boolean hidePulsing, boolean onlyShowCenteredIcon) {
ArrayList<StatusBarIconView> toShow = new ArrayList<>(
mNotificationScrollLayout.getChildCount());
@@ -310,7 +365,8 @@ public class NotificationIconAreaController implements DarkReceiver,
if (view instanceof ExpandableNotificationRow) {
NotificationEntry ent = ((ExpandableNotificationRow) view).getEntry();
if (shouldShowNotificationIcon(ent, showAmbient, showLowPriority, hideDismissed,
- hideRepliedMessages, hideCurrentMedia, hideCenteredIcon)) {
+ hideRepliedMessages, hideCurrentMedia, hideCenteredIcon, hidePulsing,
+ onlyShowCenteredIcon)) {
StatusBarIconView iconView = function.apply(ent);
if (iconView != null) {
toShow.add(iconView);
@@ -424,6 +480,8 @@ public class NotificationIconAreaController implements DarkReceiver,
iv.executeOnLayout(() -> updateTintForIcon(iv, mCenteredIconTint));
}
}
+
+ updateAodIconColors();
}
private void updateTintForIcon(StatusBarIconView v, int tint) {
@@ -437,12 +495,6 @@ public class NotificationIconAreaController implements DarkReceiver,
v.setDecorColor(tint);
}
- public void setDark(boolean dark) {
- mNotificationIcons.setDark(dark, false, 0);
- mShelfIcons.setDark(dark, false, 0);
- mCenteredIcon.setDark(dark, false, 0);
- }
-
/**
* Shows the icon view given in the center.
*/
@@ -463,12 +515,119 @@ public class NotificationIconAreaController implements DarkReceiver,
}
@Override
- public void onDozeAmountChanged(float linear, float eased) {
- mDarkAmount = linear;
- boolean fullyDark = mDarkAmount == 1f;
- if (mFullyDark != fullyDark) {
- mFullyDark = fullyDark;
- updateShelfIcons();
+ public void onDozingChanged(boolean isDozing) {
+ boolean animate = mDozeParameters.getAlwaysOn()
+ && !mDozeParameters.getDisplayNeedsBlanking();
+ mAodIcons.setDozing(isDozing, animate, 0);
+ }
+
+ public void setAnimationsEnabled(boolean enabled) {
+ mAnimationsEnabled = enabled;
+ updateAnimations();
+ }
+
+ @Override
+ public void onStateChanged(int newState) {
+ updateAodIconsVisibility(false /* animate */);
+ updateAnimations();
+ }
+
+ private void updateAnimations() {
+ boolean inShade = mStatusBarStateController.getState() == StatusBarState.SHADE;
+ mAodIcons.setAnimationsEnabled(mAnimationsEnabled && !inShade);
+ mCenteredIcon.setAnimationsEnabled(mAnimationsEnabled && inShade);
+ mNotificationIcons.setAnimationsEnabled(mAnimationsEnabled && inShade);
+ }
+
+ public void onThemeChanged() {
+ reloadAodColor();
+ updateAodIconColors();
+ }
+
+ public void appearAodIcons() {
+ DozeParameters dozeParameters = DozeParameters.getInstance(mContext);
+ if (dozeParameters.shouldControlScreenOff()) {
+ mAodIcons.setTranslationY(-mAodIconAppearTranslation);
+ mAodIcons.setAlpha(0);
+ mAodIcons.animate()
+ .setInterpolator(Interpolators.DECELERATE_QUINT)
+ .translationY(0)
+ .setDuration(AOD_ICONS_APPEAR_DURATION)
+ .start();
+ mAodIcons.animate()
+ .alpha(1)
+ .setInterpolator(Interpolators.LINEAR)
+ .setDuration(AOD_ICONS_APPEAR_DURATION)
+ .start();
+ }
+ }
+
+ private void reloadAodColor() {
+ mAodIconTint = Utils.getColorAttrDefaultColor(mContext,
+ R.attr.wallpaperTextColor);
+ }
+ private void updateAodIconColors() {
+ for (int i = 0; i < mAodIcons.getChildCount(); i++) {
+ final StatusBarIconView iv = (StatusBarIconView) mAodIcons.getChildAt(i);
+ if (iv.getWidth() != 0) {
+ updateTintForIcon(iv, mAodIconTint);
+ } else {
+ iv.executeOnLayout(() -> updateTintForIcon(iv, mAodIconTint));
+ }
+ }
+ }
+
+ @Override
+ public void onFullyHiddenChanged(boolean fullyHidden) {
+ boolean animate = true;
+ if (!mBypassController.getBypassEnabled()) {
+ animate = mDozeParameters.getAlwaysOn() && !mDozeParameters.getDisplayNeedsBlanking();
+ // We only want the appear animations to happen when the notifications get fully hidden,
+ // since otherwise the unhide animation overlaps
+ animate &= fullyHidden;
+ }
+ updateAodIconsVisibility(animate);
+ updateAodNotificationIcons();
+ }
+
+ @Override
+ public void onPulseExpansionChanged(boolean expandingChanged) {
+ if (expandingChanged) {
+ updateAodIconsVisibility(true /* animate */);
+ }
+ }
+
+ private void updateAodIconsVisibility(boolean animate) {
+ boolean visible = mBypassController.getBypassEnabled()
+ || mWakeUpCoordinator.getNotificationsFullyHidden();
+ if (mStatusBarStateController.getState() != StatusBarState.KEYGUARD) {
+ visible = false;
+ }
+ if (visible && mWakeUpCoordinator.isPulseExpanding()) {
+ visible = false;
+ }
+ if (mAodIconsVisible != visible) {
+ mAodIconsVisible = visible;
+ mAodIcons.animate().cancel();
+ if (animate) {
+ boolean wasFullyInvisible = mAodIcons.getVisibility() != View.VISIBLE;
+ if (mAodIconsVisible) {
+ if (wasFullyInvisible) {
+ // No fading here, let's just appear the icons instead!
+ mAodIcons.setVisibility(View.VISIBLE);
+ mAodIcons.setAlpha(1.0f);
+ appearAodIcons();
+ } else {
+ // We were fading out, let's fade in instead
+ CrossFadeHelper.fadeIn(mAodIcons);
+ }
+ } else {
+ CrossFadeHelper.fadeOut(mAodIcons);
+ }
+ } else {
+ mAodIcons.setAlpha(1.0f);
+ mAodIcons.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ }
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
index e20a23edc66d..a53ce9bb2014 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconContainer.java
@@ -128,7 +128,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
}.setDuration(CONTENT_FADE_DURATION);
- private static final int MAX_VISIBLE_ICONS_WHEN_DARK = 5;
+ private static final int MAX_VISIBLE_ICONS_ON_LOCK = 5;
public static final int MAX_STATIC_ICONS = 4;
private static final int MAX_DOTS = 1;
@@ -141,7 +141,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
private int mActualLayoutWidth = NO_VALUE;
private float mActualPaddingEnd = NO_VALUE;
private float mActualPaddingStart = NO_VALUE;
- private boolean mDark;
+ private boolean mDozing;
+ private boolean mOnLockScreen;
private boolean mChangingViewPositions;
private int mAddAnimationStartIndex = -1;
private int mCannedAnimationStartIndex = -1;
@@ -288,7 +289,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
}
if (child instanceof StatusBarIconView) {
- ((StatusBarIconView) child).setDark(mDark, false, 0);
+ ((StatusBarIconView) child).setDozing(mDozing, false, 0);
}
}
@@ -319,7 +320,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
if (child instanceof StatusBarIconView) {
boolean isReplacingIcon = isReplacingIcon(child);
final StatusBarIconView icon = (StatusBarIconView) child;
- if (mAnimationsEnabled && icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
+ if (areAnimationsEnabled(icon) && icon.getVisibleState() != StatusBarIconView.STATE_HIDDEN
&& child.getVisibility() == VISIBLE && isReplacingIcon) {
int animationStartIndex = findFirstViewIndexAfter(icon.getTranslationX());
if (mAddAnimationStartIndex < 0) {
@@ -330,7 +331,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
if (!mChangingViewPositions) {
mIconStates.remove(child);
- if (mAnimationsEnabled && !isReplacingIcon) {
+ if (areAnimationsEnabled(icon) && !isReplacingIcon) {
addTransientView(icon, 0);
boolean isIsolatedIcon = child == mIsolatedIcon;
icon.setVisibleState(StatusBarIconView.STATE_HIDDEN, true /* animate */,
@@ -341,6 +342,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
}
+ private boolean areAnimationsEnabled(StatusBarIconView icon) {
+ return mAnimationsEnabled || icon == mIsolatedIcon;
+ }
+
/**
* Finds the first view with a translation bigger then a given value
*/
@@ -373,7 +378,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
float translationX = getActualPaddingStart();
int firstOverflowIndex = -1;
int childCount = getChildCount();
- int maxVisibleIcons = mDark ? MAX_VISIBLE_ICONS_WHEN_DARK :
+ int maxVisibleIcons = mOnLockScreen ? MAX_VISIBLE_ICONS_ON_LOCK :
mIsStaticLayout ? MAX_STATIC_ICONS : childCount;
float layoutEnd = getLayoutEnd();
float overflowStart = getMaxOverflowStart();
@@ -390,8 +395,8 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
boolean forceOverflow = mSpeedBumpIndex != -1 && i >= mSpeedBumpIndex
&& iconState.iconAppearAmount > 0.0f || i >= maxVisibleIcons;
boolean noOverflowAfter = i == childCount - 1;
- float drawingScale = mDark && view instanceof StatusBarIconView
- ? ((StatusBarIconView) view).getIconScaleFullyDark()
+ float drawingScale = mOnLockScreen && view instanceof StatusBarIconView
+ ? ((StatusBarIconView) view).getIconScaleIncreased()
: 1f;
if (mOpenedAmount != 0.0f) {
noOverflowAfter = noOverflowAfter && !hasAmbient && !forceOverflow;
@@ -438,7 +443,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
mFirstVisibleIconState = mIconStates.get(getChildAt(0));
}
- boolean center = mDark;
+ boolean center = mOnLockScreen;
if (center && translationX < getLayoutEnd()) {
float initialTranslation =
mFirstVisibleIconState == null ? 0 : mFirstVisibleIconState.xTranslation;
@@ -558,13 +563,13 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
mChangingViewPositions = changingViewPositions;
}
- public void setDark(boolean dark, boolean fade, long delay) {
- mDark = dark;
+ public void setDozing(boolean dozing, boolean fade, long delay) {
+ mDozing = dozing;
mDisallowNextAnimation |= !fade;
for (int i = 0; i < getChildCount(); i++) {
View view = getChildAt(i);
if (view instanceof StatusBarIconView) {
- ((StatusBarIconView) view).setDark(dark, fade, delay);
+ ((StatusBarIconView) view).setDozing(dozing, fade, delay);
}
}
}
@@ -668,6 +673,10 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
}
}
+ public void setOnLockScreen(boolean onLockScreen) {
+ mOnLockScreen = onLockScreen;
+ }
+
public class IconState extends ViewState {
public static final int NO_VALUE = NotificationIconContainer.NO_VALUE;
public float iconAppearAmount = 1.0f;
@@ -690,7 +699,7 @@ public class NotificationIconContainer extends AlphaOptimizedFrameLayout {
StatusBarIconView icon = (StatusBarIconView) view;
boolean animate = false;
AnimationProperties animationProperties = null;
- boolean animationsAllowed = mAnimationsEnabled && !mDisallowNextAnimation
+ boolean animationsAllowed = areAnimationsEnabled(icon) && !mDisallowNextAnimation
&& !noAnimations;
if (animationsAllowed) {
if (justAdded || justReplaced) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 1027046b0c28..7430f7cc2cd1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -56,6 +56,7 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.keyguard.KeyguardClockSwitch;
import com.android.keyguard.KeyguardStatusView;
+import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
@@ -113,7 +114,8 @@ public class NotificationPanelView extends PanelView implements
KeyguardAffordanceHelper.Callback, NotificationStackScrollLayout.OnEmptySpaceClickListener,
OnHeadsUpChangedListener, QS.HeightListener, ZenModeController.Callback,
ConfigurationController.ConfigurationListener, StateListener,
- PulseExpansionHandler.ExpansionCallback, DynamicPrivacyController.Listener {
+ PulseExpansionHandler.ExpansionCallback, DynamicPrivacyController.Listener,
+ NotificationWakeUpCoordinator.WakeUpListener {
private static final boolean DEBUG = false;
@@ -146,12 +148,23 @@ public class NotificationPanelView extends PanelView implements
private static final AnimationProperties CLOCK_ANIMATION_PROPERTIES = new AnimationProperties()
.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ private static final AnimatableProperty KEYGUARD_HEADS_UP_SHOWING_AMOUNT
+ = AnimatableProperty.from("KEYGUARD_HEADS_UP_SHOWING_AMOUNT",
+ NotificationPanelView::setKeyguardHeadsUpShowingAmount,
+ NotificationPanelView::getKeyguardHeadsUpShowingAmount,
+ R.id.keyguard_hun_animator_tag,
+ R.id.keyguard_hun_animator_end_tag,
+ R.id.keyguard_hun_animator_start_tag);
+ private static final AnimationProperties KEYGUARD_HUN_PROPERTIES =
+ new AnimationProperties().setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
private final InjectionInflationController mInjectionInflationController;
private final PowerManager mPowerManager;
private final AccessibilityManager mAccessibilityManager;
private final NotificationWakeUpCoordinator mWakeUpCoordinator;
private final PulseExpansionHandler mPulseExpansionHandler;
+ private final KeyguardBypassController mKeyguardBypassController;
+ private final KeyguardUpdateMonitor mUpdateMonitor;
@VisibleForTesting
protected KeyguardAffordanceHelper mAffordanceHelper;
@@ -212,6 +225,8 @@ public class NotificationPanelView extends PanelView implements
private int mNotificationsHeaderCollideDistance;
private int mUnlockMoveDistance;
private float mEmptyDragAmount;
+ private float mDownX;
+ private float mDownY;
private final KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
new KeyguardClockPositionAlgorithm();
@@ -276,6 +291,12 @@ public class NotificationPanelView extends PanelView implements
private boolean mBlockingExpansionForCurrentTouch;
/**
+ * Following variables maintain state of events when input focus transfer may occur.
+ */
+ private boolean mExpectingSynthesizedDown; // expecting to see synthesized DOWN event
+ private boolean mLastEventSynthesizedDown; // last event was synthesized DOWN event
+
+ /**
* Current dark amount that follows regular interpolation curve of animation.
*/
private float mInterpolatedDarkAmount;
@@ -346,13 +367,21 @@ public class NotificationPanelView extends PanelView implements
private int mThemeResId;
private KeyguardIndicationController mKeyguardIndicationController;
private Consumer<Boolean> mAffordanceLaunchListener;
+ private int mShelfHeight;
+ private Runnable mOnReinflationListener;
+ private int mDarkIconSize;
+ private int mHeadsUpInset;
+ private boolean mHeadsUpPinnedMode;
+ private float mKeyguardHeadsUpShowingAmount = 0.0f;
+ private boolean mShowingKeyguardHeadsUp;
@Inject
public NotificationPanelView(@Named(VIEW_CONTEXT) Context context, AttributeSet attrs,
InjectionInflationController injectionInflationController,
NotificationWakeUpCoordinator coordinator,
PulseExpansionHandler pulseExpansionHandler,
- DynamicPrivacyController dynamicPrivacyController) {
+ DynamicPrivacyController dynamicPrivacyController,
+ KeyguardBypassController bypassController) {
super(context, attrs);
setWillNotDraw(!DEBUG);
mInjectionInflationController = injectionInflationController;
@@ -366,7 +395,14 @@ public class NotificationPanelView extends PanelView implements
mCommandQueue = getComponent(context, CommandQueue.class);
mDisplayId = context.getDisplayId();
mPulseExpansionHandler = pulseExpansionHandler;
+ pulseExpansionHandler.setPulseExpandAbortListener(() -> {
+ if (mQs != null) {
+ mQs.animateHeaderSlidingOut();
+ }
+ });
mThemeResId = context.getThemeResId();
+ mKeyguardBypassController = bypassController;
+ mUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
dynamicPrivacyController.addListener(this);
mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0);
@@ -415,6 +451,16 @@ public class NotificationPanelView extends PanelView implements
mWakeUpCoordinator.setStackScroller(mNotificationStackScroller);
mQsFrame = findViewById(R.id.qs_frame);
mPulseExpansionHandler.setUp(mNotificationStackScroller, this, mShadeController);
+ mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
+ @Override
+ public void onPulseExpansionChanged(boolean expandingChanged) {
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ // Position the notifications while dragging down while pulsing
+ requestScrollerTopPaddingUpdate(false /* animate */);
+ updateQSPulseExpansion();
+ }
+ }
+ });
}
@Override
@@ -459,6 +505,13 @@ public class NotificationPanelView extends PanelView implements
R.dimen.keyguard_indication_bottom_padding);
mQsNotificationTopPadding = getResources().getDimensionPixelSize(
R.dimen.qs_notification_padding);
+ mShelfHeight = getResources().getDimensionPixelSize(R.dimen.notification_shelf_height);
+ mDarkIconSize = getResources().getDimensionPixelSize(
+ R.dimen.status_bar_icon_drawing_size_dark);
+ int statusbarHeight = getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.status_bar_height);
+ mHeadsUpInset = statusbarHeight + getResources().getDimensionPixelSize(
+ R.dimen.heads_up_status_bar_padding);
}
/**
@@ -551,6 +604,9 @@ public class NotificationPanelView extends PanelView implements
setKeyguardStatusViewVisibility(mBarState, false, false);
setKeyguardBottomAreaVisibility(mBarState, false);
+ if (mOnReinflationListener != null) {
+ mOnReinflationListener.run();
+ }
}
private void initBottomArea() {
@@ -669,24 +725,30 @@ public class NotificationPanelView extends PanelView implements
boolean animateClock = animate || mAnimateNextPositionUpdate;
int stackScrollerPadding;
if (mBarState != StatusBarState.KEYGUARD) {
- stackScrollerPadding = (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
- + mQsNotificationTopPadding;
+ stackScrollerPadding = getUnlockedStackScrollerPadding();
} else {
int totalHeight = getHeight();
int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
int clockPreferredY = mKeyguardStatusView.getClockPreferredY(totalHeight);
+ boolean bypassEnabled = mKeyguardBypassController.getBypassEnabled();
+ final boolean hasVisibleNotifications =
+ !bypassEnabled && mNotificationStackScroller.getVisibleNotificationCount() != 0;
+ mKeyguardStatusView.setHasVisibleNotifications(hasVisibleNotifications);
mClockPositionAlgorithm.setup(
mStatusBarMinHeight,
totalHeight - bottomPadding,
mNotificationStackScroller.getIntrinsicContentHeight(),
getExpandedFraction(),
totalHeight,
- mKeyguardStatusView.getHeight(),
+ (int) (mKeyguardStatusView.getHeight()
+ - mShelfHeight / 2.0f - mDarkIconSize / 2.0f),
clockPreferredY,
hasCustomClock(),
- mNotificationStackScroller.getVisibleNotificationCount() != 0,
+ hasVisibleNotifications,
mInterpolatedDarkAmount,
- mEmptyDragAmount);
+ mEmptyDragAmount,
+ bypassEnabled,
+ getUnlockedStackScrollerPadding());
mClockPositionAlgorithm.run(mClockPositionResult);
PropertyAnimator.setProperty(mKeyguardStatusView, AnimatableProperty.X,
mClockPositionResult.clockX, CLOCK_ANIMATION_PROPERTIES, animateClock);
@@ -694,10 +756,9 @@ public class NotificationPanelView extends PanelView implements
mClockPositionResult.clockY, CLOCK_ANIMATION_PROPERTIES, animateClock);
updateNotificationTranslucency();
updateClock();
- stackScrollerPadding = mClockPositionResult.stackScrollerPadding;
+ stackScrollerPadding = mClockPositionResult.stackScrollerPaddingExpanded;
}
mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding);
- mNotificationStackScroller.setAntiBurnInOffsetX(mClockPositionResult.clockX);
mKeyguardBottomArea.setAntiBurnInOffsetX(mClockPositionResult.clockX);
mStackScrollerMeasuringPass++;
@@ -707,6 +768,14 @@ public class NotificationPanelView extends PanelView implements
}
/**
+ * @return the padding of the stackscroller when unlocked
+ */
+ private int getUnlockedStackScrollerPadding() {
+ return (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
+ + mQsNotificationTopPadding;
+ }
+
+ /**
* @param maximum the maximum to return at most
* @return the maximum keyguard notifications that can fit on the screen
*/
@@ -867,7 +936,7 @@ public class NotificationPanelView extends PanelView implements
protected void flingToHeight(float vel, boolean expand, float target,
float collapseSpeedUpFactor, boolean expandBecauseOfFalsing) {
mHeadsUpTouchHelper.notifyFling(!expand);
- setClosingWithAlphaFadeout(!expand && getFadeoutAlpha() == 1.0f);
+ setClosingWithAlphaFadeout(!expand && !isOnKeyguard() && getFadeoutAlpha() == 1.0f);
super.flingToHeight(vel, expand, target, collapseSpeedUpFactor, expandBecauseOfFalsing);
}
@@ -888,7 +957,8 @@ public class NotificationPanelView extends PanelView implements
MetricsLogger.count(mContext, COUNTER_PANEL_OPEN_PEEK, 1);
return true;
}
- if (mPulseExpansionHandler.onInterceptTouchEvent(event)) {
+ if (!shouldQuickSettingsIntercept(mDownX, mDownY, 0)
+ && mPulseExpansionHandler.onInterceptTouchEvent(event)) {
return true;
}
@@ -989,8 +1059,19 @@ public class NotificationPanelView extends PanelView implements
mOnlyAffordanceInThisMotion = false;
mQsTouchAboveFalsingThreshold = mQsFullyExpanded;
mDozingOnDown = isDozing();
+ mDownX = event.getX();
+ mDownY = event.getY();
mCollapsedOnDown = isFullyCollapsed();
mListenForHeadsUp = mCollapsedOnDown && mHeadsUpManager.hasPinnedHeadsUp();
+ if (mExpectingSynthesizedDown) {
+ mLastEventSynthesizedDown = true;
+ } else {
+ // down but not synthesized motion event.
+ mLastEventSynthesizedDown = false;
+ }
+ } else {
+ // not down event at all.
+ mLastEventSynthesizedDown = false;
}
}
@@ -1056,13 +1137,20 @@ public class NotificationPanelView extends PanelView implements
return false;
}
- initDownStates(event);
// Make sure the next touch won't the blocked after the current ends.
if (event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL) {
mBlockingExpansionForCurrentTouch = false;
}
- if (!mIsExpanding && mPulseExpansionHandler.onTouchEvent(event)) {
+ // When touch focus transfer happens, ACTION_DOWN->ACTION_UP may happen immediately
+ // without any ACTION_MOVE event.
+ // In such case, simply expand the panel instead of being stuck at the bottom bar.
+ if (mLastEventSynthesizedDown && event.getAction() == MotionEvent.ACTION_UP) {
+ expand(true /* animate */);
+ }
+ initDownStates(event);
+ if (!mIsExpanding && !shouldQuickSettingsIntercept(mDownX, mDownY, 0)
+ && mPulseExpansionHandler.onTouchEvent(event)) {
// We're expanding all the other ones shouldn't get this anymore
return true;
}
@@ -1179,6 +1267,39 @@ public class NotificationPanelView extends PanelView implements
}
}
+ /**
+ * Input focus transfer is about to happen.
+ */
+ public void startWaitingForOpenPanelGesture() {
+ if (!isFullyCollapsed()) {
+ return;
+ }
+ mExpectingSynthesizedDown = true;
+ onTrackingStarted();
+ }
+
+ /**
+ * Called when this view is no longer waiting for input focus transfer.
+ *
+ * There are two scenarios behind this function call. First, input focus transfer
+ * has successfully happened and this view already received synthetic DOWN event.
+ * (mExpectingSynthesizedDown == false). Do nothing.
+ *
+ * Second, before input focus transfer finished, user may have lifted finger
+ * in previous window and this window never received synthetic DOWN event.
+ * (mExpectingSynthesizedDown == true).
+ * In this case, we use the velocity to trigger fling event.
+ *
+ * @param velocity unit is in px / millis
+ */
+ public void stopWaitingForOpenPanelGesture(float velocity) {
+ if (mExpectingSynthesizedDown) {
+ mExpectingSynthesizedDown = false;
+ fling(velocity > 1f ? 1000f * velocity : 0, true /* animate */);
+ onTrackingStopped(false);
+ }
+ }
+
@Override
protected boolean flingExpands(float vel, float vectorVel, float x, float y) {
boolean expands = super.flingExpands(vel, vectorVel, x, y);
@@ -1191,8 +1312,12 @@ public class NotificationPanelView extends PanelView implements
}
@Override
- protected boolean hasConflictingGestures() {
- return mBarState != StatusBarState.SHADE;
+ protected boolean shouldGestureWaitForTouchSlop() {
+ if (mExpectingSynthesizedDown) {
+ mExpectingSynthesizedDown = false;
+ return false;
+ }
+ return isFullyCollapsed() || mBarState != StatusBarState.SHADE;
}
@Override
@@ -1333,6 +1458,8 @@ public class NotificationPanelView extends PanelView implements
mFalsingManager.setQsExpanded(expanded);
mStatusBar.setQsExpanded(expanded);
mNotificationContainerParent.setQsExpanded(expanded);
+ mPulseExpansionHandler.setQsExpanded(expanded);
+ mKeyguardBypassController.setQSExpanded(expanded);
}
}
@@ -1347,9 +1474,6 @@ public class NotificationPanelView extends PanelView implements
mBarState = statusBarState;
mKeyguardShowing = keyguardShowing;
- if (mQs != null) {
- mQs.setKeyguardShowing(mKeyguardShowing);
- }
if (oldState == StatusBarState.KEYGUARD
&& (goingToFullShade || statusBarState == StatusBarState.SHADE_LOCKED)) {
@@ -1360,6 +1484,7 @@ public class NotificationPanelView extends PanelView implements
} else if (oldState == StatusBarState.SHADE_LOCKED
&& statusBarState == StatusBarState.KEYGUARD) {
animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ mNotificationStackScroller.resetScrollPosition();
// Only animate header if the header is visible. If not, it will partially animate out
// the top of QS
if (!mQsExpanded) {
@@ -1374,10 +1499,13 @@ public class NotificationPanelView extends PanelView implements
}
}
}
+ updateKeyguardStatusBarForHeadsUp();
if (keyguardShowing) {
updateDozingVisibilities(false /* animate */);
}
-
+ // THe update needs to happen after the headerSlide in above, otherwise the translation
+ // would reset
+ updateQSPulseExpansion();
maybeAnimateBottomAreaAlpha();
resetHorizontalPanelPosition();
updateQsState();
@@ -1626,7 +1754,7 @@ public class NotificationPanelView extends PanelView implements
// padding on Keyguard, maxQsPadding denotes the top padding from the quick settings
// panel. We need to take the maximum and linearly interpolate with the panel expansion
// for a nice motion.
- int maxNotificationPadding = mClockPositionResult.stackScrollerPadding;
+ int maxNotificationPadding = getKeyguardNotificationStaticPadding();
int maxQsPadding = mQsMaxExpansionHeight + mQsNotificationTopPadding;
int max = mBarState == StatusBarState.KEYGUARD
? Math.max(maxNotificationPadding, maxQsPadding)
@@ -1634,11 +1762,12 @@ public class NotificationPanelView extends PanelView implements
return (int) MathUtils.lerp((float) mQsMinExpansionHeight, (float) max,
getExpandedFraction());
} else if (mQsSizeChangeAnimator != null) {
- return (int) mQsSizeChangeAnimator.getAnimatedValue();
+ return Math.max((int) mQsSizeChangeAnimator.getAnimatedValue(),
+ getKeyguardNotificationStaticPadding());
} else if (mKeyguardShowing) {
// We can only do the smoother transition on Keyguard when we also are not collapsing
// from a scrolled quick settings.
- return MathUtils.lerp((float) mNotificationStackScroller.getIntrinsicPadding(),
+ return MathUtils.lerp((float) getKeyguardNotificationStaticPadding(),
(float) (mQsMaxExpansionHeight + mQsNotificationTopPadding),
getQsExpansionFraction());
} else {
@@ -1646,10 +1775,43 @@ public class NotificationPanelView extends PanelView implements
}
}
+ /**
+ * @return the topPadding of notifications when on keyguard not respecting quick settings
+ * expansion
+ */
+ private int getKeyguardNotificationStaticPadding() {
+ if (!mKeyguardShowing) {
+ return 0;
+ }
+ if (!mKeyguardBypassController.getBypassEnabled()) {
+ return mClockPositionResult.stackScrollerPadding;
+ }
+ int collapsedPosition = mHeadsUpInset;
+ if (!mNotificationStackScroller.isPulseExpanding()) {
+ return collapsedPosition;
+ } else {
+ int expandedPosition = mClockPositionResult.stackScrollerPadding;
+ return (int) MathUtils.lerp(collapsedPosition, expandedPosition,
+ mNotificationStackScroller.calculateAppearFractionBypass());
+ }
+ }
+
+
protected void requestScrollerTopPaddingUpdate(boolean animate) {
- mNotificationStackScroller.updateTopPadding(calculateQsTopPadding(),
- animate, mKeyguardShowing
- && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted));
+ mNotificationStackScroller.updateTopPadding(calculateQsTopPadding(), animate);
+ if (mKeyguardShowing && mKeyguardBypassController.getBypassEnabled()) {
+ // update the position of the header
+ updateQsExpansion();
+ }
+ }
+
+
+ private void updateQSPulseExpansion() {
+ if (mQs != null) {
+ mQs.setShowCollapsedOnKeyguard(mKeyguardShowing
+ && mKeyguardBypassController.getBypassEnabled()
+ && mNotificationStackScroller.isPulseExpanding());
+ }
}
private void trackMovement(MotionEvent event) {
@@ -1780,8 +1942,16 @@ public class NotificationPanelView extends PanelView implements
@Override
protected int getMaxPanelHeight() {
+ if (mKeyguardBypassController.getBypassEnabled() && mBarState == StatusBarState.KEYGUARD) {
+ return getMaxPanelHeightBypass();
+ } else {
+ return getMaxPanelHeightNonBypass();
+ }
+ }
+
+ private int getMaxPanelHeightNonBypass() {
int min = mStatusBarMinHeight;
- if (mBarState != StatusBarState.KEYGUARD
+ if (!(mBarState == StatusBarState.KEYGUARD)
&& mNotificationStackScroller.getNotGoneChildCount() == 0) {
int minHeight = (int) (mQsMinExpansionHeight + getOverExpansionAmount());
min = Math.max(min, minHeight);
@@ -1797,6 +1967,15 @@ public class NotificationPanelView extends PanelView implements
return maxHeight;
}
+ private int getMaxPanelHeightBypass() {
+ int position = mClockPositionAlgorithm.getExpandedClockPosition()
+ + mKeyguardStatusView.getHeight();
+ if (mNotificationStackScroller.getVisibleNotificationCount() != 0) {
+ position += mShelfHeight / 2.0f + mDarkIconSize / 2.0f;
+ }
+ return position;
+ }
+
public boolean isInSettings() {
return mQsExpanded;
}
@@ -1911,15 +2090,19 @@ public class NotificationPanelView extends PanelView implements
!mHeadsUpManager.hasPinnedHeadsUp()) {
alpha = getFadeoutAlpha();
}
- if (mBarState == StatusBarState.KEYGUARD && !mHintAnimationRunning) {
+ if (mBarState == StatusBarState.KEYGUARD && !mHintAnimationRunning
+ && !mKeyguardBypassController.getBypassEnabled()) {
alpha *= mClockPositionResult.clockAlpha;
}
mNotificationStackScroller.setAlpha(alpha);
}
private float getFadeoutAlpha() {
- float alpha = (getNotificationsTopY() + mNotificationStackScroller.getFirstItemMinHeight())
- / mQsMinExpansionHeight;
+ float alpha;
+ if (mQsMinExpansionHeight == 0) {
+ return 1.0f;
+ }
+ alpha = getExpandedHeight() / mQsMinExpansionHeight;
alpha = Math.max(0, Math.min(alpha, 1));
alpha = (float) Math.pow(alpha, 0.75);
return alpha;
@@ -1946,11 +2129,25 @@ public class NotificationPanelView extends PanelView implements
}
protected float getHeaderTranslation() {
- if (mBarState == StatusBarState.KEYGUARD) {
- return 0;
+ if (mBarState == StatusBarState.KEYGUARD && !mKeyguardBypassController.getBypassEnabled()) {
+ return -mQs.getQsMinExpansionHeight();
+ }
+ float appearAmount = mNotificationStackScroller.calculateAppearFraction(mExpandedHeight);
+ float startHeight = -mQsExpansionHeight;
+ if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()
+ && mNotificationStackScroller.isPulseExpanding()) {
+ if (!mPulseExpansionHandler.isExpanding()
+ && !mPulseExpansionHandler.getLeavingLockscreen()) {
+ // If we aborted the expansion we need to make sure the header doesn't reappear
+ // again after the header has animated away
+ appearAmount = 0;
+ } else {
+ appearAmount = mNotificationStackScroller.calculateAppearFractionBypass();
+ }
+ startHeight = -mQs.getQsMinExpansionHeight();
}
- float translation = MathUtils.lerp(-mQsMinExpansionHeight, 0,
- Math.min(1.0f, mNotificationStackScroller.getAppearFraction(mExpandedHeight)))
+ float translation = MathUtils.lerp(startHeight, 0,
+ Math.min(1.0f, appearAmount))
+ mExpandOffset;
return Math.min(0, translation);
}
@@ -1963,18 +2160,18 @@ public class NotificationPanelView extends PanelView implements
float alpha;
if (mBarState == StatusBarState.KEYGUARD) {
- // When on Keyguard, we hide the header as soon as the top card of the notification
- // stack scroller is close enough (collision distance) to the bottom of the header.
- alpha = getNotificationsTopY()
+ // When on Keyguard, we hide the header as soon as we expanded close enough to the
+ // header
+ alpha = getExpandedHeight()
/
(mKeyguardStatusBar.getHeight() + mNotificationsHeaderCollideDistance);
} else {
// In SHADE_LOCKED, the top card is already really close to the header. Hide it as
// soon as we start translating the stack.
- alpha = getNotificationsTopY() / mKeyguardStatusBar.getHeight();
+ alpha = getExpandedHeight() / mKeyguardStatusBar.getHeight();
}
- alpha = MathUtils.constrain(alpha, 0, 1);
+ alpha = MathUtils.saturate(alpha);
alpha = (float) Math.pow(alpha, 0.75);
return alpha;
}
@@ -1986,6 +2183,7 @@ public class NotificationPanelView extends PanelView implements
float alphaQsExpansion = 1 - Math.min(1, getQsExpansionFraction() * 2);
float newAlpha = Math.min(getKeyguardContentsAlpha(), alphaQsExpansion)
* mKeyguardStatusBarAnimateAlpha;
+ newAlpha *= 1.0f - mKeyguardHeadsUpShowingAmount;
mKeyguardStatusBar.setAlpha(newAlpha);
mKeyguardStatusBar.setVisibility(newAlpha != 0f && !mDozing ? VISIBLE : INVISIBLE);
}
@@ -2025,13 +2223,6 @@ public class NotificationPanelView extends PanelView implements
mBigClockContainer.setAlpha(alpha);
}
- private float getNotificationsTopY() {
- if (mNotificationStackScroller.getNotGoneChildCount() == 0) {
- return getExpandedHeight();
- }
- return mNotificationStackScroller.getNotificationsTopY();
- }
-
@Override
protected void onExpandingStarted() {
super.onExpandingStarted();
@@ -2518,10 +2709,14 @@ public class NotificationPanelView extends PanelView implements
switch (mBarState) {
case StatusBarState.KEYGUARD:
if (!mDozingOnDown) {
- mLockscreenGestureLogger.write(
- MetricsEvent.ACTION_LS_HINT,
- 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
- startUnlockHintAnimation();
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ mUpdateMonitor.requestFaceAuth();
+ } else {
+ mLockscreenGestureLogger.write(
+ MetricsEvent.ACTION_LS_HINT,
+ 0 /* lengthDp - N/A */, 0 /* velocityDp - N/A */);
+ startUnlockHintAnimation();
+ }
}
return true;
case StatusBarState.SHADE_LOCKED:
@@ -2614,16 +2809,51 @@ public class NotificationPanelView extends PanelView implements
mHeadsUpExistenceChangedRunnable);
}
updateGestureExclusionRect();
+ mHeadsUpPinnedMode = inPinnedMode;
+ updateHeadsUpVisibility();
+ updateKeyguardStatusBarForHeadsUp();
+ }
+
+ private void updateKeyguardStatusBarForHeadsUp() {
+ boolean showingKeyguardHeadsUp = mKeyguardShowing
+ && mHeadsUpAppearanceController.shouldBeVisible();
+ if (mShowingKeyguardHeadsUp != showingKeyguardHeadsUp) {
+ mShowingKeyguardHeadsUp = showingKeyguardHeadsUp;
+ if (mKeyguardShowing) {
+ PropertyAnimator.setProperty(this, KEYGUARD_HEADS_UP_SHOWING_AMOUNT,
+ showingKeyguardHeadsUp ? 1.0f : 0.0f, KEYGUARD_HUN_PROPERTIES,
+ true /* animate */);
+ } else {
+ PropertyAnimator.applyImmediately(this, KEYGUARD_HEADS_UP_SHOWING_AMOUNT, 0.0f);
+ }
+ }
+ }
+
+ private void setKeyguardHeadsUpShowingAmount(float amount) {
+ mKeyguardHeadsUpShowingAmount = amount;
+ updateHeaderKeyguardAlpha();
+ }
+
+ private float getKeyguardHeadsUpShowingAmount() {
+ return mKeyguardHeadsUpShowingAmount;
}
public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
mHeadsUpAnimatingAway = headsUpAnimatingAway;
mNotificationStackScroller.setHeadsUpAnimatingAway(headsUpAnimatingAway);
+ updateHeadsUpVisibility();
+ }
+
+ private void updateHeadsUpVisibility() {
+ ((PhoneStatusBarView) mBar).setHeadsUpVisible(mHeadsUpAnimatingAway || mHeadsUpPinnedMode);
}
@Override
public void onHeadsUpPinned(NotificationEntry entry) {
- mNotificationStackScroller.generateHeadsUpAnimation(entry.getHeadsUpAnimationView(), true);
+ if (!isOnKeyguard()) {
+ mNotificationStackScroller.generateHeadsUpAnimation(entry.getHeadsUpAnimationView(),
+ true);
+ }
}
@Override
@@ -2632,7 +2862,7 @@ public class NotificationPanelView extends PanelView implements
// When we're unpinning the notification via active edge they remain heads-upped,
// we need to make sure that an animation happens in this case, otherwise the notification
// will stick to the top without any interaction.
- if (isFullyCollapsed() && entry.isRowHeadsUp()) {
+ if (isFullyCollapsed() && entry.isRowHeadsUp() && !isOnKeyguard()) {
mNotificationStackScroller.generateHeadsUpAnimation(
entry.getHeadsUpAnimationView(), false);
entry.setHeadsUpIsVisible();
@@ -2699,7 +2929,7 @@ public class NotificationPanelView extends PanelView implements
}
protected void setHorizontalPanelTranslation(float translation) {
- mNotificationStackScroller.setHorizontalPanelTranslation(translation);
+ mNotificationStackScroller.setTranslationX(translation);
mQsFrame.setTranslationX(translation);
int size = mVerticalTranslationListener.size();
for (int i = 0; i < size; i++) {
@@ -2711,6 +2941,10 @@ public class NotificationPanelView extends PanelView implements
if (mTracking) {
mNotificationStackScroller.setExpandingVelocity(getCurrentExpandVelocity());
}
+ if (mKeyguardBypassController.getBypassEnabled() && isOnKeyguard()) {
+ // The expandedHeight is always the full panel Height when bypassing
+ expandedHeight = getMaxPanelHeightNonBypass();
+ }
mNotificationStackScroller.setExpandedHeight(expandedHeight);
updateKeyguardBottomAreaAlpha();
updateBigClockAlpha();
@@ -2751,7 +2985,8 @@ public class NotificationPanelView extends PanelView implements
@Override
protected boolean isPanelVisibleBecauseOfHeadsUp() {
- return mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway;
+ return (mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway)
+ && mBarState == StatusBarState.SHADE;
}
@Override
@@ -2776,7 +3011,6 @@ public class NotificationPanelView extends PanelView implements
// nor setting these flags, since the occluded state doesn't change anymore, hence it's
// never reset.
if (!isFullyCollapsed()) {
- mLaunchingAffordance = true;
setLaunchingAffordance(true);
} else {
animate = false;
@@ -2786,7 +3020,6 @@ public class NotificationPanelView extends PanelView implements
}
public void onAffordanceLaunchEnded() {
- mLaunchingAffordance = false;
setLaunchingAffordance(false);
}
@@ -2795,8 +3028,10 @@ public class NotificationPanelView extends PanelView implements
* launched via a camera gesture.
*/
private void setLaunchingAffordance(boolean launchingAffordance) {
+ mLaunchingAffordance = launchingAffordance;
getLeftIcon().setLaunchingAffordance(launchingAffordance);
getRightIcon().setLaunchingAffordance(launchingAffordance);
+ mKeyguardBypassController.setLaunchingAffordance(launchingAffordance);
if (mAffordanceLaunchListener != null) {
mAffordanceLaunchListener.accept(launchingAffordance);
}
@@ -2860,7 +3095,7 @@ public class NotificationPanelView extends PanelView implements
mQs.setPanelView(NotificationPanelView.this);
mQs.setExpandClickListener(NotificationPanelView.this);
mQs.setHeaderClickable(mQsExpansionEnabled);
- mQs.setKeyguardShowing(mKeyguardShowing);
+ updateQSPulseExpansion();
mQs.setOverscrolling(mStackScrollerOverscrolling);
// recompute internal state when qspanel height changes
@@ -2909,7 +3144,7 @@ public class NotificationPanelView extends PanelView implements
public void setDozing(boolean dozing, boolean animate, PointF wakeUpTouchLocation) {
if (dozing == mDozing) return;
mDozing = dozing;
- mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
+ mNotificationStackScroller.setDozing(mDozing, animate, wakeUpTouchLocation);
mKeyguardBottomArea.setDozing(mDozing, animate);
if (dozing) {
@@ -2921,8 +3156,8 @@ public class NotificationPanelView extends PanelView implements
updateDozingVisibilities(animate);
}
- final float darkAmount = dozing ? 1 : 0;
- mStatusBarStateController.setDozeAmount(darkAmount, animate);
+ final float dozeAmount = dozing ? 1 : 0;
+ mStatusBarStateController.setDozeAmount(dozeAmount, animate);
}
@Override
@@ -3087,10 +3322,6 @@ public class NotificationPanelView extends PanelView implements
return mNotificationStackScroller.hasPulsingNotifications();
}
- public boolean isFullyDark() {
- return mNotificationStackScroller.isFullyDark();
- }
-
public ActivatableNotificationView getActivatedChild() {
return mNotificationStackScroller.getActivatedChild();
}
@@ -3118,7 +3349,6 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.setIconAreaController(notificationIconAreaController);
mNotificationStackScroller.setStatusBar(statusBar);
mNotificationStackScroller.setGroupManager(groupManager);
- mNotificationStackScroller.setHeadsUpManager(headsUpManager);
mNotificationStackScroller.setShelf(notificationShelf);
mNotificationStackScroller.setScrimController(scrimController);
updateShowEmptyShadeView();
@@ -3130,9 +3360,18 @@ public class NotificationPanelView extends PanelView implements
@Override
public void onDynamicPrivacyChanged() {
+ // Do not request animation when pulsing or waking up, otherwise the clock wiill be out
+ // of sync with the notification panel.
+ if (mLinearDarkAmount != 0) {
+ return;
+ }
mAnimateNextPositionUpdate = true;
}
+ public void setOnReinflationListener(Runnable onReinflationListener) {
+ mOnReinflationListener = onReinflationListener;
+ }
+
/**
* Panel and QS expansion callbacks.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index ca762cdf07f3..27c94d277cc4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -36,6 +36,9 @@ import com.android.systemui.plugins.qs.QS;
import com.android.systemui.statusbar.notification.AboveShelfObserver;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
+import java.util.ArrayList;
+import java.util.Comparator;
+
/**
* The container with notification stack scroller and quick settings inside.
*/
@@ -54,6 +57,9 @@ public class NotificationsQuickSettingsContainer extends FrameLayout
private int mBottomPadding;
private int mStackScrollerMargin;
private boolean mHasViewsAboveShelf;
+ private ArrayList<View> mDrawingOrderedChildren = new ArrayList<>();
+ private ArrayList<View> mLayoutDrawingOrder = new ArrayList<>();
+ private final Comparator<View> mIndexComparator = Comparator.comparingInt(this::indexOfChild);
public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -107,35 +113,44 @@ public class NotificationsQuickSettingsContainer extends FrameLayout
}
@Override
- protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
- boolean userSwitcherVisible = mInflated && mUserSwitcher.getVisibility() == View.VISIBLE;
- boolean statusBarVisible = mKeyguardStatusBar.getVisibility() == View.VISIBLE;
-
- final boolean qsBottom = mHasViewsAboveShelf;
- View stackQsTop = qsBottom ? mStackScroller : mQsFrame;
- View stackQsBottom = !qsBottom ? mStackScroller : mQsFrame;
+ protected void dispatchDraw(Canvas canvas) {
// Invert the order of the scroll view and user switcher such that the notifications receive
// touches first but the panel gets drawn above.
- if (child == mQsFrame) {
- return super.drawChild(canvas, userSwitcherVisible && statusBarVisible ? mUserSwitcher
- : statusBarVisible ? mKeyguardStatusBar
- : userSwitcherVisible ? mUserSwitcher
- : stackQsBottom, drawingTime);
- } else if (child == mStackScroller) {
- return super.drawChild(canvas,
- userSwitcherVisible && statusBarVisible ? mKeyguardStatusBar
- : statusBarVisible || userSwitcherVisible ? stackQsBottom
- : stackQsTop,
- drawingTime);
- } else if (child == mUserSwitcher) {
- return super.drawChild(canvas,
- userSwitcherVisible && statusBarVisible ? stackQsBottom
- : stackQsTop,
- drawingTime);
- } else if (child == mKeyguardStatusBar) {
- return super.drawChild(canvas,
- stackQsTop,
- drawingTime);
+ mDrawingOrderedChildren.clear();
+ mLayoutDrawingOrder.clear();
+ if (mInflated && mUserSwitcher.getVisibility() == View.VISIBLE) {
+ mDrawingOrderedChildren.add(mUserSwitcher);
+ mLayoutDrawingOrder.add(mUserSwitcher);
+ }
+ if (mKeyguardStatusBar.getVisibility() == View.VISIBLE) {
+ mDrawingOrderedChildren.add(mKeyguardStatusBar);
+ mLayoutDrawingOrder.add(mKeyguardStatusBar);
+ }
+ if (mStackScroller.getVisibility() == View.VISIBLE) {
+ mDrawingOrderedChildren.add(mStackScroller);
+ mLayoutDrawingOrder.add(mStackScroller);
+ }
+ if (mQsFrame.getVisibility() == View.VISIBLE) {
+ mDrawingOrderedChildren.add(mQsFrame);
+ mLayoutDrawingOrder.add(mQsFrame);
+ }
+
+ if (mHasViewsAboveShelf) {
+ // StackScroller needs to be on top
+ mDrawingOrderedChildren.remove(mStackScroller);
+ mDrawingOrderedChildren.add(mStackScroller);
+ }
+
+ // Let's now find the order that the view has when drawing regulary by sorting
+ mLayoutDrawingOrder.sort(mIndexComparator);
+ super.dispatchDraw(canvas);
+ }
+
+ @Override
+ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ int layoutIndex = mLayoutDrawingOrder.indexOf(child);
+ if (layoutIndex >= 0) {
+ return super.drawChild(canvas, mDrawingOrderedChildren.get(layoutIndex), drawingTime);
} else {
return super.drawChild(canvas, child, drawingTime);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 65b0ecc00953..063d00b806c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -107,8 +107,12 @@ public abstract class PanelBar extends FrameLayout {
return mExpanded;
}
- private void updateVisibility() {
- mPanel.setVisibility(mExpanded || mBouncerShowing ? VISIBLE : INVISIBLE);
+ protected void updateVisibility() {
+ mPanel.setVisibility(shouldPanelBeVisible() ? VISIBLE : INVISIBLE);
+ }
+
+ protected boolean shouldPanelBeVisible() {
+ return mExpanded || mBouncerShowing;
}
public boolean panelEnabled() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index a9a3b2d866e1..a5b221bbad8c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -301,7 +301,7 @@ public abstract class PanelView extends FrameLayout {
final float y = event.getY(pointerIndex);
if (event.getActionMasked() == MotionEvent.ACTION_DOWN) {
- mGestureWaitForTouchSlop = isFullyCollapsed() || hasConflictingGestures();
+ mGestureWaitForTouchSlop = shouldGestureWaitForTouchSlop();
mIgnoreXTouchSlop = isFullyCollapsed() || shouldGestureIgnoreXTouchSlop(x, y);
}
@@ -519,7 +519,7 @@ public abstract class PanelView extends FrameLayout {
return (int) (mUnlockFalsingThreshold * factor);
}
- protected abstract boolean hasConflictingGestures();
+ protected abstract boolean shouldGestureWaitForTouchSlop();
protected abstract boolean shouldGestureIgnoreXTouchSlop(float x, float y);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 68eba50984d6..660810fe7eb9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -46,6 +46,7 @@ import com.android.systemui.R;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.DarkIconDispatcher.DarkReceiver;
import com.android.systemui.statusbar.CommandQueue;
+import com.android.systemui.statusbar.policy.HeadsUpManager;
import java.util.Objects;
@@ -82,6 +83,7 @@ public class PhoneStatusBarView extends PanelBar {
* Draw this many pixels into the left/right side of the cutout to optimally use the space
*/
private int mCutoutSideNudge = 0;
+ private boolean mHeadsUpVisible;
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -379,4 +381,14 @@ public class PhoneStatusBarView extends PanelBar {
}
return null;
}
+
+ public void setHeadsUpVisible(boolean headsUpVisible) {
+ mHeadsUpVisible = headsUpVisible;
+ updateVisibility();
+ }
+
+ @Override
+ protected boolean shouldPanelBeVisible() {
+ return mHeadsUpVisible || super.shouldPanelBeVisible();
+ }
}
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 1aa8bd79af35..4392c35ee233 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -172,7 +172,6 @@ import com.android.systemui.recents.ScreenPinningRequest;
import com.android.systemui.shared.system.WindowManagerWrapper;
import com.android.systemui.stackdivider.Divider;
import com.android.systemui.stackdivider.WindowManagerProxy;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.BackDropView;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CrossFadeHelper;
@@ -194,6 +193,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.ActivityLaunchAnimator;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationClicker;
@@ -201,6 +201,7 @@ import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.NotificationListController;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationRowBinderImpl;
@@ -227,7 +228,6 @@ import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.UserInfoControllerImpl;
import com.android.systemui.statusbar.policy.UserSwitcherController;
import com.android.systemui.statusbar.policy.ZenModeController;
-import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.InjectionInflationController;
import com.android.systemui.volume.VolumeComponent;
@@ -246,8 +246,7 @@ public class StatusBar extends SystemUI implements DemoMode,
OnHeadsUpChangedListener, CommandQueue.Callbacks, ZenModeController.Callback,
ColorExtractor.OnColorsChangedListener, ConfigurationListener,
StatusBarStateController.StateListener, ShadeController,
- ActivityLaunchAnimator.Callback, AmbientPulseManager.OnAmbientChangedListener,
- AppOpsController.Callback {
+ ActivityLaunchAnimator.Callback, AppOpsController.Callback {
public static final boolean MULTIUSER_DEBUG = false;
public static final boolean ENABLE_CHILD_NOTIFICATIONS
@@ -372,6 +371,15 @@ public class StatusBar extends SystemUI implements DemoMode,
PulseExpansionHandler mPulseExpansionHandler;
@Inject
NotificationWakeUpCoordinator mWakeUpCoordinator;
+ @Inject
+ KeyguardBypassController mKeyguardBypassController;
+ @Inject
+ protected HeadsUpManagerPhone mHeadsUpManager;
+ @Inject
+ BypassHeadsUpNotifier mBypassHeadsUpNotifier;
+ @Nullable
+ @Inject
+ protected KeyguardLiftController mKeyguardLiftController;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -629,6 +637,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mGutsManager = Dependency.get(NotificationGutsManager.class);
mMediaManager = Dependency.get(NotificationMediaManager.class);
mEntryManager = Dependency.get(NotificationEntryManager.class);
+ mBypassHeadsUpNotifier.setUp(mEntryManager);
mNotificationInterruptionStateProvider =
Dependency.get(NotificationInterruptionStateProvider.class);
mViewHierarchyManager = Dependency.get(NotificationViewHierarchyManager.class);
@@ -644,7 +653,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mActivityIntentHelper = new ActivityIntentHelper(mContext);
KeyguardSliceProvider sliceProvider = KeyguardSliceProvider.getAttachedInstance();
if (sliceProvider != null) {
- sliceProvider.initDependencies(mMediaManager, mStatusBarStateController);
+ sliceProvider.initDependencies(mMediaManager, mStatusBarStateController,
+ mKeyguardBypassController, DozeParameters.getInstance(mContext));
} else {
Log.w(TAG, "Cannot init KeyguardSliceProvider dependencies");
}
@@ -678,6 +688,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
+ mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
@@ -784,6 +795,7 @@ public class StatusBar extends SystemUI implements DemoMode,
inflateStatusBarWindow(context);
mStatusBarWindow.setService(this);
+ mStatusBarWindow.setBypassController(mKeyguardBypassController);
mStatusBarWindow.setOnTouchListener(getStatusBarWindowTouchListener());
// TODO: Deal with the ugliness that comes from having some of the statusbar broken out
@@ -795,9 +807,13 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationLogger.setUpWithContainer(notifListContainer);
mNotificationIconAreaController = SystemUIFactory.getInstance()
- .createNotificationIconAreaController(context, this, mStatusBarStateController);
+ .createNotificationIconAreaController(context, this,
+ mWakeUpCoordinator, mKeyguardBypassController,
+ mStatusBarStateController);
+ mWakeUpCoordinator.setIconAreaController(mNotificationIconAreaController);
inflateShelf();
mNotificationIconAreaController.setupShelf(mNotificationShelf);
+ mNotificationPanel.setOnReinflationListener(mNotificationIconAreaController::initAodIcons);
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
// Allow plugins to reference DarkIconDispatcher and StatusBarStateController
@@ -839,7 +855,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mHeadsUpAppearanceController.destroy();
}
mHeadsUpAppearanceController = new HeadsUpAppearanceController(
- mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow);
+ mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow,
+ mStatusBarStateController, mKeyguardBypassController);
mHeadsUpAppearanceController.readFrom(oldController);
mStatusBarWindow.setStatusBarView(mStatusBarView);
updateAreThereNotifications();
@@ -851,17 +868,13 @@ public class StatusBar extends SystemUI implements DemoMode,
.commit();
mIconController = Dependency.get(StatusBarIconController.class);
- mHeadsUpManager = new HeadsUpManagerPhone(context, mStatusBarWindow, mGroupManager, this,
- mVisualStabilityManager);
+ mHeadsUpManager.setUp(mStatusBarWindow, mGroupManager, this, mVisualStabilityManager);
Dependency.get(ConfigurationController.class).addCallback(mHeadsUpManager);
mHeadsUpManager.addListener(this);
mHeadsUpManager.addListener(mNotificationPanel);
mHeadsUpManager.addListener(mGroupManager);
mHeadsUpManager.addListener(mGroupAlertTransferHelper);
mHeadsUpManager.addListener(mVisualStabilityManager);
- mAmbientPulseManager.addListener(this);
- mAmbientPulseManager.addListener(mGroupManager);
- mAmbientPulseManager.addListener(mGroupAlertTransferHelper);
mNotificationPanel.setHeadsUpManager(mHeadsUpManager);
mGroupManager.setHeadsUpManager(mHeadsUpManager);
mGroupAlertTransferHelper.setHeadsUpManager(mHeadsUpManager);
@@ -1043,7 +1056,9 @@ public class StatusBar extends SystemUI implements DemoMode,
final NotificationRowBinderImpl rowBinder =
new NotificationRowBinderImpl(
mContext,
- SystemUIFactory.getInstance().provideAllowNotificationLongPress());
+ SystemUIFactory.getInstance().provideAllowNotificationLongPress(),
+ mKeyguardBypassController,
+ mStatusBarStateController);
mPresenter = new StatusBarNotificationPresenter(mContext, mNotificationPanel,
mHeadsUpManager, mStatusBarWindow, mStackScroller, mDozeScrimController,
@@ -1144,8 +1159,9 @@ public class StatusBar extends SystemUI implements DemoMode,
private void inflateShelf() {
mNotificationShelf =
- (NotificationShelf) LayoutInflater.from(mContext).inflate(
- R.layout.status_bar_notification_shelf, mStackScroller, false);
+ (NotificationShelf) mInjectionInflater.injectable(
+ LayoutInflater.from(mContext)).inflate(
+ R.layout.status_bar_notification_shelf, mStackScroller, false);
mNotificationShelf.setOnClickListener(mGoToLockedShadeListener);
}
@@ -1174,6 +1190,7 @@ public class StatusBar extends SystemUI implements DemoMode,
if (mAmbientIndicationContainer instanceof AutoReinflateContainer) {
((AutoReinflateContainer) mAmbientIndicationContainer).inflateLayout();
}
+ mNotificationIconAreaController.onThemeChanged();
}
@Override
@@ -1212,10 +1229,11 @@ public class StatusBar extends SystemUI implements DemoMode,
mBiometricUnlockController = new BiometricUnlockController(mContext,
mDozeScrimController, keyguardViewMediator,
mScrimController, this, UnlockMethodCache.getInstance(mContext),
- new Handler(), mKeyguardUpdateMonitor, Dependency.get(TunerService.class));
+ new Handler(), mKeyguardUpdateMonitor, mKeyguardBypassController);
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
- mStatusBarWindow.findViewById(R.id.lock_icon_container));
+ mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
+ mKeyguardBypassController);
mKeyguardIndicationController
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
@@ -1530,10 +1548,16 @@ public class StatusBar extends SystemUI implements DemoMode,
});
}
} else {
- if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()) {
+ boolean bypassKeyguard = mKeyguardBypassController.getBypassEnabled()
+ && mState == StatusBarState.KEYGUARD;
+ if (!mNotificationPanel.isFullyCollapsed() || mNotificationPanel.isTracking()
+ || bypassKeyguard) {
// We are currently tracking or is open and the shade doesn't need to be kept
// open artificially.
mStatusBarWindowController.setHeadsUpShowing(false);
+ if (bypassKeyguard) {
+ mStatusBarWindowController.setForceStatusBarVisible(false);
+ }
} else {
// we need to keep the panel open artificially, let's wait until the animation
// is finished.
@@ -1550,25 +1574,15 @@ public class StatusBar extends SystemUI implements DemoMode,
}
@Override
- public void onHeadsUpPinned(NotificationEntry entry) {
- dismissVolumeDialog();
- }
-
- @Override
- public void onHeadsUpUnPinned(NotificationEntry entry) {
- }
-
- @Override
public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
mEntryManager.updateNotifications();
- }
-
- @Override
- public void onAmbientStateChanged(NotificationEntry entry, boolean isAmbient) {
- mEntryManager.updateNotifications();
- if (isAmbient) {
+ if (isDozing() && isHeadsUp) {
mDozeServiceHost.fireNotificationPulse();
- } else if (!mAmbientPulseManager.hasNotifications()) {
+ if (mPulsing) {
+ mDozeScrimController.cancelPendingPulseTimeout();
+ }
+ }
+ if (!isHeadsUp && !mHeadsUpManager.hasNotifications()) {
// There are no longer any notifications to show. We should end the pulse now.
mDozeScrimController.pulseOutNow();
}
@@ -1666,7 +1680,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- public boolean isHeadsUpShouldBeVisible() {
+ public boolean headsUpShouldBeVisible() {
return mHeadsUpAppearanceController.shouldBeVisible();
}
@@ -1914,19 +1928,18 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarKeyguardViewManager.readyForKeyguardDone();
}
- public void dispatchNotificationsPanelTouchEvent(MotionEvent ev) {
+ /**
+ * Called when another window is about to transfer it's input focus.
+ */
+ public void onInputFocusTransfer(boolean start, float velocity) {
if (!mCommandQueue.panelsEnabled()) {
return;
}
- mNotificationPanel.dispatchTouchEvent(ev);
- int action = ev.getAction();
- if (action == MotionEvent.ACTION_DOWN) {
- // Start ignoring all touch events coming to status bar window.
- // TODO: handle case where ACTION_UP is not sent over the binder
- mStatusBarWindowController.setNotTouchable(true);
- } else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- mStatusBarWindowController.setNotTouchable(false);
+ if (start) {
+ mNotificationPanel.startWaitingForOpenPanelGesture();
+ } else {
+ mNotificationPanel.stopWaitingForOpenPanelGesture(velocity);
}
}
@@ -2116,6 +2129,7 @@ public class StatusBar extends SystemUI implements DemoMode,
checkBarModes();
mAutoHideController.touchAutoHide();
}
+ mStatusBarStateController.setSystemUiVisibility(mSystemUiVisibility);
}
mLightBarController.onSystemUiVisibilityChanged(fullscreenStackVis, dockedStackVis,
mask, fullscreenStackBounds, dockedStackBounds, sbModeChanged, mStatusBarMode,
@@ -2605,8 +2619,8 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- private void executeWhenUnlocked(OnDismissAction action) {
- if (mStatusBarKeyguardViewManager.isShowing()) {
+ private void executeWhenUnlocked(OnDismissAction action, boolean requiresShadeOpen) {
+ if (mStatusBarKeyguardViewManager.isShowing() && requiresShadeOpen) {
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
}
dismissKeyguardThenExecute(action, null /* cancelAction */, false /* afterKeyguardGone */);
@@ -3156,6 +3170,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationPanel.onAffordanceLaunchEnded();
mNotificationPanel.animate().cancel();
mNotificationPanel.setAlpha(1f);
+ ViewGroupFadeHelper.reset(mNotificationPanel);
updateScrimController();
Trace.endSection();
return staying;
@@ -3567,6 +3582,9 @@ public class StatusBar extends SystemUI implements DemoMode,
*/
public void setBouncerShowing(boolean bouncerShowing) {
mBouncerShowing = bouncerShowing;
+ mKeyguardBypassController.setBouncerShowing(bouncerShowing);
+ mPulseExpansionHandler.setBouncerShowing(bouncerShowing);
+ mStatusBarWindow.setBouncerShowingScrimmed(isBouncerShowingScrimmed());
if (mStatusBarView != null) mStatusBarView.setBouncerShowing(bouncerShowing);
updateHideIconsForBouncer(true /* animate */);
mCommandQueue.recomputeDisableFlags(mDisplayId, true /* animate */);
@@ -3618,13 +3636,18 @@ public class StatusBar extends SystemUI implements DemoMode,
updateNotificationPanelTouchState();
notifyHeadsUpGoingToSleep();
dismissVolumeDialog();
+ mWakeUpCoordinator.setFullyAwake(false);
+ mBypassHeadsUpNotifier.setFullyAwake(false);
+ mKeyguardBypassController.onStartedGoingToSleep();
}
@Override
public void onStartedWakingUp() {
mDeviceInteractive = true;
mWakeUpCoordinator.setWakingUp(true);
- mAmbientPulseManager.releaseAllImmediately();
+ if (!mKeyguardBypassController.getBypassEnabled()) {
+ mHeadsUpManager.releaseAllImmediately();
+ }
mVisualStabilityManager.setScreenOn(true);
updateVisibleToUser();
updateIsKeyguard();
@@ -3638,6 +3661,8 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void onFinishedWakingUp() {
+ mWakeUpCoordinator.setFullyAwake(true);
+ mBypassHeadsUpNotifier.setFullyAwake(true);
mWakeUpCoordinator.setWakingUp(false);
if (mLaunchCameraWhenFinishedWaking) {
mNotificationPanel.launchCamera(false /* animate */, mLastCameraLaunchSource);
@@ -3655,8 +3680,9 @@ public class StatusBar extends SystemUI implements DemoMode,
private void updateNotificationPanelTouchState() {
boolean goingToSleepWithoutAnimation = isGoingToSleep()
&& !DozeParameters.getInstance(mContext).shouldControlScreenOff();
- mNotificationPanel.setTouchAndAnimationDisabled((!mDeviceInteractive && !mPulsing)
- || goingToSleepWithoutAnimation);
+ boolean disabled = (!mDeviceInteractive && !mPulsing) || goingToSleepWithoutAnimation;
+ mNotificationPanel.setTouchAndAnimationDisabled(disabled);
+ mNotificationIconAreaController.setAnimationsEnabled(!disabled);
}
final ScreenLifecycle.Observer mScreenObserver = new ScreenLifecycle.Observer() {
@@ -3748,6 +3774,12 @@ public class StatusBar extends SystemUI implements DemoMode,
"com.android.systemui:CAMERA_GESTURE");
}
vibrateForCameraGesture();
+
+ if (source == StatusBarManager.CAMERA_LAUNCH_SOURCE_POWER_DOUBLE_TAP) {
+ Log.v(TAG, "Camera launch");
+ mKeyguardUpdateMonitor.onCameraLaunched();
+ }
+
if (!mStatusBarKeyguardViewManager.isShowing()) {
startActivityDismissingKeyguard(KeyguardBottomAreaView.INSECURE_CAMERA_INTENT,
false /* onlyProvisioned */, true /* dismissShade */,
@@ -3804,7 +3836,8 @@ public class StatusBar extends SystemUI implements DemoMode,
public void notifyBiometricAuthModeChanged() {
updateDozing();
updateScrimController();
- mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock());
+ mStatusBarWindow.onBiometricAuthModeChanged(mBiometricUnlockController.isWakeAndUnlock(),
+ mBiometricUnlockController.isBiometricUnlock());
}
@VisibleForTesting
@@ -3864,6 +3897,9 @@ public class StatusBar extends SystemUI implements DemoMode,
private boolean mAnimateWakeup;
private boolean mAnimateScreenOff;
private boolean mIgnoreTouchWhilePulsing;
+ @VisibleForTesting
+ boolean mWakeLockScreenPerformsAuth = SystemProperties.getBoolean(
+ "persist.sysui.wake_performs_auth", true);
@Override
public String toString() {
@@ -3919,7 +3955,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mStatusBarWindow.suppressWakeUpGesture(true);
}
- boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_NOTIFICATION;
+ boolean passiveAuthInterrupt = reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN
+ && mWakeLockScreenPerformsAuth;
// Set the state to pulsing, so ScrimController will know what to do once we ask it to
// execute the transition. The pulse callback will then be invoked when the scrims
// are black, indicating that StatusBar is ready to present the rest of the UI.
@@ -3945,6 +3982,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
private void setPulsing(boolean pulsing) {
+ mStatusBarStateController.setPulsing(pulsing);
mStatusBarKeyguardViewManager.setPulsing(pulsing);
mKeyguardViewMediator.setPulsing(pulsing);
mNotificationPanel.setPulsing(pulsing);
@@ -4023,8 +4061,8 @@ public class StatusBar extends SystemUI implements DemoMode,
if (reason == DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN) {
mScrimController.setWakeLockScreenSensorActive(true);
}
- if (mDozeScrimController.isPulsing() && mAmbientPulseManager.hasNotifications()) {
- mAmbientPulseManager.extendPulse();
+ if (mDozeScrimController.isPulsing() && mHeadsUpManager.hasNotifications()) {
+ mHeadsUpManager.extendHeadsUp();
} else {
mDozeScrimController.extendPulse();
}
@@ -4113,12 +4151,6 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
-
- // for heads up notifications
- protected HeadsUpManagerPhone mHeadsUpManager;
-
- protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
-
// handling reordering
protected VisualStabilityManager mVisualStabilityManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 93168db861be..20bc2a742de6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
+import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_UNLOCK_FADING;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK;
import static com.android.systemui.statusbar.phone.BiometricUnlockController.MODE_WAKE_AND_UNLOCK_PULSING;
@@ -51,6 +52,7 @@ import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.ViewGroupFadeHelper;
import com.android.systemui.statusbar.phone.KeyguardBouncer.BouncerExpansionCallback;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
@@ -82,6 +84,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
// make everything a bit slower to bridge a gap until the user is unlocked and home screen has
// dranw its first frame.
private static final long KEYGUARD_DISMISS_DURATION_LOCKED = 2000;
+ private static final long BYPASS_PANEL_FADE_DURATION = 67;
private static String TAG = "StatusBarKeyguardViewManager";
@@ -132,6 +135,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private ViewGroup mContainer;
private ViewGroup mLockIconContainer;
+ private View mNotificationContainer;
protected KeyguardBouncer mBouncer;
protected boolean mShowing;
@@ -165,9 +169,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
(KeyguardMonitorImpl) Dependency.get(KeyguardMonitor.class);
private final NotificationMediaManager mMediaManager =
Dependency.get(NotificationMediaManager.class);
- private final StatusBarStateController mStatusBarStateController =
- Dependency.get(StatusBarStateController.class);
+ private final SysuiStatusBarStateController mStatusBarStateController =
+ (SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class);
private final DockManager mDockManager;
+ private KeyguardBypassController mBypassController;
private final KeyguardUpdateMonitorCallback mUpdateMonitorCallback =
new KeyguardUpdateMonitorCallback() {
@@ -205,7 +210,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
NotificationPanelView notificationPanelView,
BiometricUnlockController biometricUnlockController,
DismissCallbackRegistry dismissCallbackRegistry,
- ViewGroup lockIconContainer) {
+ ViewGroup lockIconContainer, View notificationContainer,
+ KeyguardBypassController bypassController) {
mStatusBar = statusBar;
mContainer = container;
mLockIconContainer = lockIconContainer;
@@ -218,6 +224,8 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mExpansionCallback);
mNotificationPanelView = notificationPanelView;
notificationPanelView.setExpansionListener(this);
+ mBypassController = bypassController;
+ mNotificationContainer = notificationContainer;
}
@Override
@@ -555,12 +563,32 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mBiometricUnlockController.startKeyguardFadingAway();
hideBouncer(true /* destroyView */);
if (wakeUnlockPulsing) {
- mStatusBar.fadeKeyguardWhilePulsing();
+ if (needsBypassFading()) {
+ ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
+ mNotificationContainer,
+ BYPASS_PANEL_FADE_DURATION,
+ () -> {
+ mStatusBar.hideKeyguard();
+ onKeyguardFadedAway();
+ });
+ } else {
+ mStatusBar.fadeKeyguardWhilePulsing();
+ }
wakeAndUnlockDejank();
} else {
- boolean staying = mStatusBar.hideKeyguard();
+ boolean staying = mStatusBarStateController.leaveOpenOnKeyguardHide();
if (!staying) {
mStatusBarWindowController.setKeyguardFadingAway(true);
+ if (needsBypassFading()) {
+ ViewGroupFadeHelper.fadeOutAllChildrenExcept(mNotificationPanelView,
+ mNotificationContainer,
+ BYPASS_PANEL_FADE_DURATION,
+ () -> {
+ mStatusBar.hideKeyguard();
+ });
+ } else {
+ mStatusBar.hideKeyguard();
+ }
// hide() will happen asynchronously and might arrive after the scrims
// were already hidden, this means that the transition callback won't
// be triggered anymore and StatusBarWindowController will be forever in
@@ -568,6 +596,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mStatusBar.updateScrimController();
wakeAndUnlockDejank();
} else {
+ mStatusBar.hideKeyguard();
mStatusBar.finishKeyguardFadingAway();
mBiometricUnlockController.finishKeyguardFadingAway();
}
@@ -580,6 +609,13 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
StatsLog.KEYGUARD_STATE_CHANGED__STATE__HIDDEN);
}
+ private boolean needsBypassFading() {
+ return (mBiometricUnlockController.getMode() == MODE_UNLOCK_FADING
+ || mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK_PULSING
+ || mBiometricUnlockController.getMode() == MODE_WAKE_AND_UNLOCK)
+ && mBypassController.getBypassEnabled();
+ }
+
@Override
public void onDensityOrFontScaleChanged() {
hideBouncer(true /* destroyView */);
@@ -602,6 +638,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
public void onKeyguardFadedAway() {
mContainer.postDelayed(() -> mStatusBarWindowController.setKeyguardFadingAway(false),
100);
+ ViewGroupFadeHelper.reset(mNotificationPanelView);
mStatusBar.finishKeyguardFadingAway();
mBiometricUnlockController.finishKeyguardFadingAway();
WindowManagerGlobal.getInstance().trimMemory(
@@ -677,8 +714,12 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return mBouncer.isShowing();
}
- public boolean isBouncerPartiallyVisible() {
- return mBouncer.isPartiallyVisible();
+ /**
+ * When bouncer is fully visible or {@link KeyguardBouncer#show(boolean)} was called but
+ * animation didn't finish yet.
+ */
+ public boolean bouncerIsOrWillBeShowing() {
+ return mBouncer.isShowing() || mBouncer.willShowSoon();
}
public boolean isFullscreenBouncer() {
@@ -812,6 +853,14 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
return mStatusBar.isInLaunchTransition();
}
+
+ /**
+ * @return Whether subtle animation should be used for unlocking the device.
+ */
+ public boolean shouldSubtleWindowAnimationsForUnlock() {
+ return needsBypassFading();
+ }
+
public boolean isGoingToNotificationShade() {
return ((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
.leaveOpenOnKeyguardHide();
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 e00d439dc1c7..bec53a1b2d3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -406,8 +406,7 @@ public class StatusBarNotificationActivityStarter implements NotificationActivit
}
private void handleFullScreenIntent(NotificationEntry entry) {
- boolean isHeadsUped = mNotificationInterruptionStateProvider.shouldHeadsUp(entry);
- if (!isHeadsUped && entry.notification.getNotification().fullScreenIntent != null) {
+ if (mNotificationInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry)) {
if (shouldSuppressFullScreenIntent(entry)) {
if (DEBUG) {
Log.d(TAG, "No Fullscreen intent: suppressed by DND: " + entry.key);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
index 6fe89645ef19..a87dca45bf75 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationPresenter.java
@@ -49,7 +49,6 @@ import com.android.systemui.R;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
@@ -106,7 +105,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
Dependency.get(VisualStabilityManager.class);
private final NotificationGutsManager mGutsManager =
Dependency.get(NotificationGutsManager.class);
- protected AmbientPulseManager mAmbientPulseManager = Dependency.get(AmbientPulseManager.class);
private final NotificationPanelView mNotificationPanel;
private final HeadsUpManagerPhone mHeadsUpManager;
@@ -213,7 +211,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
mEntryManager.setUpWithPresenter(this, notifListContainer, mHeadsUpManager);
mEntryManager.addNotificationEntryListener(notificationEntryListener);
mEntryManager.addNotificationLifetimeExtender(mHeadsUpManager);
- mEntryManager.addNotificationLifetimeExtender(mAmbientPulseManager);
mEntryManager.addNotificationLifetimeExtender(mGutsManager);
mEntryManager.addNotificationLifetimeExtenders(
remoteInputManager.getLifetimeExtenders());
@@ -297,7 +294,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
private void maybeEndAmbientPulse() {
if (mNotificationPanel.hasPulsingNotifications() &&
- !mAmbientPulseManager.hasNotifications()) {
+ !mHeadsUpManager.hasNotifications()) {
// We were showing a pulse for a notification, but no notifications are pulsing anymore.
// Finish the pulse.
mDozeScrimController.pulseOutNow();
@@ -343,10 +340,6 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
}
public boolean canHeadsUp(NotificationEntry entry, StatusBarNotification sbn) {
- if (mShadeController.isDozing()) {
- return false;
- }
-
if (mShadeController.isOccluded()) {
boolean devicePublic = mLockscreenUserManager.
isLockscreenPublicMode(mLockscreenUserManager.getCurrentUserId());
@@ -354,6 +347,7 @@ public class StatusBarNotificationPresenter implements NotificationPresenter,
|| mLockscreenUserManager.isLockscreenPublicMode(sbn.getUserId());
boolean needsRedaction = mLockscreenUserManager.needsRedaction(entry);
if (userPublic && needsRedaction) {
+ // TODO(b/135046837): we can probably relax this with dynamic privacy
return false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
index 6691f7a759f3..13d4b8edb8d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarRemoteInputCallback.java
@@ -48,6 +48,7 @@ import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
+import com.android.systemui.statusbar.policy.RemoteInputView;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -93,9 +94,11 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks,
@Override
public void onStateChanged(int state) {
- if (state == StatusBarState.SHADE && mStatusBarStateController.leaveOpenOnKeyguardHide()) {
+ boolean hasPendingRemoteInput = mPendingRemoteInputView != null;
+ if (state == StatusBarState.SHADE
+ && (mStatusBarStateController.leaveOpenOnKeyguardHide() || hasPendingRemoteInput)) {
if (!mStatusBarStateController.isKeyguardRequested()) {
- if (mPendingRemoteInputView != null) {
+ if (hasPendingRemoteInput) {
mMainHandler.post(mPendingRemoteInputView::callOnClick);
}
mPendingRemoteInputView = null;
@@ -105,7 +108,9 @@ public class StatusBarRemoteInputCallback implements Callback, Callbacks,
@Override
public void onLockedRemoteInput(ExpandableNotificationRow row, View clicked) {
- mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+ if (!row.isPinned()) {
+ mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
+ }
mShadeController.showBouncer(true /* scrimmed */);
mPendingRemoteInputView = clicked;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
index e949ade28b59..3d25749265f1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarTouchableRegionManager.java
@@ -26,7 +26,6 @@ import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnComputeInternalInsetsListener;
import com.android.systemui.Dependency;
-import com.android.systemui.assist.AssistManager;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ConfigurationController.ConfigurationListener;
@@ -38,7 +37,6 @@ import com.android.systemui.statusbar.policy.ConfigurationController.Configurati
public final class StatusBarTouchableRegionManager implements
OnComputeInternalInsetsListener, ConfigurationListener {
- private final AssistManager mAssistManager = Dependency.get(AssistManager.class);
private final BubbleController mBubbleController = Dependency.get(BubbleController.class);
private final Context mContext;
private final HeadsUpManagerPhone mHeadsUpManager;
@@ -48,6 +46,7 @@ public final class StatusBarTouchableRegionManager implements
private int mStatusBarHeight;
private final View mStatusBarWindowView;
private boolean mForceCollapsedUntilLayout = false;
+ private final StatusBarWindowController mStatusBarWindowController;
public StatusBarTouchableRegionManager(@NonNull Context context,
HeadsUpManagerPhone headsUpManager,
@@ -57,12 +56,17 @@ public final class StatusBarTouchableRegionManager implements
mHeadsUpManager = headsUpManager;
mStatusBar = statusBar;
mStatusBarWindowView = statusBarWindowView;
+ mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
initResources();
mBubbleController.setBubbleStateChangeListener((hasBubbles) -> {
updateTouchableRegion();
});
+
+ mStatusBarWindowController.setForcePluginOpenListener((forceOpen) -> {
+ updateTouchableRegion();
+ });
Dependency.get(ConfigurationController.class).addCallback(this);
}
@@ -77,7 +81,8 @@ public final class StatusBarTouchableRegionManager implements
mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpManager.isHeadsUpGoingAway()
|| mBubbleController.hasBubbles()
|| mForceCollapsedUntilLayout
- || hasCutoutInset;
+ || hasCutoutInset
+ || mStatusBarWindowController.getForcePluginOpen();
if (shouldObserve == mShouldAdjustInsets) {
return;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index 8621b7293711..4ddd0e9962ad 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -74,6 +74,7 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
private final DozeParameters mDozeParameters;
private final WindowManager.LayoutParams mLpChanged;
private final boolean mKeyguardScreenRotation;
+ private final long mLockScreenDisplayTimeout;
private ViewGroup mStatusBarView;
private WindowManager.LayoutParams mLp;
private boolean mHasTopUi;
@@ -82,6 +83,7 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
private float mScreenBrightnessDoze;
private final State mCurrentState = new State();
private OtherwisedCollapsedListener mListener;
+ private ForcePluginOpenListener mForcePluginOpenListener;
private final ArrayList<WeakReference<StatusBarWindowCallback>>
mCallbacks = Lists.newArrayList();
@@ -103,6 +105,8 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
mDozeParameters = dozeParameters;
mScreenBrightnessDoze = mDozeParameters.getScreenBrightnessDoze();
mLpChanged = new WindowManager.LayoutParams();
+ mLockScreenDisplayTimeout = context.getResources()
+ .getInteger(R.integer.config_lockScreenDisplayTimeout);
((SysuiStatusBarStateController) Dependency.get(StatusBarStateController.class))
.addCallback(mStateListener,
SysuiStatusBarStateController.RANK_STATUS_BAR_WINDOW_CONTROLLER);
@@ -279,7 +283,8 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
if (state.isKeyguardShowingAndNotOccluded()
&& state.statusBarState == StatusBarState.KEYGUARD
&& !state.qsExpanded) {
- mLpChanged.userActivityTimeout = KeyguardViewMediator.AWAKE_INTERVAL_DEFAULT_MS;
+ mLpChanged.userActivityTimeout = state.bouncerShowing
+ ? KeyguardViewMediator.AWAKE_INTERVAL_BOUNCER_MS : mLockScreenDisplayTimeout;
} else {
mLpChanged.userActivityTimeout = -1;
}
@@ -506,6 +511,16 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
public void setForcePluginOpen(boolean forcePluginOpen) {
mCurrentState.forcePluginOpen = forcePluginOpen;
apply(mCurrentState);
+ if (mForcePluginOpenListener != null) {
+ mForcePluginOpenListener.onChange(forcePluginOpen);
+ }
+ }
+
+ /**
+ * The forcePluginOpen state for the status bar.
+ */
+ public boolean getForcePluginOpen() {
+ return mCurrentState.forcePluginOpen;
}
public void setNotTouchable(boolean notTouchable) {
@@ -554,6 +569,10 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
mListener = listener;
}
+ public void setForcePluginOpenListener(ForcePluginOpenListener listener) {
+ mForcePluginOpenListener = listener;
+ }
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("StatusBarWindowController state:");
pw.println(mCurrentState);
@@ -656,4 +675,14 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
public interface OtherwisedCollapsedListener {
void setWouldOtherwiseCollapse(boolean otherwiseCollapse);
}
+
+ /**
+ * Listener to indicate forcePluginOpen has changed
+ */
+ public interface ForcePluginOpenListener {
+ /**
+ * Called when mState.forcePluginOpen is changed
+ */
+ void onChange(boolean forceOpen);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index 7d5f23bc1e58..94054188d769 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -149,6 +149,7 @@ public class StatusBarWindowView extends FrameLayout {
* events manually as it's outside of the regular view bounds.
*/
private boolean mExpandingBelowNotch;
+ private KeyguardBypassController mBypassController;
public StatusBarWindowView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -271,10 +272,11 @@ public class StatusBarWindowView extends FrameLayout {
/**
* Called when the biometric authentication mode changes.
* @param wakeAndUnlock If the type is {@link BiometricUnlockController#isWakeAndUnlock()}
+ * @param isUnlock If the type is {@link BiometricUnlockController#isBiometricUnlock()} ()
*/
- public void onBiometricAuthModeChanged(boolean wakeAndUnlock) {
+ public void onBiometricAuthModeChanged(boolean wakeAndUnlock, boolean isUnlock) {
if (mLockIcon != null) {
- mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock);
+ mLockIcon.onBiometricAuthModeChanged(wakeAndUnlock, isUnlock);
}
}
@@ -415,9 +417,9 @@ public class StatusBarWindowView extends FrameLayout {
}
boolean intercept = false;
if (mNotificationPanel.isFullyExpanded()
- && stackScrollLayout.getVisibility() == View.VISIBLE
&& mStatusBarStateController.getState() == StatusBarState.KEYGUARD
&& !mService.isBouncerShowing()
+ && !mBypassController.getBypassEnabled()
&& !mService.isDozing()) {
intercept = mDragDownHelper.onInterceptTouchEvent(ev);
}
@@ -440,7 +442,8 @@ public class StatusBarWindowView extends FrameLayout {
if (mService.isDozing()) {
handled = !mService.isPulsing();
}
- if ((mStatusBarStateController.getState() == StatusBarState.KEYGUARD && !handled)
+ if ((mStatusBarStateController.getState() == StatusBarState.KEYGUARD && !handled
+ && !mBypassController.getBypassEnabled())
|| mDragDownHelper.isDraggingDown()) {
// we still want to finish our drag down gesture when locking the screen
handled = mDragDownHelper.onTouchEvent(ev);
@@ -519,6 +522,16 @@ public class StatusBarWindowView extends FrameLayout {
}
}
+ public void setBypassController(KeyguardBypassController bypassController) {
+ mBypassController = bypassController;
+ }
+
+ public void setBouncerShowingScrimmed(boolean bouncerShowing) {
+ if (mLockIcon != null) {
+ mLockIcon.setBouncerShowingScrimmed(bouncerShowing);
+ }
+ }
+
public class LayoutParams extends FrameLayout.LayoutParams {
public boolean ignoreRightInset;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index 39bf7283e1be..f36c56f60965 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -16,18 +16,14 @@
package com.android.systemui.statusbar.phone;
-import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.biometrics.BiometricSourceType;
-import android.media.AudioManager;
import android.os.Build;
import android.os.Trace;
-import android.telephony.TelephonyManager;
-import com.android.internal.telephony.TelephonyIntents;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
@@ -55,6 +51,7 @@ public class UnlockMethodCache {
private boolean mTrustManaged;
private boolean mTrusted;
private boolean mDebugUnlocked = false;
+ private boolean mIsUnlockingWithFacePossible;
private UnlockMethodCache(Context ctx) {
mLockPatternUtils = new LockPatternUtils(ctx);
@@ -110,6 +107,10 @@ public class UnlockMethodCache {
mListeners.remove(listener);
}
+ public boolean isUnlockingWithFacePossible() {
+ return mIsUnlockingWithFacePossible;
+ }
+
private void update(boolean updateAlways) {
Trace.beginSection("UnlockMethodCache#update");
int user = KeyguardUpdateMonitor.getCurrentUser();
@@ -118,13 +119,15 @@ public class UnlockMethodCache {
|| (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
+ boolean hasEnrolledFaces = mKeyguardUpdateMonitor.isUnlockWithFacePossible(user);
boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
- trustManaged != mTrustManaged;
+ trustManaged != mTrustManaged || mIsUnlockingWithFacePossible != hasEnrolledFaces;
if (changed || updateAlways) {
mSecure = secure;
mCanSkipBouncer = canSkipBouncer;
mTrusted = trusted;
mTrustManaged = trustManaged;
+ mIsUnlockingWithFacePossible = hasEnrolledFaces;
notifyListeners();
}
Trace.endSection();
@@ -187,6 +190,11 @@ public class UnlockMethodCache {
public void onKeyguardVisibilityChanged(boolean showing) {
update(false /* updateAlways */);
}
+
+ @Override
+ public void onBiometricsCleared() {
+ update(false /* alwaysUpdate */);
+ }
};
public boolean isTrustManaged() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index d1a225320eb7..b84dc476dd6f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -356,6 +356,10 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
public void onDensityOrFontScaleChanged() {
}
+ public boolean isEntryAutoHeadsUpped(String key) {
+ return false;
+ }
+
/**
* This represents a notification and how long it is in a heads up mode. It also manages its
* lifecycle automatically when created.
@@ -416,16 +420,17 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
@Override
protected long calculateFinishTime() {
- return mPostTime + getRecommendedTimeoutMillis();
+ return mPostTime + getRecommendedHeadsUpTimeoutMs(mAutoDismissNotificationDecay);
}
/**
* Get user-preferred or default timeout duration. The larger one will be returned.
* @return milliseconds before auto-dismiss
+ * @param requestedTimeout
*/
- private int getRecommendedTimeoutMillis() {
+ protected int getRecommendedHeadsUpTimeoutMs(int requestedTimeout) {
return mAccessibilityMgr.getRecommendedTimeoutMillis(
- mAutoDismissNotificationDecay,
+ requestedTimeout,
AccessibilityManager.FLAG_CONTENT_CONTROLS
| AccessibilityManager.FLAG_CONTENT_ICONS
| AccessibilityManager.FLAG_CONTENT_TEXT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
index 01498e6bd54d..f61b556e22ab 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitor.java
@@ -50,5 +50,6 @@ public interface KeyguardMonitor extends CallbackController<Callback> {
interface Callback {
void onKeyguardShowingChanged();
+ default void onKeyguardFadingAwayChanged() {}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
index b53ff0e45cea..68d00708b0d3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardMonitorImpl.java
@@ -141,14 +141,24 @@ public class KeyguardMonitorImpl extends KeyguardUpdateMonitorCallback
}
public void notifyKeyguardFadingAway(long delay, long fadeoutDuration) {
- mKeyguardFadingAway = true;
+ setKeyguardFadingAway(true);
mKeyguardFadingAwayDelay = delay;
mKeyguardFadingAwayDuration = fadeoutDuration;
}
+ private void setKeyguardFadingAway(boolean keyguardFadingAway) {
+ if (mKeyguardFadingAway != keyguardFadingAway) {
+ mKeyguardFadingAway = keyguardFadingAway;
+ ArrayList<Callback> callbacks = new ArrayList<>(mCallbacks);
+ for (int i = 0; i < callbacks.size(); i++) {
+ callbacks.get(i).onKeyguardFadingAwayChanged();
+ }
+ }
+ }
+
public void notifyKeyguardDoneFading() {
- mKeyguardFadingAway = false;
mKeyguardGoingAway = false;
+ setKeyguardFadingAway(false);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 13f93b923505..b21ba096c361 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -376,9 +376,9 @@ public class MobileSignalController extends SignalController<
}
private void updateDataSim() {
- int defaultDataSub = mDefaults.getDefaultDataSubId();
- if (SubscriptionManager.isValidSubscriptionId(defaultDataSub)) {
- mCurrentState.dataSim = defaultDataSub == mSubscriptionInfo.getSubscriptionId();
+ int activeDataSubId = mDefaults.getActiveDataSubId();
+ if (SubscriptionManager.isValidSubscriptionId(activeDataSubId)) {
+ mCurrentState.dataSim = activeDataSubId == mSubscriptionInfo.getSubscriptionId();
} else {
// There doesn't seem to be a data sim selected, however if
// there isn't a MobileSignalController with dataSim set, then
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index b2972fcd1286..d545dc8f7428 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -361,7 +361,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
private MobileSignalController getDataController() {
- int dataSubId = mSubDefaults.getDefaultDataSubId();
+ int dataSubId = mSubDefaults.getActiveDataSubId();
if (!SubscriptionManager.isValidSubscriptionId(dataSubId)) {
if (DEBUG) Log.e(TAG, "No data sim selected");
return mDefaultSignalController;
@@ -1098,6 +1098,10 @@ public class NetworkControllerImpl extends BroadcastReceiver
public int getDefaultDataSubId() {
return SubscriptionManager.getDefaultDataSubscriptionId();
}
+
+ public int getActiveDataSubId() {
+ return SubscriptionManager.getActiveDataSubscriptionId();
+ }
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
index 438226ae082d..94aa39142926 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/OnHeadsUpChangedListener.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.policy;
+import android.annotation.NonNull;
+
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
/**
@@ -45,5 +47,5 @@ public interface OnHeadsUpChangedListener {
* @param entry the entry of the changed notification
* @param isHeadsUp whether the notification is now a headsUp notification
*/
- default void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {}
+ default void onHeadsUpStateChanged(@NonNull NotificationEntry entry, boolean isHeadsUp) {}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
index 640f0f0cc3f6..282d28c3b20c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyView.java
@@ -303,7 +303,7 @@ public class SmartReplyView extends ViewGroup {
};
OnClickListener onClickListener = view ->
- smartReplyView.mKeyguardDismissUtil.executeWhenUnlocked(action);
+ smartReplyView.mKeyguardDismissUtil.executeWhenUnlocked(action, !entry.isRowPinned());
if (useDelayedOnClickListener) {
onClickListener = new DelayedOnClickListener(onClickListener,
smartReplyView.mConstants.getOnClickInitDelay());
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
index 930016be2d22..41e026af7c72 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayManager.java
@@ -172,10 +172,15 @@ class ThemeOverlayManager {
private void setEnabledAsync(String pkg, UserHandle userHandle, boolean enabled) {
mExecutor.execute(() -> {
if (DEBUG) Log.d(TAG, String.format("setEnabled: %s %s %b", pkg, userHandle, enabled));
- if (enabled) {
- mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle);
- } else {
- mOverlayManager.setEnabled(pkg, false, userHandle);
+ try {
+ if (enabled) {
+ mOverlayManager.setEnabledExclusiveInCategory(pkg, userHandle);
+ } else {
+ mOverlayManager.setEnabled(pkg, false, userHandle);
+ }
+ } catch (IllegalStateException e) {
+ Log.e(TAG,
+ String.format("setEnabled failed: %s %s %b", pkg, userHandle, enabled), e);
}
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
index 31f4991a82b5..b9c5ee5a7a7e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
+++ b/packages/SystemUI/src/com/android/systemui/util/AsyncSensorManager.java
@@ -156,17 +156,21 @@ public class AsyncSensorManager extends SensorManager
* Requests for all sensors that match the given type from all plugins.
* @param sensor
* @param listener
+ * @return true if there were plugins to register the listener to
*/
- public void registerPluginListener(SensorManagerPlugin.Sensor sensor,
+ public boolean registerPluginListener(SensorManagerPlugin.Sensor sensor,
SensorManagerPlugin.SensorEventListener listener) {
if (mPlugins.isEmpty()) {
Log.w(TAG, "No plugins registered");
+ return false;
}
mHandler.post(() -> {
for (int i = 0; i < mPlugins.size(); i++) {
mPlugins.get(i).registerListener(sensor, listener);
}
});
+
+ return true;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
index d521e5534ad4..ede30046d6c3 100644
--- a/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
+++ b/packages/SystemUI/src/com/android/systemui/util/InjectionInflationController.java
@@ -32,6 +32,7 @@ import com.android.systemui.qs.QSFooterImpl;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.qs.QuickQSPanel;
import com.android.systemui.qs.QuickStatusBarHeader;
+import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.NotificationPanelView;
@@ -138,6 +139,11 @@ public class InjectionInflationController {
QSCarrierGroup createQSCarrierGroup();
/**
+ * Creates the Shelf.
+ */
+ NotificationShelf creatNotificationShelf();
+
+ /**
* Creates the KeyguardClockSwitch.
*/
KeyguardClockSwitch createKeyguardClockSwitch();
diff --git a/packages/SystemUI/tests/res/values/overlayable_icons_test.xml b/packages/SystemUI/tests/res/values/overlayable_icons_test.xml
index ba651ac82dc9..24cd8cb23ed8 100644
--- a/packages/SystemUI/tests/res/values/overlayable_icons_test.xml
+++ b/packages/SystemUI/tests/res/values/overlayable_icons_test.xml
@@ -59,6 +59,8 @@
<item>@drawable/ic_volume_bt_sco</item>
<item>@drawable/ic_volume_media</item>
<item>@drawable/ic_volume_media_mute</item>
+ <item>@drawable/ic_volume_odi_captions</item>
+ <item>@drawable/ic_volume_odi_captions_disabled</item>
<item>@drawable/ic_volume_ringer</item>
<item>@drawable/ic_volume_ringer_mute</item>
<item>@drawable/ic_volume_ringer_vibrate</item>
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 6208ab82dda6..bdc6341bde91 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -21,6 +21,7 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
@@ -52,6 +53,7 @@ import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import org.junit.Assert;
import org.junit.Before;
@@ -88,6 +90,8 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
private UserManager mUserManager;
@Mock
private DevicePolicyManager mDevicePolicyManager;
+ @Mock
+ private KeyguardBypassController mKeyguardBypassController;
private TestableLooper mTestableLooper;
private TestableKeyguardUpdateMonitor mKeyguardUpdateMonitor;
@@ -314,13 +318,44 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
@Test
public void skipsAuthentication_whenEncryptedKeyguard() {
- reset(mUserManager);
- when(mUserManager.isUserUnlocked(anyInt())).thenReturn(false);
+ when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
+ KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
+ mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
mKeyguardUpdateMonitor.dispatchStartedWakingUp();
mTestableLooper.processAllMessages();
mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
- verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any());
+ verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+ }
+
+ @Test
+ public void requiresAuthentication_whenEncryptedKeyguard_andBypass() {
+ testStrongAuthExceptOnBouncer(
+ KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT);
+ }
+
+ @Test
+ public void requiresAuthentication_whenTimeoutKeyguard_andBypass() {
+ testStrongAuthExceptOnBouncer(
+ KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
+ }
+
+ private void testStrongAuthExceptOnBouncer(int strongAuth) {
+ when(mKeyguardBypassController.canBypass()).thenReturn(true);
+ mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
+ when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(strongAuth);
+
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+ mTestableLooper.processAllMessages();
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+ verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+
+ // Stop scanning when bouncer becomes visible
+ mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true /* showingBouncer */);
+ mTestableLooper.processAllMessages();
+ clearInvocations(mFaceManager);
+ mKeyguardUpdateMonitor.requestFaceAuth();
+ verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
}
@Test
@@ -332,6 +367,50 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
}
@Test
+ public void testTriesToAuthenticate_whenTrustOnAgentKeyguard_ifBypass() {
+ mKeyguardUpdateMonitor.setKeyguardBypassController(mKeyguardBypassController);
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+ mTestableLooper.processAllMessages();
+ when(mKeyguardBypassController.canBypass()).thenReturn(true);
+ mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+ KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */);
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+ verify(mFaceManager).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+ }
+
+ @Test
+ public void testIgnoresAuth_whenTrustAgentOnKeyguard_withoutBypass() {
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+ mTestableLooper.processAllMessages();
+ mKeyguardUpdateMonitor.onTrustChanged(true /* enabled */,
+ KeyguardUpdateMonitor.getCurrentUser(), 0 /* flags */);
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+ verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+ }
+
+ @Test
+ public void testIgnoresAuth_whenLockdown() {
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+ mTestableLooper.processAllMessages();
+ when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
+ KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
+
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+ verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+ }
+
+ @Test
+ public void testIgnoresAuth_whenLockout() {
+ mKeyguardUpdateMonitor.dispatchStartedWakingUp();
+ mTestableLooper.processAllMessages();
+ when(mStrongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
+ KeyguardUpdateMonitor.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT);
+
+ mKeyguardUpdateMonitor.onKeyguardVisibilityChanged(true);
+ verify(mFaceManager, never()).authenticate(any(), any(), anyInt(), any(), any(), anyInt());
+ }
+
+ @Test
public void testOnFaceAuthenticated_skipsFaceWhenAuthenticated() {
mKeyguardUpdateMonitor.onFaceAuthenticated(KeyguardUpdateMonitor.getCurrentUser());
mKeyguardUpdateMonitor.sendKeyguardBouncerChanged(true);
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
index 3f48ea7e23ad..ef3af8a3c9bc 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/AnalogClockControllerTest.java
@@ -18,6 +18,7 @@ package com.android.keyguard.clock;
import static com.google.common.truth.Truth.assertThat;
import android.content.res.Resources;
+import android.graphics.Color;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -67,9 +68,9 @@ public final class AnalogClockControllerTest extends SysuiTestCase {
public void setColorPalette_setDigitalClock() {
ViewGroup smallClock = (ViewGroup) mClockController.getView();
// WHEN color palette is set
- mClockController.setColorPalette(true, new int[]{42});
+ mClockController.setColorPalette(true, new int[]{Color.RED});
// THEN child of small clock should have text color set.
TextView digitalClock = (TextView) smallClock.getChildAt(0);
- assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
+ assertThat(digitalClock.getCurrentTextColor()).isEqualTo(Color.RED);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
index 90083b42749e..b56986eb80d0 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/BubbleClockControllerTest.java
@@ -18,6 +18,7 @@ package com.android.keyguard.clock;
import static com.google.common.truth.Truth.assertThat;
import android.content.res.Resources;
+import android.graphics.Color;
import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper.RunWithLooper;
@@ -66,9 +67,9 @@ public final class BubbleClockControllerTest extends SysuiTestCase {
public void setColorPalette_setDigitalClock() {
ViewGroup smallClock = (ViewGroup) mClockController.getView();
// WHEN text color is set
- mClockController.setColorPalette(true, new int[]{42});
+ mClockController.setColorPalette(true, new int[]{Color.RED});
// THEN child of small clock should have text color set.
TextView digitalClock = (TextView) smallClock.getChildAt(0);
- assertThat(digitalClock.getCurrentTextColor()).isEqualTo(42);
+ assertThat(digitalClock.getCurrentTextColor()).isEqualTo(Color.RED);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt
new file mode 100644
index 000000000000..347b26deacd4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt
@@ -0,0 +1,97 @@
+/*
+ * 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.keyguard.clock
+
+import android.graphics.Color
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class ClockPaletteTest : SysuiTestCase() {
+
+ private lateinit var clockPalette: ClockPalette
+ private lateinit var colors: IntArray
+
+ @Before
+ fun setUp() {
+ clockPalette = ClockPalette()
+ // colors used are reds from light to dark.
+ val hsv: FloatArray = FloatArray(3)
+ Color.colorToHSV(Color.RED, hsv)
+ colors = IntArray(10)
+ val step: Float = (0f - hsv[2]) / colors.size
+ for (i in 0 until colors.size) {
+ hsv[2] += step
+ colors[i] = Color.HSVToColor(hsv)
+ }
+ }
+
+ @Test
+ fun testDark() {
+ // GIVEN on AOD
+ clockPalette.setDarkAmount(1f)
+ // AND GIVEN that wallpaper doesn't support dark text
+ clockPalette.setColorPalette(false, colors)
+ // THEN the secondary color should be lighter than the primary color
+ assertThat(value(clockPalette.getPrimaryColor()))
+ .isGreaterThan(value(clockPalette.getSecondaryColor()))
+ }
+
+ @Test
+ fun testDarkText() {
+ // GIVEN on lock screen
+ clockPalette.setDarkAmount(0f)
+ // AND GIVEN that wallpaper supports dark text
+ clockPalette.setColorPalette(true, colors)
+ // THEN the secondary color should be darker the primary color
+ assertThat(value(clockPalette.getPrimaryColor()))
+ .isLessThan(value(clockPalette.getSecondaryColor()))
+ }
+
+ @Test
+ fun testLightText() {
+ // GIVEN on lock screen
+ clockPalette.setDarkAmount(0f)
+ // AND GIVEN that wallpaper doesn't support dark text
+ clockPalette.setColorPalette(false, colors)
+ // THEN the secondary color should be darker than the primary color
+ assertThat(value(clockPalette.getPrimaryColor()))
+ .isGreaterThan(value(clockPalette.getSecondaryColor()))
+ }
+
+ @Test
+ fun testNullColors() {
+ // GIVEN on AOD
+ clockPalette.setDarkAmount(1f)
+ // AND GIVEN that wallpaper colors are null
+ clockPalette.setColorPalette(false, null)
+ // THEN the primary color should be whilte
+ assertThat(clockPalette.getPrimaryColor()).isEqualTo(Color.WHITE)
+ }
+
+ private fun value(color: Int): Float {
+ val hsv: FloatArray = FloatArray(3)
+ Color.colorToHSV(color, hsv)
+ return hsv[2]
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/SettingsWrapperTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/SettingsWrapperTest.kt
new file mode 100644
index 000000000000..573581dae3b1
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/SettingsWrapperTest.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.keyguard.clock
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.json.JSONObject
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.never
+import org.mockito.Mockito.verify
+
+private const val PACKAGE = "com.android.keyguard.clock.Clock"
+private const val CLOCK_FIELD = "clock"
+private const val TIMESTAMP_FIELD = "_applied_timestamp"
+private const val USER_ID = 0
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class SettingsWrapperTest : SysuiTestCase() {
+
+ private lateinit var wrapper: SettingsWrapper
+ private lateinit var migration: SettingsWrapper.Migration
+
+ @Before
+ fun setUp() {
+ migration = mock(SettingsWrapper.Migration::class.java)
+ wrapper = SettingsWrapper(getContext().contentResolver, migration)
+ }
+
+ @Test
+ fun testDecodeUnnecessary() {
+ // GIVEN a settings value that doesn't need to be decoded
+ val value = PACKAGE
+ // WHEN the value is decoded
+ val decoded = wrapper.decode(value, USER_ID)
+ // THEN the same value is returned, because decoding isn't necessary.
+ // TODO(b/135674383): Null should be returned when the migration code in removed.
+ assertThat(decoded).isEqualTo(value)
+ // AND the value is migrated to JSON format
+ verify(migration).migrate(value, USER_ID)
+ }
+
+ @Test
+ fun testDecodeJSON() {
+ // GIVEN a settings value that is encoded in JSON
+ val json: JSONObject = JSONObject()
+ json.put(CLOCK_FIELD, PACKAGE)
+ json.put(TIMESTAMP_FIELD, System.currentTimeMillis())
+ val value = json.toString()
+ // WHEN the value is decoded
+ val decoded = wrapper.decode(value, USER_ID)
+ // THEN the clock field should have been extracted
+ assertThat(decoded).isEqualTo(PACKAGE)
+ }
+
+ @Test
+ fun testDecodeJSONWithoutClockField() {
+ // GIVEN a settings value that doesn't contain the CLOCK_FIELD
+ val json: JSONObject = JSONObject()
+ json.put(TIMESTAMP_FIELD, System.currentTimeMillis())
+ val value = json.toString()
+ // WHEN the value is decoded
+ val decoded = wrapper.decode(value, USER_ID)
+ // THEN null is returned
+ assertThat(decoded).isNull()
+ // AND the value is not migrated to JSON format
+ verify(migration, never()).migrate(value, USER_ID)
+ }
+
+ @Test
+ fun testDecodeNullJSON() {
+ assertThat(wrapper.decode(null, USER_ID)).isNull()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt
index f4d59ccb372e..456f32b4bd40 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt
+++ b/packages/SystemUI/tests/src/com/android/keyguard/clock/SmallClockPositionTest.kt
@@ -52,8 +52,8 @@ class SmallClockPositionTest : SysuiTestCase() {
fun darkPosition() {
// GIVEN on AOD
position.setDarkAmount(1f)
- // THEN Y position is statusBarHeight + lockPadding + burnInY (100 + 15 + 20 = 135)
- assertThat(position.preferredY).isEqualTo(135)
+ // THEN Y is sum of statusBarHeight, lockPadding, lockHeight, lockPadding, burnInY
+ assertThat(position.preferredY).isEqualTo(185)
}
@Test
@@ -64,4 +64,4 @@ class SmallClockPositionTest : SysuiTestCase() {
// (100 + 15 + 35 + 15 = 165)
assertThat(position.preferredY).isEqualTo(165)
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java
new file mode 100644
index 000000000000..ccc9afcd4296
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/IconPackOverlayTest.java
@@ -0,0 +1,192 @@
+/*
+ * 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;
+
+import static junit.framework.Assert.fail;
+
+import static org.junit.Assert.assertEquals;
+
+import android.annotation.DrawableRes;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.text.TextUtils;
+import android.util.TypedValue;
+
+import androidx.test.filters.MediumTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.internal.util.XmlUtils;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+
+@RunWith(AndroidJUnit4.class)
+@MediumTest
+public class IconPackOverlayTest extends SysuiTestCase {
+
+ private static final String[] ICON_PACK_OVERLAY_PACKAGES = {
+ "com.android.theme.icon_pack.circular.systemui",
+ "com.android.theme.icon_pack.rounded.systemui",
+ "com.android.theme.icon_pack.filled.systemui",
+ };
+
+ private static final int[] VECTOR_ATTRIBUTES = {
+ android.R.attr.tint,
+ android.R.attr.height,
+ android.R.attr.width,
+ android.R.attr.alpha,
+ android.R.attr.autoMirrored,
+ };
+
+ private final TypedValue mTargetTypedValue = new TypedValue();
+ private final TypedValue mOverlayTypedValue = new TypedValue();
+
+ private Resources mResources;
+ private TypedArray mOverlayableIcons;
+
+ @Before
+ public void setup() {
+ mResources = mContext.getResources();
+ mOverlayableIcons = mResources.obtainTypedArray(R.array.overlayable_icons);
+ }
+
+ @After
+ public void teardown() {
+ mOverlayableIcons.recycle();
+ }
+
+ /**
+ * Ensure that all icons contained in overlayable_icons_test.xml exist in all 3 overlay icon
+ * packs for systemui. This test fails if you remove or rename an overlaid icon. If so,
+ * make the same change to the corresponding drawables in {@link #ICON_PACK_OVERLAY_PACKAGES}.
+ */
+ @Test
+ public void testIconPack_containAllOverlayedIcons() {
+ StringBuilder errors = new StringBuilder();
+
+ for (String overlayPackage : ICON_PACK_OVERLAY_PACKAGES) {
+ Resources overlayResources;
+ try {
+ overlayResources = mContext.getPackageManager()
+ .getResourcesForApplication(overlayPackage);
+ } catch (PackageManager.NameNotFoundException e) {
+ continue; // No need to test overlay resources if apk is not on the system.
+ }
+
+ for (int i = 0; i < mOverlayableIcons.length(); i++) {
+ int sysuiRid = mOverlayableIcons.getResourceId(i, 0);
+ String sysuiResourceName = mResources.getResourceName(sysuiRid);
+ String overlayResourceName = sysuiResourceName
+ .replace(mContext.getPackageName(), overlayPackage);
+ if (overlayResources.getIdentifier(overlayResourceName, null, null)
+ == Resources.ID_NULL) {
+ errors.append(String.format("[%s] is not contained in overlay package [%s]",
+ overlayResourceName, overlayPackage));
+ }
+ }
+ }
+
+ if (!TextUtils.isEmpty(errors)) {
+ fail(errors.toString());
+ }
+ }
+
+ /**
+ * Ensures that all overlay icons have the same values for {@link #VECTOR_ATTRIBUTES} as the
+ * underlying drawable in systemui. To fix this test, make the attribute change to all of the
+ * corresponding drawables in {@link #ICON_PACK_OVERLAY_PACKAGES}.
+ */
+ @Test
+ public void testIconPacks_haveEqualVectorDrawableAttributes() {
+ StringBuilder errors = new StringBuilder();
+
+ for (String overlayPackage : ICON_PACK_OVERLAY_PACKAGES) {
+ Resources overlayResources;
+ try {
+ overlayResources = mContext.getPackageManager()
+ .getResourcesForApplication(overlayPackage);
+ } catch (PackageManager.NameNotFoundException e) {
+ continue; // No need to test overlay resources if apk is not on the system.
+ }
+
+ for (int i = 0; i < mOverlayableIcons.length(); i++) {
+ int sysuiRid = mOverlayableIcons.getResourceId(i, 0);
+ String sysuiResourceName = mResources.getResourceName(sysuiRid);
+ TypedArray sysuiAttrs = getAVDAttributes(mResources, sysuiRid);
+ if (sysuiAttrs == null) {
+ errors.append(String.format("[%s] does not exist or is not a valid AVD.",
+ sysuiResourceName));
+ continue;
+ }
+
+ String overlayResourceName = sysuiResourceName
+ .replace(mContext.getPackageName(), overlayPackage);
+ int overlayRid = overlayResources.getIdentifier(overlayResourceName, null, null);
+ TypedArray overlayAttrs = getAVDAttributes(overlayResources, overlayRid);
+ if (overlayAttrs == null) {
+ errors.append(String.format("[%s] does not exist or is not a valid AVD.",
+ overlayResourceName));
+ continue;
+ }
+
+ if (!attributesEquals(sysuiAttrs, overlayAttrs)) {
+ errors.append(String.format("[%s] AVD attributes do not match [%s]\n",
+ sysuiResourceName, overlayResourceName));
+ }
+ sysuiAttrs.recycle();
+ overlayAttrs.recycle();
+ }
+ }
+
+ if (!TextUtils.isEmpty(errors)) {
+ fail(errors.toString());
+ }
+ }
+
+ private TypedArray getAVDAttributes(Resources resources, @DrawableRes int rid) {
+ try {
+ XmlResourceParser parser = resources.getXml(rid);
+ XmlUtils.nextElement(parser);
+ return resources.obtainAttributes(parser, VECTOR_ATTRIBUTES);
+ } catch (XmlPullParserException | IOException | Resources.NotFoundException e) {
+ return null;
+ }
+ }
+
+ private boolean attributesEquals(TypedArray target, TypedArray overlay) {
+ assertEquals(target.length(), overlay.length());
+ for (int i = 0; i < target.length(); i++) {
+ target.getValue(i, mTargetTypedValue);
+ overlay.getValue(i, mOverlayTypedValue);
+ if (!attributesEquals(mTargetTypedValue, mOverlayTypedValue)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ private boolean attributesEquals(TypedValue target, TypedValue overlay) {
+ return target.type == overlay.type && target.data == overlay.data;
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
index bd7f897dc1c0..59d5c243af73 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/appops/AppOpsControllerTest.java
@@ -16,9 +16,8 @@
package com.android.systemui.appops;
-import static junit.framework.TestCase.assertFalse;
-
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
index 9438cbb6ebcd..2d6ae2629ce4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeConfigurationUtil.java
@@ -36,7 +36,7 @@ public class DozeConfigurationUtil {
when(params.getPulseOnSigMotion()).thenReturn(false);
when(params.getPickupVibrationThreshold()).thenReturn(0);
when(params.getProxCheckBeforePulse()).thenReturn(true);
- when(params.getPickupSubtypePerformsProxCheck(anyInt())).thenReturn(true);
+ when(params.getPickupPerformsProxCheck()).thenReturn(true);
when(params.getPolicy()).thenReturn(mock(AlwaysOnDisplayPolicy.class));
when(params.doubleTapReportsTouchCoordinates()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
index 33042918cfc9..7df45a3d8949 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/doze/DozeSensorsTest.java
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -77,7 +78,9 @@ public class DozeSensorsTest extends SysuiTestCase {
@Mock
private AlwaysOnDisplayPolicy mAlwaysOnDisplayPolicy;
@Mock
- private TriggerSensor mMockTriggerSensor;
+ private TriggerSensor mTriggerSensor;
+ @Mock
+ private TriggerSensor mProxGatedTriggerSensor;
private SensorManagerPlugin.SensorEventListener mWakeLockScreenListener;
private TestableLooper mTestableLooper;
private DozeSensors mDozeSensors;
@@ -85,6 +88,7 @@ public class DozeSensorsTest extends SysuiTestCase {
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ when(mProxGatedTriggerSensor.performsProxCheck()).thenReturn(true);
mTestableLooper = TestableLooper.get(this);
when(mAmbientDisplayConfiguration.getWakeLockScreenDebounce()).thenReturn(5000L);
when(mAmbientDisplayConfiguration.alwaysOnEnabled(anyInt())).thenReturn(true);
@@ -114,21 +118,34 @@ public class DozeSensorsTest extends SysuiTestCase {
@Test
public void testSetListening_firstTrue_registerSettingsObserver() {
- mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor};
-
mDozeSensors.setListening(true);
- verify(mMockTriggerSensor).registerSettingsObserver(any(ContentObserver.class));
+ verify(mTriggerSensor).registerSettingsObserver(any(ContentObserver.class));
}
@Test
public void testSetListening_twiceTrue_onlyRegisterSettingsObserverOnce() {
- mDozeSensors.mSensors = new TriggerSensor[] {mMockTriggerSensor};
mDozeSensors.setListening(true);
-
mDozeSensors.setListening(true);
- verify(mMockTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class));
+ verify(mTriggerSensor, times(1)).registerSettingsObserver(any(ContentObserver.class));
+ }
+
+ @Test
+ public void testSetPaused_onlyPausesNonGatedSensors() {
+ mDozeSensors.setListening(true);
+ verify(mTriggerSensor).setListening(eq(true));
+ verify(mProxGatedTriggerSensor).setListening(eq(true));
+
+ clearInvocations(mTriggerSensor, mProxGatedTriggerSensor);
+ mDozeSensors.setPaused(true);
+ verify(mTriggerSensor).setListening(eq(false));
+ verify(mProxGatedTriggerSensor).setListening(eq(true));
+
+ clearInvocations(mTriggerSensor, mProxGatedTriggerSensor);
+ mDozeSensors.setPaused(false);
+ verify(mTriggerSensor).setListening(eq(true));
+ verify(mProxGatedTriggerSensor).setListening(eq(true));
}
private class TestableDozeSensors extends DozeSensors {
@@ -144,6 +161,7 @@ public class DozeSensorsTest extends SysuiTestCase {
mWakeLockScreenListener = (PluginSensor) sensor;
}
}
+ mSensors = new TriggerSensor[] {mTriggerSensor, mProxGatedTriggerSensor};
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 44191147f914..893f3d184acb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -48,6 +48,8 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.phone.DozeParameters;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.util.wakelock.SettableWakeLock;
@@ -76,11 +78,15 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
@Mock
private StatusBarStateController mStatusBarStateController;
@Mock
+ private KeyguardBypassController mKeyguardBypassController;
+ @Mock
private ZenModeController mZenModeController;
@Mock
private SettableWakeLock mMediaWakeLock;
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ @Mock
+ private DozeParameters mDozeParameters;
private TestableKeyguardSliceProvider mProvider;
private boolean mIsZenMode;
@@ -90,7 +96,8 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
mIsZenMode = false;
mProvider = new TestableKeyguardSliceProvider();
mProvider.attachInfo(getContext(), null);
- mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController);
+ mProvider.initDependencies(mNotificationMediaManager, mStatusBarStateController,
+ mKeyguardBypassController, mDozeParameters);
SliceProvider.setSpecs(new HashSet<>(Arrays.asList(SliceSpecs.LIST)));
}
@@ -110,7 +117,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
}
@Test
- public void onBindSlice_readsMedia() {
+ public void onBindSlice_readsMedia_withoutBypass() {
MediaMetadata metadata = mock(MediaMetadata.class);
when(metadata.getText(any())).thenReturn("metadata");
mProvider.onDozingChanged(true);
@@ -122,6 +129,19 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
}
@Test
+ public void onBindSlice_readsMedia_withBypass_notDozing() {
+ MediaMetadata metadata = mock(MediaMetadata.class);
+ when(metadata.getText(any())).thenReturn("metadata");
+ when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+ when(mDozeParameters.getAlwaysOn()).thenReturn(true);
+ mProvider.onMetadataOrStateChanged(metadata, PlaybackState.STATE_PLAYING);
+ mProvider.onBindSlice(mProvider.getUri());
+ verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_TITLE));
+ verify(metadata).getText(eq(MediaMetadata.METADATA_KEY_ARTIST));
+ verify(mNotificationMediaManager).getMediaIcon();
+ }
+
+ @Test
public void cleansDateFormat() {
mProvider.mKeyguardUpdateMonitorCallback.onTimeZoneChanged(null);
TestableLooper.get(this).processAllMessages();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
index db4f5ffcdfeb..4eee23056bc2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentTest.java
@@ -39,6 +39,7 @@ import com.android.systemui.DumpController;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiBaseFragmentTest;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.tileimpl.QSFactoryImpl;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.statusbar.phone.AutoTileManager;
@@ -139,6 +140,7 @@ public class QSFragmentTest extends SysuiBaseFragmentTest {
new RemoteInputQuickSettingsDisabler(context, mock(ConfigurationController.class)),
new InjectionInflationController(SystemUIFactory.getInstance().getRootComponent()),
context,
- mock(QSTileHost.class));
+ mock(QSTileHost.class),
+ mock(StatusBarStateController.class));
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java
deleted file mode 100644
index 0b25a7c8e07c..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AmbientPulseManagerTest.java
+++ /dev/null
@@ -1,79 +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.systemui.statusbar;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Before;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.junit.MockitoJUnit;
-import org.mockito.junit.MockitoRule;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class AmbientPulseManagerTest extends AlertingNotificationManagerTest {
- @Rule
- public MockitoRule rule = MockitoJUnit.rule();
-
- private static final int TEST_EXTENSION_TIME = 500;
- private AmbientPulseManager mAmbientPulseManager;
- private boolean mLivesPastNormalTime;
-
- protected AlertingNotificationManager createAlertingNotificationManager() {
- return mAmbientPulseManager;
- }
-
- @Before
- public void setUp() {
- mAmbientPulseManager = new AmbientPulseManager(mContext);
- mAmbientPulseManager.mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
- mAmbientPulseManager.mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
- mAmbientPulseManager.mExtensionTime = TEST_EXTENSION_TIME;
- super.setUp();
- mAmbientPulseManager.mHandler = mTestHandler;
- }
-
- @Test
- public void testExtendPulse() {
- mAmbientPulseManager.showNotification(mEntry);
- Runnable pastNormalTimeRunnable =
- () -> mLivesPastNormalTime = mAmbientPulseManager.isAlerting(mEntry.key);
- mTestHandler.postDelayed(pastNormalTimeRunnable,
- mAmbientPulseManager.mAutoDismissNotificationDecay +
- mAmbientPulseManager.mExtensionTime / 2);
- mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_TIMEOUT_TIME);
-
- mAmbientPulseManager.extendPulse();
-
- // Wait for normal time runnable and extended remove runnable and process them on arrival.
- TestableLooper.get(this).processMessages(2);
-
- assertFalse("Test timed out", mTimedOut);
- assertTrue("Pulse was not extended", mLivesPastNormalTime);
- assertFalse(mAmbientPulseManager.isAlerting(mEntry.key));
- }
-}
-
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt
new file mode 100644
index 000000000000..72e6df27a254
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt
@@ -0,0 +1,109 @@
+/*
+ * 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
+
+import com.google.common.truth.Truth.assertThat
+
+import android.graphics.Bitmap
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Point
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val WIDTH = 200
+private const val HEIGHT = 200
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class MediaArtworkProcessorTest : SysuiTestCase() {
+
+ private var screenWidth = 0
+ private var screenHeight = 0
+
+ private lateinit var processor: MediaArtworkProcessor
+
+ @Before
+ fun setUp() {
+ processor = MediaArtworkProcessor()
+
+ val point = Point()
+ context.display.getSize(point)
+ screenWidth = point.x
+ screenHeight = point.y
+ }
+
+ @After
+ fun tearDown() {
+ processor.clearCache()
+ }
+
+ @Test
+ fun testProcessArtwork() {
+ // GIVEN some "artwork", which is just a solid blue image
+ val artwork = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888)
+ Canvas(artwork).drawColor(Color.BLUE)
+ // WHEN the background is created from the artwork
+ val background = processor.processArtwork(context, artwork)!!
+ // THEN the background has the size of the screen that has been downsamples
+ assertThat(background.height).isLessThan(screenHeight)
+ assertThat(background.width).isLessThan(screenWidth)
+ assertThat(background.config).isEqualTo(Bitmap.Config.ARGB_8888)
+ }
+
+ @Test
+ fun testCache() {
+ // GIVEN a solid blue image
+ val artwork = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888)
+ Canvas(artwork).drawColor(Color.BLUE)
+ // WHEN the background is processed twice
+ val background1 = processor.processArtwork(context, artwork)!!
+ val background2 = processor.processArtwork(context, artwork)!!
+ // THEN the two bitmaps are the same
+ // Note: This is currently broken and trying to use caching causes issues
+ assertThat(background1).isNotSameAs(background2)
+ }
+
+ @Test
+ fun testConfig() {
+ // GIVEN some which is not ARGB_8888
+ val artwork = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ALPHA_8)
+ Canvas(artwork).drawColor(Color.BLUE)
+ // WHEN the background is created from the artwork
+ val background = processor.processArtwork(context, artwork)!!
+ // THEN the background has Config ARGB_8888
+ assertThat(background.config).isEqualTo(Bitmap.Config.ARGB_8888)
+ }
+
+ @Test
+ fun testRecycledArtwork() {
+ // GIVEN some "artwork", which is just a solid blue image
+ val artwork = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888)
+ Canvas(artwork).drawColor(Color.BLUE)
+ // AND the artwork is recycled
+ artwork.recycle()
+ // WHEN the background is created from the artwork
+ val background = processor.processArtwork(context, artwork)
+ // THEN the processed bitmap is null
+ assertThat(background).isNull()
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index b81e04821463..da25eed4a24e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -1,3 +1,4 @@
+
package com.android.systemui.statusbar;
import static junit.framework.Assert.assertEquals;
@@ -22,12 +23,14 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputActiveExtender;
import com.android.systemui.statusbar.NotificationRemoteInputManager.RemoteInputHistoryExtender;
import com.android.systemui.statusbar.NotificationRemoteInputManager.SmartReplyHistoryExtender;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.ShadeController;
import com.google.android.collect.Sets;
@@ -54,6 +57,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
@Mock private SmartReplyController mSmartReplyController;
@Mock private NotificationListenerService.RankingMap mRanking;
@Mock private ExpandableNotificationRow mRow;
+ @Mock private StatusBarStateController mStateController;
// Dependency mocks:
@Mock private NotificationEntryManager mEntryManager;
@@ -73,6 +77,7 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
mRemoteInputManager = new TestableNotificationRemoteInputManager(mContext,
mLockscreenUserManager, mSmartReplyController, mEntryManager,
() -> mock(ShadeController.class),
+ mStateController,
Handler.createAsync(Looper.myLooper()));
mSbn = new StatusBarNotification(TEST_PACKAGE_NAME, TEST_PACKAGE_NAME, 0, null, TEST_UID,
0, new Notification(), UserHandle.CURRENT, null, 0);
@@ -196,15 +201,15 @@ public class NotificationRemoteInputManagerTest extends SysuiTestCase {
private class TestableNotificationRemoteInputManager extends NotificationRemoteInputManager {
-
TestableNotificationRemoteInputManager(Context context,
NotificationLockscreenUserManager lockscreenUserManager,
SmartReplyController smartReplyController,
NotificationEntryManager notificationEntryManager,
Lazy<ShadeController> shadeController,
+ StatusBarStateController statusBarStateController,
Handler mainHandler) {
super(context, lockscreenUserManager, smartReplyController, notificationEntryManager,
- shadeController, mainHandler);
+ shadeController, statusBarStateController, mainHandler);
}
public void setUpWithPresenterForTest(Callback callback,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
index 028fd7afd945..7063ddf3e653 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationTestHelper.java
@@ -20,6 +20,8 @@ import static android.app.Notification.FLAG_BUBBLE;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static org.mockito.Mockito.mock;
+
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.Instrumentation;
@@ -40,11 +42,13 @@ import androidx.test.InstrumentationRegistry;
import com.android.systemui.R;
import com.android.systemui.bubbles.BubblesTestActivity;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.NotificationContentInflater.InflationFlag;
import com.android.systemui.statusbar.notification.row.NotificationContentInflaterTest;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -66,14 +70,18 @@ public class NotificationTestHelper {
private final Context mContext;
private final Instrumentation mInstrumentation;
private int mId;
- private final NotificationGroupManager mGroupManager = new NotificationGroupManager();
+ private final NotificationGroupManager mGroupManager;
private ExpandableNotificationRow mRow;
- private HeadsUpManager mHeadsUpManager;
+ private HeadsUpManagerPhone mHeadsUpManager;
public NotificationTestHelper(Context context) {
mContext = context;
mInstrumentation = InstrumentationRegistry.getInstrumentation();
- mHeadsUpManager = new HeadsUpManagerPhone(mContext, null, mGroupManager, null, null);
+ StatusBarStateController stateController = mock(StatusBarStateController.class);
+ mGroupManager = new NotificationGroupManager(stateController);
+ mHeadsUpManager = new HeadsUpManagerPhone(mContext, stateController,
+ mock(KeyguardBypassController.class));
+ mHeadsUpManager.setUp(null, mGroupManager, null, null);
mGroupManager.setHeadsUpManager(mHeadsUpManager);
}
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 5103e8e89209..58fb53aae7bb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationViewHierarchyManagerTest.java
@@ -52,6 +52,7 @@ import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.util.Assert;
@@ -109,7 +110,9 @@ public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
mHandler, mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
mock(StatusBarStateControllerImpl.class), mEntryManager,
- () -> mShadeController, new BubbleData(mContext), mock(DynamicPrivacyController.class));
+ () -> mShadeController, new BubbleData(mContext),
+ mock(KeyguardBypassController.class),
+ mock(DynamicPrivacyController.class));
Dependency.get(InitController.class).executePostInitTasks();
mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
index 81e373a8be27..185723ffa09b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/SmartReplyControllerTest.java
@@ -38,6 +38,7 @@ import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+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.phone.ShadeController;
@@ -70,6 +71,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
@Mock private StatusBarNotification mSbn;
@Mock private NotificationEntryManager mNotificationEntryManager;
@Mock private IStatusBarService mIStatusBarService;
+ @Mock private StatusBarStateController mStatusBarStateController;
@Before
public void setUp() {
@@ -85,6 +87,7 @@ public class SmartReplyControllerTest extends SysuiTestCase {
mRemoteInputManager = new NotificationRemoteInputManager(mContext,
mock(NotificationLockscreenUserManager.class), mSmartReplyController,
mNotificationEntryManager, () -> mock(ShadeController.class),
+ mStatusBarStateController,
Handler.createAsync(Looper.myLooper()));
mRemoteInputManager.setUpWithCallback(mCallback, mDelegate);
mNotification = new Notification.Builder(mContext, "")
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 72f3a62f30a7..2ca1b0611cd6 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
@@ -64,6 +64,7 @@ import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
@@ -83,6 +84,7 @@ import com.android.systemui.statusbar.notification.row.NotificationContentInflat
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.RowInflaterTask;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -247,7 +249,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mEntryManager.setNotificationRemoveInterceptor(mRemoveInterceptor);
NotificationRowBinderImpl notificationRowBinder =
- new NotificationRowBinderImpl(mContext, true /* allowLongPress */);
+ new NotificationRowBinderImpl(mContext, true, /* allowLongPress */
+ mock(KeyguardBypassController.class), mock(StatusBarStateController.class));
notificationRowBinder.setUpWithPresenter(
mPresenter, mListContainer, mHeadsUpManager, mEntryManager, mBindCallback);
notificationRowBinder.setNotificationClicker(mock(NotificationClicker.class));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
index 91a7ea87a93b..6f7751b2e2a5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationFilterTest.java
@@ -40,6 +40,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -90,7 +91,7 @@ public class NotificationFilterTest extends SysuiTestCase {
.thenReturn(PackageManager.PERMISSION_GRANTED);
mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
mDependency.injectTestDependency(NotificationGroupManager.class,
- new NotificationGroupManager());
+ new NotificationGroupManager(mock(StatusBarStateController.class)));
mDependency.injectMockDependency(ShadeController.class);
mDependency.injectTestDependency(NotificationData.KeyguardEnvironment.class, mEnvironment);
when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index 6e0ddbf0cc46..260555f71256 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -66,6 +66,7 @@ import com.android.systemui.Dependency;
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.collection.NotificationData.KeyguardEnvironment;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -125,7 +126,7 @@ public class NotificationDataTest extends SysuiTestCase {
mDependency.injectTestDependency(ForegroundServiceController.class, mFsc);
mDependency.injectTestDependency(NotificationGroupManager.class,
- new NotificationGroupManager());
+ new NotificationGroupManager(mock(StatusBarStateController.class)));
mDependency.injectMockDependency(ShadeController.class);
mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
index 8077e3fbaa0a..d526d104630e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRowTest.java
@@ -37,9 +37,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.AppOpsManager;
-import android.app.Notification;
import android.app.NotificationChannel;
-import android.os.UserHandle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
@@ -51,6 +49,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.AboveShelfChangedListener;
import com.android.systemui.statusbar.notification.stack.NotificationChildrenContainer;
@@ -138,13 +137,6 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
}
@Test
- public void testIconColorShouldBeUpdatedWhenSettingDark() throws Exception {
- ExpandableNotificationRow row = spy(mNotificationTestHelper.createRow());
- row.setDark(true, false, 0);
- verify(row).updateShelfIconColor();
- }
-
- @Test
public void testFreeContentViewWhenSafe() throws Exception {
ExpandableNotificationRow row = mNotificationTestHelper.createRow(FLAG_CONTENT_VIEW_ALL);
@@ -212,7 +204,9 @@ public class ExpandableNotificationRowTest extends SysuiTestCase {
@Test
public void testClickSound() throws Exception {
assertTrue("Should play sounds by default.", mGroupRow.isSoundEffectsEnabled());
- mGroupRow.setDark(true /* dark */, false /* fade */, 0 /* delay */);
+ StatusBarStateController mock = mock(StatusBarStateController.class);
+ when(mock.isDozing()).thenReturn(true);
+ mGroupRow.setStatusBarStateController(mock);
mGroupRow.setSecureStateProvider(()-> false);
assertFalse("Shouldn't play sounds when dark and trusted.",
mGroupRow.isSoundEffectsEnabled());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
index 06ff0478a804..2ec125e8a43b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentInflaterTest.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.notification.row;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_ALL;
-import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_AMBIENT;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_EXPANDED;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_HEADS_UP;
import static com.android.systemui.statusbar.notification.row.NotificationContentInflater.FLAG_CONTENT_VIEW_PUBLIC;
@@ -135,7 +134,6 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
mNotificationInflater);
assertNotNull(mRow.getPrivateLayout().getHeadsUpChild());
- assertNull(mRow.getShowingLayout().getAmbientChild());
verify(mRow).onNotificationUpdated();
}
@@ -178,7 +176,7 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
result,
FLAG_CONTENT_VIEW_EXPANDED,
0,
- new ArrayMap() /* cachedContentViews */, mRow, false /* redactAmbient */,
+ new ArrayMap() /* cachedContentViews */, mRow,
true /* isNewView */, (v, p, r) -> true,
new InflationCallback() {
@Override
@@ -210,14 +208,12 @@ public class NotificationContentInflaterTest extends SysuiTestCase {
@Test
public void testUpdateNeedsRedactionReinflatesChangedContentViews() {
- mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_AMBIENT, true);
mNotificationInflater.updateInflationFlag(FLAG_CONTENT_VIEW_PUBLIC, true);
mNotificationInflater.updateNeedsRedaction(true);
NotificationContentInflater.AsyncInflationTask asyncInflationTask =
(NotificationContentInflater.AsyncInflationTask) mRow.getEntry().getRunningTask();
- assertEquals(FLAG_CONTENT_VIEW_AMBIENT | FLAG_CONTENT_VIEW_PUBLIC,
- asyncInflationTask.getReInflateFlags());
+ assertEquals(FLAG_CONTENT_VIEW_PUBLIC, asyncInflationTask.getReInflateFlags());
asyncInflationTask.abort();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
index 5cd0ca7efa9e..675b3efc5a26 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationContentViewTest.java
@@ -50,8 +50,6 @@ public class NotificationContentViewTest extends SysuiTestCase {
NotificationContentView mView;
- private Icon mActionIcon;
-
@Before
@UiThreadTest
public void setup() {
@@ -62,12 +60,11 @@ public class NotificationContentViewTest extends SysuiTestCase {
doReturn(10).when(mockRow).getIntrinsicHeight();
mView.setContainingNotification(mockRow);
- mView.setHeights(10, 20, 30, 40);
+ mView.setHeights(10, 20, 30);
mView.setContractedChild(createViewWithHeight(10));
mView.setExpandedChild(createViewWithHeight(20));
mView.setHeadsUpChild(createViewWithHeight(30));
- mView.setAmbientChild(createViewWithHeight(40));
mView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
mView.layout(0, 0, mView.getMeasuredWidth(), mView.getMeasuredHeight());
@@ -81,16 +78,6 @@ public class NotificationContentViewTest extends SysuiTestCase {
@Test
@UiThreadTest
- public void animationStartType_getsClearedAfterUpdatingVisibilitiesWithoutAnimation() {
- mView.setHeadsUp(true);
- mView.setDark(true, false, 0);
- mView.setDark(false, true, 0);
- mView.setHeadsUpAnimatingAway(true);
- assertFalse(mView.isAnimatingVisibleType());
- }
-
- @Test
- @UiThreadTest
public void testShowAppOpsIcons() {
NotificationHeaderView mockContracted = mock(NotificationHeaderView.class);
when(mockContracted.findViewById(com.android.internal.R.id.notification_header))
@@ -101,14 +88,10 @@ public class NotificationContentViewTest extends SysuiTestCase {
NotificationHeaderView mockHeadsUp = mock(NotificationHeaderView.class);
when(mockHeadsUp.findViewById(com.android.internal.R.id.notification_header))
.thenReturn(mockHeadsUp);
- NotificationHeaderView mockAmbient = mock(NotificationHeaderView.class);
- when(mockAmbient.findViewById(com.android.internal.R.id.notification_header))
- .thenReturn(mockAmbient);
mView.setContractedChild(mockContracted);
mView.setExpandedChild(mockExpanded);
mView.setHeadsUpChild(mockHeadsUp);
- mView.setAmbientChild(mockAmbient);
ArraySet<Integer> ops = new ArraySet<>();
ops.add(AppOpsManager.OP_ANSWER_PHONE_CALLS);
@@ -116,7 +99,6 @@ public class NotificationContentViewTest extends SysuiTestCase {
verify(mockContracted, times(1)).showAppOpsIcons(ops);
verify(mockExpanded, times(1)).showAppOpsIcons(ops);
- verify(mockAmbient, never()).showAppOpsIcons(ops);
verify(mockHeadsUp, times(1)).showAppOpsIcons(any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index 1b4acd71ad31..524ad85c3a98 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -30,11 +30,12 @@ import android.testing.TestableLooper.RunWithLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import org.junit.Assert;
import org.junit.Before;
@@ -56,12 +57,14 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
private ExpandableNotificationRow mFirst;
private ExpandableNotificationRow mSecond;
@Mock
- private AmbientPulseManager mAmbientPulseManager;
+ private StatusBarStateController mStatusBarStateController;
+ @Mock
+ private KeyguardBypassController mBypassController;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mRoundnessManager = new NotificationRoundnessManager(mAmbientPulseManager);
+ mRoundnessManager = new NotificationRoundnessManager(mBypassController);
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
NotificationTestHelper testHelper = new NotificationTestHelper(getContext());
mFirst = testHelper.createRow();
@@ -147,11 +150,15 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
NotificationEntry entry = mock(NotificationEntry.class);
when(entry.getRow()).thenReturn(row);
- mRoundnessManager.onAmbientStateChanged(entry, true);
+ when(mStatusBarStateController.isDozing()).thenReturn(true);
+ row.setStatusBarStateController(mStatusBarStateController);
+ row.setHeadsUp(true);
+ mRoundnessManager.onHeadsUpStateChanged(entry, true);
Assert.assertEquals(1f, row.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(1f, row.getCurrentTopRoundness(), 0.0f);
- mRoundnessManager.onAmbientStateChanged(entry, false);
+ row.setHeadsUp(false);
+ mRoundnessManager.onHeadsUpStateChanged(entry, false);
Assert.assertEquals(0f, row.getCurrentBottomRoundness(), 0.0f);
Assert.assertEquals(0f, row.getCurrentTopRoundness(), 0.0f);
}
@@ -256,15 +263,15 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
}
@Test
- public void testTrackingHeadsUpNotRoundedIfPushingDown() {
+ public void testTrackingHeadsUpPartiallyRoundedIfPushingDown() {
mRoundnessManager.setExpanded(1.0f /* expandedHeight */, 0.5f /* appearFraction */);
mRoundnessManager.setTrackingHeadsUp(mFirst);
mRoundnessManager.updateRoundedChildren(new NotificationSection[]{
createSection(mSecond, mSecond),
createSection(null, null)
});
- Assert.assertEquals(0.0f, mFirst.getCurrentBottomRoundness(), 0.0f);
- Assert.assertEquals(0.0f, mFirst.getCurrentTopRoundness(), 0.0f);
+ Assert.assertEquals(0.5f, mFirst.getCurrentBottomRoundness(), 0.0f);
+ Assert.assertEquals(0.5f, mFirst.getCurrentTopRoundness(), 0.0f);
}
@Test
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 ff835871d822..92173ccbad2e 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
@@ -55,7 +55,6 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -70,6 +69,7 @@ import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.FooterView;
import com.android.systemui.statusbar.notification.row.NotificationBlockingHelperManager;
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
import com.android.systemui.statusbar.phone.ScrimController;
@@ -117,6 +117,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Mock private NotificationIconAreaController mNotificationIconAreaController;
@Mock private MetricsLogger mMetricsLogger;
@Mock private NotificationRoundnessManager mNotificationRoundnessManager;
+ @Mock private KeyguardBypassController mKeyguardBypassController;
private TestableNotificationEntryManager mEntryManager;
private int mOriginalInterruptionModelSetting;
@@ -158,16 +159,16 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
// member variables, not the spy's member variables.
mStackScrollerInternal = new NotificationStackScrollLayout(getContext(), null,
true /* allowLongPress */, mNotificationRoundnessManager,
- new AmbientPulseManager(mContext),
mock(DynamicPrivacyController.class),
mock(ConfigurationController.class),
mock(ActivityStarterDelegate.class),
- mock(StatusBarStateController.class));
+ mock(StatusBarStateController.class),
+ mHeadsUpManager,
+ mKeyguardBypassController);
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setShelf(notificationShelf);
mStackScroller.setStatusBar(mBar);
mStackScroller.setScrimController(mock(ScrimController.class));
- mStackScroller.setHeadsUpManager(mHeadsUpManager);
mStackScroller.setGroupManager(mGroupManager);
mStackScroller.setEmptyShadeView(mEmptyShadeView);
mStackScroller.setIconAreaController(mNotificationIconAreaController);
@@ -182,7 +183,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
doNothing().when(mGroupManager).collapseAllGroups();
doNothing().when(mExpandHelper).cancelImmediately();
doNothing().when(notificationShelf).setAnimationsEnabled(anyBoolean());
- doNothing().when(notificationShelf).fadeInTranslating();
}
@After
@@ -200,17 +200,6 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
}
@Test
- public void testAntiBurnInOffset() {
- final int burnInOffset = 30;
- mStackScroller.setAntiBurnInOffsetX(burnInOffset);
- mStackScroller.setDark(false /* dark */, false /* animated */, null /* touch */);
- Assert.assertEquals(0 /* expected */, mStackScroller.getTranslationX(), 0.01 /* delta */);
- mStackScroller.setDark(true /* dark */, false /* animated */, null /* touch */);
- Assert.assertEquals(burnInOffset /* expected */, mStackScroller.getTranslationX(),
- 0.01 /* delta */);
- }
-
- @Test
public void updateEmptyView_dndSuppressing() {
when(mEmptyShadeView.willBeGone()).thenReturn(true);
when(mBar.areNotificationsHidden()).thenReturn(true);
@@ -395,7 +384,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
NotificationSwipeHelper swipeActionHelper =
(NotificationSwipeHelper) mStackScroller.getSwipeActionHelper();
swipeActionHelper.setExposedMenuView(new View(mContext));
- mStackScroller.setDarkAmount(0.1f, 0.1f);
+ mStackScroller.setHideAmount(0.1f, 0.1f);
assertNull(swipeActionHelper.getExposedMenuView());
}
@@ -442,9 +431,7 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
@Test
@UiThreadTest
- public void testOnMenuShownLogging() {
- // Set up the object under test to have a valid mHeadsUpManager. See notes in setup.
- mStackScrollerInternal.setHeadsUpManager(mHeadsUpManager);
+ public void testOnMenuShownLogging() { ;
ExpandableNotificationRow row = mock(ExpandableNotificationRow.class, RETURNS_DEEP_STUBS);
when(row.getStatusBarNotification().getLogMaker()).thenReturn(new LogMaker(
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 d2d294bf8d37..a99dc7fb6924 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
@@ -37,7 +37,6 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.statusbar.NotificationMediaManager;
-import com.android.systemui.tuner.TunerService;
import org.junit.Before;
import org.junit.Test;
@@ -71,9 +70,9 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
@Mock
private UnlockMethodCache mUnlockMethodCache;
@Mock
- private TunerService mTunerService;
- @Mock
private Handler mHandler;
+ @Mock
+ private KeyguardBypassController mKeyguardBypassController;
private BiometricUnlockController mBiometricUnlockController;
@Before
@@ -81,12 +80,16 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
+ when(mUnlockMethodCache.isUnlockingWithFacePossible()).thenReturn(true);
+ when(mKeyguardBypassController.onBiometricAuthenticated(any())).thenReturn(true);
+ when(mKeyguardBypassController.canPlaySubtleWindowAnimations()).thenReturn(true);
mContext.addMockSystemService(PowerManager.class, mPowerManager);
mDependency.injectTestDependency(NotificationMediaManager.class, mMediaManager);
mDependency.injectTestDependency(StatusBarWindowController.class,
mStatusBarWindowController);
- mBiometricUnlockController = new TestableBiometricUnlockController(
- false /* faceDismissesKeyguard */);
+ mBiometricUnlockController = new BiometricUnlockController(mContext, mDozeScrimController,
+ mKeyguardViewMediator, mScrimController, mStatusBar, mUnlockMethodCache,
+ mHandler, mUpdateMonitor, 0 /* wakeUpDelay */, mKeyguardBypassController);
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
}
@@ -124,7 +127,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
@Test
public void onBiometricAuthenticated_whenFingerprintOnBouncer_dismissBouncer() {
when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
- when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
BiometricSourceType.FINGERPRINT);
@@ -138,25 +141,50 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
BiometricSourceType.FACE);
verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
+ verify(mStatusBarKeyguardViewManager, never()).notifyKeyguardAuthenticated(anyBoolean());
}
@Test
- public void onBiometricAuthenticated_whenFace_dismissingKeyguard() {
- mBiometricUnlockController = new TestableBiometricUnlockController(
- true /* faceDismissesKeyguard */);
+ public void onBiometricAuthenticated_whenFace_andBypass_dismissKeyguard() {
+ when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
BiometricSourceType.FACE);
- verify(mStatusBarKeyguardViewManager).animateCollapsePanels(anyFloat());
+ verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
+ verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(eq(false));
+ }
+
+ @Test
+ public void onBiometricAuthenticated_whenFace_andBypass_encrypted_showBouncer() {
+ when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
+ mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+
+ when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(false);
+ mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+ BiometricSourceType.FACE);
+
+ verify(mStatusBarKeyguardViewManager).showBouncer(eq(false));
+ }
+
+ @Test
+ public void onBiometricAuthenticated_whenFace_noBypass_encrypted_doNothing() {
+ mBiometricUnlockController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
+
+ when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(false);
+ mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
+ BiometricSourceType.FACE);
+
+ verify(mStatusBarKeyguardViewManager, never()).showBouncer(anyBoolean());
+ verify(mStatusBarKeyguardViewManager, never()).animateCollapsePanels(anyFloat());
}
@Test
public void onBiometricAuthenticated_whenFaceOnBouncer_dismissBouncer() {
when(mUpdateMonitor.isUnlockingWithBiometricAllowed()).thenReturn(true);
- when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true);
+ when(mStatusBarKeyguardViewManager.bouncerIsOrWillBeShowing()).thenReturn(true);
mBiometricUnlockController.onBiometricAuthenticated(UserHandle.USER_CURRENT,
BiometricSourceType.FACE);
@@ -186,15 +214,4 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
mBiometricUnlockController.onFinishedGoingToSleep(-1);
verify(mHandler).post(any());
}
-
- private class TestableBiometricUnlockController extends BiometricUnlockController {
-
- TestableBiometricUnlockController(boolean faceDismissesKeyguard) {
- super(mContext, mDozeScrimController,
- mKeyguardViewMediator, mScrimController, mStatusBar, mUnlockMethodCache,
- mHandler, mUpdateMonitor, mTunerService, 0 /* wakeUpDelay */,
- faceDismissesKeyguard);
- mFaceDismissesKeyguard = faceDismissesKeyguard;
- }
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
index f6f4eb489603..60050b182e0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/DozeParametersTest.java
@@ -16,10 +16,6 @@
package com.android.systemui.statusbar.phone;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.reset;
@@ -33,7 +29,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.doze.DozeScreenState;
-import com.android.systemui.statusbar.phone.DozeParameters.IntInOutMatcher;
import org.junit.Assert;
import org.junit.Test;
@@ -44,160 +39,6 @@ import org.junit.runner.RunWith;
public class DozeParametersTest extends SysuiTestCase {
@Test
- public void test_inOutMatcher_defaultIn() {
- IntInOutMatcher intInOutMatcher = new IntInOutMatcher("*");
-
- assertTrue(intInOutMatcher.isIn(1));
- assertTrue(intInOutMatcher.isIn(-1));
- assertTrue(intInOutMatcher.isIn(0));
- }
-
- @Test
- public void test_inOutMatcher_defaultOut() {
- IntInOutMatcher intInOutMatcher = new IntInOutMatcher("!*");
-
- assertFalse(intInOutMatcher.isIn(1));
- assertFalse(intInOutMatcher.isIn(-1));
- assertFalse(intInOutMatcher.isIn(0));
- }
-
- @Test
- public void test_inOutMatcher_someIn() {
- IntInOutMatcher intInOutMatcher = new IntInOutMatcher("1,2,3,!*");
-
- assertTrue(intInOutMatcher.isIn(1));
- assertTrue(intInOutMatcher.isIn(2));
- assertTrue(intInOutMatcher.isIn(3));
-
- assertFalse(intInOutMatcher.isIn(0));
- assertFalse(intInOutMatcher.isIn(4));
- }
-
- @Test
- public void test_inOutMatcher_someOut() {
- IntInOutMatcher intInOutMatcher = new IntInOutMatcher("!1,!2,!3,*");
-
- assertFalse(intInOutMatcher.isIn(1));
- assertFalse(intInOutMatcher.isIn(2));
- assertFalse(intInOutMatcher.isIn(3));
-
- assertTrue(intInOutMatcher.isIn(0));
- assertTrue(intInOutMatcher.isIn(4));
- }
-
- @Test
- public void test_inOutMatcher_mixed() {
- IntInOutMatcher intInOutMatcher = new IntInOutMatcher("!1,2,!3,*");
-
- assertFalse(intInOutMatcher.isIn(1));
- assertTrue(intInOutMatcher.isIn(2));
- assertFalse(intInOutMatcher.isIn(3));
-
- assertTrue(intInOutMatcher.isIn(0));
- assertTrue(intInOutMatcher.isIn(4));
- }
-
- @Test
- public void test_inOutMatcher_failEmpty() {
- try {
- new IntInOutMatcher("");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failNull() {
- try {
- new IntInOutMatcher(null);
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failEmptyClause() {
- try {
- new IntInOutMatcher("!1,*,");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failDuplicate() {
- try {
- new IntInOutMatcher("!1,*,!1");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failDuplicateDefault() {
- try {
- new IntInOutMatcher("!1,*,*");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failMalformedNot() {
- try {
- new IntInOutMatcher("!,*");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failText() {
- try {
- new IntInOutMatcher("!abc,*");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failContradiction() {
- try {
- new IntInOutMatcher("1,!1,*");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failContradictionDefault() {
- try {
- new IntInOutMatcher("1,*,!*");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
- public void test_inOutMatcher_failMissingDefault() {
- try {
- new IntInOutMatcher("1");
- fail("Expected IllegalArgumentException");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- @Test
public void test_setControlScreenOffAnimation_setsDozeAfterScreenOff_false() {
TestableDozeParameters dozeParameters = new TestableDozeParameters(getContext());
PowerManager mockedPowerManager = dozeParameters.getPowerManager();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index 0479b4a01dc9..b45707ef6c10 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -32,6 +32,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.DarkIconDispatcher;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -56,6 +57,8 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
private HeadsUpStatusBarView mHeadsUpStatusBarView;
private HeadsUpManagerPhone mHeadsUpManager;
private View mOperatorNameView;
+ private StatusBarStateController mStatusbarStateController;
+ private KeyguardBypassController mBypassController;
@Before
public void setUp() throws Exception {
@@ -67,16 +70,20 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
mock(TextView.class));
mHeadsUpManager = mock(HeadsUpManagerPhone.class);
mOperatorNameView = new View(mContext);
+ mStatusbarStateController = mock(StatusBarStateController.class);
+ mBypassController = mock(KeyguardBypassController.class);
mHeadsUpAppearanceController = new HeadsUpAppearanceController(
mock(NotificationIconAreaController.class),
mHeadsUpManager,
+ mStatusbarStateController,
+ mBypassController,
mHeadsUpStatusBarView,
mStackScroller,
mPanelView,
new View(mContext),
mOperatorNameView,
new View(mContext));
- mHeadsUpAppearanceController.setExpandedHeight(0.0f, 0.0f);
+ mHeadsUpAppearanceController.setAppearFraction(0.0f, 0.0f);
}
@Test
@@ -139,11 +146,13 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
@Test
public void testHeaderReadFromOldController() {
- mHeadsUpAppearanceController.setExpandedHeight(1.0f, 1.0f);
+ mHeadsUpAppearanceController.setAppearFraction(1.0f, 1.0f);
HeadsUpAppearanceController newController = new HeadsUpAppearanceController(
mock(NotificationIconAreaController.class),
mHeadsUpManager,
+ mStatusbarStateController,
+ mBypassController,
mHeadsUpStatusBarView,
mStackScroller,
mPanelView,
@@ -154,8 +163,8 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
Assert.assertEquals(mHeadsUpAppearanceController.mExpandedHeight,
newController.mExpandedHeight, 0.0f);
- Assert.assertEquals(mHeadsUpAppearanceController.mExpandFraction,
- newController.mExpandFraction, 0.0f);
+ Assert.assertEquals(mHeadsUpAppearanceController.mAppearFraction,
+ newController.mAppearFraction, 0.0f);
Assert.assertEquals(mHeadsUpAppearanceController.mIsExpanded,
newController.mIsExpanded);
}
@@ -172,7 +181,7 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
verify(mPanelView).removeVerticalTranslationListener(any());
verify(mPanelView).removeTrackingHeadsUpListener(any());
verify(mPanelView).setHeadsUpAppearanceController(any());
- verify(mStackScroller).removeOnExpandedHeightListener(any());
+ verify(mStackScroller).removeOnExpandedHeightChangedListener(any());
verify(mStackScroller).removeOnLayoutChangeListener(any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index 7bd41584f889..f8b9e6879dcf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -29,6 +29,7 @@ import android.view.View;
import androidx.test.filters.SmallTest;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.AlertingNotificationManagerTest;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
@@ -55,14 +56,21 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
@Mock private View mStatusBarWindowView;
@Mock private VisualStabilityManager mVSManager;
@Mock private StatusBar mBar;
+ @Mock private StatusBarStateController mStatusBarStateController;
+ @Mock private KeyguardBypassController mBypassController;
+ private boolean mLivesPastNormalTime;
private final class TestableHeadsUpManagerPhone extends HeadsUpManagerPhone {
TestableHeadsUpManagerPhone(Context context, View statusBarWindowView,
NotificationGroupManager groupManager, StatusBar bar,
- VisualStabilityManager vsManager) {
- super(context, statusBarWindowView, groupManager, bar, vsManager);
+ VisualStabilityManager vsManager,
+ StatusBarStateController statusBarStateController,
+ KeyguardBypassController keyguardBypassController) {
+ super(context, statusBarStateController, keyguardBypassController);
+ setUp(statusBarWindowView, groupManager, bar, vsManager);
mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
+ mAutoDismissNotificationDecayDozing = TEST_AUTO_DISMISS_TIME;
}
}
@@ -72,13 +80,13 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
@Before
public void setUp() {
- AccessibilityManagerWrapper mAccessibilityMgr =
+ AccessibilityManagerWrapper accessibilityMgr =
mDependency.injectMockDependency(AccessibilityManagerWrapper.class);
- when(mAccessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt()))
+ when(accessibilityMgr.getRecommendedTimeoutMillis(anyInt(), anyInt()))
.thenReturn(TEST_AUTO_DISMISS_TIME);
when(mVSManager.isReorderingAllowed()).thenReturn(true);
mHeadsUpManager = new TestableHeadsUpManagerPhone(mContext, mStatusBarWindowView,
- mGroupManager, mBar, mVSManager);
+ mGroupManager, mBar, mVSManager, mStatusBarStateController, mBypassController);
super.setUp();
mHeadsUpManager.mHandler = mTestHandler;
}
@@ -122,4 +130,26 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
// Notification is "behind" a higher priority notification so we can remove it immediately.
assertTrue(mHeadsUpManager.canRemoveImmediately(mEntry.key));
}
+
+
+ @Test
+ public void testExtendHeadsUp() {
+ when(mStatusBarStateController.isDozing()).thenReturn(true);
+ mHeadsUpManager.showNotification(mEntry);
+ Runnable pastNormalTimeRunnable =
+ () -> mLivesPastNormalTime = mHeadsUpManager.isAlerting(mEntry.key);
+ mTestHandler.postDelayed(pastNormalTimeRunnable,
+ mHeadsUpManager.mAutoDismissNotificationDecayDozing +
+ mHeadsUpManager.mExtensionTime / 2);
+ mTestHandler.postDelayed(TEST_TIMEOUT_RUNNABLE, TEST_TIMEOUT_TIME);
+
+ mHeadsUpManager.extendHeadsUp();
+
+ // Wait for normal time runnable and extended remove runnable and process them on arrival.
+ TestableLooper.get(this).processMessages(2);
+
+ assertFalse("Test timed out", mTimedOut);
+ assertTrue("Pulse was not extended", mLivesPastNormalTime);
+ assertFalse(mHeadsUpManager.isAlerting(mEntry.key));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 3bc5f3e62aaa..4e0ef56ad830 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -82,6 +82,8 @@ public class KeyguardBouncerTest extends SysuiTestCase {
@Mock
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@Mock
+ private UnlockMethodCache mUnlockMethodCache;
+ @Mock
private Handler mHandler;
private KeyguardBouncer mBouncer;
@@ -96,7 +98,7 @@ public class KeyguardBouncerTest extends SysuiTestCase {
when(mKeyguardHostView.getHeight()).thenReturn(500);
mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback,
mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager,
- mExpansionCallback, mKeyguardUpdateMonitor, mHandler) {
+ mExpansionCallback, mUnlockMethodCache, mKeyguardUpdateMonitor, mHandler) {
@Override
protected void inflateView() {
super.inflateView();
@@ -377,7 +379,7 @@ public class KeyguardBouncerTest extends SysuiTestCase {
@Test
public void testShow_delaysIfFaceAuthIsRunning() {
- when(mKeyguardUpdateMonitor.isFaceDetectionRunning()).thenReturn(true);
+ when(mUnlockMethodCache.isUnlockingWithFacePossible()).thenReturn(true);
mBouncer.show(true /* reset */);
ArgumentCaptor<Runnable> showRunnable = ArgumentCaptor.forClass(Runnable.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
index f8394f01a081..2042faba2b3a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithmTest.java
@@ -383,7 +383,8 @@ public class KeyguardClockPositionAlgorithmTest extends SysuiTestCase {
private void positionClock() {
mClockPositionAlgorithm.setup(EMPTY_MARGIN, SCREEN_HEIGHT, mNotificationStackHeight,
mPanelExpansion, SCREEN_HEIGHT, mKeyguardStatusHeight, mPreferredClockY,
- mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG);
+ mHasCustomClock, mHasVisibleNotifs, mDark, ZERO_DRAG, false /* bypassEnabled */,
+ 0 /* unlockedStackScrollerPadding */);
mClockPositionAlgorithm.run(mClockPosition);
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
index 337c35c39ca1..b1c3c83e938e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.phone;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -32,7 +33,7 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -58,7 +59,6 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
private NotificationGroupManager mGroupManager;
- private AmbientPulseManager mAmbientPulseManager;
private HeadsUpManager mHeadsUpManager;
@Mock private NotificationEntryManager mNotificationEntryManager;
@Captor
@@ -71,14 +71,12 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
@Before
public void setup() {
- mAmbientPulseManager = new AmbientPulseManager(mContext);
- mDependency.injectTestDependency(AmbientPulseManager.class, mAmbientPulseManager);
mHeadsUpManager = new HeadsUpManager(mContext) {};
when(mNotificationEntryManager.getPendingNotificationsIterator())
.thenReturn(mPendingEntries.values());
- mGroupManager = new NotificationGroupManager();
+ mGroupManager = new NotificationGroupManager(mock(StatusBarStateController.class));
mDependency.injectTestDependency(NotificationGroupManager.class, mGroupManager);
mGroupManager.setHeadsUpManager(mHeadsUpManager);
@@ -89,7 +87,6 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
verify(mNotificationEntryManager).addNotificationEntryListener(mListenerCaptor.capture());
mNotificationEntryListener = mListenerCaptor.getValue();
mHeadsUpManager.addListener(mGroupAlertTransferHelper);
- mAmbientPulseManager.addListener(mGroupAlertTransferHelper);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
index 43685f0513e7..dd274c7c09b9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupManagerTest.java
@@ -21,6 +21,7 @@ import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.junit.Assert.assertNull;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.testing.AndroidTestingRunner;
@@ -29,7 +30,7 @@ import android.testing.TestableLooper;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.AmbientPulseManager;
+import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -53,17 +54,14 @@ public class NotificationGroupManagerTest extends SysuiTestCase {
new NotificationGroupTestHelper(mContext);
@Mock HeadsUpManager mHeadsUpManager;
- @Mock AmbientPulseManager mAmbientPulseManager;
@Before
public void setup() {
- mDependency.injectTestDependency(AmbientPulseManager.class, mAmbientPulseManager);
-
initializeGroupManager();
}
private void initializeGroupManager() {
- mGroupManager = new NotificationGroupManager();
+ mGroupManager = new NotificationGroupManager(mock(StatusBarStateController.class));
mGroupManager.setHeadsUpManager(mHeadsUpManager);
}
@@ -146,21 +144,4 @@ public class NotificationGroupManagerTest extends SysuiTestCase {
assertEquals(childEntry, mGroupManager.getGroupSummary(childEntry.notification));
assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(childEntry.notification));
}
-
- @Test
- public void testAmbientPulseEntryIsIsolated() {
- NotificationEntry childEntry = mGroupTestHelper.createChildNotification();
- NotificationEntry summaryEntry = mGroupTestHelper.createSummaryNotification();
- mGroupManager.onEntryAdded(summaryEntry);
- mGroupManager.onEntryAdded(childEntry);
- mGroupManager.onEntryAdded(mGroupTestHelper.createChildNotification());
- when(mAmbientPulseManager.isAlerting(childEntry.key)).thenReturn(true);
-
- mGroupManager.onAmbientStateChanged(childEntry, true);
-
- // Child entries that are heads upped should be considered separate groups visually even if
- // they are the same group logically
- assertEquals(childEntry, mGroupManager.getGroupSummary(childEntry.notification));
- assertEquals(summaryEntry, mGroupManager.getLogicalGroupSummary(childEntry.notification));
- }
}
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 1b7ca952dbfe..d14b460d8c63 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
@@ -37,7 +37,6 @@ import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.SystemUIFactory;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.KeyguardAffordanceView;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationShelf;
@@ -46,9 +45,11 @@ import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.stack.NotificationRoundnessManager;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
@@ -111,12 +112,18 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
mDependency.injectMockDependency(ConfigurationController.class);
mDependency.injectMockDependency(ZenModeController.class);
+ KeyguardBypassController bypassController = new KeyguardBypassController(mContext,
+ mock(TunerService.class), mStatusBarStateController,
+ mock(NotificationLockscreenUserManager.class));
NotificationWakeUpCoordinator coordinator =
new NotificationWakeUpCoordinator(mContext,
- new AmbientPulseManager(mContext),
- new StatusBarStateControllerImpl());
- PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator);
- mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler);
+ mock(HeadsUpManagerPhone.class),
+ new StatusBarStateControllerImpl(),
+ bypassController);
+ PulseExpansionHandler expansionHandler = new PulseExpansionHandler(mContext, coordinator,
+ bypassController, mHeadsUpManager, mock(NotificationRoundnessManager.class));
+ mNotificationPanelView = new TestableNotificationPanelView(coordinator, expansionHandler,
+ bypassController);
mNotificationPanelView.setHeadsUpManager(mHeadsUpManager);
mNotificationPanelView.setBar(mPanelBar);
@@ -128,7 +135,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
public void testSetDozing_notifiesNsslAndStateController() {
mNotificationPanelView.setDozing(true /* dozing */, true /* animate */, null /* touch */);
InOrder inOrder = inOrder(mNotificationStackScrollLayout, mStatusBarStateController);
- inOrder.verify(mNotificationStackScrollLayout).setDark(eq(true), eq(true), eq(null));
+ inOrder.verify(mNotificationStackScrollLayout).setDozing(eq(true), eq(true), eq(null));
inOrder.verify(mStatusBarStateController).setDozeAmount(eq(1f), eq(true));
}
@@ -178,11 +185,13 @@ public class NotificationPanelViewTest extends SysuiTestCase {
private class TestableNotificationPanelView extends NotificationPanelView {
TestableNotificationPanelView(NotificationWakeUpCoordinator coordinator,
- PulseExpansionHandler expansionHandler) {
+ PulseExpansionHandler expansionHandler,
+ KeyguardBypassController bypassController) {
super(NotificationPanelViewTest.this.mContext, null,
new InjectionInflationController(
SystemUIFactory.getInstance().getRootComponent()),
- coordinator, expansionHandler, mock(DynamicPrivacyController.class));
+ coordinator, expansionHandler, mock(DynamicPrivacyController.class),
+ bypassController);
mNotificationStackScroller = mNotificationStackScrollLayout;
mKeyguardStatusView = NotificationPanelViewTest.this.mKeyguardStatusView;
mKeyguardStatusBar = NotificationPanelViewTest.this.mKeyguardStatusBar;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index f50cf5a70cdc..1b33aefd1634 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -29,6 +29,7 @@ import static org.mockito.Mockito.when;
import android.content.Context;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.view.View;
import android.view.ViewGroup;
import androidx.test.filters.SmallTest;
@@ -39,6 +40,7 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
import org.junit.Before;
import org.junit.Test;
@@ -70,7 +72,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
@Mock
private ViewGroup mLockIconContainer;
@Mock
- private StatusBarStateController mStatusBarStateController;
+ private SysuiStatusBarStateController mStatusBarStateController;
+ @Mock
+ private View mNotificationContainer;
+ @Mock
+ private KeyguardBypassController mBypassController;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Before
@@ -83,7 +89,7 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
mViewMediatorCallback, mLockPatternUtils);
mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer,
mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry,
- mLockIconContainer);
+ mLockIconContainer, mNotificationContainer, mBypassController);
mStatusBarKeyguardViewManager.show(null);
}
@@ -221,9 +227,11 @@ public class StatusBarKeyguardViewManagerTest extends SysuiTestCase {
NotificationPanelView notificationPanelView,
BiometricUnlockController fingerprintUnlockController,
DismissCallbackRegistry dismissCallbackRegistry,
- ViewGroup lockIconContainer) {
+ ViewGroup lockIconContainer, View notificationContainer,
+ KeyguardBypassController bypassController) {
super.registerStatusBar(statusBar, container, notificationPanelView,
- fingerprintUnlockController, dismissCallbackRegistry, lockIconContainer);
+ fingerprintUnlockController, dismissCallbackRegistry, lockIconContainer,
+ notificationContainer, bypassController);
mBouncer = StatusBarKeyguardViewManagerTest.this.mBouncer;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index 79e05c373534..cffd57b35f04 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -222,6 +222,7 @@ public class StatusBarTest extends SysuiTestCase {
mNotificationLogger = new NotificationLogger(mNotificationListener,
Dependency.get(UiOffloadThread.class), mEntryManager, mStatusBarStateController,
mExpansionStateLogger);
+ mNotificationLogger.setVisibilityReporter(mock(Runnable.class));
mDependency.injectTestDependency(NotificationLogger.class, mNotificationLogger);
DozeLog.traceDozing(mContext, false /* dozing */);
@@ -253,7 +254,7 @@ public class StatusBarTest extends SysuiTestCase {
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
mStatusBar = new TestableStatusBar(mStatusBarKeyguardViewManager, mUnlockMethodCache,
- mKeyguardIndicationController, mStackScroller, mHeadsUpManager,
+ mKeyguardIndicationController, mStackScroller,
mPowerManager, mNotificationPanelView, mBarService, mNotificationListener,
mNotificationLogger, mVisualStabilityManager, mViewHierarchyManager,
mEntryManager, mScrimController, mBiometricUnlockController,
@@ -269,19 +270,13 @@ public class StatusBarTest extends SysuiTestCase {
SystemUIFactory.getInstance().getRootComponent()
.getStatusBarInjector()
.createStatusBar(mStatusBar);
+ mStatusBar.setHeadsUpManager(mHeadsUpManager);
mStatusBar.putComponent(StatusBar.class, mStatusBar);
Dependency.get(InitController.class).executePostInitTasks();
mEntryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller,
mHeadsUpManager, mNotificationData);
mEntryManager.addNotificationEntryListener(mEntryListener);
mNotificationLogger.setUpWithContainer(mStackScroller);
-
- TestableLooper.get(this).setMessageHandler(m -> {
- if (m.getCallback() == mStatusBar.mNotificationLogger.getVisibilityReporter()) {
- return false;
- }
- return true;
- });
}
@Test
@@ -644,10 +639,10 @@ public class StatusBarTest extends SysuiTestCase {
@Test
public void testPulseWhileDozing_notifyAuthInterrupt() {
HashSet<Integer> reasonsWantingAuth = new HashSet<>(
- Collections.singletonList(DozeLog.PULSE_REASON_NOTIFICATION));
+ Collections.singletonList(DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN));
HashSet<Integer> reasonsSkippingAuth = new HashSet<>(
Arrays.asList(DozeLog.PULSE_REASON_INTENT,
- DozeLog.PULSE_REASON_SENSOR_WAKE_LOCK_SCREEN,
+ DozeLog.PULSE_REASON_NOTIFICATION,
DozeLog.PULSE_REASON_SENSOR_SIGMOTION,
DozeLog.REASON_SENSOR_PICKUP,
DozeLog.REASON_SENSOR_DOUBLE_TAP,
@@ -666,6 +661,7 @@ public class StatusBarTest extends SysuiTestCase {
return null;
}).when(mDozeScrimController).pulse(any(), anyInt());
+ mStatusBar.mDozeServiceHost.mWakeLockScreenPerformsAuth = true;
for (int i = 0; i < DozeLog.REASONS; i++) {
reset(mKeyguardUpdateMonitor);
mStatusBar.mDozeServiceHost.pulseWhileDozing(mock(DozeHost.PulseCallback.class), i);
@@ -765,7 +761,7 @@ public class StatusBarTest extends SysuiTestCase {
static class TestableStatusBar extends StatusBar {
public TestableStatusBar(StatusBarKeyguardViewManager man,
UnlockMethodCache unlock, KeyguardIndicationController key,
- NotificationStackScrollLayout stack, HeadsUpManagerPhone hum,
+ NotificationStackScrollLayout stack,
PowerManager pm, NotificationPanelView panelView,
IStatusBarService barService, NotificationListener notificationListener,
NotificationLogger notificationLogger,
@@ -794,7 +790,6 @@ public class StatusBarTest extends SysuiTestCase {
mUnlockMethodCache = unlock;
mKeyguardIndicationController = key;
mStackScroller = stack;
- mHeadsUpManager = hum;
mPowerManager = pm;
mNotificationPanel = panelView;
mBarService = barService;
@@ -824,6 +819,7 @@ public class StatusBarTest extends SysuiTestCase {
mAutoHideController = autoHideController;
mKeyguardUpdateMonitor = keyguardUpdateMonitor;
mStatusBarWindow = statusBarWindow;
+ mDozeServiceHost.mWakeLockScreenPerformsAuth = false;
}
private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
@@ -842,6 +838,10 @@ public class StatusBarTest extends SysuiTestCase {
mState = state;
}
+ void setHeadsUpManager(HeadsUpManagerPhone headsUpManager) {
+ mHeadsUpManager = headsUpManager;
+ }
+
public void setUserSetupForTest(boolean userSetup) {
mUserSetup = userSetup;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 3464fe574007..9ae9ceb2629f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -181,6 +181,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
protected void setDefaultSubId(int subId) {
when(mMockSubDefaults.getDefaultDataSubId()).thenReturn(subId);
when(mMockSubDefaults.getDefaultVoiceSubId()).thenReturn(subId);
+ when(mMockSubDefaults.getActiveDataSubId()).thenReturn(subId);
}
protected void setSubscriptions(int... subIds) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
index 8c5fac47885f..0cb575483466 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SmartReplyViewTest.java
@@ -109,7 +109,9 @@ public class SmartReplyViewTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
mReceiver = new BlockingQueueIntentReceiver();
mContext.registerReceiver(mReceiver, new IntentFilter(TEST_ACTION));
- mDependency.get(KeyguardDismissUtil.class).setDismissHandler(action -> action.onDismiss());
+ mDependency.get(KeyguardDismissUtil.class).setDismissHandler((action, unused) -> {
+ action.onDismiss();
+ });
mDependency.injectMockDependency(ShadeController.class);
mDependency.injectTestDependency(ActivityStarter.class, mActivityStarter);
mDependency.injectTestDependency(SmartReplyConstants.class, mConstants);
@@ -162,7 +164,7 @@ public class SmartReplyViewTest extends SysuiTestCase {
@Test
public void testSendSmartReply_keyguardCancelled() throws InterruptedException {
- mDependency.get(KeyguardDismissUtil.class).setDismissHandler(action -> {});
+ mDependency.get(KeyguardDismissUtil.class).setDismissHandler((action, unused) -> {});
setSmartReplies(TEST_CHOICES);
mView.getChildAt(2).performClick();
@@ -173,7 +175,9 @@ public class SmartReplyViewTest extends SysuiTestCase {
@Test
public void testSendSmartReply_waitsForKeyguard() throws InterruptedException {
AtomicReference<OnDismissAction> actionRef = new AtomicReference<>();
- mDependency.get(KeyguardDismissUtil.class).setDismissHandler(actionRef::set);
+ mDependency.get(KeyguardDismissUtil.class).setDismissHandler((action, unused) -> {
+ actionRef.set(action);
+ });
setSmartReplies(TEST_CHOICES);
mView.getChildAt(2).performClick();
diff --git a/packages/overlays/Android.mk b/packages/overlays/Android.mk
index 3f16c128f664..3eb90491f902 100644
--- a/packages/overlays/Android.mk
+++ b/packages/overlays/Android.mk
@@ -44,7 +44,6 @@ LOCAL_REQUIRED_MODULES := \
IconPackRoundedSystemUIOverlay \
IconPackRoundedThemePickerUIOverlay \
IconShapeRoundedRectOverlay \
- IconShapeSquareOverlay \
IconShapeSquircleOverlay \
IconShapeTeardropOverlay \
NavigationBarMode3ButtonOverlay \
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_battery_80_24dp.xml
index 22e183c694d5..4d8dbdba9207 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_battery_80_24dp.xml
@@ -21,5 +21,5 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z M15,13c0,0.55-0.45,1-1,1h-1v1c0,0.55-0.45,1-1,1s-1-0.45-1-1v-1h-1c-0.55,0-1-0.45-1-1s0.45-1,1-1h1v-1 c0-0.55,0.45-1,1-1s1,0.45,1,1v1h1C14.55,12,15,12.45,15,13z" />
+ android:pathData="M18,19V7c0-1.66-1.34-3-3-3h-1c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9C7.34,4,6,5.34,6,7v12c0,1.66,1.34,3,3,3h6 C16.66,22,18,20.66,18,19z M9,5.5h6c0.83,0,1.5,0.67,1.5,1.5v1h-9V7C7.5,6.17,8.17,5.5,9,5.5z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_misc_hid.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_misc_hid.xml
index e182886d4252..5096f2f0f2e9 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_misc_hid.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_bt_misc_hid.xml
@@ -20,7 +20,6 @@
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path android:pathData="M0,0h24v24H0V0z" />
<path
android:fillColor="@android:color/white"
android:pathData="M9,16.5V20c0,1.1,0.9,2,2,2h2c1.1,0,2-0.9,2-2v-3.5l-3-3L9,16.5z M13.5,20c0,0.28-0.22,0.5-0.5,0.5h-2 c-0.28,0-0.5-0.22-0.5-0.5v-2.88l1.5-1.5l1.5,1.5V20z M15,7.5V4c0-1.1-0.9-2-2-2h-2C9.9,2,9,2.9,9,4v3.5l3,3L15,7.5z M10.5,4 c0-0.28,0.22-0.5,0.5-0.5h2c0.28,0,0.5,0.22,0.5,0.5v2.88L12,8.38l-1.5-1.5V4z M7.5,9H4c-1.1,0-2,0.9-2,2v2c0,1.1,0.9,2,2,2h3.5 l3-3L7.5,9z M6.88,13.5H4c-0.28,0-0.5-0.22-0.5-0.5v-2c0-0.28,0.22-0.5,0.5-0.5h2.88l1.5,1.5L6.88,13.5z M20,9h-3.5l-3,3l3,3H20 c1.1,0,2-0.9,2-2v-2C22,9.9,21.1,9,20,9z M20.5,13c0,0.28-0.22,0.5-0.5,0.5h-2.88l-1.5-1.5l1.5-1.5H20c0.28,0,0.5,0.22,0.5,0.5V13z" />
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_file_copy.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_file_copy.xml
index dc6ab95e23b1..b8e9845d5039 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_file_copy.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_file_copy.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="#FF737373"
+ android:tint="@*android:color/material_grey_600"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml
index 1e3400b40e79..5a67f95788ee 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock.xml
@@ -16,7 +16,6 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="32dp"
- android:tint="?android:attr/textColor"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="32dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml
index f4606a2a9d3e..21abd6e2d3ba 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lock_open.xml
@@ -16,7 +16,6 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="32dp"
- android:tint="?android:attr/textColor"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="32dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
index 4344e32a75aa..455bdd50ceba 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml
index f0d782e03d11..aca3d52c1a24 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_mode_edit.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_delete_accent.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_notifications_alerted.xml
index d30eb7c0f098..86863b3b6c98 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_delete_accent.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_notifications_alerted.xml
@@ -16,17 +16,19 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="?android:attr/colorAccent"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M20,4h-1h-4c0-0.55-0.45-1-1-1h-4C9.45,3,9,3.45,9,4H5H4C3.59,4,3.25,4.34,3.25,4.75S3.59,5.5,4,5.5h1V18 c0,1.66,1.34,3,3,3h8c1.66,0,3-1.34,3-3V5.5h1c0.41,0,0.75-0.34,0.75-0.75S20.41,4,20,4z M17.5,18c0,0.83-0.67,1.5-1.5,1.5H8 c-0.83,0-1.5-0.67-1.5-1.5V5.5h11V18z" />
+ android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M14.25,8c-0.41,0-0.75,0.34-0.75,0.75v7.5c0,0.41,0.34,0.75,0.75,0.75S15,16.66,15,16.25v-7.5C15,8.34,14.66,8,14.25,8z" />
+ android:pathData="M21.5,10.25c0-2.79-1.22-5.43-3.35-7.24c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06 C18.97,5.68,20,7.9,20,10.25c0,0.41,0.34,0.75,0.75,0.75S21.5,10.66,21.5,10.25z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M9.75,8C9.34,8,9,8.34,9,8.75v7.5C9,16.66,9.34,17,9.75,17s0.75-0.34,0.75-0.75v-7.5C10.5,8.34,10.16,8,9.75,8z" />
+ android:pathData="M12,2.5c-0.83,0-1.5,0.67-1.5,1.5v0.7C7.91,5.36,6,7.71,6,10.5V15c0,0.55-0.45,1-1,1s-1,0.45-1,1v2h16v-2 c0-0.55-0.45-1-1-1s-1-0.45-1-1v-4.5c0-2.79-1.91-5.14-4.5-5.8V4C13.5,3.17,12.83,2.5,12,2.5z M16.5,10.5V15 c0,1.21,0.86,2.22,2,2.45v0.05h-13v-0.05c1.14-0.23,2-1.24,2-2.45v-4.5C7.5,8.02,9.52,6,12,6S16.5,8.02,16.5,10.5z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml
index 28733c1890cb..85c184b9f9a8 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_phone.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_battery_saver.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
index a558337902c4..73310b03f625 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
index 452a032c49e9..19731249bfc7 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
new file mode 100644
index 000000000000..3cf7541219f0
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M12,20.5 L12,3.5 C16.687,3.5 20.5,7.313 20.5,12 C20.5,16.687 16.687,20.5 12,20.5 M12,2 C10.619,2 9.304,2.279 8.107,2.786 C7.51,3.039 6.941,3.349 6.409,3.708 C6.143,3.888 5.886,4.08 5.639,4.283 C4.651,5.099 3.822,6.1 3.207,7.233 C2.899,7.8 2.645,8.4 2.449,9.026 C2.255,9.652 2.12,10.305 2.052,10.978 C2.018,11.313 2,11.654 2,12 C2,17.522 6.478,22 12,22 C17.522,22 22,17.522 22,12 C22,6.478 17.522,2 12,2"
+ android:strokeWidth="1" />
+</vector>
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_0_4_bar.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_0_4_bar.xml
index e09aeb7f1d2f..d9dfa54697e4 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_0_4_bar.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_0_4_bar.xml
@@ -19,28 +19,32 @@
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M20,22H18.5V4.75A0.76 0.76 ,0,0,1,19.25,4h0a0.76 0.76 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M15.33,22h-1.5V9.75A0.76 0.76 ,0,0,1,14.58,9h0a0.75 0.75 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M10.67,22H9.17V14.75A0.75 0.75 ,0,0,1,9.92,14h0a0.76 0.76 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M6,22H4.5V19.75A0.76 0.76 ,0,0,1,5.25,19h0a0.76 0.76 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
+ <group
+ android:translateX="4.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M16,18 L14.5,18 L14.5,0.75 C14.5053858,0.338037936 14.8380379,0.00538581231 15.25,0 L15.25,0 C15.6619621,0.00538581231 15.9946142,0.338037936 16,0.75 L16,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M11.33,18 L9.83,18 L9.83,5.75 C9.83538581,5.33803794 10.1680379,5.00538581 10.58,5 L10.58,5 C10.9942136,5 11.33,5.33578644 11.33,5.75 L11.33,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M6.67,18 L5.17,18 L5.17,10.75 C5.17,10.3357864 5.50578644,10 5.92,10 L5.92,10 C6.33196206,10.0053858 6.66461419,10.3380379 6.67,10.75 L6.67,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M2,18 L0.5,18 L0.5,15.75 C0.505385812,15.3380379 0.838037936,15.0053858 1.25,15 L1.25,15 C1.66196206,15.0053858 1.99461419,15.3380379 2,15.75 L2,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_1_4_bar.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_1_4_bar.xml
index 26e96ab4c5c8..70f91afab7d5 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_1_4_bar.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_1_4_bar.xml
@@ -19,25 +19,30 @@
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M20,22H18.5V4.75A0.76 0.76 ,0,0,1,19.25,4h0a0.76 0.76 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M15.33,22h-1.5V9.75A0.76 0.76 ,0,0,1,14.58,9h0a0.75 0.75 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M10.67,22H9.17V14.75A0.75 0.75 ,0,0,1,9.92,14h0a0.76 0.76 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6,22H4.5V19.75A0.76 0.76 ,0,0,1,5.25,19h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
+ <group
+ android:translateX="4.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M16,18 L14.5,18 L14.5,0.75 C14.5053858,0.338037936 14.8380379,0.00538581231 15.25,0 L15.25,0 C15.6619621,0.00538581231 15.9946142,0.338037936 16,0.75 L16,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M11.33,18 L9.83,18 L9.83,5.75 C9.83538581,5.33803794 10.1680379,5.00538581 10.58,5 L10.58,5 C10.9942136,5 11.33,5.33578644 11.33,5.75 L11.33,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M6.67,18 L5.17,18 L5.17,10.75 C5.17,10.3357864 5.50578644,10 5.92,10 L5.92,10 C6.33196206,10.0053858 6.66461419,10.3380379 6.67,10.75 L6.67,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M2,18 L0.5,18 L0.5,15.75 C0.505385812,15.3380379 0.838037936,15.0053858 1.25,15 L1.25,15 C1.66196206,15.0053858 1.99461419,15.3380379 2,15.75 L2,18 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_2_4_bar.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_2_4_bar.xml
index 53be899d5a8d..f014eea9354f 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_2_4_bar.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_2_4_bar.xml
@@ -19,22 +19,28 @@
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M20,22H18.5V4.75A0.76 0.76 ,0,0,1,19.25,4h0a0.76 0.76 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M15.33,22h-1.5V9.75A0.76 0.76 ,0,0,1,14.58,9h0a0.75 0.75 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M10.67,22H9.17V14.75A0.75 0.75 ,0,0,1,9.92,14h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6,22H4.5V19.75A0.76 0.76 ,0,0,1,5.25,19h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
+ <group
+ android:translateX="4.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M16,18 L14.5,18 L14.5,0.75 C14.5053858,0.338037936 14.8380379,0.00538581231 15.25,0 L15.25,0 C15.6619621,0.00538581231 15.9946142,0.338037936 16,0.75 L16,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M11.33,18 L9.83,18 L9.83,5.75 C9.83538581,5.33803794 10.1680379,5.00538581 10.58,5 L10.58,5 C10.9942136,5 11.33,5.33578644 11.33,5.75 L11.33,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M6.67,18 L5.17,18 L5.17,10.75 C5.17,10.3357864 5.50578644,10 5.92,10 L5.92,10 C6.33196206,10.0053858 6.66461419,10.3380379 6.67,10.75 L6.67,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M2,18 L0.5,18 L0.5,15.75 C0.505385812,15.3380379 0.838037936,15.0053858 1.25,15 L1.25,15 C1.66196206,15.0053858 1.99461419,15.3380379 2,15.75 L2,18 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_3_4_bar.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_3_4_bar.xml
index 9139bb449509..9b83fab35144 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_3_4_bar.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_3_4_bar.xml
@@ -19,19 +19,26 @@
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillAlpha="0.3"
- android:fillColor="@android:color/white"
- android:pathData="M20,22H18.5V4.75A0.76 0.76 ,0,0,1,19.25,4h0a0.76 0.76 ,0,0,1,0.75 0.75 Z"
- android:strokeAlpha="0.3"
- android:strokeWidth="1" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M15.33,22h-1.5V9.75A0.76 0.76 ,0,0,1,14.58,9h0a0.75 0.75 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M10.67,22H9.17V14.75A0.75 0.75 ,0,0,1,9.92,14h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6,22H4.5V19.75A0.76 0.76 ,0,0,1,5.25,19h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
+ <group
+ android:translateX="4.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillAlpha="0.3"
+ android:fillColor="@android:color/white"
+ android:pathData="M16,18 L14.5,18 L14.5,0.75 C14.5053858,0.338037936 14.8380379,0.00538581231 15.25,0 L15.25,0 C15.6619621,0.00538581231 15.9946142,0.338037936 16,0.75 L16,18 Z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M11.33,18 L9.83,18 L9.83,5.75 C9.83538581,5.33803794 10.1680379,5.00538581 10.58,5 L10.58,5 C10.9942136,5 11.33,5.33578644 11.33,5.75 L11.33,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M6.67,18 L5.17,18 L5.17,10.75 C5.17,10.3357864 5.50578644,10 5.92,10 L5.92,10 C6.33196206,10.0053858 6.66461419,10.3380379 6.67,10.75 L6.67,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M2,18 L0.5,18 L0.5,15.75 C0.505385812,15.3380379 0.838037936,15.0053858 1.25,15 L1.25,15 C1.66196206,15.0053858 1.99461419,15.3380379 2,15.75 L2,18 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_4_4_bar.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_4_4_bar.xml
index 2c8d70123f60..6f7f48d1ea96 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_4_4_bar.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/ic_signal_cellular_4_4_bar.xml
@@ -19,16 +19,24 @@
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M20,22H18.5V4.75A0.76 0.76 ,0,0,1,19.25,4h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M15.33,22h-1.5V9.75A0.76 0.76 ,0,0,1,14.58,9h0a0.75 0.75 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M10.67,22H9.17V14.75A0.75 0.75 ,0,0,1,9.92,14h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6,22H4.5V19.75A0.76 0.76 ,0,0,1,5.25,19h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
+ <group
+ android:translateX="4.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M16,18 L14.5,18 L14.5,0.75 C14.5053858,0.338037936 14.8380379,0.00538581231 15.25,0 L15.25,0 C15.6619621,0.00538581231 15.9946142,0.338037936 16,0.75 L16,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M11.33,18 L9.83,18 L9.83,5.75 C9.83538581,5.33803794 10.1680379,5.00538581 10.58,5 L10.58,5 C10.9942136,5 11.33,5.33578644 11.33,5.75 L11.33,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M6.67,18 L5.17,18 L5.17,10.75 C5.17,10.3357864 5.50578644,10 5.92,10 L5.92,10 C6.33196206,10.0053858 6.66461419,10.3380379 6.67,10.75 L6.67,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M2,18 L0.5,18 L0.5,15.75 C0.505385812,15.3380379 0.838037936,15.0053858 1.25,15 L1.25,15 C1.66196206,15.0053858 1.99461419,15.3380379 2,15.75 L2,18 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_activity_recognition.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
index 5ad146eb21ac..cbd60d880fb2 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml
new file mode 100644
index 000000000000..64802640a9ec
--- /dev/null
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_aural.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M12.64,3 L12.64,8.82352941 C12.2536,8.5 11.772,8.29411765 11.24,8.29411765 C10.0024,8.29411765 9,9.34705882 9,10.6470588 C9,11.9470588 10.0024,13 11.24,13 C12.4776,13 13.48,11.9470588 13.48,10.6470588 L13.48,5.00157166 L15.02,5.00157166 C15.5576,5.00157166 16,4.53686577 16,3.97215989 L16,3 L12.64,3 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20,2 C20,0.9 19.1,0 18,0 L6,0 C4.9,0 4,0.9 4,2 L4,14 C4,15.1 4.9,16 6,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 Z M18.5,14 C18.5,14.28 18.28,14.5 18,14.5 L6,14.5 C5.72,14.5 5.5,14.28 5.5,14 L5.5,2 C5.5,1.72 5.72,1.5 6,1.5 L18,1.5 C18.28,1.5 18.5,1.72 18.5,2 L18.5,14 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M0.5,4.75 L0.5,16.75 C0.5,18.27 1.73,19.5 3.25,19.5 L15.25,19.5 C15.66,19.5 16,19.16 16,18.75 C16,18.34 15.66,18 15.25,18 L3.25,18 C2.56,18 2,17.44 2,16.75 L2,4.75 C2,4.34 1.66,4 1.25,4 C0.84,4 0.5,4.34 0.5,4.75 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_calendar.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_calendar.xml
index 781c0f8e8ea5..397050fd88f4 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_calendar.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_calendar.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_call_log.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_call_log.xml
index 126b70cff251..b56eec39334c 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_call_log.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_call_log.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_camera.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_camera.xml
index 70d4fcc945df..c8cb2e2cfc1f 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_camera.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_camera.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_contacts.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_contacts.xml
index 6da4b269d312..6124df86e931 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_contacts.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_contacts.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_location.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_location.xml
index d443a7484e5a..77ff42ad3e25 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_location.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_location.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_microphone.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_microphone.xml
index cdac2d8cadaa..06aa0cd3f238 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_microphone.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_microphone.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_phone_calls.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_phone_calls.xml
index 991f320add6c..3aea5f44902b 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_phone_calls.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_phone_calls.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sensors.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sensors.xml
index e4dee2adc467..4d70fc90850e 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sensors.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sensors.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml
index d15cfa3b1e3a..30ed8c92a198 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_sms.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_storage.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_storage.xml
index 29d26736135b..52cd4c1c7153 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_storage.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_storage.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_visual.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_visual.xml
index 519136a28725..1c461791c868 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_visual.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/drawable/perm_group_visual.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml
index ae5cc2bf9883..30f29f778858 100644
--- a/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml
+++ b/packages/overlays/IconPackCircularAndroidOverlay/res/values/config.xml
@@ -30,4 +30,12 @@
<string name="config_batterymeterPowersavePath" translatable="false">
M 3.75,11.25 H 5.25 V 12.75 C 5.25,13.16 5.59,13.5 6,13.5 6.41,13.5 6.75,13.16 6.75,12.75 V 11.25 H 8.25 C 8.66,11.25 9,10.91 9,10.5 9,10.09 8.6601,9.75 8.25,9.75 H 6.75 V 8.25 C 6.75,7.84 6.41,7.5 6,7.5 5.59,7.5 5.25,7.84 5.25,8.25 V 9.75 H 3.75 C 3.34,9.75 3,10.09 3,10.5 3,10.91 3.34,11.25 3.75,11.25 Z
</string>
+ <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+ <string name="config_signalXPath" translatable="false">
+ M 17.81,18.75 L 19.81,16.75 C 20.01,16.56 20.09,16.28 20.02,16.02 C 19.96,15.75 19.75,15.54 19.48,15.47 C 19.22,15.41 18.94,15.49 18.75,15.69 L 16.75,17.69 L 14.75,15.69 C 14.56,15.49 14.28,15.41 14.02,15.47 C 13.75,15.54 13.54,15.75 13.47,16.02 C 13.41,16.28 13.49,16.56 13.69,16.75 L 15.69,18.75 L 13.69,20.75 C 13.4,21.04 13.4,21.52 13.69,21.81 C 13.98,22.1 14.46,22.1 14.75,21.81 L 16.75,19.81 L 18.75,21.81 C 19.04,22.1 19.52,22.1 19.81,21.81 C 20.1,21.52 20.1,21.04 19.81,20.75 Z
+ </string>
+ <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+ should be cut out to display config_signalXPath.-->
+ <item name="config_signalCutoutWidthFraction" format="float" type="dimen">10.5</item>
+ <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item>
</resources>
diff --git a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
index 4c9b5d7b1c48..f1f0f507d4b9 100644
--- a/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackCircularLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/textColorPrimary"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_arrow_back.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_arrow_back.xml
index 920ecb5deb70..a9e1ffe6d69e 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_arrow_back.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_arrow_back.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml
deleted file mode 100644
index 01d87ce25a2f..000000000000
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:tint="?android:attr/colorAccent"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M9.75,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5C9.34,12.25,9,12.59,9,13 S9.34,13.75,9.75,13.75z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6,19c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7c0-1.66-1.34-3-3-3h-1c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9 C7.34,4,6,5.34,6,7V19z M7.5,7c0-0.83,0.67-1.5,1.5-1.5h6c0.83,0,1.5,0.67,1.5,1.5v12c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V7z" />
-</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml
deleted file mode 100644
index a558337902c4..000000000000
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M9.75,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5C9.34,12.25,9,12.59,9,13 S9.34,13.75,9.75,13.75z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6,19c0,1.66,1.34,3,3,3h6c1.66,0,3-1.34,3-3V7c0-1.66-1.34-3-3-3h-1c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1H9 C7.34,4,6,5.34,6,7V19z M7.5,7c0-0.83,0.67-1.5,1.5-1.5h6c0.83,0,1.5,0.67,1.5,1.5v12c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V7z" />
-</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_cellular_off.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_cellular_off.xml
index 57fcebc91d2e..6df47564407e 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_cellular_off.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_cellular_off.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorAccent"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
index 9569e68be613..82df1de6211c 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
index 9dea4ca2ea28..b8e9845d5039 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="#757575"
+ android:tint="@*android:color/material_grey_600"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml
index 77c0a158ebdd..ba3c5808d26c 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_data_saver.xml
@@ -15,18 +15,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M12,7a0.76 0.76 ,0,0,0-0.75 0.75 v3.5H7.75a0.75 0.75 ,0,0,0,0,1.5h3.5v3.5a0.75 0.75 ,0,0,0,1.5,0v-3.5h3.5a0.75 0.75 ,0,0,0,0-1.5h-3.5V7.75A0.76 0.76 ,0,0,0,12,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z" />
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17.5000671,10 C17.5000671,6.198 14.6680671,3.064 11.0000671,2.574 L11.0000671,0.05 C16.0500671,0.55 20.0000671,4.82 20.0000671,10 C20.0000671,11.45 19.6800671,12.83 19.1200671,14.07 L16.9560671,12.796 C17.3040671,11.932 17.5000671,10.989 17.5000671,10 Z M10.0000671,17.5 C12.3900671,17.5 14.5140671,16.378 15.8870671,14.637 C16.6270671,15.073 18.0500671,15.91 18.0500671,15.91 C15.9790671,18.732 12.4710671,20.427 8.60106711,19.906 C4.22106711,19.316 0.68406711,15.774 0.0940671101,11.394 C-0.68693289,5.591 3.49306711,0.594 9.00006711,0.05 L9.00006711,2.574 C5.33206711,3.064 2.50006711,6.198 2.50006711,10 C2.50006711,14.142 5.85806711,17.5 10.0000671,17.5 Z M6,10 C6.00538581,9.58803794 6.33803794,9.25538581 6.75,9.25 L9.25,9.25 L9.25,6.75 C9.25,6.33578644 9.58578644,6 10,6 C10.4142136,6 10.75,6.33578644 10.75,6.75 L10.75,9.25 L13.25,9.25 C13.6642136,9.25 14,9.58578644 14,10 C14,10.4142136 13.6642136,10.75 13.25,10.75 L10.75,10.75 L10.75,13.25 C10.75,13.6642136 10.4142136,14 10,14 C9.58578644,14 9.25,13.6642136 9.25,13.25 L9.25,10.75 L6.75,10.75 C6.33803794,10.7446142 6.00538581,10.4119621 6,10 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
index 17a191e2ad07..14898c465a31 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_eject_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_eject_24dp.xml
index 1c1fa4b7a5ee..abbab51e90e1 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_eject_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_eject_24dp.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_find_in_page_24px.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
new file mode 100644
index 000000000000..fd1a00dc738b
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="4.000100"
+ android:translateY="2.000100" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M7.9999,15.2499 C6.2079,15.2499 4.7499,13.7919 4.7499,11.9999 C4.7499,10.2079 6.2079,8.7499 7.9999,8.7499 C9.7919,8.7499 11.2499,10.2079 11.2499,11.9999 C11.2499,13.7919 9.7919,15.2499 7.9999,15.2499 L7.9999,15.2499 Z M1.4999,17.7779 L1.4999,2.2219 C1.4999,1.8239 1.8529,1.4999 2.2859,1.4999 L9.6769,1.4999 L14.4999,6.1889 L14.4999,17.5799 L11.8269,14.7879 C12.3999,14.0029 12.7499,13.0439 12.7499,11.9999 C12.7499,9.3809 10.6189,7.2499 7.9999,7.2499 C5.3809,7.2499 3.2499,9.3809 3.2499,11.9999 C3.2499,14.6189 5.3809,16.7499 7.9999,16.7499 C9.0329,16.7499 9.9829,16.4089 10.7649,15.8469 L13.3039,18.4999 L2.2859,18.4999 C1.8529,18.4999 1.4999,18.1759 1.4999,17.7779 L1.4999,17.7779 Z M10.2859,-0.0001 L2.2859,-0.0001 C1.0229,-0.0001 -0.0001,0.9949 -0.0001,2.2219 L-0.0001,17.7779 C-0.0001,19.0049 1.0229,19.9999 2.2859,19.9999 L13.7139,19.9999 C14.9769,19.9999 15.9999,19.0049 15.9999,17.7779 L15.9999,5.5559 L10.2859,-0.0001 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help_actionbar.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help_actionbar.xml
index 8b388f2d8761..b980a2cce710 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help_actionbar.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_help_actionbar.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_network_cell.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_network_cell.xml
index b6fa9fcf8294..1d72e5fa284f 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_network_cell.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_network_cell.xml
@@ -15,21 +15,30 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M20,22H18.5V4.75A0.76 0.76 ,0,0,1,19.25,4h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M15.33,22h-1.5V9.75A0.76 0.76 ,0,0,1,14.58,9h0a0.75 0.75 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M10.67,22H9.17V14.75A0.75 0.75 ,0,0,1,9.92,14h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M6,22H4.5V19.75A0.76 0.76 ,0,0,1,5.25,19h0a0.76 0.76 ,0,0,1,0.75 0.75 Z" />
+ <group
+ android:translateX="4.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M16,18 L14.5,18 L14.5,0.75 C14.5053858,0.338037936 14.8380379,0.00538581231 15.25,0 L15.25,0 C15.6619621,0.00538581231 15.9946142,0.338037936 16,0.75 L16,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M11.33,18 L9.83,18 L9.83,5.75 C9.83538581,5.33803794 10.1680379,5.00538581 10.58,5 L10.58,5 C10.9942136,5 11.33,5.33578644 11.33,5.75 L11.33,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M6.67,18 L5.17,18 L5.17,10.75 C5.17,10.3357864 5.50578644,10 5.92,10 L5.92,10 C6.33196206,10.0053858 6.66461419,10.3380379 6.67,10.75 L6.67,18 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M2,18 L0.5,18 L0.5,15.75 C0.505385812,15.3380379 0.838037936,15.0053858 1.25,15 L1.25,15 C1.66196206,15.0053858 1.99461419,15.3380379 2,15.75 L2,18 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
index 2dc6545c0fe3..2a21776232b4 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_scan_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_scan_24dp.xml
new file mode 100644
index 000000000000..f160fe9cdd1e
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_scan_24dp.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorAccent"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="3.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M1.5,4.5 L1.5,1.9 C1.5,1.6790861 1.6790861,1.5 1.9,1.5 L4.1,1.5 C4.3209139,1.5 4.5,1.6790861 4.5,1.9 L4.5,4.5 L1.5,4.5 L1.5,4.5 Z M0,6 L6,6 L6,1.5 C6,0.671572875 5.32842712,0 4.5,0 L1.5,0 C0.671572875,0 0,0.671572875 0,1.5 L0,6 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M13.5,4.5 L13.5,1.9 C13.5,1.6790861 13.6790861,1.5 13.9,1.5 L16.1,1.5 C16.3209139,1.5 16.5,1.6790861 16.5,1.9 L16.5,4.5 L13.5,4.5 L13.5,4.5 Z M12,6 L18,6 L18,1.5 C18,0.671572875 17.3284271,0 16.5,0 L13.5,0 C12.6715729,0 12,0.671572875 12,1.5 L12,6 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4.5,13.5 L4.5,16.1 C4.5,16.3209139 4.3209139,16.5 4.1,16.5 L1.9,16.5 C1.6790861,16.5 1.5,16.3209139 1.5,16.1 L1.5,13.5 L4.5,13.5 L4.5,13.5 Z M6,12 L0,12 L0,16.5 C0,17.3284271 0.671572875,18 1.5,18 L4.5,18 C5.32842712,18 6,17.3284271 6,16.5 L6,12 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 2 8 L 0 8 L 0 10 L 2 10 L 2 8 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M9,0 C8.58803794,0.00538581231 8.25538581,0.338037936 8.25,0.75 L8.25,5.75 C8.25000002,6.16421355 8.58578645,6.49999997 9,6.49999997 C9.41421355,6.49999997 9.74999998,6.16421355 9.75,5.75 L9.75,0.75 C9.74461419,0.338037936 9.41196206,0.00538581231 9,0 L9,0 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M13.75,12.25 L17.25,12.25 C17.6619621,12.2553858 17.9946142,12.5880379 18,13 C17.9946142,13.4119621 17.6619621,13.7446142 17.25,13.75 L13.75,13.75 L13.75,17.25 C13.75,17.6642136 13.4142136,18 13,18 C12.5857864,18 12.25,17.6642136 12.25,17.25 L12.25,13.75 L8.74999997,13.75 C8.33578642,13.75 8,13.4142136 8,13 C8,12.5857864 8.33578642,12.25 8.74999997,12.25 L12.25,12.25 L12.25,8.75 C12.2553858,8.33803794 12.5880379,8.00538581 13,8 C13.4119621,8.00538581 13.7446142,8.33803794 13.75,8.75 L13.75,12.25 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 6 8 L 4 8 L 4 10 L 6 10 L 6 8 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_data_usage.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_data_usage.xml
index e48cc146a515..855e4bb2a39d 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_data_usage.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_data_usage.xml
@@ -22,8 +22,7 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M12,19.52a7.5,7.5,0,0,1-0.77-15V2.06A10,10,0,1,0,22,12.77h-2.5A7.52,7.52,0,0,1,12,19.52Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M19.48,11.27H22a10,10,0,0,0-9.23-9.22v2.5A7.51,7.51,0,0,1,19.48,11.27Z" />
+ android:fillType="evenOdd"
+ android:pathData="M19.5000671,12 C19.5000671,8.198 16.6680671,5.064 13.0000671,4.574 L13.0000671,2.05 C18.0500671,2.55 22.0000671,6.82 22.0000671,12 C22.0000671,13.45 21.6800671,14.83 21.1200671,16.07 L18.9560671,14.796 C19.3040671,13.932 19.5000671,12.989 19.5000671,12 Z M12.0000671,19.5 C14.3900671,19.5 16.5140671,18.378 17.8870671,16.637 C18.6270671,17.073 20.0500671,17.91 20.0500671,17.91 C17.9790671,20.732 14.4710671,22.427 10.6010671,21.906 C6.22106711,21.316 2.68406711,17.774 2.09406711,13.394 C1.31306711,7.591 5.49306711,2.594 11.0000671,2.05 L11.0000671,4.574 C7.33206711,5.064 4.50006711,8.198 4.50006711,12 C4.50006711,16.142 7.85806711,19.5 12.0000671,19.5 Z"
+ android:strokeWidth="1" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml
new file mode 100644
index 000000000000..0572fb72f82e
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_disable.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="1.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M11,18.5 C6.313,18.5 2.5,14.687 2.5,10 C2.5,8.182 3.078,6.498 4.055,5.114 L15.887,16.945 C14.503,17.922 12.818,18.5 11,18.5 M20.031,18.969 L2.032,0.971 C1.739,0.678 1.264,0.678 0.971,0.971 C0.678,1.264 0.678,1.738 0.971,2.031 L2.983,4.043 C1.742,5.707 1,7.765 1,10 C1,15.522 5.477,20 11,20 C13.236,20 15.293,19.258 16.957,18.017 L18.971,20.029 C19.117,20.176 19.309,20.249 19.501,20.249 C19.693,20.249 19.885,20.176 20.031,20.029 C20.324,19.736 20.324,19.262 20.031,18.969"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M11,1.5 C15.687,1.5 19.5,5.313 19.5,10 C19.5,11.782 18.946,13.436 18.006,14.804 L19.078,15.877 C20.281,14.226 21,12.199 21,10 C21,4.478 16.522,0 11,0 C8.801,0 6.774,0.719 5.124,1.922 L6.196,2.994 C7.564,2.054 9.218,1.5 11,1.5"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml
new file mode 100644
index 000000000000..41962b27b270
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_enable.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M12.25,0.2637 L12.25,1.8127 C15.847,2.8017 18.5,6.0927 18.5,9.9997 C18.5,14.6867 14.687,18.4997 10,18.4997 C5.313,18.4997 1.5,14.6867 1.5,9.9997 C1.5,6.0927 4.153,2.8017 7.75,1.8127 L7.75,0.2637 C3.312,1.2847 0,5.2517 0,9.9997 C0,15.5227 4.477,19.9997 10,19.9997 C15.523,19.9997 20,15.5227 20,9.9997 C20,5.2517 16.687,1.2847 12.25,0.2637"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M15.0303,9.9697 C14.7373,9.6767 14.2623,9.6767 13.9693,9.9697 L10.7503,13.1897 L10.7503,0.7387 C10.7503,0.3307 10.4143,-0.0003 10.0003,-0.0003 C9.5863,-0.0003 9.2503,0.3307 9.2503,0.7387 L9.2503,13.1897 L6.0303,9.9697 C5.7373,9.6767 5.2623,9.6767 4.9693,9.9697 C4.6763,10.2627 4.6763,10.7377 4.9693,11.0307 L10.0003,16.0607 L15.0303,11.0307 C15.3233,10.7377 15.3233,10.2627 15.0303,9.9697"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_language.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_language.xml
new file mode 100644
index 000000000000..2c83c3481ba4
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_language.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.15,3.89,9.38,8.89,9.93c0.01,0.01,0.01,0.01,0.01,0.02l0.02-0.02C11.28,21.98,11.64,22,12,22 s0.72-0.02,1.08-0.06l0.02,0.02c0.01-0.01,0.01-0.01,0.01-0.02c5-0.55,8.89-4.79,8.89-9.93C22,6.48,17.52,2,12,2z M19.35,7.75 h-3.39c-0.39-1.35-0.97-2.67-1.73-3.94C16.41,4.4,18.24,5.84,19.35,7.75z M20.5,12c0,0.96-0.17,1.89-0.47,2.75h-3.69 c0.33-1.82,0.32-3.67-0.02-5.5h3.71C20.33,10.11,20.5,11.04,20.5,12z M12,20.5c-0.1,0-0.2-0.01-0.3-0.02 c-0.96-1.36-1.68-2.78-2.14-4.23h4.89c-0.47,1.45-1.18,2.87-2.14,4.23C12.2,20.49,12.1,20.5,12,20.5z M9.16,14.75 c-0.37-1.82-0.36-3.67,0.02-5.5h5.64c0.38,1.83,0.39,3.68,0.02,5.5H9.16z M3.5,12c0-0.96,0.17-1.89,0.47-2.75h3.71 c-0.34,1.83-0.35,3.68-0.02,5.5H3.97C3.67,13.89,3.5,12.96,3.5,12z M12,3.5c0.09,0,0.17,0.01,0.26,0.01 c0.96,1.37,1.68,2.79,2.16,4.24H9.58c0.48-1.45,1.2-2.87,2.16-4.24C11.83,3.51,11.91,3.5,12,3.5z M9.77,3.81 C9.01,5.08,8.43,6.4,8.04,7.75H4.65C5.76,5.84,7.59,4.4,9.77,3.81z M4.65,16.25h3.36c0.38,1.34,0.95,2.66,1.71,3.93 C7.56,19.58,5.75,18.15,4.65,16.25z M14.28,20.18c0.75-1.27,1.32-2.59,1.71-3.93h3.36C18.25,18.15,16.44,19.58,14.28,20.18z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_multiuser.xml
index db4d302eb240..d6d655871b74 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_battery_status_bad_24dp.xml
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_multiuser.xml
@@ -16,13 +16,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M9.74,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5c-0.41,0-0.75,0.34-0.75,0.75 S9.33,13.75,9.74,13.75z" />
+ android:pathData="M8,8c0,2.21,1.79,4,4,4s4-1.79,4-4c0-2.21-1.79-4-4-4S8,5.79,8,8z M12,5.5c1.38,0,2.5,1.12,2.5,2.5 c0,1.38-1.12,2.5-2.5,2.5S9.5,9.38,9.5,8C9.5,6.62,10.62,5.5,12,5.5z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M17,4h-3V3.49c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1 V5C18,4.45,17.55,4,17,4z M16.5,20.5h-9v-15h9V20.5z" />
+ android:pathData="M20,20c0-3.99-4-6-8-6s-8,2.01-8,6H20z M12,15.5c2.57,0,5.3,0.95,6.2,3H5.8C6.7,16.45,9.43,15.5,12,15.5z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
deleted file mode 100644
index fde996584f57..000000000000
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M19.42,11.84c-0.19,0-0.38-0.07-0.53-0.22C17.05,9.77,14.6,8.75,12,8.75s-5.05,1.02-6.89,2.86 c-0.29,0.29-0.77,0.29-1.06,0c-0.29-0.29-0.29-0.77,0-1.06C6.17,8.43,9,7.25,12,7.25s5.83,1.17,7.95,3.3 c0.29,0.29,0.29,0.77,0,1.06C19.8,11.76,19.61,11.84,19.42,11.84z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M22.61,8.65c-0.19,0-0.38-0.07-0.53-0.22C19.38,5.74,15.81,4.25,12,4.25S4.62,5.74,1.92,8.43c-0.29,0.29-0.77,0.29-1.06,0 s-0.29-0.77,0-1.06C3.84,4.39,7.79,2.75,12,2.75s8.16,1.64,11.14,4.61c0.29,0.29,0.29,0.77,0,1.06 C22.99,8.57,22.8,8.65,22.61,8.65z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M16.25,15c-0.19,0-0.38-0.07-0.53-0.22c-1-0.99-2.32-1.53-3.73-1.53s-2.73,0.54-3.73,1.53c-0.29,0.29-0.77,0.29-1.06-0.01 s-0.29-0.77,0.01-1.06c1.28-1.27,2.98-1.96,4.78-1.96s3.5,0.7,4.78,1.96c0.29,0.29,0.3,0.77,0.01,1.06 C16.64,14.93,16.45,15,16.25,15z" />
-</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
new file mode 100644
index 000000000000..a0233ba8acc9
--- /dev/null
+++ b/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="4.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M12.9902,13.5098 C12.9902,13.7858 12.7652,14.0098 12.4902,14.0098 C12.2142,14.0098 11.9902,13.7858 11.9902,13.5098 L11.9902,11.5098 C11.9902,11.2348 12.2142,11.0098 12.4902,11.0098 C12.7652,11.0098 12.9902,11.2348 12.9902,11.5098 L12.9902,13.5098 Z M12.4902,16.0098 C12.2142,16.0098 11.9902,15.7858 11.9902,15.5098 C11.9902,15.2348 12.2142,15.0098 12.4902,15.0098 C12.7652,15.0098 12.9902,15.2348 12.9902,15.5098 C12.9902,15.7858 12.7652,16.0098 12.4902,16.0098 L12.4902,16.0098 Z M15.5182,11.7848 C15.8372,10.9048 16.0102,9.9558 16.0102,8.9698 C16.0102,6.0698 14.5002,3.4798 12.1102,2.0098 L14.5102,2.0098 C14.9102,1.9998 15.2502,1.6598 15.2502,1.2498 C15.2502,0.8398 14.9102,0.4998 14.5002,0.4998 L9.2502,0.4998 L9.2502,6.2498 C9.2502,6.6598 9.5902,6.9998 10.0002,6.9998 C10.4102,6.9998 10.7502,6.6598 10.7502,6.2498 L10.7502,2.9398 C13.0302,4.0598 14.5002,6.3698 14.5002,8.9698 C14.5002,9.5068 14.4172,10.0238 14.2982,10.5268 C13.7682,10.2048 13.1542,10.0098 12.4902,10.0098 C10.5562,10.0098 8.9902,11.5768 8.9902,13.5098 C8.9902,15.4438 10.5562,17.0098 12.4902,17.0098 C14.4232,17.0098 15.9902,15.4438 15.9902,13.5098 C15.9902,12.8798 15.8092,12.2958 15.5182,11.7848 L15.5182,11.7848 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M6.3901,1.04 C2.6301,1.91 0.0001,5.21 0.0001,9.07 C0.0001,11.65 1.2001,13.98 3.1301,15.5 L1.5001,15.5 C1.0901,15.5 0.7501,15.84 0.7501,16.25 C0.7501,16.66 1.0901,17 1.5001,17 L6.7501,17 L6.7501,11.75 C6.7501,11.34 6.4101,11 6.0001,11 C5.5901,11 5.2501,11.34 5.2501,11.75 L5.2501,15.09 C2.9701,13.97 1.5001,11.66 1.5001,9.06 C1.5001,5.91 3.6501,3.21 6.7301,2.5 C7.1301,2.41 7.3901,2 7.2901,1.6 C7.2001,1.2 6.8001,0.95 6.3901,1.04"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_arrow_back.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_arrow_back.xml
index 920ecb5deb70..a9e1ffe6d69e 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_arrow_back.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_arrow_back.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
index dbd9b8e6d494..fae73a4c0e09 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
@@ -20,7 +20,7 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="?android:attr/colorPrimary"
+ android:fillColor="?android:attr/colorBackgroundFloating"
android:pathData="M18.94,9.75L18.5,9.31V8.69V6c0-0.28-0.22-0.5-0.5-0.5h-2.69h-0.62l-0.44-0.44l-1.9-1.9 C12.23,3.04,12.08,3.02,12,3.02c-0.08,0-0.23,0.02-0.35,0.15l-1.9,1.9L9.31,5.5H8.69H6C5.72,5.5,5.5,5.72,5.5,6v2.69v0.62 L5.06,9.75l-1.9,1.9C3.04,11.77,3.02,11.92,3.02,12s0.02,0.23,0.15,0.35l1.9,1.9l0.44,0.44v0.62V18c0,0.28,0.22,0.5,0.5,0.5h2.69 h0.62l0.44,0.44l1.9,1.9c0.13,0.13,0.28,0.15,0.35,0.15c0.08,0,0.23-0.02,0.35-0.15l1.9-1.9l0.44-0.44h0.62H18 c0.28,0,0.5-0.22,0.5-0.5v-2.69v-0.62l0.44-0.44l1.9-1.9c0.13-0.13,0.15-0.28,0.15-0.35s-0.02-0.23-0.15-0.35L18.94,9.75z M12,17 c-2.76,0-5-2.24-5-5s2.24-5,5-5s5,2.24,5,5S14.76,17,12,17z" />
<path
android:fillColor="?android:attr/colorControlActivated"
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml
index c4728eb3f389..77197a58a04a 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_camera.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
+ android:height="17dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="24dp" >
+ android:width="17dp" >
<path
android:fillColor="@android:color/white"
android:pathData="M22,8c0-1.66-1.34-3-3-3h-2l-2-2H9L7,5H5C3.34,5,2,6.34,2,8v13h20V8z M20.5,19.5h-17V8c0-0.83,0.67-1.5,1.5-1.5h14 c0.83,0,1.5,0.67,1.5,1.5V19.5z" />
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml
index 938d2412bef8..cdc3bfbd3d5f 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver.xml
@@ -15,17 +15,17 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="18dp "
+ android:height="18dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="18dp " >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M12,7a0.76 0.76 ,0,0,0-0.75 0.75 v3.5H7.75a0.75 0.75 ,0,0,0,0,1.5h3.5v3.5a0.75 0.75 ,0,0,0,1.5,0v-3.5h3.5a0.75 0.75 ,0,0,0,0-1.5h-3.5V7.75A0.76 0.76 ,0,0,0,12,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z" />
+ android:width="18dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17.5000671,10 C17.5000671,6.198 14.6680671,3.064 11.0000671,2.574 L11.0000671,0.05 C16.0500671,0.55 20.0000671,4.82 20.0000671,10 C20.0000671,11.45 19.6800671,12.83 19.1200671,14.07 L16.9560671,12.796 C17.3040671,11.932 17.5000671,10.989 17.5000671,10 Z M10.0000671,17.5 C12.3900671,17.5 14.5140671,16.378 15.8870671,14.637 C16.6270671,15.073 18.0500671,15.91 18.0500671,15.91 C15.9790671,18.732 12.4710671,20.427 8.60106711,19.906 C4.22106711,19.316 0.68406711,15.774 0.0940671101,11.394 C-0.68693289,5.591 3.49306711,0.594 9.00006711,0.05 L9.00006711,2.574 C5.33206711,3.064 2.50006711,6.198 2.50006711,10 C2.50006711,14.142 5.85806711,17.5 10.0000671,17.5 Z M6,10 C6.00538581,9.58803794 6.33803794,9.25538581 6.75,9.25 L9.25,9.25 L9.25,6.75 C9.25,6.33578644 9.58578644,6 10,6 C10.4142136,6 10.75,6.33578644 10.75,6.75 L10.75,9.25 L13.25,9.25 C13.6642136,9.25 14,9.58578644 14,10 C14,10.4142136 13.6642136,10.75 13.25,10.75 L10.75,10.75 L10.75,13.25 C10.75,13.6642136 10.4142136,14 10,14 C9.58578644,14 9.25,13.6642136 9.25,13.25 L9.25,10.75 L6.75,10.75 C6.33803794,10.7446142 6.00538581,10.4119621 6,10 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml
index 3d620a18bb1a..7dab949f9da5 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_data_saver_off.xml
@@ -21,8 +21,7 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z" />
+ android:fillType="evenOdd"
+ android:pathData="M19.5000671,12 C19.5000671,8.198 16.6680671,5.064 13.0000671,4.574 L13.0000671,2.05 C18.0500671,2.55 22.0000671,6.82 22.0000671,12 C22.0000671,13.45 21.6800671,14.83 21.1200671,16.07 L18.9560671,14.796 C19.3040671,13.932 19.5000671,12.989 19.5000671,12 Z M12.0000671,19.5 C14.3900671,19.5 16.5140671,18.378 17.8870671,16.637 C18.6270671,17.073 20.0500671,17.91 20.0500671,17.91 C17.9790671,20.732 14.4710671,22.427 10.6010671,21.906 C6.22106711,21.316 2.68406711,17.774 2.09406711,13.394 C1.31306711,7.591 5.49306711,2.594 11.0000671,2.05 L11.0000671,4.574 C7.33206711,5.064 4.50006711,8.198 4.50006711,12 C4.50006711,16.142 7.85806711,19.5 12.0000671,19.5 Z"
+ android:strokeWidth="1" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
index fc38ed431759..c7a0266cbfca 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
index 659b4e164415..9bdc79a23008 100644
--- a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
new file mode 100644
index 000000000000..e210bcb04849
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="4.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M3.75,11.5 L13.25,11.5 C13.664,11.5 14,11.836 14,12.25 C14,12.664 13.664,13 13.25,13 L3.75,13 C3.336,13 3,12.664 3,12.25 C3,11.836 3.336,11.5 3.75,11.5"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M3.75,8.5 L3.75,8.5 C4.164,8.5 4.5,8.836 4.5,9.25 C4.5,9.664 4.164,10 3.75,10 C3.336,10 3,9.664 3,9.25 C3,8.836 3.336,8.5 3.75,8.5"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17,12.25 L17,12.25 C17,12.664 16.664,13 16.25,13 C15.836,13 15.5,12.664 15.5,12.25 C15.5,11.836 15.836,11.5 16.25,11.5 C16.664,11.5 17,11.836 17,12.25"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17,9.25 L17,9.25 C17,9.664 16.664,10 16.25,10 L6.75,10 C6.336,10 6,9.664 6,9.25 C6,8.836 6.336,8.5 6.75,8.5 L16.25,8.5 C16.664,8.5 17,8.836 17,9.25"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M18,0 L2,0 C0.896,0 0,0.896 0,2 L0,14 C0,15.104 0.896,16 2,16 L18,16 C19.104,16 20,15.104 20,14 L20,2 C20,0.896 19.104,0 18,0 M18,1.5 C18.275,1.5 18.5,1.725 18.5,2 L18.5,14 C18.5,14.275 18.275,14.5 18,14.5 L2,14.5 C1.725,14.5 1.5,14.275 1.5,14 L1.5,2 C1.5,1.725 1.725,1.5 2,1.5 L18,1.5"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
new file mode 100644
index 000000000000..660f64a8cead
--- /dev/null
+++ b/packages/overlays/IconPackCircularSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="1.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M19,3.5 C19.275,3.5 19.5,3.725 19.5,4 L19.5,16 C19.5,16.09 19.47,16.17 19.428,16.244 L20.497,17.313 C20.807,16.961 21,16.506 21,16 L21,4 C21,2.896 20.104,2 19,2 L5.184,2 L6.684,3.5 L19,3.5 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M19,3.5 C19.275,3.5 19.5,3.725 19.5,4 L19.5,16 C19.5,16.09 19.47,16.17 19.428,16.244 L20.497,17.313 C20.807,16.961 21,16.506 21,16 L21,4 C21,2.896 20.104,2 19,2 L5.184,2 L6.684,3.5 L19,3.5 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M18,14.25 C18,13.836 17.664,13.5 17.25,13.5 C17.091,13.5 16.951,13.561 16.829,13.646 L17.854,14.671 C17.939,14.549 18,14.409 18,14.25"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M4.75,12 C5.164,12 5.5,11.664 5.5,11.25 C5.5,10.836 5.164,10.5 4.75,10.5 C4.336,10.5 4,10.836 4,11.25 C4,11.664 4.336,12 4.75,12"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M3,16.5 C2.725,16.5 2.5,16.275 2.5,16 L2.5,4 C2.5,3.878 2.549,3.77 2.622,3.684 L9.439,10.5 L7.75,10.5 C7.336,10.5 7,10.836 7,11.25 C7,11.664 7.336,12 7.75,12 L10.939,12 L12.439,13.5 L4.75,13.5 C4.336,13.5 4,13.836 4,14.25 C4,14.664 4.336,15 4.75,15 L13.939,15 L15.44,16.5 L3,16.5 Z M20.03,18.969 L2.03,0.971 C1.737,0.678 1.263,0.678 0.97,0.971 C0.677,1.264 0.677,1.738 0.97,2.031 L1.558,2.619 C1.214,2.979 1,3.463 1,4 L1,16 C1,17.104 1.896,18 3,18 L16.94,18 L18.97,20.029 C19.116,20.176 19.308,20.249 19.5,20.249 C19.692,20.249 19.884,20.176 20.03,20.029 C20.323,19.736 20.323,19.262 20.03,18.969 L20.03,18.969 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17.25,12 C17.664,12 18,11.664 18,11.25 C18,10.836 17.664,10.5 17.25,10.5 L13.684,10.5 L15.184,12 L17.25,12 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_delete_accent.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_battery_80_24dp.xml
index e65987e1d5f6..eb8550fb9f44 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_delete_accent.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_battery_80_24dp.xml
@@ -16,14 +16,16 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="?android:attr/colorAccent"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
<path
+ android:fillAlpha="0.3"
android:fillColor="@android:color/white"
- android:pathData="M18,4h-2.5l-0.71-0.71C14.61,3.11,14.35,3,14.09,3H9.9C9.64,3,9.38,3.11,9.2,3.29L8.49,4h-2.5c-0.55,0-1,0.45-1,1 s0.45,1,1,1h12c0.55,0,1-0.45,1-1C19,4.45,18.55,4,18,4z" />
+ android:pathData="M17,5.33C17,4.6,16.4,4,15.67,4H14V2h-4v2H8.33C7.6,4,7,4.6,7,5.33V9h10V5.33z"
+ android:strokeAlpha="0.3"
+ android:strokeWidth="1" />
<path
android:fillColor="@android:color/white"
- android:pathData="M6,19c0,1.1,0.9,2,2,2h8c1.1,0,2-0.9,2-2V7H6V19z" />
+ android:pathData="M7,9v11.67C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V9H7z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
index df79827ce624..8ff3c1cf06f5 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bluetooth_share_icon.xml
@@ -22,5 +22,5 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z" />
+ android:pathData="M13.51,12l3.75-3.74c0.41-0.41,0.41-1.07,0-1.48l-4.47-4.47l-0.03-0.03c-0.42-0.39-1.08-0.37-1.48,0.05 C11.1,2.52,11,2.78,11,3.04v6.44L6.95,5.43c-0.41-0.41-1.06-0.41-1.47,0c-0.41,0.41-0.41,1.06,0,1.47l5.09,5.1l-5.09,5.09 c-0.41,0.41-0.41,1.06,0,1.47c0.41,0.41,1.06,0.41,1.47,0L11,14.51v6.45c0,0.57,0.47,1.04,1.04,1.04c0.26,0,0.52-0.1,0.71-0.28 l0.05-0.05l4.46-4.46c0.41-0.41,0.41-1.07,0-1.48L13.51,12z M12.99,5.37l2.15,2.15l-2.15,2.15V5.37z M12.99,18.62v-4.3l2.15,2.15 L12.99,18.62z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_misc_hid.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_misc_hid.xml
index b86d9ba1849b..6b9735c1acfb 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_misc_hid.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_bt_misc_hid.xml
@@ -20,7 +20,6 @@
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path android:pathData="M0,0h24v24H0V0z" />
<path
android:fillColor="@android:color/white"
android:pathData="M15,7.09V3c0-0.55-0.45-1-1-1h-4C9.45,2,9,2.45,9,3v4.09c0,0.27,0.11,0.52,0.29,0.71l2,2c0.39,0.39,1.02,0.39,1.41,0l2-2 C14.89,7.61,15,7.35,15,7.09z M7.09,9H3c-0.55,0-1,0.45-1,1v4c0,0.55,0.45,1,1,1h4.09c0.27,0,0.52-0.11,0.71-0.29l2-2 c0.39-0.39,0.39-1.02,0-1.41l-2-2C7.61,9.11,7.35,9,7.09,9z M9,16.91V21c0,0.55,0.45,1,1,1h4c0.55,0,1-0.45,1-1v-4.09 c0-0.27-0.11-0.52-0.29-0.71l-2-2c-0.39-0.39-1.02-0.39-1.41,0l-2,2C9.11,16.39,9,16.65,9,16.91z M16.21,9.29l-2,2 c-0.39,0.39-0.39,1.02,0,1.41l2,2c0.19,0.19,0.44,0.29,0.71,0.29H21c0.55,0,1-0.45,1-1v-4c0-0.55-0.45-1-1-1h-4.09 C16.65,9,16.39,9.11,16.21,9.29z" />
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_file_copy.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_file_copy.xml
index 6245147c538b..e479f506bac5 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_file_copy.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_file_copy.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="#FF737373"
+ android:tint="@*android:color/material_grey_600"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml
index 07c81ddf563c..b2fa85f9fd16 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock.xml
@@ -16,7 +16,6 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="32dp"
- android:tint="?android:attr/textColor"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="32dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml
index 698ce668c1e9..13bfbf901adb 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lock_open.xml
@@ -16,7 +16,6 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="32dp"
- android:tint="?android:attr/textColor"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="32dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
index 4cd05f3374c9..16541e614965 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml
index bf8df45826ec..bb3c043f68f5 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_mode_edit.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_notifications_alerted.xml
index 03e142e2be35..0847a3564998 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_notifications_alerted.xml
@@ -21,11 +21,14 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M11.29,19.29c0.39,0.39,1.03,0.4,1.42,0L14,18c0.47-0.47,0.38-1.28-0.22-1.58C13.25,16.15,12.64,16,12,16 c-0.64,0-1.24,0.15-1.77,0.41c-0.59,0.29-0.69,1.11-0.22,1.58L11.29,19.29z" />
+ android:pathData="M4.12,9.67C4.42,7.73,5.38,6,6.77,4.73C7.19,4.35,7.2,3.7,6.8,3.3c-0.39-0.39-1-0.39-1.4-0.03 C3.7,4.84,2.52,6.96,2.15,9.34c-0.1,0.61,0.37,1.16,0.99,1.16C3.63,10.5,4.04,10.15,4.12,9.67z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M17.6,14.39l0.71-0.71c0.42-0.42,0.39-1.12-0.08-1.5C16.52,10.82,14.35,10,12,10c-2.34,0-4.5,0.81-6.21,2.17 c-0.47,0.37-0.51,1.07-0.09,1.49l0.71,0.71c0.35,0.36,0.92,0.39,1.32,0.08C8.91,13.54,10.39,13,12,13c1.61,0,3.1,0.55,4.29,1.47 C16.69,14.78,17.25,14.75,17.6,14.39z" />
+ android:pathData="M18.6,3.28c-0.4-0.37-1.02-0.36-1.4,0.02c-0.4,0.4-0.38,1.04,0.03,1.42c1.38,1.27,2.35,3,2.65,4.94 c0.08,0.49,0.5,0.84,0.98,0.84c0.61,0,1.09-0.55,0.99-1.16C21.47,6.96,20.29,4.84,18.6,3.28z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M21.83,10.16l0.71-0.71c0.42-0.42,0.38-1.09-0.06-1.48C19.68,5.5,16.01,4,12,4C8.01,4,4.36,5.49,1.56,7.94 C1.12,8.33,1.08,9,1.49,9.41l0.71,0.71c0.37,0.37,0.96,0.4,1.35,0.06C5.81,8.2,8.77,7,12,7c3.25,0,6.22,1.22,8.49,3.22 C20.88,10.56,21.47,10.53,21.83,10.16z" />
+ android:pathData="M12,22c1.1,0,2-0.9,2-2h-4C10,21.1,10.9,22,12,22z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18,16v-5c0-3.07-1.64-5.64-4.5-6.32V4c0-0.83-0.67-1.5-1.5-1.5S10.5,3.17,10.5,4v0.68C7.63,5.36,6,7.92,6,11v5 l-2.15,2.15c-0.19,0.2-0.19,0.51,0.01,0.71C3.95,18.95,4.07,19,4.2,19h15.6c0.45,0,0.67-0.54,0.35-0.85L18,16z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml
index de348159cc6c..adf521c853ae 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_phone.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_battery_saver.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
index 22e183c694d5..4f7d96381e6e 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
index 09643e606350..18a60d82faed 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
@@ -16,10 +16,11 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z" />
+ android:pathData="M13.51,12l3.75-3.74c0.41-0.41,0.41-1.07,0-1.48l-4.47-4.47l-0.03-0.03c-0.42-0.39-1.08-0.37-1.48,0.05 C11.1,2.52,11,2.78,11,3.04v6.44L6.95,5.43c-0.41-0.41-1.06-0.41-1.47,0c-0.41,0.41-0.41,1.06,0,1.47l5.09,5.1l-5.09,5.09 c-0.41,0.41-0.41,1.06,0,1.47c0.41,0.41,1.06,0.41,1.47,0L11,14.51v6.45c0,0.57,0.47,1.04,1.04,1.04c0.26,0,0.52-0.1,0.71-0.28 l0.05-0.05l4.46-4.46c0.41-0.41,0.41-1.07,0-1.48L13.51,12z M12.99,5.37l2.15,2.15l-2.15,2.15V5.37z M12.99,18.62v-4.3l2.15,2.15 L12.99,18.62z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
index 4ddeae66401c..5eea8895aaa1 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
@@ -16,11 +16,10 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="?android:attr/colorAccent"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M10,2v2H8.33C7.6,4,7,4.6,7,5.33v15.33C7,21.4,7.6,22,8.33,22h7.33C16.4,22,17,21.4,17,20.67V5.33C17,4.6,16.4,4,15.67,4 H14V2H10z M15,13c0,0.55-0.45,1-1,1h-1v1c0,0.55-0.45,1-1,1s-1-0.45-1-1v-1h-1c-0.55,0-1-0.45-1-1s0.45-1,1-1h1v-1 c0-0.55,0.45-1,1-1s1,0.45,1,1v1h1C14.55,12,15,12.45,15,13z" />
-</vector> \ No newline at end of file
+ android:pathData="M12,2C6.48,2,2,6.48,2,12c0,5.52,4.48,10,10,10c5.52,0,10-4.48,10-10C22,6.48,17.52,2,12,2z M12,20V4c4.41,0,8,3.59,8,8 C20,16.41,16.41,20,12,20z" />
+</vector>
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
index 58800c8d29be..18a60d82faed 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/ic_settings_bluetooth.xml
@@ -22,5 +22,5 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M17.21,6.79l-4.5-4.5c-0.29-0.29-0.72-0.37-1.09-0.22C11.25,2.23,11,2.6,11,3v6.59l-3.8-3.8c-0.39-0.39-1.02-0.39-1.41,0 c-0.39,0.39-0.39,1.02,0,1.41l4.8,4.8l-4.8,4.8c-0.39,0.39-0.39,1.02,0,1.41c0.39,0.39,1.02,0.39,1.41,0l3.8-3.8V21 c0,0.4,0.24,0.77,0.62,0.92C11.74,21.98,11.87,22,12,22c0.26,0,0.52-0.1,0.71-0.29l4.5-4.5c0.39-0.39,0.39-1.02,0-1.41L13.42,12 l3.79-3.79C17.6,7.82,17.6,7.18,17.21,6.79z M15.09,16.5L13,18.58v-4.17L15.09,16.5z M13,9.58V5.42l2.08,2.08L13,9.58z" />
+ android:pathData="M13.51,12l3.75-3.74c0.41-0.41,0.41-1.07,0-1.48l-4.47-4.47l-0.03-0.03c-0.42-0.39-1.08-0.37-1.48,0.05 C11.1,2.52,11,2.78,11,3.04v6.44L6.95,5.43c-0.41-0.41-1.06-0.41-1.47,0c-0.41,0.41-0.41,1.06,0,1.47l5.09,5.1l-5.09,5.09 c-0.41,0.41-0.41,1.06,0,1.47c0.41,0.41,1.06,0.41,1.47,0L11,14.51v6.45c0,0.57,0.47,1.04,1.04,1.04c0.26,0,0.52-0.1,0.71-0.28 l0.05-0.05l4.46-4.46c0.41-0.41,0.41-1.07,0-1.48L13.51,12z M12.99,5.37l2.15,2.15l-2.15,2.15V5.37z M12.99,18.62v-4.3l2.15,2.15 L12.99,18.62z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_activity_recognition.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
index e1849bbee061..67d28c60b7a0 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml
new file mode 100644
index 000000000000..3f5c75b66f4c
--- /dev/null
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_aural.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20 2H8c-1.1 0-2 0.9-2 2v12c0 1.1 0.9 2 2 2h12c1.1 0 2-0.9 2-2V4c0-1.1-0.9-2-2-2zm-2 5h-3v5.5c0 1.38-1.12 2.5-2.5 2.5S10 13.88 10 12.5s1.12-2.5 2.5-2.5c0.57 0 1.08 0.19 1.5 0.51 V5h4v2zM4 6H2v14c0 1.1 0.9 2 2 2h14v-2H4V6z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_calendar.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_calendar.xml
index 16359b04178d..0144ba2fbf36 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_calendar.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_calendar.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_call_log.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_call_log.xml
index 8d70f484e731..590ced09e4af 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_call_log.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_call_log.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_camera.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_camera.xml
index 03075a688846..b063e2bb6985 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_camera.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_camera.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_contacts.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_contacts.xml
index 50cd6331e42a..54cfeec0355e 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_contacts.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_contacts.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_location.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_location.xml
index ebd9e61d8efe..3815921846b7 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_location.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_location.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_microphone.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_microphone.xml
index 39acc9ca82a1..e6493bc95ff2 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_microphone.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_microphone.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_phone_calls.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_phone_calls.xml
index 2b6e32a59cab..ae84541e0801 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_phone_calls.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_phone_calls.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sensors.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sensors.xml
index 2128e79b350a..88f0c541caf5 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sensors.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sensors.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml
index eef9e62f15b0..7a320e0c81e2 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_sms.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_storage.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_storage.xml
index 3a863a342354..0ad7e6d3484b 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_storage.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_storage.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_visual.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_visual.xml
index 57c7ae9f6efa..d5bdb872825e 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_visual.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/drawable/perm_group_visual.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml
index 6b59b6265c54..f1d8c7345396 100644
--- a/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml
+++ b/packages/overlays/IconPackFilledAndroidOverlay/res/values/config.xml
@@ -33,4 +33,12 @@
M 9,11 C 9,11.55 8.55,12 8,12 H 7 V 13 C 7,13.55 6.55,14 6,14 5.45,14 5,13.55 5,13 V 12 H 4 C 3.45,12 3,11.55 3,11 3,10.45 3.45,10.005 4,10 H 5 V 9 C 5,8.45 5.45,8 6,8 6.55,8 7,8.45 7,9 V 10 H 8 C 8.55,10 9,10.45 9,11 Z
</string>
<bool name="config_batterymeterDualTone">true</bool>
+ <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+ <string name="config_signalXPath" translatable="false">
+ M 21.7,20.28 L 19.92,18.5 L 21.7,16.72 C 22.1,16.32 22.1,15.68 21.71,15.29 C 21.32,14.9 20.68,14.9 20.28,15.3 L 18.5,17.08 L 16.72,15.3 C 16.32,14.9 15.68,14.9 15.29,15.29 C 14.9,15.68 14.9,16.32 15.3,16.72 L 17.08,18.5 L 15.3,20.28 C 14.9,20.68 14.9,21.32 15.29,21.71 C 15.68,22.1 16.32,22.1 16.72,21.7 L 18.5,19.92 L 20.28,21.7 C 20.68,22.1 21.32,22.1 21.71,21.71 C 22.1,21.32 22.1,20.68 21.7,20.28
+ </string>
+ <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+ should be cut out to display config_signalXPath.-->
+ <item name="config_signalCutoutWidthFraction" format="float" type="dimen">11</item>
+ <item name="config_signalCutoutHeightFraction" format="float" type="dimen">11</item>
</resources>
diff --git a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
index 30e866095675..b3625ac9cf15 100644
--- a/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackFilledLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/textColorPrimary"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_arrow_back.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_arrow_back.xml
index b4f2a9de63a6..deb77c820ecb 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_arrow_back.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_arrow_back.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_cellular_off.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_cellular_off.xml
index 32ce0f5ea249..466ae50cb46a 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_cellular_off.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_cellular_off.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorAccent"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
index e1a8b1feb22b..b5b514a57e9d 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
index be607a3c4d33..e479f506bac5 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="#757575"
+ android:tint="@*android:color/material_grey_600"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml
index 2718efadfe59..5c85eb36b41c 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_data_saver.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
index 21368fe5782b..a451ef831e78 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_eject_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_eject_24dp.xml
index 5a9511a5cfbe..7af92461d3f9 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_eject_24dp.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_eject_24dp.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_find_in_page_24px.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
new file mode 100644
index 000000000000..dd35dae227b0
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M20 19.59V8l-6-6H6c-1.1 0-1.99 0.9 -1.99 2L4 20c0 1.1 0.89 2 1.99 2H18c0.45 0 0.85-0.15 1.19-0.4l-4.43-4.43c-0.8 0.52 -1.74 0.83 -2.76 0.83 -2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5c0 1.02-0.31 1.96-0.83 2.75L20 19.59zM9 13c0 1.66 1.34 3 3 3s3-1.34 3-3-1.34-3-3-3-3 1.34-3 3z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help_actionbar.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help_actionbar.xml
index ed6d553f5f37..4d6d9dd0a9e5 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help_actionbar.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_help_actionbar.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_network_cell.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_network_cell.xml
index 2e9433b08220..d62758e51976 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_network_cell.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_network_cell.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
index 9944bb5b4f69..c6cd0159854e 100644
--- a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_scan_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_scan_24dp.xml
new file mode 100644
index 000000000000..146e20fc68d0
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_scan_24dp.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorAccent"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4,9 L8,9 C8.55228475,9 9,8.55228475 9,8 L9,4 C9,3.44771525 8.55228475,3 8,3 L4,3 C3.44771525,3 3,3.44771525 3,4 L3,8 C3,8.55228475 3.44771525,9 4,9 Z M5,5 L7,5 L7,7 L5,7 L5,5 Z M15,4 L15,8 C15,8.55228475 15.4477153,9 16,9 L20,9 C20.5522847,9 21,8.55228475 21,8 L21,4 C21,3.44771525 20.5522847,3 20,3 L16,3 C15.4477153,3 15,3.44771525 15,4 Z M19,7 L17,7 L17,5 L19,5 L19,7 Z M4,21 L8,21 C8.55228475,21 9,20.5522847 9,20 L9,16 C9,15.4477153 8.55228475,15 8,15 L4,15 C3.44771525,15 3,15.4477153 3,16 L3,20 C3,20.5522847 3.44771525,21 4,21 Z M5,17 L7,17 L7,19 L5,19 L5,17 Z M7.4,11 L8.6,11 C8.8209139,11 9,11.1790861 9,11.4 L9,12.6 C9,12.8209139 8.8209139,13 8.6,13 L7.4,13 C7.1790861,13 7,12.8209139 7,12.6 L7,11.4 C7,11.1790861 7.1790861,11 7.4,11 Z M4.6,13 L3.4,13 C3.1790861,13 3,12.8209139 3,12.6 L3,11.4 C3,11.1790861 3.1790861,11 3.4,11 L4.6,11 C4.8209139,11 5,11.1790861 5,11.4 L5,12.6 C5,12.8209139 4.8209139,13 4.6,13 L4.6,13 Z M11.6,9 C11.2686292,9 11,8.73137085 11,8.4 L11,3.6 C11,3.26862915 11.2686292,3 11.6,3 L12.4,3 C12.7313708,3 13,3.26862915 13,3.6 L13,8.4 C13,8.73137085 12.7313708,9 12.4,9 L11.6,9 Z M17,15 L20.5,15 C20.7761424,15 21,15.2238576 21,15.5 L21,16.5 C21,16.7761424 20.7761424,17 20.5,17 L17,17 L17,20.5 C17,20.7761424 16.7761424,21 16.5,21 L15.5,21 C15.2238576,21 15,20.7761424 15,20.5 L15,17 L11.5,17 C11.2238576,17 11,16.7761424 11,16.5 L11,15.5 C11,15.2238576 11.2238576,15 11.5,15 L15,15 L15,11.5 C15,11.2238576 15.2238576,11 15.5,11 L16.5,11 C16.7761424,11 17,11.2238576 17,11.5 L17,15 Z"
+ android:strokeWidth="1" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml
new file mode 100644
index 000000000000..b816e4e838fe
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_disable.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:scaleX="-1"
+ android:translateX="-12.000000"
+ android:translateY="-12.000000" >
+ <path
+ android:fillType="evenOdd"
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z"
+ android:strokeWidth="1" />
+ </group>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12.11,2 C10.33,2 8.67,2.46 7.22,3.28 L8.7,4.76 C9.74,4.28 10.89,4 12.11,4 C16.52,4 20.11,7.59 20.11,12 C20.11,13.22 19.83,14.37 19.35,15.41 L20.83,16.89 C21.65,15.44 22.11,13.78 22.11,12 C22.11,6.48 17.63,2 12.11,2 Z M18.23,17.13 L6.98,5.87 L4.12750442,3.01750442 C3.73635677,2.62635677 3.10252735,2.62523693 2.71,3.015 C2.31926097,3.40298735 2.31703029,4.0342698 2.70501764,4.42500883 C2.70584509,4.42584216 2.70667402,4.42667402 2.70750442,4.42750442 L4.19,5.91 C2.88,7.59 2.11,9.71 2.11,12 C2.11,17.52 6.59,22 12.11,22 C14.4,22 16.52,21.23 18.2,19.92 L19.685,21.405 C20.0743607,21.7943607 20.7056393,21.7943607 21.095,21.405 C21.4843607,21.0156393 21.4843607,20.3843607 21.095,19.995 L18.23,17.13 Z M12.11,20 C7.7,20 4.11,16.41 4.11,12 C4.11,10.26 4.67,8.65 5.62,7.34 L16.77,18.49 C15.46,19.44 13.85,20 12.11,20 Z M8.7,4.76 L7.22,3.28 L8.7,4.76 Z"
+ android:strokeWidth="1" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml
new file mode 100644
index 000000000000..d0b6209b38ad
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_enable.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:scaleX="-1"
+ android:translateX="-12.000000"
+ android:translateY="-12.000000" >
+ <path
+ android:fillType="evenOdd"
+ android:pathData="M 0 0 H 24 V 24 H 0 V 0 Z"
+ android:strokeWidth="1" />
+ </group>
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M13.0016705,11.5012475 L15.3917467,11.5012475 C15.9314188,11.5012475 16.206996,12.1426752 15.8165949,12.5140281 L12.4292913,15.822445 C12.1961989,16.0553846 11.8138355,16.0598858 11.5761501,15.8314475 C11.5738536,15.8280716 11.5704089,15.8258209 11.5681124,15.822445 L8.17851232,12.5117775 C7.79729714,12.1392993 8.06713319,11.5012475 8.60565705,11.5012475 L11.002341,11.5012475 L11.002341,2.99966471 C11.002341,2.44756514 11.4499062,2 12.0020057,2 C12.5541053,2 13.0016705,2.44756514 13.0016705,2.99966471 L13.0016705,11.5012475 Z M15,2.46 L15,4.59 C17.93,5.78 20,8.65 20,12 C20,16.41 16.41,20 12,20 C7.59,20 4,16.41 4,12 C4,8.65 6.07,5.78 9,4.59 L9,2.46 C4.94,3.74 2,7.53 2,12 C2,17.52 6.48,22 12,22 C17.52,22 22,17.52 22,12 C22,7.53 19.06,3.74 15,2.46 Z"
+ android:strokeWidth="1" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_language.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_language.xml
new file mode 100644
index 000000000000..e23b9b6ebf58
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_language.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M11.99,2C6.47,2,2,6.48,2,12c0,5.52,4.47,10,9.99,10C17.52,22,22,17.52,22,12C22,6.48,17.52,2,11.99,2z M18.92,8h-2.95 c-0.31-1.24-0.78-2.43-1.38-3.56C16.41,5.07,17.95,6.33,18.92,8z M12,4.04c0.83,1.2,1.48,2.53,1.91,3.96h-3.82 C10.52,6.57,11.17,5.24,12,4.04z M4.26,14C4.1,13.36,4,12.69,4,12s0.1-1.36,0.26-2h3.38c-0.08,0.66-0.14,1.32-0.14,2 s0.06,1.34,0.14,2H4.26z M5.08,16h2.95c0.32,1.25,0.78,2.45,1.38,3.56C7.58,18.94,6.05,17.67,5.08,16z M8.03,8H5.08 c0.97-1.67,2.5-2.94,4.33-3.56C8.81,5.57,8.34,6.76,8.03,8z M12,19.96c-0.83-1.2-1.48-2.53-1.91-3.96h3.82 C13.48,17.43,12.83,18.76,12,19.96z M14.34,14H9.66c-0.09-0.66-0.16-1.32-0.16-2s0.07-1.35,0.16-2h4.68c0.09,0.65,0.16,1.32,0.16,2 S14.43,13.34,14.34,14z M14.59,19.56c0.6-1.11,1.06-2.31,1.38-3.56h2.95C17.95,17.67,16.41,18.93,14.59,19.56z M16.36,14 c0.08-0.66,0.14-1.32,0.14-2s-0.06-1.34-0.14-2h3.38C19.9,10.64,20,11.31,20,12s-0.1,1.36-0.26,2H16.36z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_multiuser.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_multiuser.xml
new file mode 100644
index 000000000000..accc694238d9
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_settings_multiuser.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M 12 4 C 14.2091389993 4 16 5.79086100068 16 8 C 16 10.2091389993 14.2091389993 12 12 12 C 9.79086100068 12 8 10.2091389993 8 8 C 8 5.79086100068 9.79086100068 4 12 4 Z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,13.5c-2.67,0-8,1.34-8,4v2C4,19.77,4.22,20,4.5,20h15c0.27,0,0.5-0.23,0.5-0.5v-2C20,14.84,14.67,13.5,12,13.5z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
new file mode 100644
index 000000000000..f2dd9e818fc4
--- /dev/null
+++ b/packages/overlays/IconPackFilledSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path android:pathData="M0 0h24v24H0z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M3 12c0 2.21 0.91 4.2 2.36 5.64L3 20h6v-6l-2.24 2.24C5.68 15.15 5 13.66 5 12c0-2.61 1.67-4.83 4-5.65V4.26C5.55 5.15 3 8.27 3 12zm8 5h2v-2h-2v2zM21 4h-6v6l2.24-2.24C18.32 8.85 19 10.34 19 12c0 2.61-1.67 4.83-4 5.65v2.09c3.45-0.89 6-4.01 6-7.74 0-2.21-0.91-4.2-2.36-5.64L21 4zm-10 9h2V7h-2v6z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_arrow_back.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_arrow_back.xml
index b4f2a9de63a6..deb77c820ecb 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_arrow_back.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_arrow_back.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
index e82e9a3ee185..1b881eac9fc2 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
@@ -23,6 +23,6 @@
android:fillColor="?android:attr/colorControlActivated"
android:pathData="M4,15.3V19c0,0.55,0.45,1,1,1h3.69l2.6,2.6c0.39,0.39,1.02,0.39,1.41,0l2.6-2.6H19c0.55,0,1-0.45,1-1v-3.69l2.6-2.6 c0.39-0.39,0.39-1.02,0-1.41L20,8.69V5c0-0.55-0.45-1-1-1h-3.69l-2.6-2.6c-0.39-0.39-1.02-0.39-1.41,0L8.69,4H5C4.45,4,4,4.45,4,5 v3.69l-2.6,2.6c-0.39,0.39-0.39,1.02,0,1.41L4,15.3z M12,7c2.76,0,5,2.24,5,5s-2.24,5-5,5s-5-2.24-5-5S9.24,7,12,7z" />
<path
- android:fillColor="?android:attr/colorPrimary"
+ android:fillColor="?android:attr/colorBackgroundFloating"
android:pathData="M 12 7 C 14.7614237492 7 17 9.23857625085 17 12 C 17 14.7614237492 14.7614237492 17 12 17 C 9.23857625085 17 7 14.7614237492 7 12 C 7 9.23857625085 9.23857625085 7 12 7 Z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml
index ae3e7e2d60c6..fac551cf4a63 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_camera.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
+ android:height="17dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="24dp" >
+ android:width="17dp" >
<path
android:fillColor="@android:color/white"
android:pathData="M 12 8.8 C 13.7673111995 8.8 15.2 10.2326888005 15.2 12 C 15.2 13.7673111995 13.7673111995 15.2 12 15.2 C 10.2326888005 15.2 8.8 13.7673111995 8.8 12 C 8.8 10.2326888005 10.2326888005 8.8 12 8.8 Z" />
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml
index f5056f2a1f12..bbe2cff62720 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_cast_connected.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="17dp"
+ android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="17dp" >
+ android:width="24dp" >
<path
android:fillColor="@android:color/white"
android:pathData="M2.07,10.05C1.5,10,1.02,10.45,1,11.03c-0.01,0.52,0.34,0.96,0.85,1.01c4.26,0.43,7.68,3.82,8.1,8.08 C10,20.62,10.43,21,10.94,21c0.59,0,1.06-0.51,1-1.1C11.42,14.69,7.28,10.56,2.07,10.05z" />
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml
index 3d4cf5e88f07..28b8ba1bccfc 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_data_saver.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="18dp "
+ android:height="18dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="18dp " >
+ android:width="18dp" >
<path
android:fillColor="@android:color/white"
android:pathData="M11,11H9c-0.55,0-1,0.45-1,1s0.45,1,1,1h2v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2h2c0.55,0,1-0.45,1-1s-0.45-1-1-1h-2V9 c0-0.55-0.45-1-1-1s-1,0.45-1,1V11z" />
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
index f661673e1fea..59a18bad6c66 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
index 8640a7950672..e498f803f687 100644
--- a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
new file mode 100644
index 000000000000..42ef41cfe9c0
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="4.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M8,8 L16,8 L16,6 L8,6 L8,8 Z M14,12 L16,12 L16,10 L14,10 L14,12 Z M4,12 L12,12 L12,10 L4,10 L4,12 Z M4,8 L6,8 L6,6 L4,6 L4,8 Z M18,0 L2,0 C0.9,0 0,0.9 0,2 L0,14 C0,15.1 0.9,16 2,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 C20,0.9 19.1,0 18,0 L18,0 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
new file mode 100644
index 000000000000..f164ba877096
--- /dev/null
+++ b/packages/overlays/IconPackFilledSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M6,14 L13.17,14 L11.17,12 L6,12 L6,14 Z M6,8 L6,10 L8,10 L8,8.83 L7.17,8 L6,8 Z M1.293,0.7085 C1.68545692,0.318530482 2.3194559,0.319620835 2.71056916,0.71093794 L20.4851837,18.4948164 C20.8744727,18.8843082 20.8743905,19.5156095 20.485,19.905 C20.0956393,20.2943607 19.4643607,20.2943607 19.075,19.905 L17.17,18 L4,18 C2.9,18 2,17.1 2,16 L2,4 C2,3.663 2.092,3.35 2.241,3.071 L1.29096704,2.12154004 C1.29014848,2.12072198 1.28933135,2.11990248 1.28851564,2.11908157 C0.900232614,1.7283219 0.902240332,1.09678302 1.293,0.7085 Z M6.82,2 L20,2 C21.1,2 22,2.9 22,4 L22,16 C22,16.342 21.905,16.659 21.753,16.94 L18,13.187 L18,12 L16.814,12 L14.815,10 L18,10 L18,8 L12.816,8 L8.819,4 L6.82,2 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_battery_80_24dp.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_battery_80_24dp.xml
new file mode 100644
index 000000000000..c19ca31d41b2
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_battery_80_24dp.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M13,2.49h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1V5c0-0.55-0.45-1-1-1h-3 V3.49C14,2.94,13.55,2.49,13,2.49z M16.5,9.01h-9V5.5h9V9.01z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_file_copy.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_file_copy.xml
index 97945f00395e..1feaab1663c1 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_file_copy.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_file_copy.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="#FF737373"
+ android:tint="@*android:color/material_grey_600"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml
index ac8e4781b904..d0b85e70920d 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock.xml
@@ -16,7 +16,6 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="32dp"
- android:tint="?android:attr/textColor"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="32dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml
index 345d6b181b92..6f19afe7c484 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lock_open.xml
@@ -16,7 +16,6 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="32dp"
- android:tint="?android:attr/textColor"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="32dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
index 16f0868987fb..fae8445a0a42 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_lockscreen_ime.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml
index 5db3b12ac1dd..c44a8d6fb9c5 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_mode_edit.xml
@@ -16,10 +16,17 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M20.08,5.08l-1.17-1.17c-0.39-0.39-0.9-0.58-1.41-0.58c-0.51,0-1.02,0.2-1.41,0.59L3.29,16.71C3.11,16.89,3,17.15,3,17.41 l0,2.59c0,0.55,0.45,1,1,1c0,0,0,0,0,0L6.59,21c0.26,0,0.52-0.11,0.71-0.29l10.68-10.68l0,0l1.06-1.06l0,0l1.05-1.06 C20.87,7.13,20.87,5.86,20.08,5.08z M6.38,19.5l-1.88,0l0-1.88L15.03,7.09l1.88,1.88L6.38,19.5z M19.02,6.85l-1.06,1.06l-1.88-1.88 l1.05-1.05c0.13-0.13,0.28-0.15,0.35-0.15c0.08,0,0.23,0.02,0.35,0.15l1.17,1.17c0.13,0.13,0.15,0.28,0.15,0.35 C19.17,6.57,19.15,6.72,19.02,6.85z" />
+ <group
+ android:translateX="3.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M14.971,4.992 L13.092,3.115 L14.499,1.707 L16.38,3.583 L14.971,4.992 Z M3.38,16.588 L1.501,16.592 L1.502,14.708 L12.031,4.176 L13.91,6.054 L3.38,16.588 Z M17.794,2.874 L15.205,0.292 C15.01,0.097 14.755,0 14.499,0 C14.243,0 13.987,0.098 13.792,0.293 L0.295,13.794 C0.108,13.981 0.002,14.236 0.002,14.5 L-1.42108547e-14,17.594 C-1.42108547e-14,17.87 0.224,18.094 0.5,18.094 L0.501,18.094 L3.589,18.088 C3.854,18.087 4.107,17.982 4.294,17.795 L17.795,4.289 C18.185,3.898 18.185,3.264 17.794,2.874 L17.794,2.874 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_delete_accent.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_notifications_alerted.xml
index b4d88271284c..752dab5082a4 100644
--- a/packages/overlays/IconPackCircularSettingsOverlay/res/drawable/ic_delete_accent.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_notifications_alerted.xml
@@ -16,17 +16,19 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="?android:attr/colorAccent"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M9,20h6c1.66,0,3-1.34,3-3V6h0.5c0.41,0,0.75-0.34,0.75-0.75S18.91,4.5,18.5,4.5H18h-3l-1-1h-4l-1,1H6H5.5 c-0.41,0-0.75,0.34-0.75,0.75S5.09,6,5.5,6H6v11C6,18.66,7.34,20,9,20z M16.5,6v11c0,0.83-0.67,1.5-1.5,1.5H9 c-0.83,0-1.5-0.67-1.5-1.5V6H16.5z" />
+ android:pathData="M14,20h-4c0,1.1,0.9,2,2,2S14,21.1,14,20z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M13.97,16c0.41,0,0.75-0.34,0.75-0.75v-6.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v6.5 C13.22,15.66,13.55,16,13.97,16z" />
+ android:pathData="M12,2.5c-0.69,0-1.25,0.56-1.25,1.25v0.77C8.04,5.11,6,7.51,6,10.4V17H4.75C4.34,17,4,17.34,4,17.75s0.34,0.75,0.75,0.75 h14.5c0.41,0,0.75-0.34,0.75-0.75S19.66,17,19.25,17H18v-6.6c0-2.88-2.04-5.29-4.75-5.87V3.75C13.25,3.06,12.69,2.5,12,2.5z M16.5,10.4V17h-9v-6.6c0-2.48,2.02-4.5,4.5-4.5S16.5,7.91,16.5,10.4z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M10,16c0.41,0,0.75-0.34,0.75-0.75v-6.5C10.75,8.34,10.41,8,10,8S9.25,8.34,9.25,8.75v6.5C9.25,15.66,9.59,16,10,16z" />
+ android:pathData="M5.85,3.01C3.72,4.82,2.5,7.46,2.5,10.25C2.5,10.66,2.84,11,3.25,11S4,10.66,4,10.25c0-2.35,1.03-4.57,2.82-6.1 C7.14,3.88,7.17,3.41,6.91,3.1C6.64,2.78,6.17,2.74,5.85,3.01z" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18.15,3.01c-0.32-0.27-0.79-0.23-1.06,0.08c-0.27,0.32-0.23,0.79,0.08,1.06C18.97,5.68,20,7.9,20,10.25 c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75C21.5,7.46,20.28,4.82,18.15,3.01z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml
index 21153928240f..c6e8f57f5ec1 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_phone.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_battery_saver.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
index db4d302eb240..ca37d581332b 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_battery_saver.xml
@@ -15,7 +15,9 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
index 3d270b3fce42..5e1a5f20c6d6 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_bluetooth.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
new file mode 100644
index 000000000000..3cf7541219f0
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/ic_qs_ui_mode_night.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M12,20.5 L12,3.5 C16.687,3.5 20.5,7.313 20.5,12 C20.5,16.687 16.687,20.5 12,20.5 M12,2 C10.619,2 9.304,2.279 8.107,2.786 C7.51,3.039 6.941,3.349 6.409,3.708 C6.143,3.888 5.886,4.08 5.639,4.283 C4.651,5.099 3.822,6.1 3.207,7.233 C2.899,7.8 2.645,8.4 2.449,9.026 C2.255,9.652 2.12,10.305 2.052,10.978 C2.018,11.313 2,11.654 2,12 C2,17.522 6.478,22 12,22 C17.522,22 22,17.522 22,12 C22,6.478 17.522,2 12,2"
+ android:strokeWidth="1" />
+</vector>
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_activity_recognition.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
index b470603cddd0..669704775311 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_activity_recognition.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml
new file mode 100644
index 000000000000..8cd240d47b2d
--- /dev/null
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_aural.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M18,0 L6,0 C4.9,0 4,0.9 4,2 L4,14 C4,15.1 4.9,16 6,16 L18,16 C19.1,16 20,15.1 20,14 L20,2 C20,0.9 19.1,0 18,0 Z M18.5,14 C18.5,14.28 18.28,14.5 18,14.5 L6,14.5 C5.72,14.5 5.5,14.28 5.5,14 L5.5,2 C5.5,1.72 5.72,1.5 6,1.5 L18,1.5 C18.28,1.5 18.5,1.72 18.5,2 L18.5,14 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M15.86,3.10740288 C15.7704,3.02963963 15.6528,2.990758 15.5352,3.00186703 L13.0152,3.27959295 C12.8024,3.30736554 12.64,3.48511013 12.64,3.69618182 L12.64,9.056292 C12.2536,8.75079349 11.772,8.55638535 11.24,8.55638535 C10.0024,8.55638535 9,9.55064413 9,10.7781927 C9,12.0057412 10.0024,13 11.24,13 C12.4776,13 13.48,12.0057412 13.48,10.7781927 L13.48,5.01241596 L15.6248,4.77912619 C15.8376,4.7513536 16,4.57360901 16,4.36253732 L16,3.41845591 C16,3.30181102 15.9496,3.18516614 15.86,3.10740288 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M15.25,18 L3.25,18 C2.56,18 2,17.44 2,16.75 L2,4.75 C2,4.34 1.66,4 1.25,4 C0.84,4 0.5,4.34 0.5,4.75 L0.5,16.75 C0.5,18.27 1.73,19.5 3.25,19.5 L15.25,19.5 C15.66,19.5 16,19.16 16,18.75 C16,18.34 15.66,18 15.25,18 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_calendar.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_calendar.xml
index e9dddd071481..4e61af0dbf34 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_calendar.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_calendar.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_call_log.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_call_log.xml
index 2d6a6b916789..8d3c43c3d216 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_call_log.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_call_log.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_camera.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_camera.xml
index e3498c380d11..7d42ff758b8c 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_camera.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_camera.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_contacts.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_contacts.xml
index 987ed184a826..5d68581757ba 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_contacts.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_contacts.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_location.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_location.xml
index 2da48d857617..5dce9cb985b3 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_location.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_location.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_microphone.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_microphone.xml
index ddf14df872f2..b45e8322628d 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_microphone.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_microphone.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_phone_calls.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_phone_calls.xml
index 516ee36d7f48..fe45a97a3287 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_phone_calls.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_phone_calls.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sensors.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sensors.xml
index 65a193d98b32..c84cb0e99bde 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sensors.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sensors.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml
index b5509d12a059..96b70f7fbfbd 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_sms.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_storage.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_storage.xml
index 9b17e55f0be1..9240bb48b35e 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_storage.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_storage.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_visual.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_visual.xml
index 350bb4b80c85..2cd1bc0f17b0 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_visual.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/drawable/perm_group_visual.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="@android:color/black"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml b/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml
index ebcac82c695f..b7bfaad56249 100644
--- a/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml
+++ b/packages/overlays/IconPackRoundedAndroidOverlay/res/values/config.xml
@@ -30,4 +30,12 @@
<string name="config_batterymeterPowersavePath" translatable="false">
M 3.75,11.25 H 5.25 V 12.75 C 5.25,13.16 5.59,13.5 6,13.5 6.41,13.5 6.75,13.16 6.75,12.75 V 11.25 H 8.25 C 8.66,11.25 9,10.91 9,10.5 9,10.09 8.66,9.7499 8.25,9.7499 H 6.75 V 8.2499 C 6.75,7.8399 6.41,7.4999 6,7.4999 5.59,7.4999 5.2794,7.841 5.25,8.2499 V 9.7499 H 3.75 C 3.34,9.7499 3,10.09 3,10.5 3,10.91 3.3401,11.25 3.75,11.25 Z
</string>
+ <!-- X path for SignalDrawable as defined on a 24x24 canvas. -->
+ <string name="config_signalXPath" translatable="false">
+ M 20.72,16.22 L 19,17.94 L 17.28,16.22 C 16.99,15.93 16.51,15.93 16.22,16.22 C 15.93,16.51 15.93,16.99 16.22,17.28 L 17.94,19 L 16.22,20.72 C 15.93,21.01 15.93,21.49 16.22,21.78 C 16.37,21.93 16.56,22 16.75,22 C 16.94,22 17.13,21.93 17.28,21.78 L 19,20.06 L 20.72,21.78 C 20.87,21.93 21.06,22 21.25,22 C 21.44,22 21.63,21.93 21.78,21.78 C 22.07,21.49 22.07,21.01 21.78,20.72 L 20.06,19 L 21.78,17.28 C 22.07,16.99 22.07,16.51 21.78,16.22 C 21.49,15.93 21.01,15.93 20.72,16.22 Z
+ </string>
+ <!-- config_signalCutout{Height,Width}Fraction define fraction of the 24x24 canvas that
+ should be cut out to display config_signalXPath.-->
+ <item name="config_signalCutoutWidthFraction" format="float" type="dimen">10</item>
+ <item name="config_signalCutoutHeightFraction" format="float" type="dimen">10</item>
</resources>
diff --git a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
index 86cb525e203a..70621ae19749 100644
--- a/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
+++ b/packages/overlays/IconPackRoundedLauncherOverlay/res/drawable/ic_setting.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/textColorPrimary"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_arrow_back.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_arrow_back.xml
index 03f06e997e26..34f79b4478c9 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_arrow_back.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_arrow_back.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_cellular_off.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_cellular_off.xml
index 710387ca88d5..34d40ec813e4 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_cellular_off.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_cellular_off.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorAccent"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
index 7df03ad48705..1e86983cd551 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_chevron_right_24dp.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
index b3f642191ca3..1feaab1663c1 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_content_copy_grey600_24dp.xml
@@ -16,7 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="#757575"
+ android:tint="@*android:color/material_grey_600"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml
index 9acb62da7d43..ba3c5808d26c 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_data_saver.xml
@@ -15,18 +15,19 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M8,12a0.76 0.76 ,0,0,0,0.75 0.75 h2.5v2.5a0.75 0.75 ,0,0,0,1.5,0v-2.5h2.5a0.75 0.75 ,0,0,0,0-1.5h-2.5V8.75a0.75 0.75 ,0,0,0-1.5,0v2.5H8.75A0.76 0.76 ,0,0,0,8,12Z" />
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17.5000671,10 C17.5000671,6.198 14.6680671,3.064 11.0000671,2.574 L11.0000671,0.05 C16.0500671,0.55 20.0000671,4.82 20.0000671,10 C20.0000671,11.45 19.6800671,12.83 19.1200671,14.07 L16.9560671,12.796 C17.3040671,11.932 17.5000671,10.989 17.5000671,10 Z M10.0000671,17.5 C12.3900671,17.5 14.5140671,16.378 15.8870671,14.637 C16.6270671,15.073 18.0500671,15.91 18.0500671,15.91 C15.9790671,18.732 12.4710671,20.427 8.60106711,19.906 C4.22106711,19.316 0.68406711,15.774 0.0940671101,11.394 C-0.68693289,5.591 3.49306711,0.594 9.00006711,0.05 L9.00006711,2.574 C5.33206711,3.064 2.50006711,6.198 2.50006711,10 C2.50006711,14.142 5.85806711,17.5 10.0000671,17.5 Z M6,10 C6.00538581,9.58803794 6.33803794,9.25538581 6.75,9.25 L9.25,9.25 L9.25,6.75 C9.25,6.33578644 9.58578644,6 10,6 C10.4142136,6 10.75,6.33578644 10.75,6.75 L10.75,9.25 L13.25,9.25 C13.6642136,9.25 14,9.58578644 14,10 C14,10.4142136 13.6642136,10.75 13.25,10.75 L10.75,10.75 L10.75,13.25 C10.75,13.6642136 10.4142136,14 10,14 C9.58578644,14 9.25,13.6642136 9.25,13.25 L9.25,10.75 L6.75,10.75 C6.33803794,10.7446142 6.00538581,10.4119621 6,10 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
index 9283216b1a2f..463525d4bf26 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_devices_other.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_eject_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_eject_24dp.xml
index 4e37a8866dfb..0d4bd9bc48d0 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_eject_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_eject_24dp.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_find_in_page_24px.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
new file mode 100644
index 000000000000..36d5c7cf4cbf
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_find_in_page_24px.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="4.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M8.0001,15.25 C6.2081,15.25 4.7501,13.792 4.7501,12 C4.7501,10.208 6.2081,8.75 8.0001,8.75 C9.7921,8.75 11.2501,10.208 11.2501,12 C11.2501,13.792 9.7921,15.25 8.0001,15.25 L8.0001,15.25 Z M1.5001,18.5 L1.5001,1.5 L9.3791,1.5 L14.5001,6.621 L14.5001,17.439 L11.8371,14.776 C12.5921,13.735 12.9531,12.393 12.6341,10.949 C12.2191,9.075 10.6391,7.595 8.7411,7.307 C5.5431,6.82 2.8181,9.547 3.3071,12.745 C3.5971,14.642 5.0781,16.221 6.9521,16.634 C8.3941,16.952 9.7361,16.592 10.7761,15.837 L13.4391,18.5 L1.5001,18.5 Z M10.0001,0 L1.5001,0 C0.6721,0 0.0001,0.672 0.0001,1.5 L0.0001,18.5 C0.0001,19.328 0.6721,20 1.5001,20 L14.5001,20 C15.3281,20 16.0001,19.328 16.0001,18.5 L16.0001,6 L10.0001,0 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help_actionbar.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help_actionbar.xml
index e0a6f9553b15..c7d672efa574 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help_actionbar.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_help_actionbar.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_network_cell.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_network_cell.xml
index 10e0f2fd1fca..fbe5ef03ad80 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_network_cell.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_network_cell.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
index 81f18fb4b383..56a67c912176 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_notifications_off_24dp.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_scan_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_scan_24dp.xml
new file mode 100644
index 000000000000..3d79f7946b31
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_scan_24dp.xml
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorAccent"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="3.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4.5,1.5 L4.5,4.5 L1.5,4.5 L1.5,1.5 L4.5,1.5 L4.5,1.5 Z M5,0 L1,0 C0.44771525,0 0,0.44771525 0,1 L0,5 C0,5.55228475 0.44771525,6 1,6 L5,6 C5.55228475,6 6,5.55228475 6,5 L6,1 C6,0.44771525 5.55228475,0 5,0 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M16.5,1.5 L16.5,4.5 L13.5,4.5 L13.5,1.5 L16.5,1.5 L16.5,1.5 Z M17,0 L13,0 C12.4477153,0 12,0.44771525 12,1 L12,5 C12,5.55228475 12.4477153,6 13,6 L17,6 C17.5522847,6 18,5.55228475 18,5 L18,1 C18,0.44771525 17.5522847,0 17,0 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M4.5,13.5 L4.5,16.5 L1.5,16.5 L1.5,13.5 L4.5,13.5 L4.5,13.5 Z M5,12 L1,12 C0.44771525,12 0,12.4477153 0,13 L0,17 C0,17.5522847 0.44771525,18 1,18 L5,18 C5.55228475,18 6,17.5522847 6,17 L6,13 C6,12.4477153 5.55228475,12 5,12 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M13.75,12.25 L17.25,12.25 C17.6619621,12.2553858 17.9946142,12.5880379 18,13 C17.9946142,13.4119621 17.6619621,13.7446142 17.25,13.75 L13.75,13.75 L13.75,17.25 C13.75,17.6642136 13.4142136,18 13,18 C12.5857864,18 12.25,17.6642136 12.25,17.25 L12.25,13.75 L8.74999997,13.75 C8.33578642,13.75 8,13.4142136 8,13 C8,12.5857864 8.33578642,12.25 8.74999997,12.25 L12.25,12.25 L12.25,8.75 C12.2553858,8.33803794 12.5880379,8.00538581 13,8 C13.4119621,8.00538581 13.7446142,8.33803794 13.75,8.75 L13.75,12.25 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M1.6,8 L0.4,8 C0.1790861,8 0,8.1790861 0,8.4 L0,9.6 C0,9.8209139 0.1790861,10 0.4,10 L1.6,10 C1.8209139,10 2,9.8209139 2,9.6 L2,8.4 C2,8.1790861 1.8209139,8 1.6,8 L1.6,8 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M9,0 C8.58803794,0.00538581231 8.25538581,0.338037936 8.25,0.75 L8.25,5.75 C8.25000002,6.16421355 8.58578645,6.49999997 9,6.49999997 C9.41421355,6.49999997 9.74999998,6.16421355 9.75,5.75 L9.75,0.75 C9.74461419,0.338037936 9.41196206,0.00538581231 9,0 L9,0 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M5.6,8 L4.4,8 C4.1790861,8 4,8.1790861 4,8.4 L4,9.6 C4,9.8209139 4.1790861,10 4.4,10 L5.6,10 C5.8209139,10 6,9.8209139 6,9.6 L6,8.4 C6,8.1790861 5.8209139,8 5.6,8 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_data_usage.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_data_usage.xml
index b9c131b80ab6..855e4bb2a39d 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_data_usage.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_data_usage.xml
@@ -22,8 +22,7 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M12,20c-4.4,0-8-3.6-8-8c0-4.2,3.2-7.6,7.2-8V2C5.7,2.4,1.6,7.3,2,12.8c0.4,5.5,5.3,9.6,10.8,9.2c4.9-0.4,8.8-4.3,9.2-9.2 h-2C19.6,16.8,16.2,20,12,20z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M20,11.2h2c-0.4-4.9-4.3-8.9-9.2-9.2v2C16.6,4.4,19.6,7.4,20,11.2z" />
+ android:fillType="evenOdd"
+ android:pathData="M19.5000671,12 C19.5000671,8.198 16.6680671,5.064 13.0000671,4.574 L13.0000671,2.05 C18.0500671,2.55 22.0000671,6.82 22.0000671,12 C22.0000671,13.45 21.6800671,14.83 21.1200671,16.07 L18.9560671,14.796 C19.3040671,13.932 19.5000671,12.989 19.5000671,12 Z M12.0000671,19.5 C14.3900671,19.5 16.5140671,18.378 17.8870671,16.637 C18.6270671,17.073 20.0500671,17.91 20.0500671,17.91 C17.9790671,20.732 14.4710671,22.427 10.6010671,21.906 C6.22106711,21.316 2.68406711,17.774 2.09406711,13.394 C1.31306711,7.591 5.49306711,2.594 11.0000671,2.05 L11.0000671,4.574 C7.33206711,5.064 4.50006711,8.198 4.50006711,12 C4.50006711,16.142 7.85806711,19.5 12.0000671,19.5 Z"
+ android:strokeWidth="1" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml
new file mode 100644
index 000000000000..0572fb72f82e
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_disable.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="1.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M11,18.5 C6.313,18.5 2.5,14.687 2.5,10 C2.5,8.182 3.078,6.498 4.055,5.114 L15.887,16.945 C14.503,17.922 12.818,18.5 11,18.5 M20.031,18.969 L2.032,0.971 C1.739,0.678 1.264,0.678 0.971,0.971 C0.678,1.264 0.678,1.738 0.971,2.031 L2.983,4.043 C1.742,5.707 1,7.765 1,10 C1,15.522 5.477,20 11,20 C13.236,20 15.293,19.258 16.957,18.017 L18.971,20.029 C19.117,20.176 19.309,20.249 19.501,20.249 C19.693,20.249 19.885,20.176 20.031,20.029 C20.324,19.736 20.324,19.262 20.031,18.969"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M11,1.5 C15.687,1.5 19.5,5.313 19.5,10 C19.5,11.782 18.946,13.436 18.006,14.804 L19.078,15.877 C20.281,14.226 21,12.199 21,10 C21,4.478 16.522,0 11,0 C8.801,0 6.774,0.719 5.124,1.922 L6.196,2.994 C7.564,2.054 9.218,1.5 11,1.5"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml
new file mode 100644
index 000000000000..ec608cdf67dd
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_enable.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M12.2502,0.2637 L12.2502,1.8127 C15.8472,2.8017 18.5002,6.0927 18.5002,9.9997 C18.5002,14.6867 14.6872,18.4997 10.0002,18.4997 C5.3132,18.4997 1.5002,14.6867 1.5002,9.9997 C1.5002,6.0927 4.1532,2.8017 7.7502,1.8127 L7.7502,0.2637 C3.3122,1.2847 0.0002,5.2517 0.0002,9.9997 C0.0002,15.5227 4.4772,19.9997 10.0002,19.9997 C15.5222,19.9997 20.0002,15.5227 20.0002,9.9997 C20.0002,5.2517 16.6872,1.2847 12.2502,0.2637"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M15.0304,9.9697 C14.7374,9.6767 14.2624,9.6767 13.9694,9.9697 L10.7504,13.1897 L10.7504,0.7387 C10.7504,0.3307 10.4144,-0.0003 10.0004,-0.0003 C9.5864,-0.0003 9.2504,0.3307 9.2504,0.7387 L9.2504,13.1897 L6.0304,9.9697 C5.7374,9.6767 5.2624,9.6767 4.9694,9.9697 C4.6764,10.2627 4.6764,10.7377 4.9694,11.0307 L9.4694,15.5307 C9.6164,15.6767 9.8074,15.7497 10.0004,15.7497 C10.1924,15.7497 10.3844,15.6767 10.5304,15.5307 L15.0304,11.0307 C15.3234,10.7377 15.3234,10.2627 15.0304,9.9697"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_language.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_language.xml
new file mode 100644
index 000000000000..730942bda59c
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_language.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,22c5.52,0,10-4.48,10-10c0-5.52-4.48-10-10-10C6.48,2,2,6.48,2,12C2,17.52,6.48,22,12,22z M4.5,16h3.14 c0.4,1.41,1.01,2.8,1.84,4.12C7.34,19.45,5.55,17.95,4.5,16z M3.5,12c0-0.87,0.13-1.71,0.38-2.5H7.3c-0.29,1.66-0.3,3.34-0.01,5 H3.88C3.63,13.71,3.5,12.87,3.5,12z M20.5,12c0,0.87-0.13,1.71-0.38,2.5h-3.42c0.29-1.66,0.28-3.34-0.01-5h3.43 C20.37,10.29,20.5,11.13,20.5,12z M15.2,14.5H8.8c-0.33-1.66-0.32-3.34,0.01-5h6.39C15.53,11.16,15.53,12.84,15.2,14.5z M11.55,20.48c-1.08-1.43-1.86-2.94-2.36-4.48h5.62c-0.5,1.54-1.28,3.05-2.36,4.48c-0.15,0.01-0.3,0.02-0.45,0.02 S11.7,20.49,11.55,20.48z M14.51,20.12c0.83-1.32,1.44-2.71,1.84-4.12h3.14C18.45,17.95,16.66,19.45,14.51,20.12z M19.5,8h-3.15 c-0.4-1.41-1.01-2.79-1.84-4.12C16.66,4.54,18.45,6.04,19.5,8z M12.45,3.52C13.52,4.96,14.3,6.46,14.8,8H9.2 c0.5-1.54,1.28-3.04,2.35-4.48C11.7,3.51,11.85,3.5,12,3.5S12.3,3.51,12.45,3.52z M9.49,3.88C8.67,5.21,8.06,6.59,7.65,8H4.5 C5.55,6.04,7.34,4.54,9.49,3.88z" />
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_multiuser.xml
index 9b39a9406dc8..83d9d2a9311e 100644
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_battery_saver_accent_24dp.xml
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_multiuser.xml
@@ -16,14 +16,14 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
- android:tint="?android:attr/colorAccent"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M9.74,13.75h1.5v1.5c0,0.41,0.34,0.75,0.75,0.75s0.75-0.34,0.75-0.75v-1.5h1.5c0.41,0,0.75-0.34,0.75-0.75 s-0.34-0.75-0.75-0.75h-1.5v-1.5c0-0.41-0.34-0.75-0.75-0.75s-0.75,0.34-0.75,0.75v1.5h-1.5c-0.41,0-0.75,0.34-0.75,0.75 S9.33,13.75,9.74,13.75z" />
+ android:pathData="M4,19c0,0.55,0.45,1,1,1h14c0.55,0,1-0.45,1-1v-3c0-1.66-1.34-3-3-3H7c-1.66,0-3,1.34-3,3V19z M5.5,16 c0-0.83,0.67-1.5,1.5-1.5h10c0.83,0,1.5,0.67,1.5,1.5v2.5h-13V16z" />
<path
android:fillColor="@android:color/white"
- android:pathData="M17,4h-3V3.49c0-0.55-0.45-1-1-1h-2c-0.55,0-1,0.45-1,1V4H7C6.45,4,6,4.45,6,5v16c0,0.55,0.45,1,1,1h10c0.55,0,1-0.45,1-1 V5C18,4.45,17.55,4,17,4z M16.5,20.5h-9v-15h9V20.5z" />
+ android:pathData="M8,8c0,2.21,1.79,4,4,4s4-1.79,4-4c0-2.21-1.79-4-4-4S8,5.79,8,8z M12,5.5c1.38,0,2.5,1.12,2.5,2.5 c0,1.38-1.12,2.5-2.5,2.5S9.5,9.38,9.5,8C9.5,6.62,10.62,5.5,12,5.5z" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
deleted file mode 100644
index 0a1c3055870d..000000000000
--- a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_settings_wireless_white.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- 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.
--->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
- android:viewportHeight="24"
- android:viewportWidth="24"
- android:width="24dp" >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M12,2.75C7.95,2.69,4.05,4.3,1.22,7.2C0.96,7.5,0.97,7.95,1.24,8.23C1.53,8.53,2,8.54,2.3,8.25c2.55-2.61,6.05-4.06,9.7-4 c3.65-0.06,7.17,1.4,9.72,4.02c0.28,0.27,0.73,0.28,1.03,0.01c0.31-0.28,0.33-0.75,0.05-1.06C19.96,4.32,16.06,2.69,12,2.75z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M15.78,14.82c0.05,0.06,0.1,0.11,0.17,0.15c0.34,0.23,0.81,0.14,1.04-0.21s0.14-0.81-0.21-1.04 c-2.64-2.64-6.91-2.64-9.55,0c-0.27,0.29-0.27,0.73,0,1.02c0.28,0.3,0.76,0.32,1.06,0.04h0.03c0,0,0,0,0.01-0.01 c2.05-2.05,5.37-2.04,7.42,0.01C15.75,14.8,15.76,14.81,15.78,14.82z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M 12 17 C 12.8284271247 17 13.5 17.6715728753 13.5 18.5 C 13.5 19.3284271247 12.8284271247 20 12 20 C 11.1715728753 20 10.5 19.3284271247 10.5 18.5 C 10.5 17.6715728753 11.1715728753 17 12 17 Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M20.03,11.79c0.3-0.29,0.3-0.77,0.01-1.06h-0.01c-2.12-2.18-5.01-3.44-8.04-3.5c-3.04,0.06-5.93,1.32-8.05,3.5 c-0.29,0.3-0.28,0.77,0.01,1.06c0.3,0.29,0.77,0.28,1.06-0.01c1.85-1.88,4.36-2.96,7-3c2.62,0.05,5.11,1.13,6.95,3 C19.25,12.07,19.73,12.08,20.03,11.79z" />
-</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
new file mode 100644
index 000000000000..e9a07cc3b988
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSettingsOverlay/res/drawable/ic_sync_problem_24dp.xml
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="3.000000"
+ android:translateY="3.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M16.7178,12.626 C17.2378,11.522 17.5288,10.291 17.5288,9 C17.5288,6.119 16.1088,3.539 13.8488,2 L15.7588,2 C16.1578,2 16.4988,1.659 16.4988,1.25 C16.4988,0.84 16.1578,0.5 15.7488,0.5 L10.7488,0.5 C10.3388,0.5 9.9988,0.84 9.9988,1.25 L9.9988,6.25 C9.9988,6.659 10.3388,7 10.7488,7 C11.1578,7 11.4988,6.659 11.4988,6.25 L11.4988,2.47 C14.1978,3.489 16.0188,6.039 16.0188,9 C16.0188,9.785 15.8828,10.542 15.6438,11.252 C15.0498,10.788 14.3108,10.5 13.4988,10.5 C11.5658,10.5 9.9988,12.066 9.9988,14 C9.9988,15.933 11.5658,17.5 13.4988,17.5 C15.4318,17.5 16.9988,15.933 16.9988,14 C16.9988,13.512 16.8978,13.048 16.7178,12.626 L16.7178,12.626 Z M13.4988,16.5 C13.2228,16.5 12.9988,16.275 12.9988,16 C12.9988,15.723 13.2228,15.5 13.4988,15.5 C13.7748,15.5 13.9988,15.723 13.9988,16 C13.9988,16.275 13.7748,16.5 13.4988,16.5 L13.4988,16.5 Z M13.9988,14 C13.9988,14.275 13.7748,14.5 13.4988,14.5 C13.2228,14.5 12.9988,14.275 12.9988,14 L12.9988,12 C12.9988,11.723 13.2228,11.5 13.4988,11.5 C13.7748,11.5 13.9988,11.723 13.9988,12 L13.9988,14 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M7.0811,0.7197 C3.1901,1.6097 0.4801,5.0097 0.4801,8.9997 C0.4801,11.8797 1.9011,14.4587 4.1611,15.9987 L2.2511,15.9987 C1.8411,15.9987 1.5011,16.3397 1.5011,16.7497 C1.5011,17.1577 1.8411,17.4997 2.2511,17.4997 L7.2511,17.4997 C7.6621,17.4997 8.0011,17.1577 8.0011,16.7497 L8.0011,11.7487 C8.0011,11.3397 7.6621,10.9997 7.2511,10.9997 C6.8411,10.9997 6.5021,11.3397 6.5021,11.7487 L6.5021,15.5287 C3.8011,14.5107 1.9811,11.9587 1.9811,8.9997 C1.9811,5.7197 4.2111,2.9097 7.4211,2.1807 C7.8221,2.0907 8.0811,1.6797 7.9801,1.2797 C7.9041,0.9347 7.5961,0.7017 7.2491,0.7017 C7.1941,0.7017 7.1381,0.7067 7.0811,0.7197"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_arrow_back.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_arrow_back.xml
index 03f06e997e26..34f79b4478c9 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_arrow_back.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_arrow_back.xml
@@ -15,6 +15,7 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:autoMirrored="true"
android:height="24dp"
android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
index 697d1c29eac7..62fcd4c3a33a 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_brightness_thumb.xml
@@ -20,7 +20,7 @@
android:viewportWidth="24"
android:width="24dp" >
<path
- android:fillColor="?android:attr/colorPrimary"
+ android:fillColor="?android:attr/colorBackgroundFloating"
android:pathData="M 12 0 L 12 0 Q 24 0 24 12 L 24 12 Q 24 24 12 24 L 12 24 Q 0 24 0 12 L 0 12 Q 0 0 12 0 Z" />
<path
android:fillColor="?android:attr/colorControlActivated"
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml
index 294e181faef8..142e078bdfd9 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_camera.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="24dp"
+ android:height="17dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="24dp" >
+ android:width="17dp" >
<path
android:fillColor="@android:color/white"
android:pathData="M22,7c0-1.1-0.9-2-2-2h-3l-1.41-1.41C15.21,3.21,14.7,3,14.17,3H9.83C9.3,3,8.79,3.21,8.41,3.59L7,5H4C2.9,5,2,5.9,2,7v12 c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V7z M20.5,19c0,0.28-0.22,0.5-0.5,0.5H4c-0.28,0-0.5-0.22-0.5-0.5V7c0-0.28,0.22-0.5,0.5-0.5 h3.62l1.85-1.85C9.57,4.55,9.69,4.5,9.83,4.5h4.34c0.13,0,0.26,0.05,0.35,0.15l1.85,1.85H20c0.28,0,0.5,0.22,0.5,0.5V19z" />
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml
index 14d88e76bb91..f2821668c870 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_cast_connected.xml
@@ -15,10 +15,10 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="17dp"
+ android:height="24dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="17dp" >
+ android:width="24dp" >
<path
android:fillColor="@android:color/white"
android:pathData="M20.5,4h-17C3.49,4,3.48,4,3.47,4C2.64,4.02,1.98,4.7,2,5.53v3.18c0,0.41,0.34,0.75,0.75,0.75S3.5,9.12,3.5,8.71 c0-1.96,0-3.21,0-3.21l17,0.03V18.5h-7.35c-0.41,0-0.75,0.34-0.75,0.75S12.74,20,13.15,20h7.35c0.01,0,0.02,0,0.03,0 c0.83-0.02,1.49-0.7,1.47-1.53V5.53c0-0.01,0-0.02,0-0.03C22,4.67,21.33,4,20.5,4z" />
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml
index ee11b84b28ba..cdc3bfbd3d5f 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver.xml
@@ -15,17 +15,17 @@
limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:height="18dp "
+ android:height="18dp"
android:viewportHeight="24"
android:viewportWidth="24"
- android:width="18dp " >
- <path
- android:fillColor="@android:color/white"
- android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M8,12a0.76 0.76 ,0,0,0,0.75 0.75 h2.5v2.5a0.75 0.75 ,0,0,0,1.5,0v-2.5h2.5a0.75 0.75 ,0,0,0,0-1.5h-2.5V8.75a0.75 0.75 ,0,0,0-1.5,0v2.5H8.75A0.76 0.76 ,0,0,0,8,12Z" />
+ android:width="18dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="2.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17.5000671,10 C17.5000671,6.198 14.6680671,3.064 11.0000671,2.574 L11.0000671,0.05 C16.0500671,0.55 20.0000671,4.82 20.0000671,10 C20.0000671,11.45 19.6800671,12.83 19.1200671,14.07 L16.9560671,12.796 C17.3040671,11.932 17.5000671,10.989 17.5000671,10 Z M10.0000671,17.5 C12.3900671,17.5 14.5140671,16.378 15.8870671,14.637 C16.6270671,15.073 18.0500671,15.91 18.0500671,15.91 C15.9790671,18.732 12.4710671,20.427 8.60106711,19.906 C4.22106711,19.316 0.68406711,15.774 0.0940671101,11.394 C-0.68693289,5.591 3.49306711,0.594 9.00006711,0.05 L9.00006711,2.574 C5.33206711,3.064 2.50006711,6.198 2.50006711,10 C2.50006711,14.142 5.85806711,17.5 10.0000671,17.5 Z M6,10 C6.00538581,9.58803794 6.33803794,9.25538581 6.75,9.25 L9.25,9.25 L9.25,6.75 C9.25,6.33578644 9.58578644,6 10,6 C10.4142136,6 10.75,6.33578644 10.75,6.75 L10.75,9.25 L13.25,9.25 C13.6642136,9.25 14,9.58578644 14,10 C14,10.4142136 13.6642136,10.75 13.25,10.75 L10.75,10.75 L10.75,13.25 C10.75,13.6642136 10.4142136,14 10,14 C9.58578644,14 9.25,13.6642136 9.25,13.25 L9.25,10.75 L6.75,10.75 C6.33803794,10.7446142 6.00538581,10.4119621 6,10 Z"
+ android:strokeWidth="1" />
+ </group>
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml
index 3d620a18bb1a..7dab949f9da5 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_data_saver_off.xml
@@ -21,8 +21,7 @@
android:width="24dp" >
<path
android:fillColor="@android:color/white"
- android:pathData="M3.36,7A10,10,0,0,0,20.27,17.64L18.1,16.39A7.5,7.5,0,1,1,11.25,4.56V2.05A10,10,0,0,0,3.36,7Z" />
- <path
- android:fillColor="@android:color/white"
- android:pathData="M21,16.35a10,10,0,0,0-8.27-14.3V4.56a7.48,7.48,0,0,1,6.1,10.54Z" />
+ android:fillType="evenOdd"
+ android:pathData="M19.5000671,12 C19.5000671,8.198 16.6680671,5.064 13.0000671,4.574 L13.0000671,2.05 C18.0500671,2.55 22.0000671,6.82 22.0000671,12 C22.0000671,13.45 21.6800671,14.83 21.1200671,16.07 L18.9560671,14.796 C19.3040671,13.932 19.5000671,12.989 19.5000671,12 Z M12.0000671,19.5 C14.3900671,19.5 16.5140671,18.378 17.8870671,16.637 C18.6270671,17.073 20.0500671,17.91 20.0500671,17.91 C17.9790671,20.732 14.4710671,22.427 10.6010671,21.906 C6.22106711,21.316 2.68406711,17.774 2.09406711,13.394 C1.31306711,7.591 5.49306711,2.594 11.0000671,2.05 L11.0000671,4.574 C7.33206711,5.064 4.50006711,8.198 4.50006711,12 C4.50006711,16.142 7.85806711,19.5 12.0000671,19.5 Z"
+ android:strokeWidth="1" />
</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
index f2284bc37287..85c2bcdbdce0 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_qs_bluetooth_connecting.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
index 15201e924933..3a26cbaf7238 100644
--- a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_alarm_mute.xml
@@ -16,6 +16,7 @@
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:height="24dp"
+ android:tint="?android:attr/colorControlNormal"
android:viewportHeight="24"
android:viewportWidth="24"
android:width="24dp" >
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
new file mode 100644
index 000000000000..ad79132bb0f8
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions.xml
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="2.000000"
+ android:translateY="4.000000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M18.0001,0 L2.0001,0 C0.8961,0 0.0001,0.896 0.0001,2 L0.0001,14 C0.0001,15.104 0.8961,16 2.0001,16 L18.0001,16 C19.1041,16 20.0001,15.104 20.0001,14 L20.0001,2 C20.0001,0.896 19.1041,0 18.0001,0 M18.0001,1.5 C18.2751,1.5 18.5001,1.725 18.5001,2 L18.5001,14 C18.5001,14.275 18.2751,14.5 18.0001,14.5 L2.0001,14.5 C1.7251,14.5 1.5001,14.275 1.5001,14 L1.5001,2 C1.5001,1.725 1.7251,1.5 2.0001,1.5 L18.0001,1.5"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M3.5001,11.5 L13.5001,11.5 C13.7761,11.5 14.0001,11.724 14.0001,12 L14.0001,12.5 C14.0001,12.776 13.7761,13 13.5001,13 L3.5001,13 C3.2241,13 3.0001,12.776 3.0001,12.5 L3.0001,12 C3.0001,11.724 3.2241,11.5 3.5001,11.5"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M3.5001,8.5 L4.0001,8.5 C4.2761,8.5 4.5001,8.724 4.5001,9 L4.5001,9.5 C4.5001,9.776 4.2761,10 4.0001,10 L3.5001,10 C3.2241,10 3.0001,9.776 3.0001,9.5 L3.0001,9 C3.0001,8.724 3.2241,8.5 3.5001,8.5"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M16.0001,11.5 L16.5001,11.5 C16.7761,11.5 17.0001,11.724 17.0001,12 L17.0001,12.5 C17.0001,12.776 16.7761,13 16.5001,13 L16.0001,13 C15.7241,13 15.5001,12.776 15.5001,12.5 L15.5001,12 C15.5001,11.724 15.7241,11.5 16.0001,11.5"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M6.5001,8.5 L16.5001,8.5 C16.7761,8.5 17.0001,8.724 17.0001,9 L17.0001,9.5 C17.0001,9.776 16.7761,10 16.5001,10 L6.5001,10 C6.2241,10 6.0001,9.776 6.0001,9.5 L6.0001,9 C6.0001,8.724 6.2241,8.5 6.5001,8.5"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
new file mode 100644
index 000000000000..2ea41f22943a
--- /dev/null
+++ b/packages/overlays/IconPackRoundedSystemUIOverlay/res/drawable/ic_volume_odi_captions_disabled.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:height="24dp"
+ android:viewportHeight="24"
+ android:viewportWidth="24"
+ android:width="24dp" >
+ <group
+ android:translateX="1.750150"
+ android:translateY="2.750000" >
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M3.74975,9.74875 L4.24975,9.74875 C4.52575,9.74875 4.74975,9.97275 4.74975,10.24875 L4.74975,10.74875 C4.74975,11.02475 4.52575,11.24875 4.24975,11.24875 L3.74975,11.24875 C3.47375,11.24875 3.24975,11.02475 3.24975,10.74875 L3.24975,10.24875 C3.24975,9.97275 3.47375,9.74875 3.74975,9.74875"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M18.24975,2.74875 C18.52475,2.74875 18.74975,2.97375 18.74975,3.24875 L18.74975,15.24875 C18.74975,15.33875 18.71975,15.41875 18.67775,15.49275 L19.74675,16.56175 C20.05675,16.20975 20.24975,15.75475 20.24975,15.24875 L20.24975,3.24875 C20.24975,2.14475 19.35375,1.24875 18.24975,1.24875 L4.43375,1.24875 L5.93375,2.74875 L18.24975,2.74875 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M17.24975,13.74875 L17.24975,13.24875 C17.24975,12.97275 17.02575,12.74875 16.74975,12.74875 L16.24975,12.74875 C16.15875,12.74875 16.07875,12.77875 16.00575,12.82075 L17.17775,13.99275 C17.21975,13.91975 17.24975,13.83875 17.24975,13.74875"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M16.74975,11.24875 C17.02575,11.24875 17.24975,11.02475 17.24975,10.74875 L17.24975,10.24875 C17.24975,9.97275 17.02575,9.74875 16.74975,9.74875 L12.93375,9.74875 L14.43375,11.24875 L16.74975,11.24875 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M2.24975,15.74875 C1.97475,15.74875 1.74975,15.52375 1.74975,15.24875 L1.74975,3.24875 C1.74975,3.12675 1.79875,3.01875 1.87175,2.93275 L8.68875,9.74875 L6.74975,9.74875 C6.47375,9.74875 6.24975,9.97275 6.24975,10.24875 L6.24975,10.74875 C6.24975,11.02475 6.47375,11.24875 6.74975,11.24875 L10.18875,11.24875 L11.68875,12.74875 L3.74975,12.74875 C3.47375,12.74875 3.24975,12.97275 3.24975,13.24875 L3.24975,13.74875 C3.24975,14.02475 3.47375,14.24875 3.74975,14.24875 L13.18875,14.24875 L14.68975,15.74875 L2.24975,15.74875 Z M19.27975,18.21775 L1.27975,0.21975 C0.98675,-0.07325 0.51275,-0.07325 0.21975,0.21975 C-0.07325,0.51275 -0.07325,0.98675 0.21975,1.27975 L0.80775,1.86775 C0.46375,2.22775 0.24975,2.71175 0.24975,3.24875 L0.24975,15.24875 C0.24975,16.35275 1.14575,17.24875 2.24975,17.24875 L16.18975,17.24875 L18.21975,19.27775 C18.51275,19.57075 18.98675,19.57075 19.27975,19.27775 C19.57275,18.98475 19.57275,18.51075 19.27975,18.21775 L19.27975,18.21775 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M2.24975,15.74875 C1.97475,15.74875 1.74975,15.52375 1.74975,15.24875 L1.74975,3.24875 C1.74975,3.12675 1.79875,3.01875 1.87175,2.93275 L0.80775,1.86775 C0.46375,2.22775 0.24975,2.71175 0.24975,3.24875 L0.24975,15.24875 C0.24975,16.35275 1.14575,17.24875 2.24975,17.24875 L16.18975,17.24875 L14.68975,15.74875 L2.24975,15.74875 Z"
+ android:strokeWidth="1" />
+ <path
+ android:fillColor="@android:color/white"
+ android:fillType="evenOdd"
+ android:pathData="M18.24975,2.74875 C18.52475,2.74875 18.74975,2.97375 18.74975,3.24875 L18.74975,15.24875 C18.74975,15.33875 18.71975,15.41875 18.67775,15.49275 L19.74675,16.56175 C20.05675,16.20975 20.24975,15.75475 20.24975,15.24875 L20.24975,3.24875 C20.24975,2.14475 19.35375,1.24875 18.24975,1.24875 L4.43375,1.24875 L5.93375,2.74875 L18.24975,2.74875 Z"
+ android:strokeWidth="1" />
+ </group>
+</vector> \ No newline at end of file
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 1a6faecaecfd..e66e596d5038 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -1255,23 +1255,21 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
}
- public void notifyPhysicalChannelConfiguration(List<PhysicalChannelConfig> configs) {
- notifyPhysicalChannelConfigurationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
- configs);
- }
-
- public void notifyPhysicalChannelConfigurationForSubscriber(int subId,
+ /**
+ * Notify physical channel configuration according to subscripton ID and phone ID
+ */
+ public void notifyPhysicalChannelConfigurationForSubscriber(int phoneId, int subId,
List<PhysicalChannelConfig> configs) {
if (!checkNotifyPermission("notifyPhysicalChannelConfiguration()")) {
return;
}
if (VDBG) {
- log("notifyPhysicalChannelConfiguration: subId=" + subId + " configs=" + configs);
+ log("notifyPhysicalChannelConfiguration: subId=" + subId + " phoneId=" + phoneId
+ + " configs=" + configs);
}
synchronized (mRecords) {
- int phoneId = SubscriptionManager.getPhoneId(subId);
if (validatePhoneId(phoneId)) {
mPhysicalChannelConfigs.set(phoneId, configs);
for (Record r : mRecords) {
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 6eb9f0c7a6bc..07482796b027 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -16,6 +16,7 @@
package com.android.server;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.IUidObserver;
@@ -193,7 +194,7 @@ public class VibratorService extends IVibratorService.Stub
// with other system events, any duration calculations should be done use startTime so as
// not to be affected by discontinuities created by RTC adjustments.
public final long startTimeDebug;
- public final int usageHint;
+ public final AudioAttributes attrs;
public final int uid;
public final String opPkg;
public final String reason;
@@ -206,12 +207,12 @@ public class VibratorService extends IVibratorService.Stub
public VibrationEffect originalEffect;
private Vibration(IBinder token, VibrationEffect effect,
- int usageHint, int uid, String opPkg, String reason) {
+ AudioAttributes attrs, int uid, String opPkg, String reason) {
this.token = token;
this.effect = effect;
this.startTime = SystemClock.elapsedRealtime();
this.startTimeDebug = System.currentTimeMillis();
- this.usageHint = usageHint;
+ this.attrs = attrs;
this.uid = uid;
this.opPkg = opPkg;
this.reason = reason;
@@ -231,7 +232,7 @@ public class VibratorService extends IVibratorService.Stub
}
public boolean isHapticFeedback() {
- if (VibratorService.this.isHapticFeedback(usageHint)) {
+ if (VibratorService.this.isHapticFeedback(attrs.getUsage())) {
return true;
}
if (effect instanceof VibrationEffect.Prebaked) {
@@ -256,15 +257,15 @@ public class VibratorService extends IVibratorService.Stub
}
public boolean isNotification() {
- return VibratorService.this.isNotification(usageHint);
+ return VibratorService.this.isNotification(attrs.getUsage());
}
public boolean isRingtone() {
- return VibratorService.this.isRingtone(usageHint);
+ return VibratorService.this.isRingtone(attrs.getUsage());
}
public boolean isAlarm() {
- return VibratorService.this.isAlarm(usageHint);
+ return VibratorService.this.isAlarm(attrs.getUsage());
}
public boolean isFromSystem() {
@@ -273,7 +274,7 @@ public class VibratorService extends IVibratorService.Stub
public VibrationInfo toInfo() {
return new VibrationInfo(
- startTimeDebug, effect, originalEffect, usageHint, uid, opPkg, reason);
+ startTimeDebug, effect, originalEffect, attrs, uid, opPkg, reason);
}
}
@@ -281,18 +282,18 @@ public class VibratorService extends IVibratorService.Stub
private final long mStartTimeDebug;
private final VibrationEffect mEffect;
private final VibrationEffect mOriginalEffect;
- private final int mUsageHint;
+ private final AudioAttributes mAttrs;
private final int mUid;
private final String mOpPkg;
private final String mReason;
public VibrationInfo(long startTimeDebug, VibrationEffect effect,
- VibrationEffect originalEffect, int usageHint, int uid,
+ VibrationEffect originalEffect, AudioAttributes attrs, int uid,
String opPkg, String reason) {
mStartTimeDebug = startTimeDebug;
mEffect = effect;
mOriginalEffect = originalEffect;
- mUsageHint = usageHint;
+ mAttrs = attrs;
mUid = uid;
mOpPkg = opPkg;
mReason = reason;
@@ -307,8 +308,8 @@ public class VibratorService extends IVibratorService.Stub
.append(mEffect)
.append(", originalEffect: ")
.append(mOriginalEffect)
- .append(", usageHint: ")
- .append(mUsageHint)
+ .append(", attrs: ")
+ .append(mAttrs)
.append(", uid: ")
.append(mUid)
.append(", opPkg: ")
@@ -549,12 +550,11 @@ public class VibratorService extends IVibratorService.Stub
}
@Override // Binder call
- public void vibrate(int uid, String opPkg, VibrationEffect effect, int usageHint, String reason,
- IBinder token) {
+ public void vibrate(int uid, String opPkg, VibrationEffect effect,
+ @Nullable AudioAttributes attrs, String reason, IBinder token) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "vibrate, reason = " + reason);
try {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
- != PackageManager.PERMISSION_GRANTED) {
+ if (!hasPermission(android.Manifest.permission.VIBRATE)) {
throw new SecurityException("Requires VIBRATE permission");
}
if (token == null) {
@@ -566,6 +566,22 @@ public class VibratorService extends IVibratorService.Stub
return;
}
+ if (attrs == null) {
+ attrs = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_UNKNOWN)
+ .build();
+ }
+
+ if (shouldBypassDnd(attrs)) {
+ if (!(hasPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ || hasPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+ || hasPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING))) {
+ final int flags = attrs.getAllFlags()
+ & ~AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY;
+ attrs = new AudioAttributes.Builder(attrs).replaceFlags(flags).build();
+ }
+ }
+
// If our current vibration is longer than the new vibration and is the same amplitude,
// then just let the current one finish.
synchronized (mLock) {
@@ -608,13 +624,13 @@ public class VibratorService extends IVibratorService.Stub
return;
}
- Vibration vib = new Vibration(token, effect, usageHint, uid, opPkg, reason);
+ Vibration vib = new Vibration(token, effect, attrs, uid, opPkg, reason);
if (mProcStatesCache.get(uid, ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND)
> ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND
&& !vib.isNotification() && !vib.isRingtone() && !vib.isAlarm()) {
Slog.e(TAG, "Ignoring incoming vibration as process with"
- + " uid = " + uid + " is background,"
- + " usage = " + AudioAttributes.usageToString(vib.usageHint));
+ + " uid= " + uid + " is background,"
+ + " attrs= " + vib.attrs);
return;
}
linkVibration(vib);
@@ -632,6 +648,11 @@ public class VibratorService extends IVibratorService.Stub
}
}
+ private boolean hasPermission(String permission) {
+ return mContext.checkCallingOrSelfPermission(permission)
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
private static boolean isRepeatingVibration(VibrationEffect effect) {
return effect.getDuration() == Long.MAX_VALUE;
}
@@ -760,14 +781,14 @@ public class VibratorService extends IVibratorService.Stub
if (vib.effect instanceof VibrationEffect.OneShot) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
VibrationEffect.OneShot oneShot = (VibrationEffect.OneShot) vib.effect;
- doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.usageHint);
+ doVibratorOn(oneShot.getDuration(), oneShot.getAmplitude(), vib.uid, vib.attrs);
mH.postDelayed(mVibrationEndRunnable, oneShot.getDuration());
} else if (vib.effect instanceof VibrationEffect.Waveform) {
// mThread better be null here. doCancelVibrate should always be
// called before startNextVibrationLocked or startVibrationLocked.
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
VibrationEffect.Waveform waveform = (VibrationEffect.Waveform) vib.effect;
- mThread = new VibrateThread(waveform, vib.uid, vib.usageHint);
+ mThread = new VibrateThread(waveform, vib.uid, vib.attrs);
mThread.start();
} else if (vib.effect instanceof VibrationEffect.Prebaked) {
Trace.asyncTraceBegin(Trace.TRACE_TAG_VIBRATOR, "vibration", 0);
@@ -788,13 +809,14 @@ public class VibratorService extends IVibratorService.Stub
return true;
}
- if (vib.usageHint == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
+ if (vib.attrs.getUsage() == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) {
return true;
}
- if (vib.usageHint == AudioAttributes.USAGE_ALARM ||
- vib.usageHint == AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY ||
- vib.usageHint == AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST) {
+ if (vib.attrs.getUsage() == AudioAttributes.USAGE_ALARM
+ || vib.attrs.getUsage() == AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY
+ || vib.attrs.getUsage()
+ == AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST) {
return true;
}
@@ -887,12 +909,24 @@ public class VibratorService extends IVibratorService.Stub
}
}
+ private static boolean shouldBypassDnd(AudioAttributes attrs) {
+ return (attrs.getAllFlags() & AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY) != 0;
+ }
+
private int getAppOpMode(Vibration vib) {
int mode = mAppOps.checkAudioOpNoThrow(AppOpsManager.OP_VIBRATE,
- vib.usageHint, vib.uid, vib.opPkg);
+ vib.attrs.getUsage(), vib.uid, vib.opPkg);
if (mode == AppOpsManager.MODE_ALLOWED) {
mode = mAppOps.startOpNoThrow(AppOpsManager.OP_VIBRATE, vib.uid, vib.opPkg);
}
+
+ if (mode == AppOpsManager.MODE_IGNORED && shouldBypassDnd(vib.attrs)) {
+ // If we're just ignoring the vibration op then this is set by DND and we should ignore
+ // if we're asked to bypass. AppOps won't be able to record this operation, so make
+ // sure we at least note it in the logs for debugging.
+ Slog.d(TAG, "Bypassing DND for vibration: " + vib);
+ mode = AppOpsManager.MODE_ALLOWED;
+ }
return mode;
}
@@ -1032,7 +1066,7 @@ public class VibratorService extends IVibratorService.Stub
return vibratorExists();
}
- private void doVibratorOn(long millis, int amplitude, int uid, int usageHint) {
+ private void doVibratorOn(long millis, int amplitude, int uid, AudioAttributes attrs) {
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "doVibratorOn");
try {
synchronized (mInputDeviceVibrators) {
@@ -1046,10 +1080,8 @@ public class VibratorService extends IVibratorService.Stub
noteVibratorOnLocked(uid, millis);
final int vibratorCount = mInputDeviceVibrators.size();
if (vibratorCount != 0) {
- final AudioAttributes attributes =
- new AudioAttributes.Builder().setUsage(usageHint).build();
for (int i = 0; i < vibratorCount; i++) {
- mInputDeviceVibrators.get(i).vibrate(millis, attributes);
+ mInputDeviceVibrators.get(i).vibrate(millis, attrs);
}
} else {
// Note: ordering is important here! Many haptic drivers will reset their
@@ -1118,7 +1150,7 @@ public class VibratorService extends IVibratorService.Stub
Slog.w(TAG, "Failed to play prebaked effect, no fallback");
return 0;
}
- Vibration fallbackVib = new Vibration(vib.token, effect, vib.usageHint, vib.uid,
+ Vibration fallbackVib = new Vibration(vib.token, effect, vib.attrs, vib.uid,
vib.opPkg, vib.reason + " (fallback)");
final int intensity = getCurrentIntensityLocked(fallbackVib);
linkVibration(fallbackVib);
@@ -1213,14 +1245,14 @@ public class VibratorService extends IVibratorService.Stub
private class VibrateThread extends Thread {
private final VibrationEffect.Waveform mWaveform;
private final int mUid;
- private final int mUsageHint;
+ private final AudioAttributes mAttrs;
private boolean mForceStop;
- VibrateThread(VibrationEffect.Waveform waveform, int uid, int usageHint) {
+ VibrateThread(VibrationEffect.Waveform waveform, int uid, AudioAttributes attrs) {
mWaveform = waveform;
mUid = uid;
- mUsageHint = usageHint;
+ mAttrs = attrs;
mTmpWorkSource.set(uid);
mWakeLock.setWorkSource(mTmpWorkSource);
}
@@ -1295,7 +1327,7 @@ public class VibratorService extends IVibratorService.Stub
// appropriate intervals.
onDuration = getTotalOnDuration(timings, amplitudes, index - 1,
repeat);
- doVibratorOn(onDuration, amplitude, mUid, mUsageHint);
+ doVibratorOn(onDuration, amplitude, mUid, mAttrs);
} else {
doVibratorSetAmplitude(amplitude);
}
@@ -1612,8 +1644,9 @@ public class VibratorService extends IVibratorService.Stub
VibrationEffect effect =
VibrationEffect.createOneShot(duration, VibrationEffect.DEFAULT_AMPLITUDE);
- vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
- "Shell Command", mToken);
+ AudioAttributes attrs = createAudioAttributes(commonOptions);
+ vibrate(Binder.getCallingUid(), description, effect, attrs, "Shell Command",
+ mToken);
return 0;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
@@ -1672,8 +1705,9 @@ public class VibratorService extends IVibratorService.Stub
amplitudesList.stream().mapToInt(Integer::intValue).toArray();
effect = VibrationEffect.createWaveform(timings, amplitudes, repeat);
}
- vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
- "Shell Command", mToken);
+ AudioAttributes attrs = createAudioAttributes(commonOptions);
+ vibrate(Binder.getCallingUid(), description, effect, attrs, "Shell Command",
+ mToken);
return 0;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
@@ -1703,14 +1737,25 @@ public class VibratorService extends IVibratorService.Stub
VibrationEffect effect =
VibrationEffect.get(id, false);
- vibrate(Binder.getCallingUid(), description, effect, AudioAttributes.USAGE_UNKNOWN,
- "Shell Command", mToken);
+ AudioAttributes attrs = createAudioAttributes(commonOptions);
+ vibrate(Binder.getCallingUid(), description, effect, attrs, "Shell Command",
+ mToken);
return 0;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_VIBRATOR);
}
}
+ private AudioAttributes createAudioAttributes(CommonOptions commonOptions) {
+ final int flags = commonOptions.force
+ ? AudioAttributes.FLAG_BYPASS_INTERRUPTION_POLICY
+ : 0;
+ return new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_UNKNOWN)
+ .setFlags(flags)
+ .build();
+ }
+
@Override
public void onHelp() {
try (PrintWriter pw = getOutPrintWriter();) {
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index 1046e82de2bc..19ad32e202fe 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -112,6 +112,7 @@ public class Watchdog extends Thread {
"android.hardware.media.c2@1.0::IComponentStore",
"android.hardware.media.omx@1.0::IOmx",
"android.hardware.media.omx@1.0::IOmxStore",
+ "android.hardware.power.stats@1.0::IPowerStats",
"android.hardware.sensors@1.0::ISensors",
"android.hardware.vr@1.0::IVr",
"android.system.suspend@1.0::ISystemSuspend"
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index e2b59b45e1e6..c2f452932775 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -108,7 +108,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
.replaceWith("?");
private ByteBuffer mUtf8BufferStat = ByteBuffer.allocateDirect(MAX_LOW_POWER_STATS_SIZE);
private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE);
- private static final int MAX_LOW_POWER_STATS_SIZE = 2048;
+ private static final int MAX_LOW_POWER_STATS_SIZE = 4096;
/**
* Replaces the information in the given rpmStats with up-to-date information.
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 1b45eb4f00bb..087c84f1a42f 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -375,7 +375,7 @@ public class AttentionManagerService extends SystemService {
private void dumpInternal(IndentingPrintWriter ipw) {
ipw.println("Attention Manager Service (dumpsys attention) state:\n");
-
+ ipw.println("isServiceEnabled=" + isServiceEnabled());
ipw.println("AttentionServicePackageName=" + getServiceConfigPackage(mContext));
ipw.println("Resolved component:");
if (mComponentName != null) {
diff --git a/services/core/java/com/android/server/biometrics/AuthenticationClient.java b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
index b899d028869b..4a9ccdee0522 100644
--- a/services/core/java/com/android/server/biometrics/AuthenticationClient.java
+++ b/services/core/java/com/android/server/biometrics/AuthenticationClient.java
@@ -46,6 +46,7 @@ public abstract class AuthenticationClient extends ClientMonitor {
// authentication while the device is already locked out. In that case, the client is created
// but not started yet. The user shouldn't receive the error haptics in this case.
private boolean mStarted;
+ private long mStartTimeMs;
/**
* This method is called when authentication starts.
@@ -75,6 +76,10 @@ public abstract class AuthenticationClient extends ClientMonitor {
mRequireConfirmation = requireConfirmation;
}
+ protected long getStartTimeMs() {
+ return mStartTimeMs;
+ }
+
@Override
public void binderDied() {
super.binderDied();
@@ -228,6 +233,7 @@ public abstract class AuthenticationClient extends ClientMonitor {
mStarted = true;
onStart();
try {
+ mStartTimeMs = System.currentTimeMillis();
final int result = getDaemonWrapper().authenticate(mOpId, getGroupId());
if (result != 0) {
Slog.w(getLogTag(), "startAuthentication failed, result=" + result);
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index db17f8397ed4..df6f73b914a8 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -170,6 +170,8 @@ public class BiometricService extends SystemService {
// the authentication.
byte[] mTokenEscrow;
+ // Timestamp when authentication started
+ private long mStartTimeMs;
// Timestamp when hardware authentication occurred
private long mAuthenticatedTimeMs;
@@ -766,10 +768,16 @@ public class BiometricService extends SystemService {
}
@Override // Binder call
- public int canAuthenticate(String opPackageName) {
- checkPermission();
+ public int canAuthenticate(String opPackageName, int userId) {
+ Slog.d(TAG, "canAuthenticate: User=" + userId
+ + ", Caller=" + UserHandle.getCallingUserId());
+
+ if (userId != UserHandle.getCallingUserId()) {
+ checkInternalPermission();
+ } else {
+ checkPermission();
+ }
- final int userId = UserHandle.getCallingUserId();
final long ident = Binder.clearCallingIdentity();
int error;
try {
@@ -965,6 +973,11 @@ public class BiometricService extends SystemService {
}
}
+ Slog.d(TAG, "checkAndGetBiometricModality: user=" + userId
+ + " isHardwareDetected=" + isHardwareDetected
+ + " hasTemplatesEnrolled=" + hasTemplatesEnrolled
+ + " enabledForApps=" + enabledForApps);
+
// Check error conditions
if (!isHardwareDetected) {
return new Pair<>(TYPE_NONE, BiometricConstants.BIOMETRIC_ERROR_HW_UNAVAILABLE);
@@ -1065,6 +1078,9 @@ public class BiometricService extends SystemService {
latency,
Utils.isDebugEnabled(getContext(), mCurrentAuthSession.mUserId));
} else {
+
+ final long latency = System.currentTimeMillis() - mCurrentAuthSession.mStartTimeMs;
+
int error = reason == BiometricPrompt.DISMISSED_REASON_NEGATIVE
? BiometricConstants.BIOMETRIC_ERROR_NEGATIVE_BUTTON
: reason == BiometricPrompt.DISMISSED_REASON_USER_CANCEL
@@ -1076,7 +1092,8 @@ public class BiometricService extends SystemService {
+ ", IsCrypto: " + mCurrentAuthSession.isCrypto()
+ ", Action: " + BiometricsProtoEnums.ACTION_AUTHENTICATE
+ ", Client: " + BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT
- + ", Error: " + error);
+ + ", Error: " + error
+ + ", Latency: " + latency);
}
// Auth canceled
StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
@@ -1087,7 +1104,8 @@ public class BiometricService extends SystemService {
BiometricsProtoEnums.CLIENT_BIOMETRIC_PROMPT,
error,
0 /* vendorCode */,
- Utils.isDebugEnabled(getContext(), mCurrentAuthSession.mUserId));
+ Utils.isDebugEnabled(getContext(), mCurrentAuthSession.mUserId),
+ latency);
}
}
@@ -1411,6 +1429,9 @@ public class BiometricService extends SystemService {
&& mCurrentAuthSession.mState == STATE_AUTH_PAUSED;
mCurrentAuthSession = mPendingAuthSession;
+
+ // Time starts when lower layers are ready to start the client.
+ mCurrentAuthSession.mStartTimeMs = System.currentTimeMillis();
mPendingAuthSession = null;
mCurrentAuthSession.mState = STATE_AUTH_STARTED;
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index d3c62bed7b5f..0c4f0bd0edc6 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -713,8 +713,6 @@ public abstract class BiometricServiceBase extends SystemService
// already generated a new authenticator id when the new biometric is enrolled.
if (identifier instanceof Fingerprint) {
updateActiveGroup(((Fingerprint)identifier).getGroupId(), null);
- } else {
- updateActiveGroup(mCurrentUserId, null);
}
}
}
@@ -1090,6 +1088,8 @@ public abstract class BiometricServiceBase extends SystemService
if (DEBUG) Slog.v(getTag(), "starting client "
+ mCurrentClient.getClass().getSuperclass().getSimpleName()
+ "(" + mCurrentClient.getOwnerString() + ")"
+ + " targetUserId: " + mCurrentClient.getTargetUserId()
+ + " currentUserId: " + mCurrentUserId
+ " cookie: " + cookie + "/" + mCurrentClient.getCookie());
if (cookie != mCurrentClient.getCookie()) {
Slog.e(getTag(), "Mismatched cookie");
diff --git a/services/core/java/com/android/server/biometrics/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
index 9c040884772c..6c7cbc166241 100644
--- a/services/core/java/com/android/server/biometrics/LoggableMonitor.java
+++ b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
@@ -33,6 +33,10 @@ public abstract class LoggableMonitor {
private long mFirstAcquireTimeMs;
+ protected long getFirstAcquireTimeMs() {
+ return mFirstAcquireTimeMs;
+ }
+
/**
* Only valid for AuthenticationClient.
* @return true if the client is authenticating for a crypto operation.
@@ -94,6 +98,10 @@ public abstract class LoggableMonitor {
}
protected final void logOnError(Context context, int error, int vendorCode, int targetUserId) {
+
+ final long latency = mFirstAcquireTimeMs != 0
+ ? (System.currentTimeMillis() - mFirstAcquireTimeMs) : -1;
+
if (DEBUG) {
Slog.v(TAG, "Error! Modality: " + statsModality()
+ ", User: " + targetUserId
@@ -101,7 +109,10 @@ public abstract class LoggableMonitor {
+ ", Action: " + statsAction()
+ ", Client: " + statsClient()
+ ", Error: " + error
- + ", VendorCode: " + vendorCode);
+ + ", VendorCode: " + vendorCode
+ + ", Latency: " + latency);
+ } else {
+ Slog.v(TAG, "Error latency: " + latency);
}
StatsLog.write(StatsLog.BIOMETRIC_ERROR_OCCURRED,
statsModality(),
@@ -111,7 +122,8 @@ public abstract class LoggableMonitor {
statsClient(),
error,
vendorCode,
- Utils.isDebugEnabled(context, targetUserId));
+ Utils.isDebugEnabled(context, targetUserId),
+ latency);
}
protected final void logOnAuthenticated(Context context, boolean authenticated,
diff --git a/services/core/java/com/android/server/biometrics/Utils.java b/services/core/java/com/android/server/biometrics/Utils.java
index 5544bede92f2..4fa29ac541f9 100644
--- a/services/core/java/com/android/server/biometrics/Utils.java
+++ b/services/core/java/com/android/server/biometrics/Utils.java
@@ -18,10 +18,15 @@ package com.android.server.biometrics;
import android.content.Context;
import android.os.Build;
+import android.os.UserHandle;
import android.provider.Settings;
public class Utils {
public static boolean isDebugEnabled(Context context, int targetUserId) {
+ if (targetUserId == UserHandle.USER_NULL) {
+ return false;
+ }
+
if (!(Build.IS_ENG || Build.IS_USERDEBUG)) {
return false;
}
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 463a49931ae1..72bac7494804 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -54,7 +54,6 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.Slog;
-import android.util.proto.ProtoOutputStream;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -79,7 +78,9 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
/**
* A service to manage multiple clients that want to access the face HAL API.
@@ -97,6 +98,107 @@ public class FaceService extends BiometricServiceBase {
"com.android.server.biometrics.face.ACTION_LOCKOUT_RESET";
private static final int CHALLENGE_TIMEOUT_SEC = 600; // 10 minutes
+ private static final String NOTIFICATION_TAG = "FaceService";
+ private static final int NOTIFICATION_ID = 1;
+
+ /**
+ * Events for bugreports.
+ */
+ public static final class AuthenticationEvent {
+ private long mStartTime;
+ private long mLatency;
+ // Only valid if mError is 0
+ private boolean mAuthenticated;
+ private int mError;
+ // Only valid if mError is ERROR_VENDOR
+ private int mVendorError;
+
+ AuthenticationEvent(long startTime, long latency, boolean authenticated, int error,
+ int vendorError) {
+ mStartTime = startTime;
+ mLatency = latency;
+ mAuthenticated = authenticated;
+ mError = error;
+ mVendorError = vendorError;
+ }
+
+ public String toString(Context context) {
+ return "Start: " + mStartTime
+ + "\tLatency: " + mLatency
+ + "\tAuthenticated: " + mAuthenticated
+ + "\tError: " + mError
+ + "\tVendorCode: " + mVendorError
+ + "\t" + FaceManager.getErrorString(context, mError, mVendorError);
+ }
+ }
+
+ /**
+ * Keep a short historical buffer of stats, with an aggregated usage time.
+ */
+ private class UsageStats {
+ static final int EVENT_LOG_SIZE = 100;
+
+ Context mContext;
+ List<AuthenticationEvent> mAuthenticationEvents;
+
+ int acceptCount;
+ int rejectCount;
+ Map<Integer, Integer> mErrorCount;
+
+ long acceptLatency;
+ long rejectLatency;
+ Map<Integer, Long> mErrorLatency;
+
+ UsageStats(Context context) {
+ mAuthenticationEvents = new ArrayList<>();
+ mErrorCount = new HashMap<>();
+ mErrorLatency = new HashMap<>();
+ mContext = context;
+ }
+
+ void addEvent(AuthenticationEvent event) {
+ if (mAuthenticationEvents.size() >= EVENT_LOG_SIZE) {
+ mAuthenticationEvents.remove(0);
+ }
+ mAuthenticationEvents.add(event);
+
+ if (event.mAuthenticated) {
+ acceptCount++;
+ acceptLatency += event.mLatency;
+ } else if (event.mError == 0) {
+ rejectCount++;
+ rejectLatency += event.mLatency;
+ } else {
+ mErrorCount.put(event.mError, mErrorCount.getOrDefault(event.mError, 0) + 1);
+ mErrorLatency.put(event.mError,
+ mErrorLatency.getOrDefault(event.mError, 0l) + event.mLatency);
+ }
+ }
+
+ void print(PrintWriter pw) {
+ pw.println("Events since last reboot: " + mAuthenticationEvents.size());
+ for (int i = 0; i < mAuthenticationEvents.size(); i++) {
+ pw.println(mAuthenticationEvents.get(i).toString(mContext));
+ }
+
+ // Dump aggregated usage stats
+ // TODO: Remove or combine with json dump in a future release
+ pw.println("Accept\tCount: " + acceptCount + "\tLatency: " + acceptLatency
+ + "\tAverage: " + (acceptCount > 0 ? acceptLatency / acceptCount : 0));
+ pw.println("Reject\tCount: " + rejectCount + "\tLatency: " + rejectLatency
+ + "\tAverage: " + (rejectCount > 0 ? rejectLatency / rejectCount : 0));
+
+ for (Integer key : mErrorCount.keySet()) {
+ final int count = mErrorCount.get(key);
+ pw.println("Error" + key + "\tCount: " + count
+ + "\tLatency: " + mErrorLatency.getOrDefault(key, 0l)
+ + "\tAverage: " + (count > 0 ? mErrorLatency.getOrDefault(key, 0l) / count
+ : 0)
+ + "\t" + FaceManager.getErrorString(mContext, key, 0 /* vendorCode */));
+ }
+ }
+ }
+
private final class FaceAuthClient extends AuthenticationClientImpl {
private int mLastAcquire;
@@ -128,6 +230,13 @@ public class FaceService extends BiometricServiceBase {
boolean authenticated, ArrayList<Byte> token) {
final boolean result = super.onAuthenticated(identifier, authenticated, token);
+ mUsageStats.addEvent(new AuthenticationEvent(
+ getStartTimeMs(),
+ System.currentTimeMillis() - getStartTimeMs() /* latency */,
+ authenticated,
+ 0 /* error */,
+ 0 /* vendorError */));
+
// For face, the authentication lifecycle ends either when
// 1) Authenticated == true
// 2) Error occurred
@@ -138,6 +247,18 @@ public class FaceService extends BiometricServiceBase {
}
@Override
+ public boolean onError(long deviceId, int error, int vendorCode) {
+ mUsageStats.addEvent(new AuthenticationEvent(
+ getStartTimeMs(),
+ System.currentTimeMillis() - getStartTimeMs() /* latency */,
+ false /* authenticated */,
+ error,
+ vendorCode));
+
+ return super.onError(deviceId, error, vendorCode);
+ }
+
+ @Override
public int[] getAcquireIgnorelist() {
if (isBiometricPrompt()) {
return mBiometricPromptIgnoreList;
@@ -177,13 +298,11 @@ public class FaceService extends BiometricServiceBase {
0 /* requestCode */, intent, 0 /* flags */, null /* options */,
UserHandle.CURRENT);
- final String id = "FaceService";
+ final String channelName = "FaceEnrollNotificationChannel";
- NotificationManager nm =
- getContext().getSystemService(NotificationManager.class);
- NotificationChannel channel = new NotificationChannel(id, name,
+ NotificationChannel channel = new NotificationChannel(channelName, name,
NotificationManager.IMPORTANCE_HIGH);
- Notification notification = new Notification.Builder(getContext(), id)
+ Notification notification = new Notification.Builder(getContext(), channelName)
.setSmallIcon(R.drawable.ic_lock)
.setContentTitle(title)
.setContentText(content)
@@ -193,10 +312,12 @@ public class FaceService extends BiometricServiceBase {
.setAutoCancel(true)
.setCategory(Notification.CATEGORY_SYSTEM)
.setContentIntent(pendingIntent)
+ .setVisibility(Notification.VISIBILITY_SECRET)
.build();
- nm.createNotificationChannel(channel);
- nm.notifyAsUser(null /* tag */, 0 /* id */, notification, UserHandle.CURRENT);
+ mNotificationManager.createNotificationChannel(channel);
+ mNotificationManager.notifyAsUser(NOTIFICATION_TAG, NOTIFICATION_ID, notification,
+ UserHandle.CURRENT);
}
return super.onAcquired(acquireInfo, vendorCode);
@@ -225,10 +346,14 @@ public class FaceService extends BiometricServiceBase {
}
@Override // Binder call
- public void enroll(final IBinder token, final byte[] cryptoToken,
+ public void enroll(int userId, final IBinder token, final byte[] cryptoToken,
final IFaceServiceReceiver receiver, final String opPackageName,
final int[] disabledFeatures) {
checkPermission(MANAGE_BIOMETRIC);
+ updateActiveGroup(userId, opPackageName);
+
+ mNotificationManager.cancelAsUser(NOTIFICATION_TAG, NOTIFICATION_ID,
+ UserHandle.CURRENT);
final boolean restricted = isRestricted();
final EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper,
@@ -324,8 +449,9 @@ public class FaceService extends BiometricServiceBase {
@Override // Binder call
public void remove(final IBinder token, final int faceId, final int userId,
- final IFaceServiceReceiver receiver) {
+ final IFaceServiceReceiver receiver, final String opPackageName) {
checkPermission(MANAGE_BIOMETRIC);
+ updateActiveGroup(userId, opPackageName);
if (token == null) {
Slog.w(TAG, "remove(): token is null");
@@ -378,8 +504,6 @@ public class FaceService extends BiometricServiceBase {
try {
if (args.length > 1 && "--hal".equals(args[0])) {
dumpHal(fd, Arrays.copyOfRange(args, 1, args.length, args.getClass()));
- } else if (args.length > 0 && "--proto".equals(args[0])) {
- dumpProto(fd);
} else {
dumpInternal(pw);
}
@@ -480,6 +604,8 @@ public class FaceService extends BiometricServiceBase {
return;
}
+ Slog.d(TAG, "Resetting lockout for user: " + mCurrentUserId);
+
try {
mDaemonWrapper.resetLockout(token);
} catch (RemoteException e) {
@@ -488,9 +614,10 @@ public class FaceService extends BiometricServiceBase {
}
@Override
- public void setFeature(int feature, boolean enabled, final byte[] token,
- IFaceServiceReceiver receiver) {
+ public void setFeature(int userId, int feature, boolean enabled, final byte[] token,
+ IFaceServiceReceiver receiver, final String opPackageName) {
checkPermission(MANAGE_BIOMETRIC);
+ updateActiveGroup(userId, opPackageName);
mHandler.post(() -> {
if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
@@ -520,8 +647,10 @@ public class FaceService extends BiometricServiceBase {
}
@Override
- public void getFeature(int feature, IFaceServiceReceiver receiver) {
+ public void getFeature(int userId, int feature, IFaceServiceReceiver receiver,
+ final String opPackageName) {
checkPermission(MANAGE_BIOMETRIC);
+ updateActiveGroup(userId, opPackageName);
mHandler.post(() -> {
// This should ideally return tri-state, but the user isn't shown settings unless
@@ -682,9 +811,12 @@ public class FaceService extends BiometricServiceBase {
@GuardedBy("this")
private IBiometricsFace mDaemon;
+ private UsageStats mUsageStats;
// One of the AuthenticationClient constants
private int mCurrentUserLockoutMode;
+ private NotificationManager mNotificationManager;
+
private int[] mBiometricPromptIgnoreList;
private int[] mBiometricPromptIgnoreListVendor;
private int[] mKeyguardIgnoreList;
@@ -704,6 +836,18 @@ public class FaceService extends BiometricServiceBase {
final Face face = new Face(getBiometricUtils()
.getUniqueName(getContext(), userId), faceId, deviceId);
FaceService.super.handleEnrollResult(face, remaining);
+
+ // Enrollment changes the authenticatorId, so update it here.
+ IBiometricsFace daemon = getFaceDaemon();
+ if (remaining == 0 && daemon != null) {
+ try {
+ mAuthenticatorIds.put(userId,
+ hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value
+ : 0L);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Unable to get authenticatorId", e);
+ }
+ }
});
}
@@ -878,6 +1022,10 @@ public class FaceService extends BiometricServiceBase {
public FaceService(Context context) {
super(context);
+ mUsageStats = new UsageStats(context);
+
+ mNotificationManager = getContext().getSystemService(NotificationManager.class);
+
mBiometricPromptIgnoreList = getContext().getResources()
.getIntArray(R.array.config_face_acquire_biometricprompt_ignorelist);
mBiometricPromptIgnoreListVendor = getContext().getResources()
@@ -896,7 +1044,10 @@ public class FaceService extends BiometricServiceBase {
public void onStart() {
super.onStart();
publishBinderService(Context.FACE_SERVICE, new FaceServiceWrapper());
- SystemServerInitThreadPool.get().submit(this::getFaceDaemon, TAG + ".onStart");
+ // Get the face daemon on FaceService's on thread so SystemServerInitThreadPool isn't
+ // blocked
+ SystemServerInitThreadPool.get().submit(() -> mHandler.post(this::getFaceDaemon),
+ TAG + ".onStart");
}
@Override
@@ -965,9 +1116,9 @@ public class FaceService extends BiometricServiceBase {
daemon.setActiveUser(userId, faceDir.getAbsolutePath());
mCurrentUserId = userId;
+ mAuthenticatorIds.put(userId,
+ hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value : 0L);
}
- mAuthenticatorIds.put(userId,
- hasEnrolledBiometrics(userId) ? daemon.getAuthenticatorId().value : 0L);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to setActiveUser():", e);
}
@@ -1142,51 +1293,9 @@ public class FaceService extends BiometricServiceBase {
Slog.e(TAG, "dump formatting failure", e);
}
pw.println(dump);
- pw.println("HAL Deaths: " + mHALDeathCount);
- mHALDeathCount = 0;
- }
-
- private void dumpProto(FileDescriptor fd) {
- final ProtoOutputStream proto = new ProtoOutputStream(fd);
- for (UserInfo user : UserManager.get(getContext()).getUsers()) {
- final int userId = user.getUserHandle().getIdentifier();
-
- final long userToken = proto.start(FaceServiceDumpProto.USERS);
-
- proto.write(FaceUserStatsProto.USER_ID, userId);
- proto.write(FaceUserStatsProto.NUM_FACES,
- getBiometricUtils().getBiometricsForUser(getContext(), userId).size());
-
- // Normal face authentications (e.g. lockscreen)
- final PerformanceStats normal = mPerformanceMap.get(userId);
- if (normal != null) {
- final long countsToken = proto.start(FaceUserStatsProto.NORMAL);
- proto.write(FaceActionStatsProto.ACCEPT, normal.accept);
- proto.write(FaceActionStatsProto.REJECT, normal.reject);
- proto.write(FaceActionStatsProto.ACQUIRE, normal.acquire);
- proto.write(FaceActionStatsProto.LOCKOUT, normal.lockout);
- proto.write(FaceActionStatsProto.LOCKOUT_PERMANENT, normal.lockout);
- proto.end(countsToken);
- }
+ pw.println("HAL deaths since last reboot: " + mHALDeathCount);
- // Statistics about secure face transactions (e.g. to unlock password
- // storage, make secure purchases, etc.)
- final PerformanceStats crypto = mCryptoPerformanceMap.get(userId);
- if (crypto != null) {
- final long countsToken = proto.start(FaceUserStatsProto.CRYPTO);
- proto.write(FaceActionStatsProto.ACCEPT, crypto.accept);
- proto.write(FaceActionStatsProto.REJECT, crypto.reject);
- proto.write(FaceActionStatsProto.ACQUIRE, crypto.acquire);
- proto.write(FaceActionStatsProto.LOCKOUT, crypto.lockout);
- proto.write(FaceActionStatsProto.LOCKOUT_PERMANENT, crypto.lockout);
- proto.end(countsToken);
- }
-
- proto.end(userToken);
- }
- proto.flush();
- mPerformanceMap.clear();
- mCryptoPerformanceMap.clear();
+ mUsageStats.print(pw);
}
private void dumpHal(FileDescriptor fd, String[] args) {
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index 24fd1b7a6daf..28336f459863 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -1035,8 +1035,7 @@ public class FingerprintService extends BiometricServiceBase {
Slog.e(TAG, "dump formatting failure", e);
}
pw.println(dump);
- pw.println("HAL Deaths: " + mHALDeathCount);
- mHALDeathCount = 0;
+ pw.println("HAL deaths since last reboot: " + mHALDeathCount);
}
private void dumpProto(FileDescriptor fd) {
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 0940a2e4b3cd..14bd2d8150da 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -402,17 +402,18 @@ public class DisplayModeDirector {
}
private static final class Vote {
- public static final int PRIORITY_USER_SETTING = 0;
// We split the app request into two priorities in case we can satisfy one desire without
// the other.
- public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 1;
- public static final int PRIORITY_APP_REQUEST_SIZE = 2;
- public static final int PRIORITY_LOW_POWER_MODE = 3;
+ public static final int PRIORITY_APP_REQUEST_REFRESH_RATE = 0;
+ public static final int PRIORITY_APP_REQUEST_SIZE = 1;
+ public static final int PRIORITY_USER_SETTING_REFRESH_RATE = 2;
+ public static final int PRIORITY_LOW_BRIGHTNESS = 3;
+ public static final int PRIORITY_LOW_POWER_MODE = 4;
// Whenever a new priority is added, remember to update MIN_PRIORITY and/or MAX_PRIORITY as
// appropriate, as well as priorityToString.
- public static final int MIN_PRIORITY = PRIORITY_USER_SETTING;
+ public static final int MIN_PRIORITY = PRIORITY_APP_REQUEST_REFRESH_RATE;
public static final int MAX_PRIORITY = PRIORITY_LOW_POWER_MODE;
/**
@@ -456,12 +457,12 @@ public class DisplayModeDirector {
public static String priorityToString(int priority) {
switch (priority) {
- case PRIORITY_USER_SETTING:
- return "PRIORITY_USER_SETTING";
case PRIORITY_APP_REQUEST_REFRESH_RATE:
return "PRIORITY_APP_REQUEST_REFRESH_RATE";
case PRIORITY_APP_REQUEST_SIZE:
return "PRIORITY_APP_REQUEST_SIZE";
+ case PRIORITY_USER_SETTING_REFRESH_RATE:
+ return "PRIORITY_USER_SETTING_REFRESH_RATE";
case PRIORITY_LOW_POWER_MODE:
return "PRIORITY_LOW_POWER_MODE";
default:
@@ -485,15 +486,20 @@ public class DisplayModeDirector {
Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
private final Uri mLowPowerModeSetting =
Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE);
+ private final Uri mBrightnessSetting =
+ Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
private final Context mContext;
private final float mDefaultPeakRefreshRate;
+ private final int mBrightnessThreshold;
SettingsObserver(@NonNull Context context, @NonNull Handler handler) {
super(handler);
mContext = context;
mDefaultPeakRefreshRate = (float) context.getResources().getInteger(
R.integer.config_defaultPeakRefreshRate);
+ mBrightnessThreshold = context.getResources().getInteger(
+ R.integer.config_brightnessThresholdOfPeakRefreshRate);
}
public void observe() {
@@ -502,9 +508,14 @@ public class DisplayModeDirector {
UserHandle.USER_SYSTEM);
cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
UserHandle.USER_SYSTEM);
+ if (mBrightnessThreshold >= 0) {
+ cr.registerContentObserver(mBrightnessSetting, false /*notifyDescendants*/, this,
+ UserHandle.USER_SYSTEM);
+ }
synchronized (mLock) {
updateRefreshRateSettingLocked();
updateLowPowerModeSettingLocked();
+ updateBrightnessSettingLocked();
}
}
@@ -515,6 +526,8 @@ public class DisplayModeDirector {
updateRefreshRateSettingLocked();
} else if (mLowPowerModeSetting.equals(uri)) {
updateLowPowerModeSettingLocked();
+ } else if (mBrightnessThreshold >=0 && mBrightnessSetting.equals(uri)) {
+ updateBrightnessSettingLocked();
}
}
}
@@ -535,7 +548,24 @@ public class DisplayModeDirector {
float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
Vote vote = Vote.forRefreshRates(0f, peakRefreshRate);
- updateVoteLocked(Vote.PRIORITY_USER_SETTING, vote);
+ updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote);
+ }
+
+ private void updateBrightnessSettingLocked() {
+ int brightness = Settings.System.getInt(mContext.getContentResolver(),
+ Settings.System.SCREEN_BRIGHTNESS, -1);
+
+ if (brightness < 0) {
+ return;
+ }
+
+ final Vote vote;
+ if (brightness <= mBrightnessThreshold) {
+ vote = Vote.forRefreshRates(0f, 60f);
+ } else {
+ vote = null;
+ }
+ updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, vote);
}
public void dumpLocked(PrintWriter pw) {
diff --git a/services/core/java/com/android/server/display/LocalDisplayAdapter.java b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
index 85fbdf6d0182..b03dc3b2ae93 100644
--- a/services/core/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/core/java/com/android/server/display/LocalDisplayAdapter.java
@@ -856,7 +856,7 @@ final class LocalDisplayAdapter extends DisplayAdapter {
private final class PhysicalDisplayEventReceiver extends DisplayEventReceiver {
PhysicalDisplayEventReceiver(Looper looper) {
- super(looper, VSYNC_SOURCE_APP);
+ super(looper, VSYNC_SOURCE_APP, CONFIG_CHANGED_EVENT_DISPATCH);
}
@Override
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 64a9e0074cb1..2e5aafe0da72 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -226,7 +226,7 @@ public final class ColorDisplayService extends SystemService {
}
}
- private void onUserChanged(int userHandle) {
+ @VisibleForTesting void onUserChanged(int userHandle) {
final ContentResolver cr = getContext().getContentResolver();
if (mCurrentUser != UserHandle.USER_NULL) {
@@ -465,12 +465,16 @@ public final class ColorDisplayService extends SystemService {
.setMatrix(mNightDisplayTintController.getColorTemperatureSetting());
}
+ // dtm.setColorMode() needs to be called before
+ // updateDisplayWhiteBalanceStatus(), this is because the latter calls
+ // DisplayTransformManager.needsLinearColorMatrix(), therefore it is dependent
+ // on the state of DisplayTransformManager.
+ final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
+ dtm.setColorMode(mode, mNightDisplayTintController.getMatrix());
+
if (mDisplayWhiteBalanceTintController.isAvailable(getContext())) {
updateDisplayWhiteBalanceStatus();
}
-
- final DisplayTransformManager dtm = getLocalService(DisplayTransformManager.class);
- dtm.setColorMode(mode, mNightDisplayTintController.getMatrix());
}
private void onAccessibilityActivated() {
@@ -931,7 +935,7 @@ public final class ColorDisplayService extends SystemService {
if (mNightDisplayTintController.isActivatedStateNotSet()
|| (mNightDisplayTintController.isActivated() != activate)) {
- mNightDisplayTintController.setActivated(activate);
+ mNightDisplayTintController.setActivated(activate, activate ? start : end);
}
updateNextAlarm(mNightDisplayTintController.isActivated(), now);
@@ -1127,6 +1131,14 @@ public final class ColorDisplayService extends SystemService {
@Override
public void setActivated(Boolean activated) {
+ setActivated(activated, LocalDateTime.now());
+ }
+
+ /**
+ * Use directly when it is important that the last activation time be exact (for example, an
+ * automatic change). Otherwise use {@link #setActivated(Boolean)}.
+ */
+ public void setActivated(Boolean activated, @NonNull LocalDateTime lastActivationTime) {
if (activated == null) {
super.setActivated(null);
return;
@@ -1138,7 +1150,7 @@ public final class ColorDisplayService extends SystemService {
// This is a true state change, so set this as the last activation time.
Secure.putStringForUser(getContext().getContentResolver(),
Secure.NIGHT_DISPLAY_LAST_ACTIVATED_TIME,
- LocalDateTime.now().toString(),
+ lastActivationTime.toString(),
mCurrentUser);
}
diff --git a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
index 532bbed9588e..123cd73a3ff3 100644
--- a/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
+++ b/services/core/java/com/android/server/display/whitebalance/AmbientFilter.java
@@ -18,6 +18,7 @@ package com.android.server.display.whitebalance;
import android.util.Slog;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.display.utils.RollingBuffer;
import java.io.PrintWriter;
@@ -155,7 +156,8 @@ abstract class AmbientFilter {
/**
* A weighted average prioritising recent changes.
*/
- static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
+ @VisibleForTesting
+ public static class WeightedMovingAverageAmbientFilter extends AmbientFilter {
// How long the latest ambient value change is predicted to last.
private static final int PREDICTION_TIME = 100; // Milliseconds
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
index 0f86b478468f..02ec10e2d49d 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceController.java
@@ -20,6 +20,7 @@ import android.annotation.NonNull;
import android.util.Slog;
import android.util.Spline;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import com.android.server.LocalServices;
import com.android.server.display.color.ColorDisplayService.ColorDisplayServiceInternal;
@@ -53,18 +54,22 @@ public class DisplayWhiteBalanceController implements
private Callbacks mCallbacks;
private AmbientSensor.AmbientBrightnessSensor mBrightnessSensor;
- private AmbientFilter mBrightnessFilter;
+
+ @VisibleForTesting
+ AmbientFilter mBrightnessFilter;
private AmbientSensor.AmbientColorTemperatureSensor mColorTemperatureSensor;
- private AmbientFilter mColorTemperatureFilter;
+
+ @VisibleForTesting
+ AmbientFilter mColorTemperatureFilter;
private DisplayWhiteBalanceThrottler mThrottler;
- // When the brightness drops below a certain threshold, it affects the color temperature
- // accuracy, so we fall back to a fixed ambient color temperature.
- private final float mLowLightAmbientBrightnessThreshold;
private final float mLowLightAmbientColorTemperature;
+ private final float mHighLightAmbientColorTemperature;
private float mAmbientColorTemperature;
- private float mPendingAmbientColorTemperature;
+
+ @VisibleForTesting
+ float mPendingAmbientColorTemperature;
private float mLastAmbientColorTemperature;
private ColorDisplayServiceInternal mColorDisplayServiceInternal;
@@ -79,6 +84,17 @@ public class DisplayWhiteBalanceController implements
// A piecewise linear relationship between ambient and display color temperatures.
private Spline.LinearSpline mAmbientToDisplayColorTemperatureSpline;
+ // In very low or very high brightness conditions ambient EQ should to set to a default
+ // instead of using mAmbientToDisplayColorTemperatureSpline. However, setting ambient EQ
+ // based on thresholds can cause the display to rapidly change color temperature. To solve
+ // this, mLowLightAmbientBrightnessToBiasSpline and mHighLightAmbientBrightnessToBiasSpline
+ // are used to smoothly interpolate from ambient color temperature to the defaults.
+ // A piecewise linear relationship between low light brightness and low light bias.
+ private Spline.LinearSpline mLowLightAmbientBrightnessToBiasSpline;
+
+ // A piecewise linear relationship between high light brightness and high light bias.
+ private Spline.LinearSpline mHighLightAmbientBrightnessToBiasSpline;
+
/**
* @param brightnessSensor
* The sensor used to detect changes in the ambient brightness.
@@ -93,12 +109,22 @@ public class DisplayWhiteBalanceController implements
* @param throttler
* The throttler used to determine whether the new display color temperature should be
* updated or not.
- * @param lowLightAmbientBrightnessThreshold
- * The ambient brightness threshold beneath which we fall back to a fixed ambient color
- * temperature.
+ * @param lowLightAmbientBrightnesses
+ * The ambient brightness used to map the ambient brightnesses to the biases used to
+ * interpolate to lowLightAmbientColorTemperature.
+ * @param lowLightAmbientBiases
+ * The biases used to map the ambient brightnesses to the biases used to interpolate to
+ * lowLightAmbientColorTemperature.
* @param lowLightAmbientColorTemperature
- * The ambient color temperature to which we fall back when the ambient brightness drops
- * beneath a certain threshold.
+ * The ambient color temperature to which we interpolate to based on the low light curve.
+ * @param highLightAmbientBrightnesses
+ * The ambient brightness used to map the ambient brightnesses to the biases used to
+ * interpolate to highLightAmbientColorTemperature.
+ * @param highLightAmbientBiases
+ * The biases used to map the ambient brightnesses to the biases used to interpolate to
+ * highLightAmbientColorTemperature.
+ * @param highLightAmbientColorTemperature
+ * The ambient color temperature to which we interpolate to based on the high light curve.
* @param ambientColorTemperatures
* The ambient color tempeartures used to map the ambient color temperature to the display
* color temperature (or null if no mapping is necessary).
@@ -119,7 +145,10 @@ public class DisplayWhiteBalanceController implements
@NonNull AmbientSensor.AmbientColorTemperatureSensor colorTemperatureSensor,
@NonNull AmbientFilter colorTemperatureFilter,
@NonNull DisplayWhiteBalanceThrottler throttler,
- float lowLightAmbientBrightnessThreshold, float lowLightAmbientColorTemperature,
+ float[] lowLightAmbientBrightnesses, float[] lowLightAmbientBiases,
+ float lowLightAmbientColorTemperature,
+ float[] highLightAmbientBrightnesses, float[] highLightAmbientBiases,
+ float highLightAmbientColorTemperature,
float[] ambientColorTemperatures, float[] displayColorTemperatures) {
validateArguments(brightnessSensor, brightnessFilter, colorTemperatureSensor,
colorTemperatureFilter, throttler);
@@ -131,8 +160,8 @@ public class DisplayWhiteBalanceController implements
mColorTemperatureSensor = colorTemperatureSensor;
mColorTemperatureFilter = colorTemperatureFilter;
mThrottler = throttler;
- mLowLightAmbientBrightnessThreshold = lowLightAmbientBrightnessThreshold;
mLowLightAmbientColorTemperature = lowLightAmbientColorTemperature;
+ mHighLightAmbientColorTemperature = highLightAmbientColorTemperature;
mAmbientColorTemperature = -1.0f;
mPendingAmbientColorTemperature = -1.0f;
mLastAmbientColorTemperature = -1.0f;
@@ -140,9 +169,55 @@ public class DisplayWhiteBalanceController implements
mAmbientColorTemperatureOverride = -1.0f;
try {
+ mLowLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline(
+ lowLightAmbientBrightnesses, lowLightAmbientBiases);
+ } catch (Exception e) {
+ Slog.e(TAG, "failed to create low light ambient brightness to bias spline.", e);
+ mLowLightAmbientBrightnessToBiasSpline = null;
+ }
+ if (mLowLightAmbientBrightnessToBiasSpline != null) {
+ if (mLowLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f ||
+ mLowLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY)
+ != 1.0f) {
+ Slog.d(TAG, "invalid low light ambient brightness to bias spline, "
+ + "bias must begin at 0.0 and end at 1.0.");
+ mLowLightAmbientBrightnessToBiasSpline = null;
+ }
+ }
+
+ try {
+ mHighLightAmbientBrightnessToBiasSpline = new Spline.LinearSpline(
+ highLightAmbientBrightnesses, highLightAmbientBiases);
+ } catch (Exception e) {
+ Slog.e(TAG, "failed to create high light ambient brightness to bias spline.", e);
+ mHighLightAmbientBrightnessToBiasSpline = null;
+ }
+ if (mHighLightAmbientBrightnessToBiasSpline != null) {
+ if (mHighLightAmbientBrightnessToBiasSpline.interpolate(0.0f) != 0.0f ||
+ mHighLightAmbientBrightnessToBiasSpline.interpolate(Float.POSITIVE_INFINITY)
+ != 1.0f) {
+ Slog.d(TAG, "invalid high light ambient brightness to bias spline, "
+ + "bias must begin at 0.0 and end at 1.0.");
+ mHighLightAmbientBrightnessToBiasSpline = null;
+ }
+ }
+
+ if (mLowLightAmbientBrightnessToBiasSpline != null &&
+ mHighLightAmbientBrightnessToBiasSpline != null) {
+ if (lowLightAmbientBrightnesses[lowLightAmbientBrightnesses.length - 1] >
+ highLightAmbientBrightnesses[0]) {
+ Slog.d(TAG, "invalid low light and high light ambient brightness to bias spline "
+ + "combination, defined domains must not intersect.");
+ mLowLightAmbientBrightnessToBiasSpline = null;
+ mHighLightAmbientBrightnessToBiasSpline = null;
+ }
+ }
+
+ try {
mAmbientToDisplayColorTemperatureSpline = new Spline.LinearSpline(
ambientColorTemperatures, displayColorTemperatures);
} catch (Exception e) {
+ Slog.e(TAG, "failed to create ambient to display color temperature spline.", e);
mAmbientToDisplayColorTemperatureSpline = null;
}
@@ -238,9 +313,8 @@ public class DisplayWhiteBalanceController implements
mColorTemperatureSensor.dump(writer);
mColorTemperatureFilter.dump(writer);
mThrottler.dump(writer);
- writer.println(" mLowLightAmbientBrightnessThreshold="
- + mLowLightAmbientBrightnessThreshold);
writer.println(" mLowLightAmbientColorTemperature=" + mLowLightAmbientColorTemperature);
+ writer.println(" mHighLightAmbientColorTemperature=" + mHighLightAmbientColorTemperature);
writer.println(" mAmbientColorTemperature=" + mAmbientColorTemperature);
writer.println(" mPendingAmbientColorTemperature=" + mPendingAmbientColorTemperature);
writer.println(" mLastAmbientColorTemperature=" + mLastAmbientColorTemperature);
@@ -248,6 +322,10 @@ public class DisplayWhiteBalanceController implements
writer.println(" mAmbientColorTemperatureOverride=" + mAmbientColorTemperatureOverride);
writer.println(" mAmbientToDisplayColorTemperatureSpline="
+ mAmbientToDisplayColorTemperatureSpline);
+ writer.println(" mLowLightAmbientBrightnessToBiasSpline="
+ + mLowLightAmbientBrightnessToBiasSpline);
+ writer.println(" mHighLightAmbientBrightnessToBiasSpline="
+ + mHighLightAmbientBrightnessToBiasSpline);
}
@Override // AmbientSensor.AmbientBrightnessSensor.Callbacks
@@ -276,15 +354,21 @@ public class DisplayWhiteBalanceController implements
mAmbientToDisplayColorTemperatureSpline.interpolate(ambientColorTemperature);
}
- final float ambientBrightness = mBrightnessFilter.getEstimate(time);
- if (ambientBrightness < mLowLightAmbientBrightnessThreshold) {
- if (mLoggingEnabled) {
- Slog.d(TAG, "low light ambient brightness: " + ambientBrightness + " < "
- + mLowLightAmbientBrightnessThreshold
- + ", falling back to fixed ambient color temperature: "
- + ambientColorTemperature + " => " + mLowLightAmbientColorTemperature);
- }
- ambientColorTemperature = mLowLightAmbientColorTemperature;
+ float ambientBrightness = mBrightnessFilter.getEstimate(time);
+
+ if (ambientColorTemperature != -1.0f &&
+ mLowLightAmbientBrightnessToBiasSpline != null) {
+ float bias = mLowLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness);
+ ambientColorTemperature =
+ bias * ambientColorTemperature + (1.0f - bias)
+ * mLowLightAmbientColorTemperature;
+ }
+ if (ambientColorTemperature != -1.0f &&
+ mHighLightAmbientBrightnessToBiasSpline != null) {
+ float bias = mHighLightAmbientBrightnessToBiasSpline.interpolate(ambientBrightness);
+ ambientColorTemperature =
+ (1.0f - bias) * ambientColorTemperature + bias
+ * mHighLightAmbientColorTemperature;
}
if (mAmbientColorTemperatureOverride != -1.0f) {
diff --git a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
index 6ff2b09988e6..4df7d6b14f25 100644
--- a/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
+++ b/services/core/java/com/android/server/display/whitebalance/DisplayWhiteBalanceFactory.java
@@ -63,19 +63,34 @@ public class DisplayWhiteBalanceFactory {
createColorTemperatureSensor(handler, sensorManager, resources);
final AmbientFilter colorTemperatureFilter = createColorTemperatureFilter(resources);
final DisplayWhiteBalanceThrottler throttler = createThrottler(resources);
- final float lowLightAmbientBrightnessThreshold = getFloat(resources,
- com.android.internal.R.dimen
- .config_displayWhiteBalanceLowLightAmbientBrightnessThreshold);
+ final float[] displayWhiteBalanceLowLightAmbientBrightnesses = getFloatArray(resources,
+ com.android.internal.R.array
+ .config_displayWhiteBalanceLowLightAmbientBrightnesses);
+ final float[] displayWhiteBalanceLowLightAmbientBiases = getFloatArray(resources,
+ com.android.internal.R.array
+ .config_displayWhiteBalanceLowLightAmbientBiases);
final float lowLightAmbientColorTemperature = getFloat(resources,
com.android.internal.R.dimen
.config_displayWhiteBalanceLowLightAmbientColorTemperature);
+ final float[] displayWhiteBalanceHighLightAmbientBrightnesses = getFloatArray(resources,
+ com.android.internal.R.array
+ .config_displayWhiteBalanceHighLightAmbientBrightnesses);
+ final float[] displayWhiteBalanceHighLightAmbientBiases = getFloatArray(resources,
+ com.android.internal.R.array
+ .config_displayWhiteBalanceHighLightAmbientBiases);
+ final float highLightAmbientColorTemperature = getFloat(resources,
+ com.android.internal.R.dimen
+ .config_displayWhiteBalanceHighLightAmbientColorTemperature);
final float[] ambientColorTemperatures = getFloatArray(resources,
com.android.internal.R.array.config_displayWhiteBalanceAmbientColorTemperatures);
final float[] displayColorTempeartures = getFloatArray(resources,
com.android.internal.R.array.config_displayWhiteBalanceDisplayColorTemperatures);
final DisplayWhiteBalanceController controller = new DisplayWhiteBalanceController(
brightnessSensor, brightnessFilter, colorTemperatureSensor, colorTemperatureFilter,
- throttler, lowLightAmbientBrightnessThreshold, lowLightAmbientColorTemperature,
+ throttler, displayWhiteBalanceLowLightAmbientBrightnesses,
+ displayWhiteBalanceLowLightAmbientBiases, lowLightAmbientColorTemperature,
+ displayWhiteBalanceHighLightAmbientBrightnesses,
+ displayWhiteBalanceHighLightAmbientBiases, highLightAmbientColorTemperature,
ambientColorTemperatures, displayColorTempeartures);
brightnessSensor.setCallbacks(controller);
colorTemperatureSensor.setCallbacks(controller);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 107e1fbbf760..433ce811c8d7 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -32,6 +32,7 @@ import static com.android.internal.widget.LockPatternUtils.USER_FRP;
import static com.android.internal.widget.LockPatternUtils.frpCredentialEnabled;
import static com.android.internal.widget.LockPatternUtils.userOwnsFrpCredential;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -169,6 +170,20 @@ public class LockSettingsService extends ILockSettings.Stub {
private static final String SEPARATE_PROFILE_CHALLENGE_KEY = "lockscreen.profilechallenge";
private static final int SYNTHETIC_PASSWORD_ENABLED_BY_DEFAULT = 1;
+ // No challenge provided
+ private static final int CHALLENGE_NONE = 0;
+ // Challenge was provided from the external caller (non-LockSettingsService)
+ private static final int CHALLENGE_FROM_CALLER = 1;
+ // Challenge was generated from within LockSettingsService, for resetLockout. When challenge
+ // type is set to internal, LSS will revokeChallenge after all profiles for that user are
+ // unlocked.
+ private static final int CHALLENGE_INTERNAL = 2;
+
+ @IntDef({CHALLENGE_NONE,
+ CHALLENGE_FROM_CALLER,
+ CHALLENGE_INTERNAL})
+ @interface ChallengeType {};
+
// Order of holding lock: mSeparateChallengeLock -> mSpManager -> this
// Do not call into ActivityManager while holding mSpManager lock.
private final Object mSeparateChallengeLock = new Object();
@@ -276,6 +291,15 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+ private class PendingResetLockout {
+ final int mUserId;
+ final byte[] mHAT;
+ PendingResetLockout(int userId, byte[] hat) {
+ mUserId = userId;
+ mHAT = hat;
+ }
+ }
+
/**
* Tie managed profile to primary profile if it is in unified mode and not tied before.
*
@@ -420,9 +444,9 @@ public class LockSettingsService extends ILockSettings.Stub {
new PasswordSlotManager());
}
- public boolean hasEnrolledBiometrics() {
+ public boolean hasEnrolledBiometrics(int userId) {
BiometricManager bm = mContext.getSystemService(BiometricManager.class);
- return bm.canAuthenticate() == BiometricManager.BIOMETRIC_SUCCESS;
+ return bm.canAuthenticate(userId) == BiometricManager.BIOMETRIC_SUCCESS;
}
public int binderGetCallingUid() {
@@ -584,7 +608,8 @@ public class LockSettingsService extends ILockSettings.Stub {
// If boot took too long and the password in vold got expired, parent keystore will
// be still locked, we ignore this case since the user will be prompted to unlock
// the device after boot.
- unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */);
+ unlockChildProfile(userId, true /* ignoreUserNotAuthenticated */,
+ CHALLENGE_NONE, 0 /* challenge */, null /* resetLockouts */);
} catch (RemoteException e) {
Slog.e(TAG, "Failed to unlock child profile");
}
@@ -1160,12 +1185,15 @@ public class LockSettingsService extends ILockSettings.Stub {
return decryptionResult;
}
- private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated)
+ private void unlockChildProfile(int profileHandle, boolean ignoreUserNotAuthenticated,
+ @ChallengeType int challengeType, long challenge,
+ @Nullable ArrayList<PendingResetLockout> resetLockouts)
throws RemoteException {
try {
doVerifyCredential(getDecryptedPasswordForTiedProfile(profileHandle),
CREDENTIAL_TYPE_PASSWORD,
- false, 0 /* no challenge */, profileHandle, null /* progressCallback */);
+ challengeType, challenge, profileHandle, null /* progressCallback */,
+ resetLockouts);
} catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
| NoSuchAlgorithmException | NoSuchPaddingException
| InvalidAlgorithmParameterException | IllegalBlockSizeException
@@ -1180,6 +1208,10 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+ private void unlockUser(int userId, byte[] token, byte[] secret) {
+ unlockUser(userId, token, secret, CHALLENGE_NONE, 0 /* challenge */, null);
+ }
+
/**
* Unlock the user (both storage and user state) and its associated managed profiles
* synchronously.
@@ -1188,7 +1220,9 @@ public class LockSettingsService extends ILockSettings.Stub {
* can end up calling into other system services to process user unlock request (via
* {@link com.android.server.SystemServiceManager#unlockUser} </em>
*/
- private void unlockUser(int userId, byte[] token, byte[] secret) {
+ private void unlockUser(int userId, byte[] token, byte[] secret,
+ @ChallengeType int challengeType, long challenge,
+ @Nullable ArrayList<PendingResetLockout> resetLockouts) {
// TODO: make this method fully async so we can update UI with progress strings
final boolean alreadyUnlocked = mUserManager.isUserUnlockingOrUnlocked(userId);
final CountDownLatch latch = new CountDownLatch(1);
@@ -1230,7 +1264,10 @@ public class LockSettingsService extends ILockSettings.Stub {
// Unlock managed profile with unified lock
if (tiedManagedProfileReadyToUnlock(profile)) {
try {
- unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */);
+ // Must pass the challenge on for resetLockout, so it's not over-written, which
+ // causes LockSettingsService to revokeChallenge inappropriately.
+ unlockChildProfile(profile.id, false /* ignoreUserNotAuthenticated */,
+ challengeType, challenge, resetLockouts);
} catch (RemoteException e) {
Log.d(TAG, "Failed to unlock child profile", e);
}
@@ -1247,6 +1284,21 @@ public class LockSettingsService extends ILockSettings.Stub {
}
}
+
+ if (resetLockouts != null && !resetLockouts.isEmpty()) {
+ mHandler.post(() -> {
+ final BiometricManager bm = mContext.getSystemService(BiometricManager.class);
+ final PackageManager pm = mContext.getPackageManager();
+ for (int i = 0; i < resetLockouts.size(); i++) {
+ bm.setActiveUser(resetLockouts.get(i).mUserId);
+ bm.resetLockout(resetLockouts.get(i).mHAT);
+ }
+ if (challengeType == CHALLENGE_INTERNAL
+ && pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ mContext.getSystemService(FaceManager.class).revokeChallenge();
+ }
+ });
+ }
}
private boolean tiedManagedProfileReadyToUnlock(UserInfo userInfo) {
@@ -1518,7 +1570,8 @@ public class LockSettingsService extends ILockSettings.Stub {
setUserKeyProtection(userId, credential, convertResponse(gkResponse));
fixateNewestUserKeyAuth(userId);
// Refresh the auth token
- doVerifyCredential(credential, credentialType, true, 0, userId, null /* progressCallback */);
+ doVerifyCredential(credential, credentialType, CHALLENGE_FROM_CALLER, 0, userId,
+ null /* progressCallback */);
synchronizeUnifiedWorkChallengeForProfiles(userId, null);
sendCredentialsOnChangeIfRequired(
credentialType, credential, userId, isLockTiedToParent);
@@ -1743,24 +1796,32 @@ public class LockSettingsService extends ILockSettings.Stub {
public VerifyCredentialResponse checkCredential(byte[] credential, int type, int userId,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
checkPasswordReadPermission(userId);
- return doVerifyCredential(credential, type, false, 0, userId, progressCallback);
+ return doVerifyCredential(credential, type, CHALLENGE_NONE, 0, userId, progressCallback);
}
@Override
public VerifyCredentialResponse verifyCredential(byte[] credential, int type, long challenge,
int userId) throws RemoteException {
checkPasswordReadPermission(userId);
- return doVerifyCredential(credential, type, true, challenge, userId,
+ return doVerifyCredential(credential, type, CHALLENGE_FROM_CALLER, challenge, userId,
null /* progressCallback */);
}
+ private VerifyCredentialResponse doVerifyCredential(byte[] credential, int credentialType,
+ @ChallengeType int challengeType, long challenge, int userId,
+ ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+ return doVerifyCredential(credential, credentialType, challengeType, challenge, userId,
+ progressCallback, null /* resetLockouts */);
+ }
+
/**
* Verify user credential and unlock the user. Fix pattern bug by deprecating the old base zero
* format.
*/
private VerifyCredentialResponse doVerifyCredential(byte[] credential, int credentialType,
- boolean hasChallenge, long challenge, int userId,
- ICheckCredentialProgressCallback progressCallback) throws RemoteException {
+ @ChallengeType int challengeType, long challenge, int userId,
+ ICheckCredentialProgressCallback progressCallback,
+ @Nullable ArrayList<PendingResetLockout> resetLockouts) throws RemoteException {
if (credential == null || credential.length == 0) {
throw new IllegalArgumentException("Credential can't be null or empty");
}
@@ -1770,8 +1831,8 @@ public class LockSettingsService extends ILockSettings.Stub {
return VerifyCredentialResponse.ERROR;
}
VerifyCredentialResponse response = null;
- response = spBasedDoVerifyCredential(credential, credentialType, hasChallenge, challenge,
- userId, progressCallback);
+ response = spBasedDoVerifyCredential(credential, credentialType, challengeType, challenge,
+ userId, progressCallback, resetLockouts);
// The user employs synthetic password based credential.
if (response != null) {
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
@@ -1803,7 +1864,7 @@ public class LockSettingsService extends ILockSettings.Stub {
}
response = verifyCredential(userId, storedHash, credentialToVerify,
- hasChallenge, challenge, progressCallback);
+ challengeType, challenge, progressCallback);
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
mStrongAuth.reportSuccessfulStrongAuthUnlock(userId);
@@ -1829,7 +1890,7 @@ public class LockSettingsService extends ILockSettings.Stub {
final VerifyCredentialResponse parentResponse = doVerifyCredential(
credential,
type,
- true /* hasChallenge */,
+ CHALLENGE_FROM_CALLER,
challenge,
parentProfileId,
null /* progressCallback */);
@@ -1842,7 +1903,7 @@ public class LockSettingsService extends ILockSettings.Stub {
// Unlock work profile, and work profile with unified lock must use password only
return doVerifyCredential(getDecryptedPasswordForTiedProfile(userId),
CREDENTIAL_TYPE_PASSWORD,
- true,
+ CHALLENGE_FROM_CALLER,
challenge,
userId, null /* progressCallback */);
} catch (UnrecoverableKeyException | InvalidKeyException | KeyStoreException
@@ -1860,7 +1921,7 @@ public class LockSettingsService extends ILockSettings.Stub {
* hash to GK.
*/
private VerifyCredentialResponse verifyCredential(int userId, CredentialHash storedHash,
- byte[] credential, boolean hasChallenge, long challenge,
+ byte[] credential, @ChallengeType int challengeType, long challenge,
ICheckCredentialProgressCallback progressCallback) throws RemoteException {
if ((storedHash == null || storedHash.hash.length == 0)
&& (credential == null || credential.length == 0)) {
@@ -1903,7 +1964,7 @@ public class LockSettingsService extends ILockSettings.Stub {
: DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC
/* TODO(roosa): keep the same password quality */,
userId, false, /* isLockTiedToParent= */ false);
- if (!hasChallenge) {
+ if (challengeType == CHALLENGE_NONE) {
notifyActivePasswordMetricsAvailable(storedHash.type, credential, userId);
// Use credentials to create recoverable keystore snapshot.
sendCredentialsOnUnlockIfRequired(storedHash.type, credential, userId);
@@ -2491,9 +2552,14 @@ public class LockSettingsService extends ILockSettings.Stub {
}
private VerifyCredentialResponse spBasedDoVerifyCredential(byte[] userCredential,
- @CredentialType int credentialType, boolean hasChallenge, long challenge, int userId,
- ICheckCredentialProgressCallback progressCallback) throws RemoteException {
- if (DEBUG) Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId);
+ @CredentialType int credentialType, @ChallengeType int challengeType, long challenge,
+ int userId, ICheckCredentialProgressCallback progressCallback,
+ @Nullable ArrayList<PendingResetLockout> resetLockouts) throws RemoteException {
+
+ final boolean hasEnrolledBiometrics = mInjector.hasEnrolledBiometrics(userId);
+
+ Slog.d(TAG, "spBasedDoVerifyCredential: user=" + userId + " challengeType=" + challengeType
+ + " hasEnrolledBiometrics=" + hasEnrolledBiometrics);
if (credentialType == CREDENTIAL_TYPE_NONE) {
userCredential = null;
}
@@ -2502,8 +2568,11 @@ public class LockSettingsService extends ILockSettings.Stub {
// TODO: When lockout is handled under the HAL for all biometrics (fingerprint),
// we need to generate challenge for each one, have it signed by GK and reset lockout
// for each modality.
- if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)
- && mInjector.hasEnrolledBiometrics()) {
+ if (challengeType == CHALLENGE_NONE && pm.hasSystemFeature(PackageManager.FEATURE_FACE)
+ && hasEnrolledBiometrics) {
+ // If there are multiple profiles in the same account, ensure we only generate the
+ // challenge once.
+ challengeType = CHALLENGE_INTERNAL;
challenge = mContext.getSystemService(FaceManager.class).generateChallenge();
}
@@ -2545,21 +2614,18 @@ public class LockSettingsService extends ILockSettings.Stub {
if (response.getResponseCode() == VerifyCredentialResponse.RESPONSE_OK) {
notifyActivePasswordMetricsAvailable(credentialType, userCredential, userId);
unlockKeystore(authResult.authToken.deriveKeyStorePassword(), userId);
- // Reset lockout only if user has enrolled templates
- if (mInjector.hasEnrolledBiometrics()) {
- BiometricManager bm = mContext.getSystemService(BiometricManager.class);
- Slog.i(TAG, "Resetting lockout, length: "
- + authResult.gkResponse.getPayload().length);
- bm.resetLockout(authResult.gkResponse.getPayload());
-
- if (!hasChallenge && pm.hasSystemFeature(PackageManager.FEATURE_FACE)) {
- mContext.getSystemService(FaceManager.class).revokeChallenge();
+
+ // Do resetLockout / revokeChallenge when all profiles are unlocked
+ if (hasEnrolledBiometrics) {
+ if (resetLockouts == null) {
+ resetLockouts = new ArrayList<>();
}
+ resetLockouts.add(new PendingResetLockout(userId, response.getPayload()));
}
final byte[] secret = authResult.authToken.deriveDiskEncryptionKey();
Slog.i(TAG, "Unlocking user " + userId + " with secret only, length " + secret.length);
- unlockUser(userId, null, secret);
+ unlockUser(userId, null, secret, challengeType, challenge, resetLockouts);
activateEscrowTokens(authResult.authToken, userId);
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 0c43d817e6f0..21b13fe234e0 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2517,14 +2517,21 @@ public class PhoneWindowManager implements WindowManagerPolicy {
@Override
public Animation createHiddenByKeyguardExit(boolean onWallpaper,
- boolean goingToNotificationShade) {
+ boolean goingToNotificationShade, boolean subtleAnimation) {
if (goingToNotificationShade) {
return AnimationUtils.loadAnimation(mContext, R.anim.lock_screen_behind_enter_fade_in);
}
- AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, onWallpaper ?
- R.anim.lock_screen_behind_enter_wallpaper :
- R.anim.lock_screen_behind_enter);
+ final int resource;
+ if (subtleAnimation) {
+ resource = R.anim.lock_screen_behind_enter_subtle;
+ } else if (onWallpaper) {
+ resource = R.anim.lock_screen_behind_enter_wallpaper;
+ } else {
+ resource = R.anim.lock_screen_behind_enter;
+ }
+
+ AnimationSet set = (AnimationSet) AnimationUtils.loadAnimation(mContext, resource);
// TODO: Use XML interpolators when we have log interpolators available in XML.
final List<Animation> animations = set.getAnimations();
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index b196754796e9..6d9c71096cb0 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -980,7 +980,7 @@ public interface WindowManagerPolicy extends WindowManagerPolicyConstants {
* Create and return an animation to re-display a window that was force hidden by Keyguard.
*/
public Animation createHiddenByKeyguardExit(boolean onWallpaper,
- boolean goingToNotificationShade);
+ boolean goingToNotificationShade, boolean subtleAnimation);
/**
* Create and return an animation to let the wallpaper disappear after being shown behind
diff --git a/services/core/java/com/android/server/power/AttentionDetector.java b/services/core/java/com/android/server/power/AttentionDetector.java
index ed11fd45ec39..56d839633ab5 100644
--- a/services/core/java/com/android/server/power/AttentionDetector.java
+++ b/services/core/java/com/android/server/power/AttentionDetector.java
@@ -40,6 +40,7 @@ import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
+import com.android.server.wm.WindowManagerInternal;
import java.io.PrintWriter;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -102,6 +103,9 @@ public class AttentionDetector {
protected AttentionManagerInternal mAttentionManager;
@VisibleForTesting
+ protected WindowManagerInternal mWindowManager;
+
+ @VisibleForTesting
protected PackageManager mPackageManager;
@VisibleForTesting
@@ -142,6 +146,7 @@ public class AttentionDetector {
mPackageManager = context.getPackageManager();
mContentResolver = context.getContentResolver();
mAttentionManager = LocalServices.getService(AttentionManagerInternal.class);
+ mWindowManager = LocalServices.getService(WindowManagerInternal.class);
mMaximumExtensionMillis = context.getResources().getInteger(
com.android.internal.R.integer.config_attentionMaximumExtension);
mMaxAttentionApiTimeoutMillis = context.getResources().getInteger(
@@ -165,14 +170,10 @@ public class AttentionDetector {
}
public long updateUserActivity(long nextScreenDimming) {
- if (nextScreenDimming == mLastActedOnNextScreenDimming) {
- return nextScreenDimming;
- }
- if (!mIsSettingEnabled) {
- return nextScreenDimming;
- }
-
- if (!isAttentionServiceSupported()) {
+ if (nextScreenDimming == mLastActedOnNextScreenDimming
+ || !mIsSettingEnabled
+ || !isAttentionServiceSupported()
+ || mWindowManager.isKeyguardShowingAndNotOccluded()) {
return nextScreenDimming;
}
@@ -297,6 +298,7 @@ public class AttentionDetector {
public void dump(PrintWriter pw) {
pw.println("AttentionDetector:");
+ pw.println(" mIsSettingEnabled=" + mIsSettingEnabled);
pw.println(" mMaximumExtensionMillis=" + mMaximumExtensionMillis);
pw.println(" mMaxAttentionApiTimeoutMillis=" + mMaxAttentionApiTimeoutMillis);
pw.println(" mLastUserActivityTime(excludingAttention)=" + mLastUserActivityTime);
diff --git a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
index b12129835ca1..d7f86cd65ae9 100644
--- a/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
+++ b/services/core/java/com/android/server/statusbar/StatusBarShellCommand.java
@@ -161,7 +161,15 @@ public class StatusBarShellCommand extends ShellCommand {
case "statusbar-expansion":
info.setStatusBarExpansionDisabled(true);
break;
-
+ case "system-icons":
+ info.setSystemIconsDisabled(true);
+ break;
+ case "clock":
+ info.setClockDisabled(true);
+ break;
+ case "notification-icons":
+ info.setNotificationIconsDisabled(true);
+ break;
default:
break;
}
@@ -221,6 +229,9 @@ public class StatusBarShellCommand extends ShellCommand {
pw.println(" recents - disable recents/overview");
pw.println(" notification-peek - disable notification peeking");
pw.println(" statusbar-expansion - disable status bar expansion");
+ pw.println(" system-icons - disable system icons appearing in status bar");
+ pw.println(" clock - disable clock appearing in status bar");
+ pw.println(" notification-icons - disable notification icons from status bar");
pw.println("");
}
diff --git a/services/core/java/com/android/server/wm/AccessibilityController.java b/services/core/java/com/android/server/wm/AccessibilityController.java
index b6a5be807fb6..4cfc1d1df2ae 100644
--- a/services/core/java/com/android/server/wm/AccessibilityController.java
+++ b/services/core/java/com/android/server/wm/AccessibilityController.java
@@ -1065,8 +1065,6 @@ final class AccessibilityController {
private final long mRecurringAccessibilityEventsIntervalMillis;
- private int mTempLayer = 0;
-
public WindowsForAccessibilityObserver(WindowManagerService windowManagerService,
WindowsForAccessibilityCallback callback) {
mContext = windowManagerService.mContext;
@@ -1091,7 +1089,7 @@ final class AccessibilityController {
}
/**
- * Check if windows have changed, and send them to the accessibilty subsystem if they have.
+ * Check if windows have changed, and send them to the accessibility subsystem if they have.
*
* @param forceSend Send the windows the accessibility even if they haven't changed.
*/
@@ -1108,8 +1106,7 @@ final class AccessibilityController {
// the window manager is still looking for where to put it.
// We will do the work when we get a focus change callback.
// TODO(b/112273690): Support multiple displays
- // TODO(b/129098348): Support embedded displays
- if (mService.getDefaultDisplayContentLocked().mCurrentFocus == null) {
+ if (!isCurrentFocusWindowOnDefaultDisplay()) {
return;
}
@@ -1395,21 +1392,35 @@ final class AccessibilityController {
}
private void populateVisibleWindowsOnScreenLocked(SparseArray<WindowState> outWindows) {
+ final List<WindowState> tempWindowStatesList = new ArrayList<>();
final DisplayContent dc = mService.getDefaultDisplayContentLocked();
- mTempLayer = 0;
dc.forAllWindows((w) -> {
if (w.isVisibleLw()) {
- outWindows.put(mTempLayer++, w);
+ tempWindowStatesList.add(w);
}
}, false /* traverseTopToBottom */);
+ // Insert the re-parented windows in another display on top of their parents in
+ // default display.
mService.mRoot.forAllWindows(w -> {
- final WindowState win = findRootDisplayParentWindow(w);
- if (win != null && win.getDisplayContent().isDefaultDisplay && w.isVisibleLw()) {
- // TODO(b/129098348): insert windows on child displays into outWindows based on
- // root-display-parent window.
- outWindows.put(mTempLayer++, w);
+ final WindowState parentWindow = findRootDisplayParentWindow(w);
+ if (parentWindow == null) {
+ return;
}
- }, false /* traverseTopToBottom */);
+
+ // TODO: Use Region instead to get rid of this complicated logic.
+ // Check the tap exclude region of the parent window. If the tap exclude region
+ // is empty, it means there is another can-receive-pointer-event view on top of
+ // the region. Hence, we don't count the window as visible.
+ if (w.isVisibleLw() && parentWindow.getDisplayContent().isDefaultDisplay
+ && parentWindow.hasTapExcludeRegion()
+ && tempWindowStatesList.contains(parentWindow)) {
+ tempWindowStatesList.add(
+ tempWindowStatesList.lastIndexOf(parentWindow) + 1, w);
+ }
+ }, true /* traverseTopToBottom */);
+ for (int i = 0; i < tempWindowStatesList.size(); i++) {
+ outWindows.put(i, tempWindowStatesList.get(i));
+ }
}
private WindowState findRootDisplayParentWindow(WindowState win) {
@@ -1425,6 +1436,23 @@ final class AccessibilityController {
return displayParentWindow;
}
+ private boolean isCurrentFocusWindowOnDefaultDisplay() {
+ final WindowState focusedWindow =
+ mService.mRoot.getTopFocusedDisplayContent().mCurrentFocus;
+ if (focusedWindow == null) {
+ return false;
+ }
+
+ final WindowState rootDisplayParentWindow = findRootDisplayParentWindow(focusedWindow);
+ if (!focusedWindow.isDefaultDisplay()
+ && (rootDisplayParentWindow == null
+ || !rootDisplayParentWindow.isDefaultDisplay())) {
+ return false;
+ }
+
+ return true;
+ }
+
private class MyHandler extends Handler {
public static final int MESSAGE_COMPUTE_CHANGED_WINDOWS = 1;
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 371a94356432..769297745ab7 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -3165,7 +3165,7 @@ final class ActivityRecord extends ConfigurationContainer {
boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow) {
return ensureActivityConfiguration(globalChanges, preserveWindow,
- false /* ignoreStopState */);
+ false /* ignoreVisibility */);
}
/**
@@ -3175,15 +3175,15 @@ final class ActivityRecord extends ConfigurationContainer {
* @param globalChanges The changes to the global configuration.
* @param preserveWindow If the activity window should be preserved on screen if the activity
* is relaunched.
- * @param ignoreStopState If we should try to relaunch the activity even if it is in the stopped
- * state. This is useful for the case where we know the activity will be
- * visible soon and we want to ensure its configuration before we make it
- * visible.
+ * @param ignoreVisibility If we should try to relaunch the activity even if it is invisible
+ * (stopped state). This is useful for the case where we know the
+ * activity will be visible soon and we want to ensure its configuration
+ * before we make it visible.
* @return False if the activity was relaunched and true if it wasn't relaunched because we
* can't or the app handles the specific configuration that is changing.
*/
boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
- boolean ignoreStopState) {
+ boolean ignoreVisibility) {
final ActivityStack stack = getActivityStack();
if (stack.mConfigWillChange) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
@@ -3199,15 +3199,9 @@ final class ActivityRecord extends ConfigurationContainer {
return true;
}
- if (!ignoreStopState && (mState == STOPPING || mState == STOPPED)) {
+ if (!ignoreVisibility && (mState == STOPPING || mState == STOPPED || !shouldBeVisible())) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Skipping config check stopped or stopping: " + this);
- return true;
- }
-
- if (!shouldBeVisible()) {
- if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
- "Skipping config check invisible stack: " + this);
+ "Skipping config check invisible: " + this);
return true;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 6bed46226b42..b33f23cfdf4e 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -40,6 +40,7 @@ import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_ACTIVITY_OPEN;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_NONE;
+import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
import static android.view.WindowManager.TRANSIT_TASK_OPEN_BEHIND;
@@ -163,6 +164,8 @@ import com.android.server.am.AppTimeTracker;
import com.android.server.am.EventLogTags;
import com.android.server.am.PendingIntentRecord;
+import com.google.android.collect.Sets;
+
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.ref.WeakReference;
@@ -1879,8 +1882,7 @@ class ActivityStack extends ConfigurationContainer {
mRootActivityContainer.ensureActivitiesVisible(resuming, 0, !PRESERVE_WINDOWS);
}
- private void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed,
- String reason) {
+ void addToStopping(ActivityRecord r, boolean scheduleIdle, boolean idleDelayed, String reason) {
if (!mStackSupervisor.mStoppingActivities.contains(r)) {
EventLog.writeEvent(EventLogTags.AM_ADD_TO_STOPPING, r.mUserId,
System.identityHashCode(r), r.shortComponentName, reason);
@@ -2175,7 +2177,7 @@ class ActivityStack extends ConfigurationContainer {
// sure it matches the current configuration.
if (r != starting && notifyClients) {
r.ensureActivityConfiguration(0 /* globalChanges */, preserveWindows,
- true /* ignoreStopState */);
+ true /* ignoreVisibility */);
}
if (!r.attachedToProcess()) {
@@ -3138,8 +3140,10 @@ class ActivityStack extends ConfigurationContainer {
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
TaskRecord rTask = r.getTaskRecord();
final int taskId = rTask.taskId;
+ final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
// mLaunchTaskBehind tasks get placed at the back of the task stack.
- if (!r.mLaunchTaskBehind && (taskForIdLocked(taskId) == null || newTask)) {
+ if (!r.mLaunchTaskBehind && allowMoveToFront
+ && (taskForIdLocked(taskId) == null || newTask)) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
@@ -3198,7 +3202,9 @@ class ActivityStack extends ConfigurationContainer {
task.setFrontOfTask();
- if (!isHomeOrRecentsStack() || numActivities() > 0) {
+ // The transition animation and starting window are not needed if {@code allowMoveToFront}
+ // is false, because the activity won't be visible.
+ if ((!isHomeOrRecentsStack() || numActivities() > 0) && allowMoveToFront) {
final DisplayContent dc = getDisplay().mDisplayContent;
if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION,
"Prepare open transition: starting " + r);
@@ -3210,6 +3216,8 @@ class ActivityStack extends ConfigurationContainer {
if (newTask) {
if (r.mLaunchTaskBehind) {
transit = TRANSIT_TASK_OPEN_BEHIND;
+ } else if (getDisplay().isSingleTaskInstance()) {
+ transit = TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
} else {
// If a new task is being launched, then mark the existing top activity as
// supporting picture-in-picture while pausing only if the starting activity
@@ -4019,6 +4027,14 @@ class ActivityStack extends ConfigurationContainer {
}
getDisplay().mDisplayContent.prepareAppTransition(transit, false);
+ // When finishing the activity pre-emptively take the snapshot before the app window
+ // is marked as hidden and any configuration changes take place
+ if (mWindowManager.mTaskSnapshotController != null) {
+ final ArraySet<Task> tasks = Sets.newArraySet(task.mTask);
+ mWindowManager.mTaskSnapshotController.snapshotTasks(tasks);
+ mWindowManager.mTaskSnapshotController.addSkipClosingAppSnapshotTasks(tasks);
+ }
+
// Tell window manager to prepare for this one to be removed.
r.setVisibility(false);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 0a88eef86ea8..eda9d24ef3c5 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -2307,12 +2307,12 @@ class ActivityStarter {
// isLockTaskModeViolation fails below.
if (mReuseTask == null) {
+ final boolean toTop = !mLaunchTaskBehind && !mAvoidMoveToFront;
final TaskRecord task = mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.mUserId),
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
- mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity, mSourceRecord,
- mOptions);
+ mVoiceInteractor, toTop, mStartActivity, mSourceRecord, mOptions);
addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
updateBounds(mStartActivity.getTaskRecord(), mLaunchParams.mBounds);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 5459edeb3d8b..ab35652eb525 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -34,7 +34,6 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.os.SystemClock;
import android.service.voice.IVoiceInteractionSession;
-import android.util.Pair;
import android.util.SparseIntArray;
import android.util.proto.ProtoOutputStream;
@@ -189,6 +188,13 @@ public abstract class ActivityTaskManagerInternal {
public abstract void notifyDockedStackMinimizedChanged(boolean minimized);
/**
+ * Notify listeners that contents are drawn for the first time on a single task display.
+ *
+ * @param displayId An ID of the display on which contents are drawn.
+ */
+ public abstract void notifySingleTaskDisplayDrawn(int displayId);
+
+ /**
* Start activity {@code intents} as if {@code packageName} on user {@code userId} did it.
*
* - DO NOT call it with the calling UID cleared.
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index e2421d6d1a93..0f96f99c3348 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1451,9 +1451,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
.execute();
}
+ /**
+ * Start the recents activity to perform the recents animation.
+ *
+ * @param intent The intent to start the recents activity.
+ * @param recentsAnimationRunner Pass {@code null} to only preload the activity.
+ */
@Override
- public void startRecentsActivity(Intent intent, IAssistDataReceiver assistDataReceiver,
- IRecentsAnimationRunner recentsAnimationRunner) {
+ public void startRecentsActivity(Intent intent, @Deprecated IAssistDataReceiver unused,
+ @Nullable IRecentsAnimationRunner recentsAnimationRunner) {
enforceCallerIsRecentsOrHasPermission(MANAGE_ACTIVITY_STACKS, "startRecentsActivity()");
final int callingPid = Binder.getCallingPid();
final long origId = Binder.clearCallingIdentity();
@@ -1464,9 +1470,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// Start a new recents animation
final RecentsAnimation anim = new RecentsAnimation(this, mStackSupervisor,
- getActivityStartController(), mWindowManager, callingPid);
- anim.startRecentsActivity(intent, recentsAnimationRunner, recentsComponent,
- recentsUid, assistDataReceiver);
+ getActivityStartController(), mWindowManager, intent, recentsComponent,
+ recentsUid, callingPid);
+ if (recentsAnimationRunner == null) {
+ anim.preloadRecentsActivity();
+ } else {
+ anim.startRecentsActivity(recentsAnimationRunner);
+ }
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -6100,7 +6110,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
- public void notifyAppTransitionStarting(SparseIntArray reasons, long timestamp) {
+ public void notifyAppTransitionStarting(SparseIntArray reasons,
+ long timestamp) {
synchronized (mGlobalLock) {
mStackSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
reasons, timestamp);
@@ -6108,6 +6119,11 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
+ public void notifySingleTaskDisplayDrawn(int displayId) {
+ mTaskChangeNotificationController.notifySingleTaskDisplayDrawn(displayId);
+ }
+
+ @Override
public void notifyAppTransitionFinished() {
synchronized (mGlobalLock) {
mStackSupervisor.notifyAppTransitionDone();
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index e6a83dedded9..557a609dbc7b 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -23,12 +23,14 @@ import static android.view.WindowManager.TRANSIT_ACTIVITY_RELAUNCH;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_NONE;
+import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
import static android.view.WindowManager.TRANSIT_TASK_CHANGE_WINDOWING_MODE;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
@@ -1801,8 +1803,10 @@ public class AppTransition implements Dump {
}
final boolean toShade =
(mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0;
+ final boolean subtle =
+ (mNextAppTransitionFlags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0;
return mService.mPolicy.createHiddenByKeyguardExit(
- transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade);
+ transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER, toShade, subtle);
}
int getAppStackClipMode() {
@@ -2080,6 +2084,9 @@ public class AppTransition implements Dump {
case TRANSIT_CRASHING_ACTIVITY_CLOSE: {
return "TRANSIT_CRASHING_ACTIVITY_CLOSE";
}
+ case TRANSIT_SHOW_SINGLE_TASK_DISPLAY: {
+ return "TRANSIT_SHOW_SINGLE_TASK_DISPLAY";
+ }
default: {
return "<UNKNOWN: " + transition + ">";
}
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index d4c4e6a93fa6..d4e95cfb8025 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -23,11 +23,13 @@ import static android.view.WindowManager.TRANSIT_ACTIVITY_RELAUNCH;
import static android.view.WindowManager.TRANSIT_CRASHING_ACTIVITY_CLOSE;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER;
import static android.view.WindowManager.TRANSIT_NONE;
+import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
import static android.view.WindowManager.TRANSIT_TASK_CLOSE;
import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE;
import static android.view.WindowManager.TRANSIT_TASK_OPEN;
@@ -211,6 +213,12 @@ public class AppTransitionController {
mService.mAtmInternal.notifyAppTransitionStarting(mTempTransitionReasons.clone(),
SystemClock.uptimeMillis());
+ if (transit == TRANSIT_SHOW_SINGLE_TASK_DISPLAY) {
+ mService.mAnimator.addAfterPrepareSurfacesRunnable(() -> {
+ mService.mAtmInternal.notifySingleTaskDisplayDrawn(mDisplayContent.getDisplayId());
+ });
+ }
+
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
mDisplayContent.pendingLayoutChanges |=
@@ -418,7 +426,8 @@ public class AppTransitionController {
private void handleNonAppWindowsInTransition(int transit, int flags) {
if (transit == TRANSIT_KEYGUARD_GOING_AWAY) {
if ((flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER) != 0
- && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0) {
+ && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION) == 0
+ && (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) == 0) {
Animation anim = mService.mPolicy.createKeyguardWallpaperExit(
(flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
if (anim != null) {
@@ -430,7 +439,8 @@ public class AppTransitionController {
|| transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER) {
mDisplayContent.startKeyguardExitOnNonAppWindows(
transit == TRANSIT_KEYGUARD_GOING_AWAY_ON_WALLPAPER,
- (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0);
+ (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE) != 0,
+ (flags & TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION) != 0);
}
}
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index 03cae429904f..eab5e0dd270e 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -79,6 +79,7 @@ import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_NORMAL;
import static com.android.server.wm.WindowManagerService.UPDATE_FOCUS_WILL_PLACE_SURFACES;
import static com.android.server.wm.WindowManagerService.logWithStack;
import static com.android.server.wm.WindowState.LEGACY_POLICY_VISIBILITY;
+import static com.android.server.wm.WindowStateAnimator.HAS_DRAWN;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_AFTER_ANIM;
import static com.android.server.wm.WindowStateAnimator.STACK_CLIP_BEFORE_ANIM;
@@ -540,6 +541,18 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
// If the app was already visible, don't reset the waitingToShow state.
if (isHidden()) {
waitingToShow = true;
+
+ // Let's reset the draw state in order to prevent the starting window to be
+ // immediately dismissed when the app still has the surface.
+ forAllWindows(w -> {
+ if (w.mWinAnimator.mDrawState == HAS_DRAWN) {
+ w.mWinAnimator.resetDrawState();
+
+ // Force add to mResizingWindows, so that we are guaranteed to get
+ // another reportDrawn callback.
+ w.resetLastContentInsets();
+ }
+ }, true /* traverseTopToBottom */);
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index b837d9ec874b..a1b87605ac1f 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -2559,6 +2559,9 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
void removeImmediately() {
mRemovingDisplay = true;
try {
+ if (mParentWindow != null) {
+ mParentWindow.removeEmbeddedDisplayContent(this);
+ }
// Clear all transitions & screen frozen states when removing display.
mOpeningApps.clear();
mClosingApps.clear();
@@ -3489,12 +3492,14 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
/**
* Starts the Keyguard exit animation on all windows that don't belong to an app token.
*/
- void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade) {
+ void startKeyguardExitOnNonAppWindows(boolean onWallpaper, boolean goingToShade,
+ boolean subtle) {
final WindowManagerPolicy policy = mWmService.mPolicy;
forAllWindows(w -> {
if (w.mAppToken == null && policy.canBeHiddenByKeyguardLw(w)
&& w.wouldBeVisibleIfPolicyIgnored() && !w.isVisible()) {
- w.startAnimation(policy.createHiddenByKeyguardExit(onWallpaper, goingToShade));
+ w.startAnimation(policy.createHiddenByKeyguardExit(
+ onWallpaper, goingToShade, subtle));
}
}, true /* traverseTopToBottom */);
}
@@ -5046,6 +5051,7 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
*/
void reparentDisplayContent(WindowState win, SurfaceControl sc) {
mParentWindow = win;
+ mParentWindow.addEmbeddedDisplayContent(this);
mParentSurfaceControl = sc;
if (mPortalWindowHandle == null) {
mPortalWindowHandle = createPortalWindowHandle(sc.toString());
@@ -5076,12 +5082,12 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
throw new IllegalArgumentException(
"The given window is not the parent window of this display.");
}
- if (mLocationInParentWindow.x != x || mLocationInParentWindow.y != y) {
- mLocationInParentWindow.x = x;
- mLocationInParentWindow.y = y;
+ if (!mLocationInParentWindow.equals(x, y)) {
+ mLocationInParentWindow.set(x, y);
if (mWmService.mAccessibilityController != null) {
mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
}
+ notifyLocationInParentDisplayChanged();
}
}
@@ -5089,6 +5095,30 @@ class DisplayContent extends WindowContainer<DisplayContent.DisplayChildWindowCo
return mLocationInParentWindow;
}
+ Point getLocationInParentDisplay() {
+ final Point location = new Point();
+ if (mParentWindow != null) {
+ // LocationInParentWindow indicates the offset to (0,0) of window, but what we need is
+ // the offset to (0,0) of display.
+ DisplayContent dc = this;
+ do {
+ final WindowState displayParent = dc.getParentWindow();
+ location.x += displayParent.getFrameLw().left
+ + (dc.getLocationInParentWindow().x * displayParent.mGlobalScale + 0.5f);
+ location.y += displayParent.getFrameLw().top
+ + (dc.getLocationInParentWindow().y * displayParent.mGlobalScale + 0.5f);
+ dc = displayParent.getDisplayContent();
+ } while (dc != null && dc.getParentWindow() != null);
+ }
+ return location;
+ }
+
+ void notifyLocationInParentDisplayChanged() {
+ forAllWindows(w -> {
+ w.updateLocationInParentDisplayIfNeeded();
+ }, false /* traverseTopToBottom */);
+ }
+
@VisibleForTesting
SurfaceControl getWindowingLayer() {
return mWindowingLayer;
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 169f03b0023d..ca4749f7b365 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
import static android.view.WindowManager.TRANSIT_KEYGUARD_GOING_AWAY;
@@ -26,6 +27,7 @@ import static android.view.WindowManager.TRANSIT_KEYGUARD_OCCLUDE;
import static android.view.WindowManager.TRANSIT_KEYGUARD_UNOCCLUDE;
import static android.view.WindowManager.TRANSIT_UNSET;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_NO_WINDOW_ANIMATIONS;
+import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
@@ -238,6 +240,9 @@ class KeyguardController {
if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER) != 0) {
result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
}
+ if ((keyguardGoingAwayFlags & KEYGUARD_GOING_AWAY_FLAG_SUBTLE_WINDOW_ANIMATIONS) != 0) {
+ result |= TRANSIT_FLAG_KEYGUARD_GOING_AWAY_SUBTLE_ANIMATION;
+ }
return result;
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 434239f6ecf7..bf627ec5680c 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -34,7 +34,6 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_T
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_RECENTS_ANIMATIONS;
import android.app.ActivityOptions;
-import android.app.IAssistDataReceiver;
import android.content.ComponentName;
import android.content.Intent;
import android.os.RemoteException;
@@ -58,7 +57,12 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
private final ActivityStartController mActivityStartController;
private final WindowManagerService mWindowManager;
private final ActivityDisplay mDefaultDisplay;
+ private final Intent mTargetIntent;
+ private final ComponentName mRecentsComponent;
+ private final int mRecentsUid;
private final int mCallingPid;
+ private final int mUserId;
+ private final int mTargetActivityType;
/**
* The activity which has been launched behind. We need to remember the activity because the
@@ -66,27 +70,90 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
* for the exact activity.
*/
private ActivityRecord mLaunchedTargetActivity;
- private int mTargetActivityType;
// The stack to restore the target stack behind when the animation is finished
private ActivityStack mRestoreTargetBehindStack;
RecentsAnimation(ActivityTaskManagerService atm, ActivityStackSupervisor stackSupervisor,
ActivityStartController activityStartController, WindowManagerService wm,
- int callingPid) {
+ Intent targetIntent, ComponentName recentsComponent, int recentsUid, int callingPid) {
mService = atm;
mStackSupervisor = stackSupervisor;
mDefaultDisplay = mService.mRootActivityContainer.getDefaultDisplay();
mActivityStartController = activityStartController;
mWindowManager = wm;
+ mTargetIntent = targetIntent;
+ mRecentsComponent = recentsComponent;
+ mRecentsUid = recentsUid;
mCallingPid = callingPid;
+ mUserId = atm.getCurrentUserId();
+ mTargetActivityType = targetIntent.getComponent() != null
+ && recentsComponent.equals(targetIntent.getComponent())
+ ? ACTIVITY_TYPE_RECENTS
+ : ACTIVITY_TYPE_HOME;
+ }
+
+ /**
+ * Starts the recents activity in background without animation if the record doesn't exist or
+ * the client isn't launched. If the recents activity is already alive, ensure its configuration
+ * is updated to the current one.
+ */
+ void preloadRecentsActivity() {
+ if (DEBUG) Slog.d(TAG, "Preload recents with " + mTargetIntent);
+ ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
+ mTargetActivityType);
+ ActivityRecord targetActivity = getTargetActivity(targetStack);
+ if (targetActivity != null) {
+ if (targetActivity.visible || targetActivity.isTopRunningActivity()) {
+ // The activity is ready.
+ return;
+ }
+ if (targetActivity.attachedToProcess()) {
+ // The activity may be relaunched if it cannot handle the current configuration
+ // changes. The activity will be paused state if it is relaunched, otherwise it
+ // keeps the original stopped state.
+ targetActivity.ensureActivityConfiguration(0 /* globalChanges */,
+ false /* preserveWindow */, true /* ignoreVisibility */);
+ if (DEBUG) Slog.d(TAG, "Updated config=" + targetActivity.getConfiguration());
+ }
+ } else {
+ // Create the activity record. Because the activity is invisible, this doesn't really
+ // start the client.
+ startRecentsActivityInBackground("preloadRecents");
+ targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED, mTargetActivityType);
+ targetActivity = getTargetActivity(targetStack);
+ if (targetActivity == null) {
+ Slog.w(TAG, "Cannot start " + mTargetIntent);
+ return;
+ }
+ }
+
+ if (!targetActivity.attachedToProcess()) {
+ if (DEBUG) Slog.d(TAG, "Real start recents");
+ mStackSupervisor.startSpecificActivityLocked(targetActivity, false /* andResume */,
+ false /* checkConfig */);
+ // Make sure the activity won't be involved in transition.
+ if (targetActivity.mAppWindowToken != null) {
+ targetActivity.mAppWindowToken.getDisplayContent().mUnknownAppVisibilityController
+ .appRemovedOrHidden(targetActivity.mAppWindowToken);
+ }
+ }
+
+ // Invisible activity should be stopped. If the recents activity is alive and its doesn't
+ // need to relaunch by current configuration, then it may be already in stopped state.
+ if (!targetActivity.isState(ActivityStack.ActivityState.STOPPING,
+ ActivityStack.ActivityState.STOPPED)) {
+ // Add to stopping instead of stop immediately. So the client has the chance to perform
+ // traversal in non-stopped state (ViewRootImpl.mStopped) that would initialize more
+ // things (e.g. the measure can be done earlier). The actual stop will be performed when
+ // it reports idle.
+ targetStack.addToStopping(targetActivity, true /* scheduleIdle */,
+ true /* idleDelayed */, "preloadRecents");
+ }
}
- void startRecentsActivity(Intent intent, IRecentsAnimationRunner recentsAnimationRunner,
- ComponentName recentsComponent, int recentsUid,
- @Deprecated IAssistDataReceiver assistDataReceiver) {
- if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + intent
- + " assistDataReceiver=" + assistDataReceiver);
+ void startRecentsActivity(IRecentsAnimationRunner recentsAnimationRunner) {
+ if (DEBUG) Slog.d(TAG, "startRecentsActivity(): intent=" + mTargetIntent);
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "RecentsAnimation#startRecentsActivity");
// TODO(multi-display) currently only support recents animation in default display.
@@ -100,15 +167,9 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
}
// If the activity is associated with the recents stack, then try and get that first
- final int userId = mService.getCurrentUserId();
- mTargetActivityType = intent.getComponent() != null
- && recentsComponent.equals(intent.getComponent())
- ? ACTIVITY_TYPE_RECENTS
- : ACTIVITY_TYPE_HOME;
ActivityStack targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
- ActivityRecord targetActivity = getTargetActivity(targetStack, intent.getComponent(),
- userId);
+ ActivityRecord targetActivity = getTargetActivity(targetStack);
final boolean hasExistingActivity = targetActivity != null;
if (hasExistingActivity) {
final ActivityDisplay display = targetActivity.getDisplay();
@@ -127,7 +188,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
true /* forceSend */, targetActivity);
}
- mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
+ mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(mTargetIntent);
mService.mH.post(() -> mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, true));
@@ -148,23 +209,12 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
}
} else {
// No recents activity, create the new recents activity bottom most
- ActivityOptions options = ActivityOptions.makeBasic();
- options.setLaunchActivityType(mTargetActivityType);
- options.setAvoidMoveToFront();
- intent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
-
- mActivityStartController
- .obtainStarter(intent, "startRecentsActivity_noTargetActivity")
- .setCallingUid(recentsUid)
- .setCallingPackage(recentsComponent.getPackageName())
- .setActivityOptions(SafeActivityOptions.fromBundle(options.toBundle()))
- .setMayWait(userId)
- .execute();
+ startRecentsActivityInBackground("startRecentsActivity_noTargetActivity");
// Move the recents activity into place for the animation
targetStack = mDefaultDisplay.getStack(WINDOWING_MODE_UNDEFINED,
mTargetActivityType);
- targetActivity = getTargetActivity(targetStack, intent.getComponent(), userId);
+ targetActivity = getTargetActivity(targetStack);
mDefaultDisplay.moveStackBehindBottomMostVisibleStack(targetStack);
if (DEBUG) {
Slog.d(TAG, "Moved stack=" + targetStack + " behind stack="
@@ -176,7 +226,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
// TODO: Maybe wait for app to draw in this particular case?
- if (DEBUG) Slog.d(TAG, "Started intent=" + intent);
+ if (DEBUG) Slog.d(TAG, "Started intent=" + mTargetIntent);
}
// Mark the target activity as launch-behind to bump its visibility for the
@@ -383,6 +433,21 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
}
}
+ private void startRecentsActivityInBackground(String reason) {
+ final ActivityOptions options = ActivityOptions.makeBasic();
+ options.setLaunchActivityType(mTargetActivityType);
+ options.setAvoidMoveToFront();
+ mTargetIntent.addFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_NO_ANIMATION);
+
+ mActivityStartController
+ .obtainStarter(mTargetIntent, reason)
+ .setCallingUid(mRecentsUid)
+ .setCallingPackage(mRecentsComponent.getPackageName())
+ .setActivityOptions(new SafeActivityOptions(options))
+ .setMayWait(mUserId)
+ .execute();
+ }
+
/**
* Called only when the animation should be canceled prior to starting.
*/
@@ -412,15 +477,15 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
* @return the top activity in the {@param targetStack} matching the {@param component}, or just
* the top activity of the top task if no task matches the component.
*/
- private ActivityRecord getTargetActivity(ActivityStack targetStack, ComponentName component,
- int userId) {
+ private ActivityRecord getTargetActivity(ActivityStack targetStack) {
if (targetStack == null) {
return null;
}
for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
final TaskRecord task = targetStack.getChildAt(i);
- if (task.userId == userId && task.getBaseIntent().getComponent().equals(component)) {
+ if (task.userId == mUserId
+ && task.getBaseIntent().getComponent().equals(mTargetIntent.getComponent())) {
return task.getTopActivity();
}
}
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 3ec461d065ff..d58c61368f9a 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -35,6 +35,7 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.INVALID_DISPLAY;
+import static android.view.WindowManager.TRANSIT_SHOW_SINGLE_TASK_DISPLAY;
import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
@@ -1217,6 +1218,15 @@ class RootActivityContainer extends ConfigurationContainer
if (displayShouldSleep) {
stack.goToSleepIfPossible(false /* shuttingDown */);
} else {
+ // When the display which can only contain one task turns on, start a special
+ // transition. {@link AppTransitionController#handleAppTransitionReady} later
+ // picks up the transition, and schedules
+ // {@link ITaskStackListener#onSingleTaskDisplayDrawn} callback which is
+ // triggered after contents are drawn on the display.
+ if (display.isSingleTaskInstance()) {
+ display.mDisplayContent.prepareAppTransition(
+ TRANSIT_SHOW_SINGLE_TASK_DISPLAY, false);
+ }
stack.awakeFromSleepingLocked();
if (stack.isFocusedStackOnDisplay()
&& !mStackSupervisor.getKeyguardController()
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index b90d60227be4..6fd802d10e98 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -279,7 +279,8 @@ class ScreenRotationAnimation {
mService.mDisplayManagerInternal.screenshot(displayId);
if (gb != null) {
try {
- surface.attachAndQueueBuffer(gb.getGraphicBuffer());
+ surface.attachAndQueueBufferWithColorSpace(gb.getGraphicBuffer(),
+ gb.getColorSpace());
} catch (RuntimeException e) {
Slog.w(TAG, "Failed to attach screenshot - " + e.getMessage());
}
diff --git a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
index 22f529b28b8e..8f72cdad8dce 100644
--- a/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
+++ b/services/core/java/com/android/server/wm/TapExcludeRegionHolder.java
@@ -52,4 +52,11 @@ class TapExcludeRegionHolder {
region.op(r, Region.Op.UNION);
}
}
+
+ /**
+ * Return true if tap exclude region is empty.
+ */
+ boolean isEmpty() {
+ return mTapExcludeRegions.size() == 0;
+ }
}
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index c7fcc2cda80f..f776062b31a1 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -54,7 +54,8 @@ class TaskChangeNotificationController {
private static final int NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG = 19;
private static final int NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG = 20;
private static final int NOTIFY_BACK_PRESSED_ON_TASK_ROOT = 21;
- private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 22;
+ private static final int NOTIFY_SINGLE_TASK_DISPLAY_DRAWN = 22;
+ private static final int NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG = 23;
// Delay in notifying task stack change listeners (in millis)
private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -155,6 +156,10 @@ class TaskChangeNotificationController {
l.onSizeCompatModeActivityChanged(m.arg1, (IBinder) m.obj);
};
+ private final TaskStackConsumer mNotifySingleTaskDisplayDrawn = (l, m) -> {
+ l.onSingleTaskDisplayDrawn(m.arg1);
+ };
+
private final TaskStackConsumer mNotifyTaskDisplayChanged = (l, m) -> {
l.onTaskDisplayChanged(m.arg1, m.arg2);
};
@@ -238,6 +243,9 @@ class TaskChangeNotificationController {
case NOTIFY_BACK_PRESSED_ON_TASK_ROOT:
forAllRemoteListeners(mNotifyBackPressedOnTaskRoot, msg);
break;
+ case NOTIFY_SINGLE_TASK_DISPLAY_DRAWN:
+ forAllRemoteListeners(mNotifySingleTaskDisplayDrawn, msg);
+ break;
case NOTIFY_TASK_DISPLAY_CHANGED_LISTENERS_MSG:
forAllRemoteListeners(mNotifyTaskDisplayChanged, msg);
break;
@@ -487,6 +495,16 @@ class TaskChangeNotificationController {
}
/**
+ * Notify listeners that contents are drawn for the first time on a single task display.
+ */
+ void notifySingleTaskDisplayDrawn(int displayId) {
+ final Message msg = mHandler.obtainMessage(NOTIFY_SINGLE_TASK_DISPLAY_DRAWN,
+ displayId, 0 /* unused */);
+ forAllLocalListeners(mNotifySingleTaskDisplayDrawn, msg);
+ msg.sendToTarget();
+ }
+
+ /**
* Notify listeners that a task is reparented to another display.
*/
void notifyTaskDisplayChanged(int taskId, int newDisplayId) {
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index ee4e462cb85e..bb1570e1ecb1 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -69,7 +69,7 @@ class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable {
if (buffer != null) {
final Surface surface = new Surface();
surface.copyFrom(mSurfaceControl);
- surface.attachAndQueueBuffer(buffer);
+ surface.attachAndQueueBufferWithColorSpace(buffer, screenshotBuffer.getColorSpace());
surface.release();
}
getPendingTransaction().show(mSurfaceControl);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
index c3762d6352b8..1905476f4729 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotSurface.java
@@ -284,7 +284,6 @@ class TaskSnapshotSurface implements StartingSurface {
}
private void drawSnapshot() {
- final GraphicBuffer buffer = mSnapshot.getSnapshot();
mSurface.copyFrom(mSurfaceControl);
if (DEBUG_STARTING_WINDOW) Slog.v(TAG, "Drawing snapshot surface sizeMismatch="
@@ -293,9 +292,9 @@ class TaskSnapshotSurface implements StartingSurface {
// The dimensions of the buffer and the window don't match, so attaching the buffer
// will fail. Better create a child window with the exact dimensions and fill the parent
// window with the background color!
- drawSizeMismatchSnapshot(buffer);
+ drawSizeMismatchSnapshot();
} else {
- drawSizeMatchSnapshot(buffer);
+ drawSizeMatchSnapshot();
}
synchronized (mService.mGlobalLock) {
mShownTime = SystemClock.uptimeMillis();
@@ -307,15 +306,17 @@ class TaskSnapshotSurface implements StartingSurface {
mSnapshot = null;
}
- private void drawSizeMatchSnapshot(GraphicBuffer buffer) {
- mSurface.attachAndQueueBuffer(buffer);
+ private void drawSizeMatchSnapshot() {
+ mSurface.attachAndQueueBufferWithColorSpace(mSnapshot.getSnapshot(),
+ mSnapshot.getColorSpace());
mSurface.release();
}
- private void drawSizeMismatchSnapshot(GraphicBuffer buffer) {
+ private void drawSizeMismatchSnapshot() {
if (!mSurface.isValid()) {
throw new IllegalStateException("mSurface does not hold a valid surface.");
}
+ final GraphicBuffer buffer = mSnapshot.getSnapshot();
final SurfaceSession session = new SurfaceSession();
// We consider nearly matched dimensions as there can be rounding errors and the user won't
// notice very minute differences from scaling one dimension more than the other
@@ -355,7 +356,7 @@ class TaskSnapshotSurface implements StartingSurface {
} finally {
SurfaceControl.closeTransaction();
}
- surface.attachAndQueueBuffer(buffer);
+ surface.attachAndQueueBufferWithColorSpace(buffer, mSnapshot.getColorSpace());
surface.release();
if (aspectRatioMismatch) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index fb57d73c9a21..09ba2c8b1c6d 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -4576,8 +4576,11 @@ public class WindowManagerService extends IWindowManager.Stub
AccessibilityController accessibilityController = null;
synchronized (mGlobalLock) {
- // TODO(multidisplay): Accessibility supported only of default desiplay.
- if (mAccessibilityController != null && displayContent.isDefaultDisplay) {
+ // TODO(multidisplay): Accessibility supported only of default display and
+ // embedded displays.
+ if (mAccessibilityController != null
+ && (displayContent.isDefaultDisplay
+ || displayContent.getParentWindow() != null)) {
accessibilityController = mAccessibilityController;
}
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 43ad091b08c0..9ea6e30ef89b 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -170,6 +170,7 @@ import android.os.UserHandle;
import android.os.WorkSource;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
import android.util.Slog;
@@ -319,6 +320,9 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
int mLayoutSeq = -1;
+ /** @see #addEmbeddedDisplayContent(DisplayContent dc) */
+ private final ArraySet<DisplayContent> mEmbeddedDisplayContents = new ArraySet<>();
+
/**
* Used to store last reported to client configuration and check if we have newer available.
* We'll send configuration to client only if it is different from the last applied one and
@@ -539,6 +543,12 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
private final Point mTmpPoint = new Point();
/**
+ * If a window is on a display which has been re-parented to a view in another window,
+ * use this offset to indicate the correct location.
+ */
+ private final Point mLastReportedDisplayOffset = new Point();
+
+ /**
* Whether the window was resized by us while it was gone for layout.
*/
boolean mResizedWhileGone = false;
@@ -1792,11 +1802,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
startMoveAnimation(left, top);
}
- //TODO (multidisplay): Accessibility supported only for the default display.
- if (mWmService.mAccessibilityController != null
- && getDisplayContent().getDisplayId() == DEFAULT_DISPLAY) {
+ // TODO (multidisplay): Accessibility supported only for the default display and
+ // embedded displays
+ if (mWmService.mAccessibilityController != null && (getDisplayId() == DEFAULT_DISPLAY
+ || getDisplayContent().getParentWindow() != null)) {
mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
}
+ updateLocationInParentDisplayIfNeeded();
try {
mClient.moved(left, top);
@@ -3177,11 +3189,13 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
displayCutout);
}
- //TODO (multidisplay): Accessibility supported only for the default display.
+ // TODO (multidisplay): Accessibility supported only for the default display and
+ // embedded displays
if (mWmService.mAccessibilityController != null && (getDisplayId() == DEFAULT_DISPLAY
|| getDisplayContent().getParentWindow() != null)) {
mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
}
+ updateLocationInParentDisplayIfNeeded();
mWindowFrames.resetInsetsChanged();
mWinAnimator.mSurfaceResized = false;
@@ -3199,6 +3213,36 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
}
+ void updateLocationInParentDisplayIfNeeded() {
+ final int embeddedDisplayContentsSize = mEmbeddedDisplayContents.size();
+ // If there is any embedded display which is re-parented to this window, we need to
+ // notify all windows in the embedded display about the location change.
+ if (embeddedDisplayContentsSize != 0) {
+ for (int i = embeddedDisplayContentsSize - 1; i >= 0; i--) {
+ final DisplayContent edc = mEmbeddedDisplayContents.valueAt(i);
+ edc.notifyLocationInParentDisplayChanged();
+ }
+ }
+ // If this window is in a embedded display which is re-parented to another window,
+ // we may need to update its correct on-screen location.
+ final DisplayContent dc = getDisplayContent();
+ if (dc.getParentWindow() == null) {
+ return;
+ }
+
+ final Point offset = dc.getLocationInParentDisplay();
+ if (mLastReportedDisplayOffset.equals(offset)) {
+ return;
+ }
+
+ mLastReportedDisplayOffset.set(offset.x, offset.y);
+ try {
+ mClient.locationInParentDisplayChanged(mLastReportedDisplayOffset);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to update offset from DisplayContent", e);
+ }
+ }
+
/**
* Called when the insets state changed.
*/
@@ -3618,6 +3662,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
pw.println(prefix + "isOnScreen=" + isOnScreen());
pw.println(prefix + "isVisible=" + isVisible());
+ pw.println(prefix + "mEmbeddedDisplayContents=" + mEmbeddedDisplayContents);
}
@Override
@@ -4243,7 +4288,8 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
return;
}
- //TODO (multidisplay): Accessibility is supported only for the default display.
+ // TODO (multidisplay): Accessibility supported only for the default display and
+ // embedded displays
if (mWmService.mAccessibilityController != null && (getDisplayId() == DEFAULT_DISPLAY
|| getDisplayContent().getParentWindow() != null)) {
mWmService.mAccessibilityController.onSomeWindowResizedOrMovedLocked();
@@ -4615,6 +4661,28 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
}
/**
+ * Add the DisplayContent of the embedded display which is re-parented to this window to
+ * the list of embedded displays.
+ *
+ * @param dc DisplayContent of the re-parented embedded display.
+ * @return {@code true} if the giving DisplayContent is added, {@code false} otherwise.
+ */
+ boolean addEmbeddedDisplayContent(DisplayContent dc) {
+ return mEmbeddedDisplayContents.add(dc);
+ }
+
+ /**
+ * Remove the DisplayContent of the embedded display which is re-parented to this window from
+ * the list of embedded displays.
+ *
+ * @param dc DisplayContent of the re-parented embedded display.
+ * @return {@code true} if the giving DisplayContent is removed, {@code false} otherwise.
+ */
+ boolean removeEmbeddedDisplayContent(DisplayContent dc) {
+ return mEmbeddedDisplayContents.remove(dc);
+ }
+
+ /**
* Updates the last inset values to the current ones.
*/
void updateLastInsetValues() {
@@ -5036,6 +5104,10 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
tempRegion.recycle();
}
+ boolean hasTapExcludeRegion() {
+ return mTapExcludeRegionHolder != null && !mTapExcludeRegionHolder.isEmpty();
+ }
+
@Override
public boolean isInputMethodTarget() {
return getDisplayContent().mInputMethodTarget == this;
diff --git a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
index 8bb8aae76849..fb2913b09ace 100644
--- a/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/color/ColorDisplayServiceTest.java
@@ -113,6 +113,8 @@ public class ColorDisplayServiceTest {
mUserId = UserHandle.USER_NULL;
mContext = null;
+ FakeSettingsProvider.clearSettingsProvider();
+
LocalServices.removeServiceForTest(ColorDisplayService.ColorDisplayServiceInternal.class);
}
@@ -924,11 +926,8 @@ public class ColorDisplayServiceTest {
startService();
assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
- if (isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
- assertActiveColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
- } else if (isColorModeValid(ColorDisplayManager.COLOR_MODE_AUTOMATIC)) {
- assertActiveColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC);
- }
+ assertActiveColorMode(mContext.getResources().getInteger(
+ R.integer.config_accessibilityColorMode));
}
@Test
@@ -942,11 +941,8 @@ public class ColorDisplayServiceTest {
startService();
assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
- if (isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
- assertActiveColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
- } else if (isColorModeValid(ColorDisplayManager.COLOR_MODE_AUTOMATIC)) {
- assertActiveColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC);
- }
+ assertActiveColorMode(mContext.getResources().getInteger(
+ R.integer.config_accessibilityColorMode));
}
@Test
@@ -961,11 +957,8 @@ public class ColorDisplayServiceTest {
startService();
assertUserColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
- if (isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
- assertActiveColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
- } else if (isColorModeValid(ColorDisplayManager.COLOR_MODE_AUTOMATIC)) {
- assertActiveColorMode(ColorDisplayManager.COLOR_MODE_AUTOMATIC);
- }
+ assertActiveColorMode(mContext.getResources().getInteger(
+ R.integer.config_accessibilityColorMode));
}
@Test
@@ -1020,11 +1013,15 @@ public class ColorDisplayServiceTest {
@Test
public void displayWhiteBalance_enabledAfterLinearColorModeSelected() {
+ if (!isColorModeValid(ColorDisplayManager.COLOR_MODE_SATURATED)) {
+ return;
+ }
setDisplayWhiteBalanceEnabled(true);
- setNightDisplayActivated(false /* activated */, -30 /* lastActivatedTimeOffset */);
+ mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_SATURATED);
startService();
- mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
+ assertDwbActive(false);
+ mBinderService.setColorMode(ColorDisplayManager.COLOR_MODE_NATURAL);
mCds.updateDisplayWhiteBalanceStatus();
assertDwbActive(true);
}
@@ -1032,10 +1029,8 @@ public class ColorDisplayServiceTest {
@Test
public void displayWhiteBalance_disabledWhileAccessibilityColorCorrectionEnabled() {
setDisplayWhiteBalanceEnabled(true);
- startService();
setAccessibilityColorCorrection(true);
-
- mCds.updateDisplayWhiteBalanceStatus();
+ startService();
assertDwbActive(false);
setAccessibilityColorCorrection(false);
@@ -1046,10 +1041,8 @@ public class ColorDisplayServiceTest {
@Test
public void displayWhiteBalance_disabledWhileAccessibilityColorInversionEnabled() {
setDisplayWhiteBalanceEnabled(true);
- startService();
setAccessibilityColorInversion(true);
-
- mCds.updateDisplayWhiteBalanceStatus();
+ startService();
assertDwbActive(false);
setAccessibilityColorInversion(false);
@@ -1159,7 +1152,7 @@ public class ColorDisplayServiceTest {
InstrumentationRegistry.getInstrumentation().runOnMainSync(() -> {
mCds.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
- mCds.onStartUser(mUserId);
+ mCds.onUserChanged(mUserId);
});
}
diff --git a/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
new file mode 100644
index 000000000000..6b0798bdce22
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/display/whitebalance/AmbientLuxTest.java
@@ -0,0 +1,490 @@
+/*
+ * 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.server.display.whitebalance;
+
+import com.android.internal.R;
+import com.google.common.collect.ImmutableList;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyLong;
+import static org.mockito.Matchers.eq;
+import org.mockito.stubbing.Answer;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import org.mockito.Spy;
+
+import android.content.ContextWrapper;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.TypedValue;
+
+import androidx.test.InstrumentationRegistry;
+
+import org.junit.Before;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.List;
+
+@RunWith(JUnit4.class)
+public final class AmbientLuxTest {
+ private static final int AMBIENT_COLOR_TYPE = 20705;
+ private static final String AMBIENT_COLOR_TYPE_STR = "colorSensoryDensoryDoc";
+ private static final float LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE = 5432.1f;
+ private static final float HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE = 3456.7f;
+
+ private Handler mHandler = new Handler(Looper.getMainLooper());
+ private Sensor mLightSensor;
+ private Sensor mAmbientColorSensor;
+ private ContextWrapper mContextSpy;
+ private Resources mResourcesSpy;
+
+ @Mock private SensorManager mSensorManagerMock;
+
+ @Mock private TypedArray mBrightnesses;
+ @Mock private TypedArray mBiases;
+ @Mock private TypedArray mHighLightBrightnesses;
+ @Mock private TypedArray mHighLightBiases;
+
+ @Before
+ public void setUp() throws Exception {
+ MockitoAnnotations.initMocks(this);
+ mLightSensor = createSensor(Sensor.TYPE_LIGHT, null);
+ mAmbientColorSensor = createSensor(AMBIENT_COLOR_TYPE, AMBIENT_COLOR_TYPE_STR);
+ mContextSpy = spy(new ContextWrapper(InstrumentationRegistry.getContext()));
+ mResourcesSpy = spy(mContextSpy.getResources());
+ when(mContextSpy.getResources()).thenReturn(mResourcesSpy);
+ when(mSensorManagerMock.getDefaultSensor(Sensor.TYPE_LIGHT)).thenReturn(mLightSensor);
+ final List<Sensor> sensorList = ImmutableList.of(mLightSensor, mAmbientColorSensor);
+ when(mSensorManagerMock.getSensorList(Sensor.TYPE_ALL)).thenReturn(sensorList);
+ when(mResourcesSpy.getString(
+ R.string.config_displayWhiteBalanceColorTemperatureSensorName))
+ .thenReturn(AMBIENT_COLOR_TYPE_STR);
+ when(mResourcesSpy.getInteger(
+ R.integer.config_displayWhiteBalanceDecreaseDebounce))
+ .thenReturn(0);
+ when(mResourcesSpy.getInteger(
+ R.integer.config_displayWhiteBalanceIncreaseDebounce))
+ .thenReturn(0);
+ mockResourcesFloat(R.dimen.config_displayWhiteBalanceLowLightAmbientColorTemperature,
+ LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE);
+ mockResourcesFloat(R.dimen.config_displayWhiteBalanceHighLightAmbientColorTemperature,
+ HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE);
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceAmbientColorTemperatures))
+ .thenReturn(createTypedArray());
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceDisplayColorTemperatures))
+ .thenReturn(createTypedArray());
+
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceLowLightAmbientBrightnesses))
+ .thenReturn(mBrightnesses);
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceLowLightAmbientBiases))
+ .thenReturn(mBiases);
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceHighLightAmbientBrightnesses))
+ .thenReturn(mHighLightBrightnesses);
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceHighLightAmbientBiases))
+ .thenReturn(mHighLightBiases);
+ mockThrottler();
+ }
+
+ @Test
+ public void testNoSpline() throws Exception {
+ setBrightnesses();
+ setBiases();
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ ambientColorTemperature, 0.001);
+ }
+ }
+
+ @Test
+ public void testSpline_OneSegment() throws Exception {
+ final float lowerBrightness = 10.0f;
+ final float upperBrightness = 50.0f;
+ setBrightnesses(lowerBrightness, upperBrightness);
+ setBiases(0.0f, 1.0f);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+ setEstimatedBrightnessAndUpdate(controller,
+ mix(lowerBrightness, upperBrightness, t));
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, t), 0.001);
+ }
+
+ setEstimatedBrightnessAndUpdate(controller, 0.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+ setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+ }
+
+ @Test
+ public void testSpline_TwoSegments() throws Exception {
+ final float brightness0 = 10.0f;
+ final float brightness1 = 50.0f;
+ final float brightness2 = 60.0f;
+ setBrightnesses(brightness0, brightness1, brightness2);
+ final float bias0 = 0.0f;
+ final float bias1 = 0.25f;
+ final float bias2 = 1.0f;
+ setBiases(bias0, bias1, bias2);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+ float luxOverride = mix(brightness0, brightness1, t);
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ float bias = mix(bias0, bias1, t);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, bias), 0.001);
+ }
+
+ for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+ float luxOverride = mix(brightness1, brightness2, t);
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ float bias = mix(bias1, bias2, t);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ mix(LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, bias), 0.001);
+ }
+
+ setEstimatedBrightnessAndUpdate(controller, 0.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+ setEstimatedBrightnessAndUpdate(controller, brightness2 + 1.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+ }
+
+ @Test
+ public void testSpline_VerticalSegment() throws Exception {
+ final float lowerBrightness = 10.0f;
+ final float upperBrightness = 10.0f;
+ setBrightnesses(lowerBrightness, upperBrightness);
+ setBiases(0.0f, 1.0f);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ setEstimatedBrightnessAndUpdate(controller, 0.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ LOW_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+ setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+ }
+
+ @Test
+ public void testSpline_InvalidEndBias() throws Exception {
+ setBrightnesses(10.0f, 1000.0f);
+ setBiases(0.0f, 2.0f);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ ambientColorTemperature, 0.001);
+ }
+ }
+
+ @Test
+ public void testSpline_InvalidBeginBias() throws Exception {
+ setBrightnesses(10.0f, 1000.0f);
+ setBiases(0.1f, 1.0f);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ ambientColorTemperature, 0.001);
+ }
+ }
+
+ @Test
+ public void testSpline_OneSegmentHighLight() throws Exception {
+ final float lowerBrightness = 10.0f;
+ final float upperBrightness = 50.0f;
+ setHighLightBrightnesses(lowerBrightness, upperBrightness);
+ setHighLightBiases(0.0f, 1.0f);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+ setEstimatedBrightnessAndUpdate(controller,
+ mix(lowerBrightness, upperBrightness, t));
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ mix(HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, 1.0f - t),
+ 0.001);
+ }
+
+ setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+ setEstimatedBrightnessAndUpdate(controller, 0.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+ }
+
+ @Test
+ public void testSpline_TwoSegmentsHighLight() throws Exception {
+ final float brightness0 = 10.0f;
+ final float brightness1 = 50.0f;
+ final float brightness2 = 60.0f;
+ setHighLightBrightnesses(brightness0, brightness1, brightness2);
+ final float bias0 = 0.0f;
+ final float bias1 = 0.25f;
+ final float bias2 = 1.0f;
+ setHighLightBiases(bias0, bias1, bias2);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 6000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+ float luxOverride = mix(brightness0, brightness1, t);
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ float bias = mix(bias0, bias1, t);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ mix(HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, 1.0f - bias),
+ 0.01);
+ }
+
+ for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+ float luxOverride = mix(brightness1, brightness2, t);
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ float bias = mix(bias1, bias2, t);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ mix(HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, ambientColorTemperature, 1.0f - bias),
+ 0.01);
+ }
+
+ setEstimatedBrightnessAndUpdate(controller, brightness2 + 1.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ HIGH_LIGHT_AMBIENT_COLOR_TEMPERATURE, 0.001);
+
+ setEstimatedBrightnessAndUpdate(controller, 0.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+ }
+
+ @Test
+ public void testSpline_InvalidCombinations() throws Exception {
+ setBrightnesses(100.0f, 200.0f);
+ setBiases(0.0f, 1.0f);
+ setHighLightBrightnesses(150.0f, 250.0f);
+ setHighLightBiases(0.0f, 1.0f);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = 8000.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float luxOverride = 0.1f; luxOverride <= 10000; luxOverride *= 10) {
+ setEstimatedBrightnessAndUpdate(controller, luxOverride);
+ assertEquals(controller.mPendingAmbientColorTemperature,
+ ambientColorTemperature, 0.001);
+ }
+ }
+
+ @Test
+ public void testLowLight_DefaultAmbient() throws Exception {
+ final float lowerBrightness = 10.0f;
+ final float upperBrightness = 50.0f;
+ setBrightnesses(lowerBrightness, upperBrightness);
+ setBiases(0.0f, 1.0f);
+
+ DisplayWhiteBalanceController controller =
+ DisplayWhiteBalanceFactory.create(mHandler, mSensorManagerMock, mResourcesSpy);
+ final float ambientColorTemperature = -1.0f;
+ setEstimatedColorTemperature(controller, ambientColorTemperature);
+ controller.mBrightnessFilter = spy(controller.mBrightnessFilter);
+
+ for (float t = 0.0f; t <= 1.0f; t += 0.1f) {
+ setEstimatedBrightnessAndUpdate(controller,
+ mix(lowerBrightness, upperBrightness, t));
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature,
+ 0.001);
+ }
+
+ setEstimatedBrightnessAndUpdate(controller, 0.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+
+ setEstimatedBrightnessAndUpdate(controller, upperBrightness + 1.0f);
+ assertEquals(controller.mPendingAmbientColorTemperature, ambientColorTemperature, 0.001);
+ }
+
+ void mockThrottler() {
+ when(mResourcesSpy.getInteger(
+ R.integer.config_displayWhiteBalanceDecreaseDebounce)).thenReturn(0);
+ when(mResourcesSpy.getInteger(
+ R.integer.config_displayWhiteBalanceIncreaseDebounce)).thenReturn(0);
+ TypedArray base = mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceBaseThresholds);
+ TypedArray inc = mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceIncreaseThresholds);
+ TypedArray dec = mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceDecreaseThresholds);
+ base = spy(base);
+ inc = spy(inc);
+ dec = spy(dec);
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceBaseThresholds)).thenReturn(base);
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceIncreaseThresholds)).thenReturn(inc);
+ when(mResourcesSpy.obtainTypedArray(
+ R.array.config_displayWhiteBalanceDecreaseThresholds)).thenReturn(dec);
+ setFloatArrayResource(base, new float[]{0.0f});
+ setFloatArrayResource(inc, new float[]{0.0f});
+ setFloatArrayResource(dec, new float[]{0.0f});
+ }
+
+ private void mockResourcesFloat(int id, float floatValue) {
+ doAnswer(new Answer<Void>() {
+ public Void answer(InvocationOnMock invocation) {
+ TypedValue value = (TypedValue)invocation.getArgument(1);
+ value.type = TypedValue.TYPE_FLOAT;
+ value.data = Float.floatToIntBits(floatValue);
+ return null;
+ }
+ }).when(mResourcesSpy).getValue(
+ eq(id),
+ any(TypedValue.class), eq(true));
+ }
+
+ private void setEstimatedColorTemperature(DisplayWhiteBalanceController controller,
+ float ambientColorTemperature) {
+ AmbientFilter colorTemperatureFilter = spy(controller.mColorTemperatureFilter);
+ controller.mColorTemperatureFilter = colorTemperatureFilter;
+ when(colorTemperatureFilter.getEstimate(anyLong())).thenReturn(ambientColorTemperature);
+ }
+
+ private void setEstimatedBrightnessAndUpdate(DisplayWhiteBalanceController controller,
+ float brightness) {
+ when(controller.mBrightnessFilter.getEstimate(anyLong())).thenReturn(brightness);
+ controller.updateAmbientColorTemperature();
+ }
+
+ private void setBrightnesses(float... vals) {
+ setFloatArrayResource(mBrightnesses, vals);
+ }
+
+ private void setBiases(float... vals) {
+ setFloatArrayResource(mBiases, vals);
+ }
+
+ private void setHighLightBrightnesses(float... vals) {
+ setFloatArrayResource(mHighLightBrightnesses, vals);
+ }
+
+ private void setHighLightBiases(float... vals) {
+ setFloatArrayResource(mHighLightBiases, vals);
+ }
+
+ private void setFloatArrayResource(TypedArray array, float[] vals) {
+ when(array.length()).thenReturn(vals.length);
+ for (int i = 0; i < vals.length; i++) {
+ when(array.getFloat(i, Float.NaN)).thenReturn(vals[i]);
+ }
+ }
+
+ private void setSensorType(Sensor sensor, int type, String strType) throws Exception {
+ Method setter = Sensor.class.getDeclaredMethod("setType", Integer.TYPE);
+ setter.setAccessible(true);
+ setter.invoke(sensor, type);
+ if (strType != null) {
+ Field f = sensor.getClass().getDeclaredField("mStringType");
+ f.setAccessible(true);
+ f.set(sensor, strType);
+ }
+ }
+
+ private Sensor createSensor(int type, String strType) throws Exception {
+ Constructor<Sensor> constr = Sensor.class.getDeclaredConstructor();
+ constr.setAccessible(true);
+ Sensor sensor = constr.newInstance();
+ setSensorType(sensor, type, strType);
+ return sensor;
+ }
+
+ private TypedArray createTypedArray() throws Exception {
+ TypedArray mockArray = mock(TypedArray.class);
+ return mockArray;
+ }
+
+ private static float mix(float a, float b, float t) {
+ return (1.0f - t) * a + t * b;
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index f85e2cc10800..5c67d0422aca 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -110,7 +110,7 @@ public class LockSettingsServiceTestable extends LockSettingsService {
}
@Override
- public boolean hasEnrolledBiometrics() {
+ public boolean hasEnrolledBiometrics(int userId) {
return false;
}
diff --git a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
index a63f49b1fe3d..44769180824e 100644
--- a/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/AttentionDetectorTest.java
@@ -42,6 +42,8 @@ import android.service.attention.AttentionService;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.SmallTest;
+import com.android.server.wm.WindowManagerInternal;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -57,6 +59,8 @@ public class AttentionDetectorTest extends AndroidTestCase {
@Mock
private AttentionManagerInternal mAttentionManagerInternal;
@Mock
+ private WindowManagerInternal mWindowManagerInternal;
+ @Mock
private Runnable mOnUserAttention;
private TestableAttentionDetector mAttentionDetector;
private long mAttentionTimeout;
@@ -71,6 +75,7 @@ public class AttentionDetectorTest extends AndroidTestCase {
PackageManager.PERMISSION_GRANTED);
when(mAttentionManagerInternal.checkAttention(anyLong(), any()))
.thenReturn(true);
+ when(mWindowManagerInternal.isKeyguardShowingAndNotOccluded()).thenReturn(false);
mAttentionDetector = new TestableAttentionDetector();
mAttentionDetector.onWakefulnessChangeStarted(PowerManagerInternal.WAKEFULNESS_AWAKE);
mAttentionDetector.setAttentionServiceSupported(true);
@@ -117,6 +122,15 @@ public class AttentionDetectorTest extends AndroidTestCase {
}
@Test
+ public void testOnUserActivity_doesntCheckIfInLockscreen() {
+ when(mWindowManagerInternal.isKeyguardShowingAndNotOccluded()).thenReturn(true);
+
+ long when = registerAttention();
+ verify(mAttentionManagerInternal, never()).checkAttention(anyLong(), any());
+ assertThat(mNextDimming).isEqualTo(when);
+ }
+
+ @Test
public void testOnUserActivity_doesntCheckIfNotSufficientPermissions() {
when(mPackageManager.checkPermission(any(), any())).thenReturn(
PackageManager.PERMISSION_DENIED);
@@ -299,6 +313,7 @@ public class AttentionDetectorTest extends AndroidTestCase {
TestableAttentionDetector() {
super(AttentionDetectorTest.this.mOnUserAttention, new Object());
mAttentionManager = mAttentionManagerInternal;
+ mWindowManager = mWindowManagerInternal;
mPackageManager = AttentionDetectorTest.this.mPackageManager;
mContentResolver = getContext().getContentResolver();
mMaximumExtensionMillis = 10000L;
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 2ce33fcc62b4..8c4544249b5c 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -50,6 +50,9 @@
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityRequestedOrientationChange" />
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityTaskChangeCallbacks" />
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityTaskDescriptionChange" />
+ <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityViewTestActivity" />
+ <activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityInActivityView"
+ android:resizeableActivity="true" />
<activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity"
android:showWhenLocked="true" />
</application>
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
index 4986a6d5bd0d..ecf3acd32d4f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTestsBase.java
@@ -85,6 +85,7 @@ import org.mockito.invocation.InvocationOnMock;
import java.io.File;
import java.util.List;
+import java.util.function.Consumer;
/**
* A base class to handle common operations in activity related unit tests.
@@ -169,8 +170,12 @@ class ActivityTestsBase {
* Delegates task creation to {@link #TaskBuilder} to avoid the dependency of window hierarchy
* when starting activity in unit tests.
*/
- void mockTaskRecordFactory() {
- final TaskRecord task = new TaskBuilder(mSupervisor).setCreateStack(false).build();
+ void mockTaskRecordFactory(Consumer<TaskBuilder> taskBuilderSetup) {
+ final TaskBuilder taskBuilder = new TaskBuilder(mSupervisor).setCreateStack(false);
+ if (taskBuilderSetup != null) {
+ taskBuilderSetup.accept(taskBuilder);
+ }
+ final TaskRecord task = taskBuilder.build();
final TaskRecordFactory factory = mock(TaskRecordFactory.class);
TaskRecord.setTaskRecordFactory(factory);
doReturn(task).when(factory).create(any() /* service */, anyInt() /* taskId */,
@@ -178,6 +183,10 @@ class ActivityTestsBase {
any() /* voiceInteractor */);
}
+ void mockTaskRecordFactory() {
+ mockTaskRecordFactory(null /* taskBuilderSetup */);
+ }
+
/**
* Builder for creating new activities.
*/
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 1f8b33eb5bb4..9630b7d46e3c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -42,8 +42,11 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import android.app.IApplicationThread;
import android.content.ComponentName;
import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
import android.platform.test.annotations.Presubmit;
import android.view.IRecentsAnimationRunner;
@@ -111,6 +114,57 @@ public class RecentsAnimationTest extends ActivityTestsBase {
}
@Test
+ public void testPreloadRecentsActivity() {
+ // Ensure that the fake recent component can be resolved by the recents intent.
+ mockTaskRecordFactory(builder -> builder.setComponent(mRecentsComponent));
+ ActivityInfo aInfo = new ActivityInfo();
+ aInfo.applicationInfo = new ApplicationInfo();
+ aInfo.applicationInfo.uid = 10001;
+ aInfo.applicationInfo.targetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
+ aInfo.packageName = aInfo.applicationInfo.packageName = mRecentsComponent.getPackageName();
+ aInfo.processName = "recents";
+ doReturn(aInfo).when(mSupervisor).resolveActivity(any() /* intent */, any() /* rInfo */,
+ anyInt() /* startFlags */, any() /* profilerInfo */);
+
+ // Assume its process is alive because the caller should be the recents service.
+ WindowProcessController wpc = new WindowProcessController(mService, 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));
+
+ Intent recentsIntent = new Intent().setComponent(mRecentsComponent);
+ // Null animation indicates to preload.
+ mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
+ null /* recentsAnimationRunner */);
+
+ ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
+ ActivityStack recentsStack = display.getStack(WINDOWING_MODE_FULLSCREEN,
+ ACTIVITY_TYPE_RECENTS);
+ assertThat(recentsStack).isNotNull();
+
+ ActivityRecord recentsActivity = recentsStack.getTopActivity();
+ // The activity is started in background so it should be invisible and will be stopped.
+ assertThat(recentsActivity).isNotNull();
+ assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity);
+ assertFalse(recentsActivity.visible);
+
+ // Assume it is stopped to test next use case.
+ recentsActivity.activityStoppedLocked(null /* newIcicle */, null /* newPersistentState */,
+ null /* description */);
+ mSupervisor.mStoppingActivities.remove(recentsActivity);
+
+ spyOn(recentsActivity);
+ // Start when the recents activity exists. It should ensure the configuration.
+ mService.startRecentsActivity(recentsIntent, null /* assistDataReceiver */,
+ null /* recentsAnimationRunner */);
+
+ verify(recentsActivity).ensureActivityConfiguration(anyInt() /* globalChanges */,
+ anyBoolean() /* preserveWindow */, eq(true) /* ignoreVisibility */);
+ assertThat(mSupervisor.mStoppingActivities).contains(recentsActivity);
+ }
+
+ @Test
public void testRestartRecentsActivity() throws Exception {
// Have a recents activity that is not attached to its process (ActivityRecord.app = null).
ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
index 62247d889485..19fd93fee5f0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskStackChangedListenerTest.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static org.junit.Assert.assertEquals;
@@ -26,18 +28,22 @@ import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.TaskDescription;
import android.app.ActivityTaskManager;
+import android.app.ActivityView;
import android.app.IActivityManager;
import android.app.ITaskStackListener;
+import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.app.TaskStackListener;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
+import android.os.Bundle;
import android.os.RemoteException;
import android.platform.test.annotations.Presubmit;
import android.support.test.uiautomator.UiDevice;
import android.text.TextUtils;
+import android.view.ViewGroup;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.MediumTest;
@@ -231,6 +237,40 @@ public class TaskStackChangedListenerTest {
assertTrue(activity.mOnDetachedFromWindowCalled);
}
+ @Test
+ public void testTaskOnSingleTaskDisplayDrawn() throws Exception {
+ final Instrumentation instrumentation = getInstrumentation();
+
+ final CountDownLatch activityViewReadyLatch = new CountDownLatch(1);
+ final CountDownLatch singleTaskDisplayDrawnLatch = new CountDownLatch(1);
+ registerTaskStackChangedListener(new TaskStackListener() {
+ @Override
+ public void onSingleTaskDisplayDrawn(int displayId) throws RemoteException {
+ singleTaskDisplayDrawnLatch.countDown();
+ }
+ });
+ final ActivityViewTestActivity activity =
+ (ActivityViewTestActivity) startTestActivity(ActivityViewTestActivity.class);
+ final ActivityView activityView = activity.getActivityView();
+ activityView.setCallback(new ActivityView.StateCallback() {
+ @Override
+ public void onActivityViewReady(ActivityView view) {
+ activityViewReadyLatch.countDown();
+ }
+
+ @Override
+ public void onActivityViewDestroyed(ActivityView view) {
+ }
+ });
+ waitForCallback(activityViewReadyLatch);
+
+ final Context context = instrumentation.getContext();
+ Intent intent = new Intent(context, ActivityInActivityView.class);
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ activityView.startActivity(intent);
+ waitForCallback(singleTaskDisplayDrawnLatch);
+ }
+
/**
* Starts the provided activity and returns the started instance.
*/
@@ -369,4 +409,29 @@ public class TaskStackChangedListenerTest {
mOnDetachedFromWindowCountDownLatch = countDownLatch;
}
}
+
+ public static class ActivityViewTestActivity extends TestActivity {
+ private ActivityView mActivityView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mActivityView = new ActivityView(this, null /* attrs */, 0 /* defStyle */,
+ true /* singleTaskInstance */);
+ setContentView(mActivityView);
+
+ ViewGroup.LayoutParams layoutParams = mActivityView.getLayoutParams();
+ layoutParams.width = MATCH_PARENT;
+ layoutParams.height = MATCH_PARENT;
+ mActivityView.requestLayout();
+ }
+
+ ActivityView getActivityView() {
+ return mActivityView;
+ }
+ }
+
+ // Activity that has {@link android.R.attr#resizeableActivity} attribute set to {@code true}
+ public static class ActivityInActivityView extends TestActivity {}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
index 83aa620b9573..a7586810a824 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestIWindow.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import android.graphics.Point;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -43,6 +44,10 @@ public class TestIWindow extends IWindow.Stub {
}
@Override
+ public void locationInParentDisplayChanged(Point offset) throws RemoteException {
+ }
+
+ @Override
public void insetsChanged(InsetsState insetsState) throws RemoteException {
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index d034f274f1e1..2e5ce69a8564 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -142,7 +142,7 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public Animation createHiddenByKeyguardExit(boolean onWallpaper,
- boolean goingToNotificationShade) {
+ boolean goingToNotificationShade, boolean subtleAnimation) {
return null;
}
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
index 7a834696387c..a8cafb33790d 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerService.java
@@ -61,6 +61,7 @@ import android.os.Parcel;
import android.os.ParcelUuid;
import android.os.PowerManager;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.ArrayMap;
@@ -75,6 +76,7 @@ import com.android.server.SystemService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Map;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@@ -102,6 +104,80 @@ public class SoundTriggerService extends SystemService {
private Object mCallbacksLock;
private final TreeMap<UUID, IRecognitionStatusCallback> mCallbacks;
+ class SoundModelStatTracker {
+ private class SoundModelStat {
+ SoundModelStat() {
+ mStartCount = 0;
+ mTotalTimeMsec = 0;
+ mLastStartTimestampMsec = 0;
+ mLastStopTimestampMsec = 0;
+ mIsStarted = false;
+ }
+ long mStartCount; // Number of times that given model started
+ long mTotalTimeMsec; // Total time (msec) that given model was running since boot
+ long mLastStartTimestampMsec; // SystemClock.elapsedRealtime model was last started
+ long mLastStopTimestampMsec; // SystemClock.elapsedRealtime model was last stopped
+ boolean mIsStarted; // true if model is currently running
+ }
+ private final TreeMap<UUID, SoundModelStat> mModelStats;
+
+ SoundModelStatTracker() {
+ mModelStats = new TreeMap<UUID, SoundModelStat>();
+ }
+
+ public synchronized void onStart(UUID id) {
+ SoundModelStat stat = mModelStats.get(id);
+ if (stat == null) {
+ stat = new SoundModelStat();
+ mModelStats.put(id, stat);
+ }
+
+ if (stat.mIsStarted) {
+ Slog.e(TAG, "error onStart(): Model " + id + " already started");
+ return;
+ }
+
+ stat.mStartCount++;
+ stat.mLastStartTimestampMsec = SystemClock.elapsedRealtime();
+ stat.mIsStarted = true;
+ }
+
+ public synchronized void onStop(UUID id) {
+ SoundModelStat stat = mModelStats.get(id);
+ if (stat == null) {
+ Slog.e(TAG, "error onStop(): Model " + id + " has no stats available");
+ return;
+ }
+
+ if (!stat.mIsStarted) {
+ Slog.e(TAG, "error onStop(): Model " + id + " already stopped");
+ return;
+ }
+
+ stat.mLastStopTimestampMsec = SystemClock.elapsedRealtime();
+ stat.mTotalTimeMsec += stat.mLastStopTimestampMsec - stat.mLastStartTimestampMsec;
+ stat.mIsStarted = false;
+ }
+
+ public synchronized void dump(PrintWriter pw) {
+ long curTime = SystemClock.elapsedRealtime();
+ pw.println("Model Stats:");
+ for (Map.Entry<UUID, SoundModelStat> entry : mModelStats.entrySet()) {
+ UUID uuid = entry.getKey();
+ SoundModelStat stat = entry.getValue();
+ long totalTimeMsec = stat.mTotalTimeMsec;
+ if (stat.mIsStarted) {
+ totalTimeMsec += curTime - stat.mLastStartTimestampMsec;
+ }
+ pw.println(uuid + ", total_time(msec)=" + totalTimeMsec
+ + ", total_count=" + stat.mStartCount
+ + ", last_start=" + stat.mLastStartTimestampMsec
+ + ", last_stop=" + stat.mLastStopTimestampMsec);
+ }
+ }
+ }
+
+ private final SoundModelStatTracker mSoundModelStatTracker;
/** Number of ops run by the {@link RemoteSoundTriggerDetectionService} per package name */
@GuardedBy("mLock")
private final ArrayMap<String, NumOps> mNumOpsPerPackage = new ArrayMap<>();
@@ -115,6 +191,7 @@ public class SoundTriggerService extends SystemService {
mCallbacksLock = new Object();
mCallbacks = new TreeMap<>();
mLock = new Object();
+ mSoundModelStatTracker = new SoundModelStatTracker();
}
@Override
@@ -193,8 +270,12 @@ public class SoundTriggerService extends SystemService {
return STATUS_ERROR;
}
- return mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
+ int ret = mSoundTriggerHelper.startGenericRecognition(parcelUuid.getUuid(), model,
callback, config);
+ if (ret == STATUS_OK) {
+ mSoundModelStatTracker.onStart(parcelUuid.getUuid());
+ }
+ return ret;
}
@Override
@@ -208,7 +289,12 @@ public class SoundTriggerService extends SystemService {
+ parcelUuid));
if (!isInitialized()) return STATUS_ERROR;
- return mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(), callback);
+
+ int ret = mSoundTriggerHelper.stopGenericRecognition(parcelUuid.getUuid(), callback);
+ if (ret == STATUS_OK) {
+ mSoundModelStatTracker.onStop(parcelUuid.getUuid());
+ }
+ return ret;
}
@Override
@@ -252,6 +338,9 @@ public class SoundTriggerService extends SystemService {
// Unload the model if it is loaded.
mSoundTriggerHelper.unloadGenericSoundModel(soundModelId.getUuid());
mDbHelper.deleteGenericSoundModel(soundModelId.getUuid());
+
+ // Stop recognition if it is started.
+ mSoundModelStatTracker.onStop(soundModelId.getUuid());
}
@Override
@@ -403,6 +492,8 @@ public class SoundTriggerService extends SystemService {
synchronized (mCallbacksLock) {
mCallbacks.put(soundModelId.getUuid(), callback);
}
+
+ mSoundModelStatTracker.onStart(soundModelId.getUuid());
}
return STATUS_OK;
}
@@ -467,6 +558,8 @@ public class SoundTriggerService extends SystemService {
synchronized (mCallbacksLock) {
mCallbacks.remove(soundModelId.getUuid());
}
+
+ mSoundModelStatTracker.onStop(soundModelId.getUuid());
}
return STATUS_OK;
}
@@ -1266,6 +1359,9 @@ public class SoundTriggerService extends SystemService {
mSoundTriggerHelper.dump(fd, pw, args);
// log
sEventLogger.dump(pw);
+
+ // stats
+ mSoundModelStatTracker.dump(pw);
}
private synchronized boolean isInitialized() {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 6a88825a8188..a9e489951a93 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -852,6 +852,19 @@ public class CarrierConfigManager {
"carrier_metered_roaming_apn_types_strings";
/**
+ * APN types that are not allowed on cellular
+ * @hide
+ */
+ public static final String KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY =
+ "carrier_wwan_disallowed_apn_types_string_array";
+
+ /**
+ * APN types that are not allowed on IWLAN
+ * @hide
+ */
+ public static final String KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY =
+ "carrier_wlan_disallowed_apn_types_string_array";
+ /**
* CDMA carrier ERI (Enhanced Roaming Indicator) file name
* @hide
*/
@@ -3173,6 +3186,10 @@ public class CarrierConfigManager {
new String[]{"default", "mms", "dun", "supl"});
sDefaults.putStringArray(KEY_CARRIER_METERED_ROAMING_APN_TYPES_STRINGS,
new String[]{"default", "mms", "dun", "supl"});
+ sDefaults.putStringArray(KEY_CARRIER_WWAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
+ new String[]{""});
+ sDefaults.putStringArray(KEY_CARRIER_WLAN_DISALLOWED_APN_TYPES_STRING_ARRAY,
+ new String[]{""});
sDefaults.putIntArray(KEY_ONLY_SINGLE_DC_ALLOWED_INT_ARRAY,
new int[]{
4, /* IS95A */
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 1c048571f12f..484fd3b17c02 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2984,10 +2984,10 @@ public class SubscriptionManager {
* @param info the subscriptionInfo to check against.
* @return true if this subscription should be visible to the API caller.
*
+ * @hide
*/
- private boolean isSubscriptionVisible(SubscriptionInfo info) {
+ public boolean isSubscriptionVisible(SubscriptionInfo info) {
if (info == null) return false;
-
// If subscription is NOT grouped opportunistic subscription, it's visible.
if (info.getGroupUuid() == null || !info.isOpportunistic()) return true;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index b38d35a0a792..22a8232d1a0b 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -10920,6 +10920,9 @@ public class TelephonyManager {
try {
IOns iOpportunisticNetworkService = getIOns();
if (iOpportunisticNetworkService == null || availableNetworks == null) {
+ if (executor == null || callback == null) {
+ return;
+ }
Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
callback.accept(UPDATE_AVAILABLE_NETWORKS_INVALID_ARGUMENTS);
}));
diff --git a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index f2f3c2d85fd4..dc026d48c6cf 100644
--- a/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -68,8 +68,7 @@ interface ITelephonyRegistry {
void notifyOtaspChanged(in int subId, in int otaspMode);
@UnsupportedAppUsage
void notifyCellInfo(in List<CellInfo> cellInfo);
- void notifyPhysicalChannelConfiguration(in List<PhysicalChannelConfig> configs);
- void notifyPhysicalChannelConfigurationForSubscriber(in int subId,
+ void notifyPhysicalChannelConfigurationForSubscriber(in int phoneId, in int subId,
in List<PhysicalChannelConfig> configs);
void notifyPreciseCallState(int phoneId, int subId, int ringingCallState,
int foregroundCallState, int backgroundCallState);
diff --git a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
index 45ddc3eed39c..f88a7c41c02b 100644
--- a/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
+++ b/tests/Internal/src/com/android/internal/colorextraction/ColorExtractorTest.java
@@ -39,8 +39,6 @@ import com.android.internal.colorextraction.types.Tonal;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
/**
* Tests color extraction generation.
@@ -49,14 +47,13 @@ import org.mockito.MockitoAnnotations;
@RunWith(AndroidJUnit4.class)
public class ColorExtractorTest {
- Context mContext;
- @Mock
- WallpaperManager mWallpaperManager;
+ private Context mContext;
+ private WallpaperManager mWallpaperManager;
@Before
public void setup() {
- MockitoAnnotations.initMocks(this);
mContext = InstrumentationRegistry.getContext();
+ mWallpaperManager = mock(WallpaperManager.class);
}
@Test
diff --git a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
index 388c7d03dff2..c50229ae30f4 100644
--- a/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
+++ b/tests/permission/src/com/android/framework/permission/tests/VibratorServicePermissionTest.java
@@ -16,9 +16,7 @@
package com.android.framework.permission.tests;
-import junit.framework.TestCase;
-
-import android.media.AudioManager;
+import android.media.AudioAttributes;
import android.os.Binder;
import android.os.IVibratorService;
import android.os.Process;
@@ -27,6 +25,9 @@ import android.os.ServiceManager;
import android.os.VibrationEffect;
import android.test.suitebuilder.annotation.SmallTest;
+import junit.framework.TestCase;
+
+
/**
* Verify that Hardware apis cannot be called without required permissions.
*/
@@ -51,7 +52,10 @@ public class VibratorServicePermissionTest extends TestCase {
try {
final VibrationEffect effect =
VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE);
- mVibratorService.vibrate(Process.myUid(), null, effect, AudioManager.STREAM_ALARM,
+ final AudioAttributes attrs = new AudioAttributes.Builder()
+ .setUsage(AudioAttributes.USAGE_ALARM)
+ .build();
+ mVibratorService.vibrate(Process.myUid(), null, effect, attrs,
"testVibrate", new Binder());
fail("vibrate did not throw SecurityException as expected");
} catch (SecurityException e) {