summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp42
-rw-r--r--core/api/current.txt15
-rw-r--r--core/api/system-current.txt1
-rw-r--r--core/api/test-current.txt1
-rw-r--r--core/java/Android.bp39
-rw-r--r--core/java/android/annotation/AnimRes.java37
-rw-r--r--core/java/android/annotation/AnimatorRes.java37
-rw-r--r--core/java/android/annotation/AnyRes.java39
-rw-r--r--core/java/android/annotation/AnyThread.java51
-rw-r--r--core/java/android/annotation/AppIdInt.java36
-rw-r--r--core/java/android/annotation/ArrayRes.java37
-rw-r--r--core/java/android/annotation/AttrRes.java37
-rw-r--r--core/java/android/annotation/BinderThread.java43
-rw-r--r--core/java/android/annotation/BoolRes.java37
-rw-r--r--core/java/android/annotation/BroadcastBehavior.java61
-rw-r--r--core/java/android/annotation/BytesLong.java36
-rw-r--r--core/java/android/annotation/CallSuper.java43
-rw-r--r--core/java/android/annotation/CallbackExecutor.java39
-rw-r--r--core/java/android/annotation/CheckResult.java58
-rw-r--r--core/java/android/annotation/ColorInt.java42
-rw-r--r--core/java/android/annotation/ColorLong.java48
-rw-r--r--core/java/android/annotation/ColorRes.java37
-rw-r--r--core/java/android/annotation/Condemned.java44
-rw-r--r--core/java/android/annotation/CurrentTimeMillisLong.java39
-rw-r--r--core/java/android/annotation/CurrentTimeSecondsLong.java39
-rw-r--r--core/java/android/annotation/DimenRes.java37
-rw-r--r--core/java/android/annotation/Dimension.java50
-rw-r--r--core/java/android/annotation/DisplayContext.java60
-rw-r--r--core/java/android/annotation/DrawableRes.java37
-rw-r--r--core/java/android/annotation/DurationMillisLong.java36
-rw-r--r--core/java/android/annotation/ElapsedRealtimeLong.java41
-rw-r--r--core/java/android/annotation/FloatRange.java55
-rw-r--r--core/java/android/annotation/FontRes.java37
-rw-r--r--core/java/android/annotation/FractionRes.java37
-rw-r--r--core/java/android/annotation/HalfFloat.java48
-rw-r--r--core/java/android/annotation/Hide.java41
-rw-r--r--core/java/android/annotation/IdRes.java37
-rw-r--r--core/java/android/annotation/IntDef.java64
-rw-r--r--core/java/android/annotation/IntRange.java48
-rw-r--r--core/java/android/annotation/IntegerRes.java37
-rw-r--r--core/java/android/annotation/InterpolatorRes.java37
-rw-r--r--core/java/android/annotation/LayoutRes.java37
-rw-r--r--core/java/android/annotation/LongDef.java62
-rw-r--r--core/java/android/annotation/MainThread.java47
-rw-r--r--core/java/android/annotation/MenuRes.java37
-rw-r--r--core/java/android/annotation/NavigationRes.java37
-rw-r--r--core/java/android/annotation/NonNull.java38
-rw-r--r--core/java/android/annotation/NonUiContext.java49
-rw-r--r--core/java/android/annotation/Nullable.java45
-rw-r--r--core/java/android/annotation/OWNERS3
-rw-r--r--core/java/android/annotation/PluralsRes.java37
-rw-r--r--core/java/android/annotation/Px.java42
-rw-r--r--core/java/android/annotation/RawRes.java37
-rw-r--r--core/java/android/annotation/RequiresFeature.java52
-rw-r--r--core/java/android/annotation/RequiresNoPermission.java48
-rw-r--r--core/java/android/annotation/RequiresPermission.java137
-rw-r--r--core/java/android/annotation/SdkConstant.java36
-rw-r--r--core/java/android/annotation/Size.java52
-rw-r--r--core/java/android/annotation/StringDef.java56
-rw-r--r--core/java/android/annotation/StringRes.java37
-rw-r--r--core/java/android/annotation/StyleRes.java37
-rw-r--r--core/java/android/annotation/StyleableRes.java37
-rw-r--r--core/java/android/annotation/SuppressAutoDoc.java39
-rw-r--r--core/java/android/annotation/SuppressLint.java38
-rw-r--r--core/java/android/annotation/SystemApi.java80
-rw-r--r--core/java/android/annotation/SystemService.java42
-rw-r--r--core/java/android/annotation/TargetApi.java36
-rw-r--r--core/java/android/annotation/TestApi.java42
-rw-r--r--core/java/android/annotation/TransitionRes.java37
-rw-r--r--core/java/android/annotation/UiContext.java58
-rw-r--r--core/java/android/annotation/UiThread.java51
-rw-r--r--core/java/android/annotation/UptimeMillisLong.java41
-rw-r--r--core/java/android/annotation/UserHandleAware.java49
-rw-r--r--core/java/android/annotation/UserIdInt.java36
-rw-r--r--core/java/android/annotation/Widget.java37
-rw-r--r--core/java/android/annotation/WorkerThread.java48
-rw-r--r--core/java/android/annotation/XmlRes.java37
-rw-r--r--core/java/android/app/ActivityThread.java16
-rw-r--r--core/java/android/app/AppOpsManager.java10
-rw-r--r--core/java/android/app/ApplicationPackageManager.java2
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java14
-rw-r--r--core/java/android/app/people/PeopleSpaceTile.java107
-rw-r--r--core/java/android/content/ContentProvider.java37
-rw-r--r--core/java/android/content/ContentResolver.java86
-rw-r--r--core/java/android/content/pm/ApkChecksum.java6
-rw-r--r--core/java/android/content/pm/ApplicationInfo.java59
-rw-r--r--core/java/android/content/pm/Checksum.java21
-rw-r--r--core/java/android/content/pm/PackageManager.java2
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackageUtils.java7
-rw-r--r--core/java/android/os/AggregateBatteryConsumer.java20
-rw-r--r--core/java/android/os/BatteryStats.java30
-rw-r--r--core/java/android/os/BatteryUsageStats.java87
-rw-r--r--core/java/android/os/FileUtils.java2
-rw-r--r--core/java/android/os/ParcelFileDescriptor.java58
-rw-r--r--core/java/android/os/SystemBatteryConsumer.java198
-rw-r--r--core/java/android/os/VintfObject.java10
-rw-r--r--core/java/android/view/FrameMetrics.java6
-rw-r--r--core/java/android/view/ViewRootImpl.java4
-rw-r--r--core/java/android/view/translation/UiTranslationManager.java10
-rw-r--r--core/java/android/widget/AbsListView.java21
-rw-r--r--core/java/android/widget/EdgeEffect.java67
-rw-r--r--core/java/android/widget/HorizontalScrollView.java21
-rw-r--r--core/java/android/widget/ScrollView.java22
-rw-r--r--core/java/com/android/internal/annotations/CompositeRWLock.java47
-rw-r--r--core/java/com/android/internal/annotations/GuardedBy.java58
-rw-r--r--core/java/com/android/internal/annotations/Immutable.java30
-rw-r--r--core/java/com/android/internal/annotations/VisibleForNative.java28
-rw-r--r--core/java/com/android/internal/annotations/VisibleForTesting.java50
-rw-r--r--core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java6
-rw-r--r--core/java/com/android/internal/os/BatteryChargeCalculator.java31
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java14
-rw-r--r--core/java/com/android/internal/os/BatteryUsageStatsProvider.java2
-rw-r--r--core/java/com/android/internal/os/BluetoothPowerCalculator.java15
-rw-r--r--core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java10
-rw-r--r--core/java/com/android/internal/os/IdlePowerCalculator.java4
-rw-r--r--core/java/com/android/internal/os/MemoryPowerCalculator.java4
-rw-r--r--core/java/com/android/internal/os/MobileRadioPowerCalculator.java10
-rw-r--r--core/java/com/android/internal/os/PhonePowerCalculator.java4
-rw-r--r--core/java/com/android/internal/os/ScreenPowerCalculator.java8
-rw-r--r--core/java/com/android/internal/os/WifiPowerCalculator.java17
-rw-r--r--core/java/com/android/internal/widget/RecyclerView.java38
-rw-r--r--core/java/com/android/internal/widget/ViewPager.java22
-rw-r--r--core/jni/android_media_AudioAttributes.cpp6
-rw-r--r--core/jni/android_os_VintfObject.cpp41
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/values-as/strings.xml6
-rw-r--r--core/res/res/values-bn/strings.xml6
-rw-r--r--core/res/res/values-de/strings.xml6
-rw-r--r--core/res/res/values-gu/strings.xml6
-rw-r--r--core/res/res/values-iw/strings.xml6
-rw-r--r--core/res/res/values-ne/strings.xml2
-rw-r--r--core/res/res/values-or/strings.xml6
-rw-r--r--core/res/res/values-pa/strings.xml6
-rw-r--r--core/res/res/values-te/strings.xml6
-rw-r--r--core/res/res/values-ur/strings.xml6
-rw-r--r--core/res/res/values/attrs.xml10
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java45
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java15
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java261
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java267
-rw-r--r--core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java14
-rw-r--r--core/tests/coretests/src/android/app/activity/ActivityThreadTest.java9
-rw-r--r--core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java79
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryChargeCalculatorTest.java11
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java11
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java43
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java12
-rw-r--r--core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java10
-rw-r--r--core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java8
-rw-r--r--core/tests/coretests/src/com/android/internal/os/MemoryPowerCalculatorTest.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java23
-rw-r--r--core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java33
-rw-r--r--core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java47
-rw-r--r--graphics/java/android/graphics/FrameInfo.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java17
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java11
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java62
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java14
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java27
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAccessibilityUtil.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java4
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java2
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java2
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedUiEventLoggerTest.java2
-rw-r--r--libs/androidfw/include/androidfw/ResourceTypes.h5
-rw-r--r--libs/hwui/FrameInfo.h2
-rw-r--r--mime/java/android/content/type/DefaultMimeMapFactory.java2
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java13
-rw-r--r--packages/SystemUI/Android.bp7
-rw-r--r--packages/SystemUI/AndroidManifest.xml10
-rw-r--r--packages/SystemUI/animation/Android.bp1
-rw-r--r--packages/SystemUI/plugin/Android.bp1
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java12
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml2
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml28
-rw-r--r--packages/SystemUI/res/drawable/qs_media_button_background.xml1
-rw-r--r--packages/SystemUI/res/layout/media_carousel.xml4
-rw-r--r--packages/SystemUI/res/layout/media_smartspace_recommendations.xml53
-rw-r--r--packages/SystemUI/res/layout/media_view.xml51
-rw-r--r--packages/SystemUI/res/layout/notification_conversation_info.xml1
-rw-r--r--packages/SystemUI/res/layout/people_tile_empty_layout.xml29
-rw-r--r--packages/SystemUI/res/layout/priority_onboarding_half_shell.xml166
-rw-r--r--packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml2
-rw-r--r--packages/SystemUI/res/values-af/strings.xml6
-rw-r--r--packages/SystemUI/res/values-am/strings.xml6
-rw-r--r--packages/SystemUI/res/values-as/strings.xml15
-rw-r--r--packages/SystemUI/res/values-az/strings.xml6
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml6
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml9
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml6
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml6
-rw-r--r--packages/SystemUI/res/values-da/strings.xml6
-rw-r--r--packages/SystemUI/res/values-de/strings.xml9
-rw-r--r--packages/SystemUI/res/values-el/strings.xml6
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml6
-rw-r--r--packages/SystemUI/res/values-es/strings.xml6
-rw-r--r--packages/SystemUI/res/values-et/strings.xml6
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml6
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml24
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml8
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml6
-rw-r--r--packages/SystemUI/res/values-is/strings.xml6
-rw-r--r--packages/SystemUI/res/values-it/strings.xml6
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml9
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-km/strings.xml6
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml15
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml6
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml6
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml15
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-or/strings.xml15
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml9
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml6
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml6
-rw-r--r--packages/SystemUI/res/values-si/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml6
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml6
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml6
-rw-r--r--packages/SystemUI/res/values-te/strings.xml9
-rw-r--r--packages/SystemUI/res/values-th/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml6
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml6
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml24
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml6
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml6
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml6
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/strings.xml26
-rw-r--r--packages/SystemUI/res/values/styles.xml47
-rw-r--r--packages/SystemUI/res/xml/media_recommendation_collapsed.xml15
-rw-r--r--packages/SystemUI/res/xml/media_recommendation_expanded.xml39
-rw-r--r--packages/SystemUI/res/xml/people_space_widget_info.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/Prefs.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java104
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt77
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java215
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java100
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java382
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java54
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java42
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java438
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java80
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt291
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java363
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java44
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java141
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt83
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java41
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java235
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java292
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java236
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java77
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java5
-rw-r--r--services/Android.bp6
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java11
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java5
-rw-r--r--services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java5
-rw-r--r--services/api/Android.bp4
-rw-r--r--services/api/current.txt53
-rw-r--r--services/api/lint-baseline.txt4
-rw-r--r--services/api/non-updatable-current.txt71
-rw-r--r--services/api/non-updatable-lint-baseline.txt9
-rw-r--r--services/api/non-updatable-removed.txt1
-rw-r--r--services/core/java/android/content/pm/PackageManagerInternal.java2
-rw-r--r--services/core/java/com/android/server/IntentResolver.java34
-rw-r--r--services/core/java/com/android/server/WatchedIntentResolver.java30
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java6
-rw-r--r--services/core/java/com/android/server/app/GameManagerService.java368
-rw-r--r--services/core/java/com/android/server/appop/DiscreteRegistry.java39
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java169
-rw-r--r--services/core/java/com/android/server/pm/ApkChecksums.java16
-rw-r--r--services/core/java/com/android/server/pm/ComponentResolver.java232
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileIntentFilter.java44
-rw-r--r--services/core/java/com/android/server/pm/CrossProfileIntentResolver.java34
-rw-r--r--services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java6
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java167
-rw-r--r--services/core/java/com/android/server/pm/PersistentPreferredActivity.java44
-rw-r--r--services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java35
-rw-r--r--services/core/java/com/android/server/pm/PreferredActivity.java44
-rw-r--r--services/core/java/com/android/server/pm/PreferredIntentResolver.java35
-rw-r--r--services/core/java/com/android/server/pm/Settings.java13
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java2
-rw-r--r--services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java2
-rw-r--r--services/core/java/com/android/server/telecom/TelecomLoaderService.java22
-rw-r--r--services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java2
-rw-r--r--services/core/java/com/android/server/timezonedetector/OrdinalGenerator.java15
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneCanonicalizer.java35
-rw-r--r--services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java3
-rw-r--r--services/core/java/com/android/server/utils/SnapshotCache.java30
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java18
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java33
-rw-r--r--services/core/java/com/android/server/wm/Task.java6
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerShellCommand.java111
-rw-r--r--services/core/java/com/android/server/wm/WindowProcessController.java28
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java2
-rw-r--r--services/incremental/IncrementalService.cpp55
-rw-r--r--services/incremental/ServiceWrappers.cpp9
-rw-r--r--services/incremental/ServiceWrappers.h5
-rw-r--r--services/incremental/test/IncrementalServiceTest.cpp16
-rw-r--r--services/net/Android.bp6
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java326
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java43
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java77
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/OrdinalGeneratorTest.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneCanonicalizerTest.java54
-rw-r--r--services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/OWNERS4
-rw-r--r--services/tests/servicestests/src/com/android/server/utils/WatcherTest.java9
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java56
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java7
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java136
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskTests.java15
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java9
-rw-r--r--test-mock/Android.bp1
-rw-r--r--tests/HwAccelerationTest/res/layout/stretch_layout.xml2
-rw-r--r--tests/Input/src/com/android/test/input/ViewFrameInfoTest.kt6
-rw-r--r--tests/UpdatableSystemFontTest/Android.bp14
-rw-r--r--tests/UpdatableSystemFontTest/AndroidManifest.xml30
-rw-r--r--tests/UpdatableSystemFontTest/AndroidTest.xml5
-rw-r--r--tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java315
-rw-r--r--tools/aapt/Android.bp3
-rw-r--r--tools/aapt/Command.cpp55
-rw-r--r--tools/aapt2/dump/DumpManifest.cpp21
395 files changed, 5373 insertions, 8183 deletions
diff --git a/Android.bp b/Android.bp
index 685c69df6823..acf86a0cfa2d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -67,6 +67,7 @@ filegroup {
name: "framework-non-updatable-sources",
srcs: [
// Java/AIDL sources under frameworks/base
+ ":framework-annotations",
":framework-blobstore-sources",
":framework-core-sources",
":framework-drm-sources",
@@ -388,47 +389,6 @@ platform_compat_config {
}
filegroup {
- name: "framework-annotations",
- srcs: [
- "core/java/android/annotation/AnyThread.java",
- "core/java/android/annotation/AppIdInt.java",
- "core/java/android/annotation/BytesLong.java",
- "core/java/android/annotation/CallbackExecutor.java",
- "core/java/android/annotation/CallSuper.java",
- "core/java/android/annotation/CheckResult.java",
- "core/java/android/annotation/CurrentTimeMillisLong.java",
- "core/java/android/annotation/CurrentTimeSecondsLong.java",
- "core/java/android/annotation/DrawableRes.java",
- "core/java/android/annotation/DurationMillisLong.java",
- "core/java/android/annotation/Hide.java",
- "core/java/android/annotation/IntDef.java",
- "core/java/android/annotation/IntRange.java",
- "core/java/android/annotation/LongDef.java",
- "core/java/android/annotation/MainThread.java",
- "core/java/android/annotation/NonNull.java",
- "core/java/android/annotation/Nullable.java",
- "core/java/android/annotation/RequiresNoPermission.java",
- "core/java/android/annotation/RequiresPermission.java",
- "core/java/android/annotation/SdkConstant.java",
- "core/java/android/annotation/StringDef.java",
- "core/java/android/annotation/SystemApi.java",
- "core/java/android/annotation/SystemService.java",
- "core/java/android/annotation/TestApi.java",
- "core/java/android/annotation/UserIdInt.java",
- "core/java/android/annotation/WorkerThread.java",
- "core/java/com/android/internal/annotations/GuardedBy.java",
- "core/java/com/android/internal/annotations/Immutable.java",
- "core/java/com/android/internal/annotations/VisibleForTesting.java",
- ],
-}
-
-java_library {
- name: "framework-annotations-lib",
- srcs: [":framework-annotations"],
- sdk_version: "core_current",
-}
-
-filegroup {
name: "framework-ike-shared-srcs",
visibility: ["//packages/modules/IPsec"],
srcs: [
diff --git a/core/api/current.txt b/core/api/current.txt
index 7ed8b6c17574..989ca3427453 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -586,7 +586,6 @@ package android {
field public static final int dropDownWidth = 16843362; // 0x1010262
field public static final int duplicateParentState = 16842985; // 0x10100e9
field public static final int duration = 16843160; // 0x1010198
- field public static final int edgeEffectType;
field public static final int editTextBackground = 16843602; // 0x1010352
field public static final int editTextColor = 16843601; // 0x1010351
field public static final int editTextPreferenceStyle = 16842898; // 0x1010092
@@ -11921,6 +11920,7 @@ package android.content.pm {
method public int getGwpAsanMode();
method public int getMemtagMode();
method public int getNativeHeapZeroInitialized();
+ method public int getRequestRawExternalStorageAccess();
method public boolean isProfileable();
method public boolean isProfileableByShell();
method public boolean isResourceOverlay();
@@ -11976,6 +11976,9 @@ package android.content.pm {
field public static final int MEMTAG_DEFAULT = -1; // 0xffffffff
field public static final int MEMTAG_OFF = 0; // 0x0
field public static final int MEMTAG_SYNC = 2; // 0x2
+ field public static final int RAW_EXTERNAL_STORAGE_ACCESS_DEFAULT = 0; // 0x0
+ field public static final int RAW_EXTERNAL_STORAGE_ACCESS_NOT_REQUESTED = 2; // 0x2
+ field public static final int RAW_EXTERNAL_STORAGE_ACCESS_REQUESTED = 1; // 0x1
field public static final int ZEROINIT_DEFAULT = -1; // 0xffffffff
field public static final int ZEROINIT_DISABLED = 0; // 0x0
field public static final int ZEROINIT_ENABLED = 1; // 0x1
@@ -53791,7 +53794,6 @@ package android.widget {
method public int getCheckedItemPosition();
method public android.util.SparseBooleanArray getCheckedItemPositions();
method public int getChoiceMode();
- method public int getEdgeEffectType();
method public int getListPaddingBottom();
method public int getListPaddingLeft();
method public int getListPaddingRight();
@@ -53833,7 +53835,6 @@ package android.widget {
method public void setChoiceMode(int);
method public void setDrawSelectorOnTop(boolean);
method public void setEdgeEffectColor(@ColorInt int);
- method public void setEdgeEffectType(int);
method public void setFastScrollAlwaysVisible(boolean);
method public void setFastScrollEnabled(boolean);
method public void setFastScrollStyle(int);
@@ -54524,7 +54525,6 @@ package android.widget {
method @ColorInt public int getColor();
method public float getDistance();
method public int getMaxHeight();
- method public int getType();
method public boolean isFinished();
method public void onAbsorb(int);
method public void onPull(float);
@@ -54534,10 +54534,7 @@ package android.widget {
method public void setBlendMode(@Nullable android.graphics.BlendMode);
method public void setColor(@ColorInt int);
method public void setSize(int, int);
- method public void setType(int);
field public static final android.graphics.BlendMode DEFAULT_BLEND_MODE;
- field public static final int TYPE_GLOW = 0; // 0x0
- field public static final int TYPE_STRETCH = 1; // 0x1
}
public class EditText extends android.widget.TextView {
@@ -54842,7 +54839,6 @@ package android.widget {
method public boolean executeKeyEvent(android.view.KeyEvent);
method public void fling(int);
method public boolean fullScroll(int);
- method public int getEdgeEffectType();
method @ColorInt public int getLeftEdgeEffectColor();
method public int getMaxScrollAmount();
method @ColorInt public int getRightEdgeEffectColor();
@@ -54850,7 +54846,6 @@ package android.widget {
method public boolean isSmoothScrollingEnabled();
method public boolean pageScroll(int);
method public void setEdgeEffectColor(@ColorInt int);
- method public void setEdgeEffectType(int);
method public void setFillViewport(boolean);
method public void setLeftEdgeEffectColor(@ColorInt int);
method public void setRightEdgeEffectColor(@ColorInt int);
@@ -55736,7 +55731,6 @@ package android.widget {
method public void fling(int);
method public boolean fullScroll(int);
method @ColorInt public int getBottomEdgeEffectColor();
- method public int getEdgeEffectType();
method public int getMaxScrollAmount();
method @ColorInt public int getTopEdgeEffectColor();
method public boolean isFillViewport();
@@ -55745,7 +55739,6 @@ package android.widget {
method public void scrollToDescendant(@NonNull android.view.View);
method public void setBottomEdgeEffectColor(@ColorInt int);
method public void setEdgeEffectColor(@ColorInt int);
- method public void setEdgeEffectType(int);
method public void setFillViewport(boolean);
method public void setSmoothScrollingEnabled(boolean);
method public void setTopEdgeEffectColor(@ColorInt int);
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c7960dd406ed..990f43de5ec5 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2520,7 +2520,6 @@ package android.content.om {
package android.content.pm {
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
- method @Nullable public Boolean hasRequestRawExternalStorageAccess();
method public boolean isEncryptionAware();
method public boolean isInstantApp();
method public boolean isOem();
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 35767b3acb8c..1330234f6521 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -1810,6 +1810,7 @@ package android.os {
public class VintfObject {
method public static String[] getHalNamesAndVersions();
+ method @NonNull public static String getPlatformSepolicyVersion();
method public static String getSepolicyVersion();
method public static Long getTargetFrameworkCompatibilityMatrixVersion();
method public static java.util.Map<java.lang.String,java.lang.String[]> getVndkSnapshots();
diff --git a/core/java/Android.bp b/core/java/Android.bp
index c8a8d36a1b20..793d0ef164fa 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -46,44 +46,6 @@ filegroup {
"android/accounts/AccountsException.java",
"android/accounts/AuthenticatorException.java",
"android/accounts/OperationCanceledException.java",
- "android/annotation/AnimatorRes.java",
- "android/annotation/AnimRes.java",
- "android/annotation/AnyRes.java",
- "android/annotation/ArrayRes.java",
- "android/annotation/AttrRes.java",
- "android/annotation/BoolRes.java",
- "android/annotation/BroadcastBehavior.java",
- "android/annotation/CallbackExecutor.java",
- "android/annotation/CallSuper.java",
- "android/annotation/CheckResult.java",
- "android/annotation/ColorInt.java",
- "android/annotation/ColorRes.java",
- "android/annotation/DimenRes.java",
- "android/annotation/DrawableRes.java",
- "android/annotation/FontRes.java",
- "android/annotation/FractionRes.java",
- "android/annotation/IntDef.java",
- "android/annotation/IntegerRes.java",
- "android/annotation/IntRange.java",
- "android/annotation/LayoutRes.java",
- "android/annotation/NonNull.java",
- "android/annotation/Nullable.java",
- "android/annotation/PluralsRes.java",
- "android/annotation/RawRes.java",
- "android/annotation/RequiresNoPermission.java",
- "android/annotation/RequiresPermission.java",
- "android/annotation/SdkConstant.java",
- "android/annotation/Size.java",
- "android/annotation/StringDef.java",
- "android/annotation/StringRes.java",
- "android/annotation/StyleableRes.java",
- "android/annotation/StyleRes.java",
- "android/annotation/SuppressLint.java",
- "android/annotation/SystemApi.java",
- "android/annotation/SystemService.java",
- "android/annotation/TestApi.java",
- "android/annotation/UserIdInt.java",
- "android/annotation/XmlRes.java",
"android/app/Application.java",
"android/app/IApplicationThread.aidl",
"android/app/IServiceConnection.aidl",
@@ -124,7 +86,6 @@ filegroup {
"android/util/AndroidException.java",
"android/view/DisplayAdjustments.java",
"android/view/ViewDebug.java",
- "com/android/internal/annotations/VisibleForTesting.java",
],
visibility: ["//frameworks/base/test-mock"],
}
diff --git a/core/java/android/annotation/AnimRes.java b/core/java/android/annotation/AnimRes.java
deleted file mode 100644
index 56f8acf82313..000000000000
--- a/core/java/android/annotation/AnimRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an anim resource reference (e.g. {@link android.R.anim#fade_in}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AnimRes {
-}
diff --git a/core/java/android/annotation/AnimatorRes.java b/core/java/android/annotation/AnimatorRes.java
deleted file mode 100644
index cd4c189b7531..000000000000
--- a/core/java/android/annotation/AnimatorRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an animator resource reference (e.g. {@link android.R.animator#fade_in}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AnimatorRes {
-}
diff --git a/core/java/android/annotation/AnyRes.java b/core/java/android/annotation/AnyRes.java
deleted file mode 100644
index 44411a04a8e7..000000000000
--- a/core/java/android/annotation/AnyRes.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a resource reference of any type. If the specific type is known, use
- * one of the more specific annotations instead, such as {@link StringRes} or
- * {@link DrawableRes}.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AnyRes {
-}
diff --git a/core/java/android/annotation/AnyThread.java b/core/java/android/annotation/AnyThread.java
deleted file mode 100644
index ee36a42b3fc6..000000000000
--- a/core/java/android/annotation/AnyThread.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated method can be called from any thread (e.g. it is
- * "thread safe".) If the annotated element is a class, then all methods in the
- * class can be called from any thread.
- * <p>
- * The main purpose of this method is to indicate that you believe a method can
- * be called from any thread; static tools can then check that nothing you call
- * from within this method or class have more strict threading requirements.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- * &#64;AnyThread
- * public void deliverResult(D data) { ... }
- * </code>
- * </pre>
- *
- * @memberDoc This method is safe to call from any thread.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface AnyThread {
-}
diff --git a/core/java/android/annotation/AppIdInt.java b/core/java/android/annotation/AppIdInt.java
deleted file mode 100644
index 29838dd5bd7c..000000000000
--- a/core/java/android/annotation/AppIdInt.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element is a multi-user application ID. This is
- * <em>not</em> the same as a UID.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AppIdInt {
-}
diff --git a/core/java/android/annotation/ArrayRes.java b/core/java/android/annotation/ArrayRes.java
deleted file mode 100644
index 1407af1d1422..000000000000
--- a/core/java/android/annotation/ArrayRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an array resource reference (e.g. {@link android.R.array#phoneTypes}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface ArrayRes {
-}
diff --git a/core/java/android/annotation/AttrRes.java b/core/java/android/annotation/AttrRes.java
deleted file mode 100644
index 285b80ce45ca..000000000000
--- a/core/java/android/annotation/AttrRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an attribute reference (e.g. {@link android.R.attr#action}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface AttrRes {
-}
diff --git a/core/java/android/annotation/BinderThread.java b/core/java/android/annotation/BinderThread.java
deleted file mode 100644
index ca5e14c2adb9..000000000000
--- a/core/java/android/annotation/BinderThread.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated method should only be called on the binder thread.
- * If the annotated element is a class, then all methods in the class should be called
- * on the binder thread.
- * <p>
- * Example:
- * <pre><code>
- * &#64;BinderThread
- * public BeamShareData createBeamShareData() { ... }
- * </code></pre>
- *
- * {@hide}
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface BinderThread {
-} \ No newline at end of file
diff --git a/core/java/android/annotation/BoolRes.java b/core/java/android/annotation/BoolRes.java
deleted file mode 100644
index f50785b1e1cf..000000000000
--- a/core/java/android/annotation/BoolRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a boolean resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface BoolRes {
-}
diff --git a/core/java/android/annotation/BroadcastBehavior.java b/core/java/android/annotation/BroadcastBehavior.java
deleted file mode 100644
index 70d82cb5151b..000000000000
--- a/core/java/android/annotation/BroadcastBehavior.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import android.content.Intent;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Description of how the annotated broadcast action behaves.
- *
- * @hide
- */
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.SOURCE)
-public @interface BroadcastBehavior {
- /**
- * This broadcast will only be delivered to an explicit target.
- *
- * @see Intent#setPackage(String)
- * @see Intent#setComponent(android.content.ComponentName)
- */
- boolean explicitOnly() default false;
-
- /**
- * This broadcast will only be delivered to registered receivers.
- *
- * @see Intent#FLAG_RECEIVER_REGISTERED_ONLY
- */
- boolean registeredOnly() default false;
-
- /**
- * This broadcast will include all {@code AndroidManifest.xml} receivers
- * regardless of process state.
- *
- * @see Intent#FLAG_RECEIVER_INCLUDE_BACKGROUND
- */
- boolean includeBackground() default false;
-
- /**
- * This broadcast is protected and can only be sent by the OS.
- */
- boolean protectedBroadcast() default false;
-}
diff --git a/core/java/android/annotation/BytesLong.java b/core/java/android/annotation/BytesLong.java
deleted file mode 100644
index f5e1a9c5f7fd..000000000000
--- a/core/java/android/annotation/BytesLong.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative number of bytes.
- * @paramDoc Value is a non-negative number of bytes.
- * @returnDoc Value is a non-negative number of bytes.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface BytesLong {
-}
diff --git a/core/java/android/annotation/CallSuper.java b/core/java/android/annotation/CallSuper.java
deleted file mode 100644
index c16b51161cac..000000000000
--- a/core/java/android/annotation/CallSuper.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that any overriding methods should invoke this method as well.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- * &#64;CallSuper
- * public abstract void onFocusLost();
- * </code>
- * </pre>
- *
- * @memberDoc If you override this method you <em>must</em> call through to the
- * superclass implementation.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD})
-public @interface CallSuper {
-}
diff --git a/core/java/android/annotation/CallbackExecutor.java b/core/java/android/annotation/CallbackExecutor.java
deleted file mode 100644
index 4258f730eb16..000000000000
--- a/core/java/android/annotation/CallbackExecutor.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-import java.util.concurrent.Executor;
-
-/**
- * @paramDoc Callback and listener events are dispatched through this
- * {@link Executor}, providing an easy way to control which thread is
- * used. To dispatch events through the main thread of your
- * application, you can use
- * {@link android.content.Context#getMainExecutor() Context.getMainExecutor()}.
- * To dispatch events through a shared thread pool, you can use
- * {@link android.os.AsyncTask#THREAD_POOL_EXECUTOR AsyncTask#THREAD_POOL_EXECUTOR}.
- * @hide
- */
-@Retention(SOURCE)
-@Target(PARAMETER)
-public @interface CallbackExecutor {
-}
diff --git a/core/java/android/annotation/CheckResult.java b/core/java/android/annotation/CheckResult.java
deleted file mode 100644
index 97d031a760a6..000000000000
--- a/core/java/android/annotation/CheckResult.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated method returns a result that it typically is
- * an error to ignore. This is usually used for methods that have no side effect,
- * so calling it without actually looking at the result usually means the developer
- * has misunderstood what the method does.
- * <p>
- * Example:
- * <pre>{@code
- * public @CheckResult String trim(String s) { return s.trim(); }
- * ...
- * s.trim(); // this is probably an error
- * s = s.trim(); // ok
- * }</pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD})
-public @interface CheckResult {
- /** Defines the name of the suggested method to use instead, if applicable (using
- * the same signature format as javadoc.) If there is more than one possibility,
- * list them all separated by commas.
- * <p>
- * For example, ProcessBuilder has a method named {@code redirectErrorStream()}
- * which sounds like it might redirect the error stream. It does not. It's just
- * a getter which returns whether the process builder will redirect the error stream,
- * and to actually set it, you must call {@code redirectErrorStream(boolean)}.
- * In that case, the method should be defined like this:
- * <pre>
- * &#64;CheckResult(suggest="#redirectErrorStream(boolean)")
- * public boolean redirectErrorStream() { ... }
- * </pre>
- */
- String suggest() default "";
-} \ No newline at end of file
diff --git a/core/java/android/annotation/ColorInt.java b/core/java/android/annotation/ColorInt.java
deleted file mode 100644
index 4671b1b9f887..000000000000
--- a/core/java/android/annotation/ColorInt.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element represents a packed color
- * int, {@code AARRGGBB}. If applied to an int array, every element
- * in the array represents a color integer.
- * <p>
- * Example:
- * <pre>{@code
- * public abstract void setTextColor(@ColorInt int color);
- * }</pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER,METHOD,LOCAL_VARIABLE,FIELD})
-public @interface ColorInt {
-} \ No newline at end of file
diff --git a/core/java/android/annotation/ColorLong.java b/core/java/android/annotation/ColorLong.java
deleted file mode 100644
index 9b19c76802c9..000000000000
--- a/core/java/android/annotation/ColorLong.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * <p>Denotes that the annotated element represents a packed color
- * long. If applied to a long array, every element in the array
- * represents a color long. For more information on how colors
- * are packed in a long, please refer to the documentation of
- * the {@link android.graphics.Color} class.</p>
- *
- * <p>Example:</p>
- *
- * <pre>{@code
- * public void setFillColor(@ColorLong long color);
- * }</pre>
- *
- * @see android.graphics.Color
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER,METHOD,LOCAL_VARIABLE,FIELD})
-public @interface ColorLong {
-}
diff --git a/core/java/android/annotation/ColorRes.java b/core/java/android/annotation/ColorRes.java
deleted file mode 100644
index 061faa05c738..000000000000
--- a/core/java/android/annotation/ColorRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a color resource reference (e.g. {@link android.R.color#black}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface ColorRes {
-}
diff --git a/core/java/android/annotation/Condemned.java b/core/java/android/annotation/Condemned.java
deleted file mode 100644
index 186409b3e204..000000000000
--- a/core/java/android/annotation/Condemned.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * A program element annotated &#64;Condemned is one that programmers are
- * blocked from using, typically because it's about to be completely destroyed.
- * <p>
- * This is a stronger version of &#64;Deprecated, and it's typically used to
- * mark APIs that only existed temporarily in a preview SDK, and which only
- * continue to exist temporarily to support binary compatibility.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
-public @interface Condemned {
-}
diff --git a/core/java/android/annotation/CurrentTimeMillisLong.java b/core/java/android/annotation/CurrentTimeMillisLong.java
deleted file mode 100644
index 355bb5a2f960..000000000000
--- a/core/java/android/annotation/CurrentTimeMillisLong.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative timestamp measured as the number of
- * milliseconds since 1970-01-01T00:00:00Z.
- * @paramDoc Value is a non-negative timestamp measured as the number of
- * milliseconds since 1970-01-01T00:00:00Z.
- * @returnDoc Value is a non-negative timestamp measured as the number of
- * milliseconds since 1970-01-01T00:00:00Z.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface CurrentTimeMillisLong {
-}
diff --git a/core/java/android/annotation/CurrentTimeSecondsLong.java b/core/java/android/annotation/CurrentTimeSecondsLong.java
deleted file mode 100644
index 2b4ffd77ad34..000000000000
--- a/core/java/android/annotation/CurrentTimeSecondsLong.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative timestamp measured as the number of
- * seconds since 1970-01-01T00:00:00Z.
- * @paramDoc Value is a non-negative timestamp measured as the number of
- * seconds since 1970-01-01T00:00:00Z.
- * @returnDoc Value is a non-negative timestamp measured as the number of
- * seconds since 1970-01-01T00:00:00Z.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface CurrentTimeSecondsLong {
-}
diff --git a/core/java/android/annotation/DimenRes.java b/core/java/android/annotation/DimenRes.java
deleted file mode 100644
index 02ae00c6868c..000000000000
--- a/core/java/android/annotation/DimenRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a dimension resource reference (e.g. {@link android.R.dimen#app_icon_size}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface DimenRes {
-}
diff --git a/core/java/android/annotation/Dimension.java b/core/java/android/annotation/Dimension.java
deleted file mode 100644
index 5f705ad52d9b..000000000000
--- a/core/java/android/annotation/Dimension.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a numeric parameter, field or method return value is expected
- * to represent a dimension.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE})
-public @interface Dimension {
- @Unit
- int unit() default PX;
-
- int DP = 0;
- int PX = 1;
- int SP = 2;
-
- @IntDef({PX, DP, SP})
- @Retention(SOURCE)
- @interface Unit {}
-}
diff --git a/core/java/android/annotation/DisplayContext.java b/core/java/android/annotation/DisplayContext.java
deleted file mode 100644
index e6b464ac237a..000000000000
--- a/core/java/android/annotation/DisplayContext.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.app.Activity;
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.WindowManager;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes a {@link Context} that is tied to a {@link Display} and can be used to obtain one
- * via {@link Context#getDisplay}, but <b>may not</b> be able to obtain {@link WindowManager},
- * {@link LayoutInflater} or {@link WallpaperManager} via {@link Context#getSystemService(String)}.
- * If the UI services mentioned above are required, please use contexts which are marked as
- * {@link UiContext}.
- * <p>
- * {@link Activity}, and the result of {@link Context#createWindowContext(int, Bundle)} or
- * {@link Context#createDisplayContext(Display)} can be
- * used where a {@link DisplayContext} is required.
- * <p>
- * This is a marker annotation and has no specific attributes.
- *
- * @see Context#getDisplay()
- * @see Context#getSystemService(String)
- * @see Context#getSystemService(Class)
- * @see Context#createDisplayContext(Display)
- * @see Context#createWindowContext(int, Bundle)
- * @see UiContext
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE, METHOD, PARAMETER, FIELD})
-public @interface DisplayContext {
-}
diff --git a/core/java/android/annotation/DrawableRes.java b/core/java/android/annotation/DrawableRes.java
deleted file mode 100644
index ebefa1d78ab1..000000000000
--- a/core/java/android/annotation/DrawableRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a drawable resource reference (e.g. {@link android.R.attr#alertDialogIcon}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface DrawableRes {
-}
diff --git a/core/java/android/annotation/DurationMillisLong.java b/core/java/android/annotation/DurationMillisLong.java
deleted file mode 100644
index ce77532a6c6e..000000000000
--- a/core/java/android/annotation/DurationMillisLong.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative duration in milliseconds.
- * @paramDoc Value is a non-negative duration in milliseconds.
- * @returnDoc Value is a non-negative duration in milliseconds.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface DurationMillisLong {
-}
diff --git a/core/java/android/annotation/ElapsedRealtimeLong.java b/core/java/android/annotation/ElapsedRealtimeLong.java
deleted file mode 100644
index f77ff72062a6..000000000000
--- a/core/java/android/annotation/ElapsedRealtimeLong.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.os.SystemClock;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative timestamp in the
- * {@link SystemClock#elapsedRealtime()} time base.
- * @paramDoc Value is a non-negative timestamp in the
- * {@link SystemClock#elapsedRealtime()} time base.
- * @returnDoc Value is a non-negative timestamp in the
- * {@link SystemClock#elapsedRealtime()} time base.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface ElapsedRealtimeLong {
-}
diff --git a/core/java/android/annotation/FloatRange.java b/core/java/android/annotation/FloatRange.java
deleted file mode 100644
index 05b51680b1b0..000000000000
--- a/core/java/android/annotation/FloatRange.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element should be a float or double in the given range
- * <p>
- * Example:
- * <pre><code>
- * &#64;FloatRange(from=0.0,to=1.0)
- * public float getAlpha() {
- * ...
- * }
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE})
-public @interface FloatRange {
- /** Smallest value. Whether it is inclusive or not is determined
- * by {@link #fromInclusive} */
- double from() default Double.NEGATIVE_INFINITY;
- /** Largest value. Whether it is inclusive or not is determined
- * by {@link #toInclusive} */
- double to() default Double.POSITIVE_INFINITY;
-
- /** Whether the from value is included in the range */
- boolean fromInclusive() default true;
-
- /** Whether the to value is included in the range */
- boolean toInclusive() default true;
-} \ No newline at end of file
diff --git a/core/java/android/annotation/FontRes.java b/core/java/android/annotation/FontRes.java
deleted file mode 100644
index dbacb5876dce..000000000000
--- a/core/java/android/annotation/FontRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a Font resource reference (e.g. R.font.myfont).
- *
- * @hide
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface FontRes {
-}
diff --git a/core/java/android/annotation/FractionRes.java b/core/java/android/annotation/FractionRes.java
deleted file mode 100644
index fd84d3e85fdf..000000000000
--- a/core/java/android/annotation/FractionRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a fraction resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface FractionRes {
-}
diff --git a/core/java/android/annotation/HalfFloat.java b/core/java/android/annotation/HalfFloat.java
deleted file mode 100644
index 256008c5e31f..000000000000
--- a/core/java/android/annotation/HalfFloat.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * <p>Denotes that the annotated element represents a half-precision floating point
- * value. Such values are stored in short data types and can be manipulated with
- * the {@link android.util.Half} class. If applied to an array of short, every
- * element in the array represents a half-precision float.</p>
- *
- * <p>Example:</p>
- *
- * <pre>{@code
- * public abstract void setPosition(@HalfFloat short x, @HalfFloat short y, @HalfFloat short z);
- * }</pre>
- *
- * @see android.util.Half
- * @see android.util.Half#toHalf(float)
- * @see android.util.Half#toFloat(short)
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER, METHOD, LOCAL_VARIABLE, FIELD})
-public @interface HalfFloat {
-}
diff --git a/core/java/android/annotation/Hide.java b/core/java/android/annotation/Hide.java
deleted file mode 100644
index c8e5a4a97ae7..000000000000
--- a/core/java/android/annotation/Hide.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates that an API is hidden by default, in a similar fashion to the
- * <pre>@hide</pre> javadoc tag.
- *
- * <p>Note that, in order for this to work, metalava has to be invoked with
- * the flag {@code --hide-annotation android.annotation.Hide}.
- * @hide
- */
-@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
-@Retention(RetentionPolicy.CLASS)
-public @interface Hide {
-}
diff --git a/core/java/android/annotation/IdRes.java b/core/java/android/annotation/IdRes.java
deleted file mode 100644
index b286965c99d9..000000000000
--- a/core/java/android/annotation/IdRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an id resource reference (e.g. {@link android.R.id#copy}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface IdRes {
-}
diff --git a/core/java/android/annotation/IntDef.java b/core/java/android/annotation/IntDef.java
deleted file mode 100644
index f84a67655dc3..000000000000
--- a/core/java/android/annotation/IntDef.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element of integer type, represents
- * a logical type and that its value should be one of the explicitly
- * named constants. If the {@link #flag()} attribute is set to true,
- * multiple constants can be combined.
- * <p>
- * <pre><code>
- * &#64;Retention(SOURCE)
- * &#64;IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- * public @interface NavigationMode {}
- * public static final int NAVIGATION_MODE_STANDARD = 0;
- * public static final int NAVIGATION_MODE_LIST = 1;
- * public static final int NAVIGATION_MODE_TABS = 2;
- * ...
- * public abstract void setNavigationMode(@NavigationMode int mode);
- * &#64;NavigationMode
- * public abstract int getNavigationMode();
- * </code></pre>
- * For a flag, set the flag attribute:
- * <pre><code>
- * &#64;IntDef(
- * flag = true,
- * value = {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({ANNOTATION_TYPE})
-public @interface IntDef {
- /** Defines the constant prefix for this element */
- String[] prefix() default {};
- /** Defines the constant suffix for this element */
- String[] suffix() default {};
-
- /** Defines the allowed constants for this element */
- int[] value() default {};
-
- /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
- boolean flag() default false;
-}
diff --git a/core/java/android/annotation/IntRange.java b/core/java/android/annotation/IntRange.java
deleted file mode 100644
index c043e2db6a98..000000000000
--- a/core/java/android/annotation/IntRange.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element should be an int or long in the given range
- * <p>
- * Example:
- * <pre><code>
- * &#64;IntRange(from=0,to=255)
- * public int getAlpha() {
- * ...
- * }
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,PARAMETER,FIELD,LOCAL_VARIABLE,ANNOTATION_TYPE})
-public @interface IntRange {
- /** Smallest value, inclusive */
- long from() default Long.MIN_VALUE;
- /** Largest value, inclusive */
- long to() default Long.MAX_VALUE;
-} \ No newline at end of file
diff --git a/core/java/android/annotation/IntegerRes.java b/core/java/android/annotation/IntegerRes.java
deleted file mode 100644
index 5313f4adf46e..000000000000
--- a/core/java/android/annotation/IntegerRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an integer resource reference (e.g. {@link android.R.integer#config_shortAnimTime}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface IntegerRes {
-}
diff --git a/core/java/android/annotation/InterpolatorRes.java b/core/java/android/annotation/InterpolatorRes.java
deleted file mode 100644
index 8877a5f9a4f1..000000000000
--- a/core/java/android/annotation/InterpolatorRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an interpolator resource reference (e.g. {@link android.R.interpolator#cycle}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface InterpolatorRes {
-}
diff --git a/core/java/android/annotation/LayoutRes.java b/core/java/android/annotation/LayoutRes.java
deleted file mode 100644
index 15ba86f98159..000000000000
--- a/core/java/android/annotation/LayoutRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a layout resource reference (e.g. {@link android.R.layout#list_content}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface LayoutRes {
-}
diff --git a/core/java/android/annotation/LongDef.java b/core/java/android/annotation/LongDef.java
deleted file mode 100644
index 8723eef86328..000000000000
--- a/core/java/android/annotation/LongDef.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated long element represents
- * a logical type and that its value should be one of the explicitly
- * named constants. If the {@link #flag()} attribute is set to true,
- * multiple constants can be combined.
- * <p>
- * <pre><code>
- * &#64;Retention(SOURCE)
- * &#64;LongDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- * public @interface NavigationMode {}
- * public static final long NAVIGATION_MODE_STANDARD = 0;
- * public static final long NAVIGATION_MODE_LIST = 1;
- * public static final long NAVIGATION_MODE_TABS = 2;
- * ...
- * public abstract void setNavigationMode(@NavigationMode long mode);
- * &#64;NavigationMode
- * public abstract long getNavigationMode();
- * </code></pre>
- * For a flag, set the flag attribute:
- * <pre><code>
- * &#64;LongDef(
- * flag = true,
- * value = {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({ANNOTATION_TYPE})
-public @interface LongDef {
- /** Defines the constant prefix for this element */
- String[] prefix() default "";
-
- /** Defines the allowed constants for this element */
- long[] value() default {};
-
- /** Defines whether the constants can be used as a flag, or just as an enum (the default) */
- boolean flag() default false;
-}
diff --git a/core/java/android/annotation/MainThread.java b/core/java/android/annotation/MainThread.java
deleted file mode 100644
index a070246e5ef3..000000000000
--- a/core/java/android/annotation/MainThread.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated method should only be called on the main thread.
- * If the annotated element is a class, then all methods in the class should be
- * called on the main thread.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- * &#64;MainThread
- * public void deliverResult(D data) { ... }
- * </code>
- * </pre>
- *
- * @memberDoc This method must be called from the main thread of your app.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface MainThread {
-}
diff --git a/core/java/android/annotation/MenuRes.java b/core/java/android/annotation/MenuRes.java
deleted file mode 100644
index b6dcc4604cfb..000000000000
--- a/core/java/android/annotation/MenuRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a menu resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface MenuRes {
-}
diff --git a/core/java/android/annotation/NavigationRes.java b/core/java/android/annotation/NavigationRes.java
deleted file mode 100644
index 3af5ecff84a6..000000000000
--- a/core/java/android/annotation/NavigationRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a navigation resource reference (e.g. {@code R.navigation.flow}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface NavigationRes {
-}
diff --git a/core/java/android/annotation/NonNull.java b/core/java/android/annotation/NonNull.java
deleted file mode 100644
index 20472bacf6ad..000000000000
--- a/core/java/android/annotation/NonNull.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that a parameter, field or method return value can never be null.
- * <p>
- * This is a marker annotation and it has no specific attributes.
- *
- * @paramDoc This value cannot be {@code null}.
- * @returnDoc This value cannot be {@code null}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface NonNull {
-}
diff --git a/core/java/android/annotation/NonUiContext.java b/core/java/android/annotation/NonUiContext.java
deleted file mode 100644
index c119ca20ba11..000000000000
--- a/core/java/android/annotation/NonUiContext.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.WindowManager;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes a {@link Context} that <b>can not</b> be used to obtain a {@link Display} via
- * {@link Context#getDisplay} nor to obtain a {@link WindowManager}, {@link LayoutInflater} or
- * {@link WallpaperManager} via {@link Context#getSystemService(String)}.
- * <p>
- * This is a marker annotation and has no specific attributes.
- *
- * @see Context#getDisplay()
- * @see Context#getSystemService(String)
- * @see Context#getSystemService(Class)
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE, METHOD, PARAMETER, FIELD})
-public @interface NonUiContext {
-}
diff --git a/core/java/android/annotation/Nullable.java b/core/java/android/annotation/Nullable.java
deleted file mode 100644
index b8473e750c95..000000000000
--- a/core/java/android/annotation/Nullable.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that a parameter, field or method return value can be null.
- * <p>
- * When decorating a method call parameter, this denotes that the parameter can
- * legitimately be null and the method will gracefully deal with it. Typically
- * used on optional parameters.
- * <p>
- * When decorating a method, this denotes the method might legitimately return
- * null.
- * <p>
- * This is a marker annotation and it has no specific attributes.
- *
- * @paramDoc This value may be {@code null}.
- * @returnDoc This value may be {@code null}.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface Nullable {
-}
diff --git a/core/java/android/annotation/OWNERS b/core/java/android/annotation/OWNERS
deleted file mode 100644
index e1ef54460b56..000000000000
--- a/core/java/android/annotation/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-tnorbye@google.com
-aurimas@google.com
-per-file UnsupportedAppUsage.java = mathewi@google.com, satayev@google.com, andreionea@google.com
diff --git a/core/java/android/annotation/PluralsRes.java b/core/java/android/annotation/PluralsRes.java
deleted file mode 100644
index 31ac729aaa47..000000000000
--- a/core/java/android/annotation/PluralsRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a plurals resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface PluralsRes {
-}
diff --git a/core/java/android/annotation/Px.java b/core/java/android/annotation/Px.java
deleted file mode 100644
index cec7f80405d3..000000000000
--- a/core/java/android/annotation/Px.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a numeric parameter, field or method return value is expected
- * to represent a pixel dimension.
- *
- * @memberDoc This units of this value are pixels.
- * @paramDoc This units of this value are pixels.
- * @returnDoc This units of this value are pixels.
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD, LOCAL_VARIABLE})
-@Dimension(unit = Dimension.PX)
-public @interface Px {
-}
diff --git a/core/java/android/annotation/RawRes.java b/core/java/android/annotation/RawRes.java
deleted file mode 100644
index 39970b36fd95..000000000000
--- a/core/java/android/annotation/RawRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a raw resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface RawRes {
-}
diff --git a/core/java/android/annotation/RequiresFeature.java b/core/java/android/annotation/RequiresFeature.java
deleted file mode 100644
index 08861d42be39..000000000000
--- a/core/java/android/annotation/RequiresFeature.java
+++ /dev/null
@@ -1,52 +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 android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.content.pm.PackageManager;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element requires one or more device features. This
- * is used to auto-generate documentation.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE,FIELD,METHOD,CONSTRUCTOR})
-public @interface RequiresFeature {
- /**
- * The name of the device feature that is required.
- */
- String value();
-
- /**
- * Defines the name of the method that should be called to check whether the feature is
- * available, using the same signature format as javadoc. The feature checking method can have
- * multiple parameters, but the feature name parameter must be of type String and must also be
- * the first String-type parameter.
- * <p>
- * By default, the enforcement is {@link PackageManager#hasSystemFeature(String)}.
- */
- String enforcement() default("android.content.pm.PackageManager#hasSystemFeature");
-}
diff --git a/core/java/android/annotation/RequiresNoPermission.java b/core/java/android/annotation/RequiresNoPermission.java
deleted file mode 100644
index cdbf36ec20dd..000000000000
--- a/core/java/android/annotation/RequiresNoPermission.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.CLASS;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element requires no permissions.
- * <p>
- * This explicit annotation helps distinguish which of three states that an
- * element may exist in:
- * <ul>
- * <li>Annotated with {@link RequiresPermission}, indicating that an element
- * requires (or may require) one or more permissions.
- * <li>Annotated with {@link RequiresNoPermission}, indicating that an element
- * requires no permissions.
- * <li>Neither annotation, indicating that no explicit declaration about
- * permissions has been made for that element.
- * </ul>
- *
- * @see RequiresPermission
- * @hide
- */
-@Retention(CLASS)
-@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD,PARAMETER})
-public @interface RequiresNoPermission {
-}
diff --git a/core/java/android/annotation/RequiresPermission.java b/core/java/android/annotation/RequiresPermission.java
deleted file mode 100644
index 0379d303ab92..000000000000
--- a/core/java/android/annotation/RequiresPermission.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.CLASS;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element requires (or may require) one or more permissions.
- * <p/>
- * Example of requiring a single permission:
- * <pre>{@code
- * {@literal @}RequiresPermission(Manifest.permission.SET_WALLPAPER)
- * public abstract void setWallpaper(Bitmap bitmap) throws IOException;
- *
- * {@literal @}RequiresPermission(ACCESS_COARSE_LOCATION)
- * public abstract Location getLastKnownLocation(String provider);
- * }</pre>
- * Example of requiring at least one permission from a set:
- * <pre>{@code
- * {@literal @}RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- * public abstract Location getLastKnownLocation(String provider);
- * }</pre>
- * Example of requiring multiple permissions:
- * <pre>{@code
- * {@literal @}RequiresPermission(allOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- * public abstract Location getLastKnownLocation(String provider);
- * }</pre>
- * Example of requiring separate read and write permissions for a content provider:
- * <pre>{@code
- * {@literal @}RequiresPermission.Read(@RequiresPermission(READ_HISTORY_BOOKMARKS))
- * {@literal @}RequiresPermission.Write(@RequiresPermission(WRITE_HISTORY_BOOKMARKS))
- * public static final Uri BOOKMARKS_URI = Uri.parse("content://browser/bookmarks");
- * }</pre>
- * <p>
- * When specified on a parameter, the annotation indicates that the method requires
- * a permission which depends on the value of the parameter. For example, consider
- * {@link android.app.Activity#startActivity(android.content.Intent)
- * Activity#startActivity(Intent)}:
- * <pre>{@code
- * public void startActivity(@RequiresPermission Intent intent) { ... }
- * }</pre>
- * Notice how there are no actual permission names listed in the annotation. The actual
- * permissions required will depend on the particular intent passed in. For example,
- * the code may look like this:
- * <pre>{@code
- * Intent intent = new Intent(Intent.ACTION_CALL);
- * startActivity(intent);
- * }</pre>
- * and the actual permission requirement for this particular intent is described on
- * the Intent name itself:
- * <pre>{@code
- * {@literal @}RequiresPermission(Manifest.permission.CALL_PHONE)
- * public static final String ACTION_CALL = "android.intent.action.CALL";
- * }</pre>
- *
- * @see RequiresNoPermission
- * @hide
- */
-@Retention(CLASS)
-@Target({ANNOTATION_TYPE,METHOD,CONSTRUCTOR,FIELD,PARAMETER})
-public @interface RequiresPermission {
- /**
- * The name of the permission that is required, if precisely one permission
- * is required. If more than one permission is required, specify either
- * {@link #allOf()} or {@link #anyOf()} instead.
- * <p>
- * If specified, {@link #anyOf()} and {@link #allOf()} must both be null.
- */
- String value() default "";
-
- /**
- * Specifies a list of permission names that are all required.
- * <p>
- * If specified, {@link #anyOf()} and {@link #value()} must both be null.
- */
- String[] allOf() default {};
-
- /**
- * Specifies a list of permission names where at least one is required
- * <p>
- * If specified, {@link #allOf()} and {@link #value()} must both be null.
- */
- String[] anyOf() default {};
-
- /**
- * If true, the permission may not be required in all cases (e.g. it may only be
- * enforced on certain platforms, or for certain call parameters, etc.
- */
- boolean conditional() default false;
-
- /**
- * Specifies that the given permission is required for read operations.
- * <p>
- * When specified on a parameter, the annotation indicates that the method requires
- * a permission which depends on the value of the parameter (and typically
- * the corresponding field passed in will be one of a set of constants which have
- * been annotated with a <code>@RequiresPermission</code> annotation.)
- */
- @Target({FIELD, METHOD, PARAMETER})
- @interface Read {
- RequiresPermission value() default @RequiresPermission;
- }
-
- /**
- * Specifies that the given permission is required for write operations.
- * <p>
- * When specified on a parameter, the annotation indicates that the method requires
- * a permission which depends on the value of the parameter (and typically
- * the corresponding field passed in will be one of a set of constants which have
- * been annotated with a <code>@RequiresPermission</code> annotation.)
- */
- @Target({FIELD, METHOD, PARAMETER})
- @interface Write {
- RequiresPermission value() default @RequiresPermission;
- }
-}
diff --git a/core/java/android/annotation/SdkConstant.java b/core/java/android/annotation/SdkConstant.java
deleted file mode 100644
index 0a5318609847..000000000000
--- a/core/java/android/annotation/SdkConstant.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Indicates a constant field value should be exported to be used in the SDK tools.
- * @hide
- */
-@Target({ ElementType.FIELD })
-@Retention(RetentionPolicy.SOURCE)
-public @interface SdkConstant {
- public static enum SdkConstantType {
- ACTIVITY_INTENT_ACTION, BROADCAST_INTENT_ACTION, SERVICE_ACTION, INTENT_CATEGORY, FEATURE;
- }
-
- SdkConstantType value();
-}
diff --git a/core/java/android/annotation/Size.java b/core/java/android/annotation/Size.java
deleted file mode 100644
index 7c3e70f658e9..000000000000
--- a/core/java/android/annotation/Size.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated element should have a given size or length.
- * Note that "-1" means "unset". Typically used with a parameter or
- * return value of type array or collection.
- * <p>
- * Example:
- * <pre>{@code
- * public void getLocationInWindow(@Size(2) int[] location) {
- * ...
- * }
- * }</pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({PARAMETER,LOCAL_VARIABLE,METHOD,FIELD})
-public @interface Size {
- /** An exact size (or -1 if not specified) */
- long value() default -1;
- /** A minimum size, inclusive */
- long min() default Long.MIN_VALUE;
- /** A maximum size, inclusive */
- long max() default Long.MAX_VALUE;
- /** The size must be a multiple of this factor */
- long multiple() default 1;
-} \ No newline at end of file
diff --git a/core/java/android/annotation/StringDef.java b/core/java/android/annotation/StringDef.java
deleted file mode 100644
index a37535b9c98e..000000000000
--- a/core/java/android/annotation/StringDef.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated String element, represents a logical
- * type and that its value should be one of the explicitly named constants.
- * <p>
- * Example:
- * <pre><code>
- * &#64;Retention(SOURCE)
- * &#64;StringDef({
- * POWER_SERVICE,
- * WINDOW_SERVICE,
- * LAYOUT_INFLATER_SERVICE
- * })
- * public @interface ServiceName {}
- * public static final String POWER_SERVICE = "power";
- * public static final String WINDOW_SERVICE = "window";
- * public static final String LAYOUT_INFLATER_SERVICE = "layout_inflater";
- * ...
- * public abstract Object getSystemService(@ServiceName String name);
- * </code></pre>
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({ANNOTATION_TYPE})
-public @interface StringDef {
- /** Defines the constant prefix for this element */
- String[] prefix() default {};
- /** Defines the constant suffix for this element */
- String[] suffix() default {};
-
- /** Defines the allowed constants for this element */
- String[] value() default {};
-}
diff --git a/core/java/android/annotation/StringRes.java b/core/java/android/annotation/StringRes.java
deleted file mode 100644
index 190b68a9960b..000000000000
--- a/core/java/android/annotation/StringRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a String resource reference (e.g. {@link android.R.string#ok}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface StringRes {
-}
diff --git a/core/java/android/annotation/StyleRes.java b/core/java/android/annotation/StyleRes.java
deleted file mode 100644
index 4453b8d89153..000000000000
--- a/core/java/android/annotation/StyleRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a integer parameter, field or method return value is expected
- * to be a style resource reference (e.g. {@link android.R.style#TextAppearance}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface StyleRes {
-}
diff --git a/core/java/android/annotation/StyleableRes.java b/core/java/android/annotation/StyleableRes.java
deleted file mode 100644
index 3c1895e6dce9..000000000000
--- a/core/java/android/annotation/StyleableRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that a integer parameter, field or method return value is expected
- * to be a styleable resource reference (e.g. {@link android.R.styleable#TextView_text}).
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface StyleableRes {
-}
diff --git a/core/java/android/annotation/SuppressAutoDoc.java b/core/java/android/annotation/SuppressAutoDoc.java
deleted file mode 100644
index e34e03bcee29..000000000000
--- a/core/java/android/annotation/SuppressAutoDoc.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that any automatically generated documentation should be suppressed
- * for the annotated method, parameter, or field.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
-public @interface SuppressAutoDoc {
-}
diff --git a/core/java/android/annotation/SuppressLint.java b/core/java/android/annotation/SuppressLint.java
deleted file mode 100644
index 2d3456b0ea46..000000000000
--- a/core/java/android/annotation/SuppressLint.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Indicates that Lint should ignore the specified warnings for the annotated element. */
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
-@Retention(RetentionPolicy.CLASS)
-public @interface SuppressLint {
- /**
- * The set of warnings (identified by the lint issue id) that should be
- * ignored by lint. It is not an error to specify an unrecognized name.
- */
- String[] value();
-}
diff --git a/core/java/android/annotation/SystemApi.java b/core/java/android/annotation/SystemApi.java
deleted file mode 100644
index a468439c8e74..000000000000
--- a/core/java/android/annotation/SystemApi.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates an API is exposed for use by bundled system applications.
- * <p>
- * These APIs are not guaranteed to remain consistent release-to-release,
- * and are not for use by apps linking against the Android SDK.
- * </p><p>
- * This annotation should only appear on API that is already marked <pre>@hide</pre>.
- * </p>
- *
- * @hide
- */
-@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
-@Retention(RetentionPolicy.RUNTIME)
-public @interface SystemApi {
- enum Client {
- /**
- * Specifies that the intended clients of a SystemApi are privileged apps.
- * This is the default value for {@link #client}.
- */
- PRIVILEGED_APPS,
-
- /**
- * Specifies that the intended clients of a SystemApi are used by classes in
- * <pre>BOOTCLASSPATH</pre> in mainline modules. Mainline modules can also expose
- * this type of system APIs too when they're used only by the non-updatable
- * platform code.
- */
- MODULE_LIBRARIES,
-
- /**
- * Specifies that the system API is available only in the system server process.
- * Use this to expose APIs from code loaded by the system server process <em>but</em>
- * not in <pre>BOOTCLASSPATH</pre>.
- */
- SYSTEM_SERVER
- }
-
- /**
- * The intended client of this SystemAPI.
- */
- Client client() default android.annotation.SystemApi.Client.PRIVILEGED_APPS;
-
- /**
- * Container for {@link SystemApi} that allows it to be applied repeatedly to types.
- */
- @Retention(RetentionPolicy.RUNTIME)
- @Target(TYPE)
- @interface Container {
- SystemApi[] value();
- }
-}
diff --git a/core/java/android/annotation/SystemService.java b/core/java/android/annotation/SystemService.java
deleted file mode 100644
index c05c1bab06d2..000000000000
--- a/core/java/android/annotation/SystemService.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Description of a system service available through
- * {@link android.content.Context#getSystemService(Class)}. This is used to auto-generate
- * documentation explaining how to obtain a reference to the service.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target(TYPE)
-public @interface SystemService {
- /**
- * The string name of the system service that can be passed to
- * {@link android.content.Context#getSystemService(String)}.
- *
- * @see android.content.Context#getSystemServiceName(Class)
- */
- String value();
-}
diff --git a/core/java/android/annotation/TargetApi.java b/core/java/android/annotation/TargetApi.java
deleted file mode 100644
index 975318e4de67..000000000000
--- a/core/java/android/annotation/TargetApi.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/** Indicates that Lint should treat this type as targeting a given API level, no matter what the
- project target is. */
-@Target({TYPE, METHOD, CONSTRUCTOR, FIELD})
-@Retention(RetentionPolicy.CLASS)
-public @interface TargetApi {
- /**
- * This sets the target api level for the type..
- */
- int value();
-}
diff --git a/core/java/android/annotation/TestApi.java b/core/java/android/annotation/TestApi.java
deleted file mode 100644
index 0e9ed3751246..000000000000
--- a/core/java/android/annotation/TestApi.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Indicates an API is exposed for use by CTS.
- * <p>
- * These APIs are not guaranteed to remain consistent release-to-release,
- * and are not for use by apps linking against the Android SDK.
- * </p>
- *
- * @hide
- */
-@Target({TYPE, FIELD, METHOD, CONSTRUCTOR, ANNOTATION_TYPE, PACKAGE})
-@Retention(RetentionPolicy.SOURCE)
-public @interface TestApi {
-}
diff --git a/core/java/android/annotation/TransitionRes.java b/core/java/android/annotation/TransitionRes.java
deleted file mode 100644
index 06bac74984a5..000000000000
--- a/core/java/android/annotation/TransitionRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be a transition resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface TransitionRes {
-}
diff --git a/core/java/android/annotation/UiContext.java b/core/java/android/annotation/UiContext.java
deleted file mode 100644
index 47becc08c2f3..000000000000
--- a/core/java/android/annotation/UiContext.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.app.Activity;
-import android.app.WallpaperManager;
-import android.content.Context;
-import android.os.Bundle;
-import android.view.Display;
-import android.view.LayoutInflater;
-import android.view.WindowManager;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes a {@link Context} that can be used to create UI, meaning that it can provide a
- * {@link Display} via {@link Context#getDisplay} and can be used to obtain a {@link WindowManager},
- * {@link LayoutInflater} or {@link WallpaperManager} via {@link Context#getSystemService(String)}.
- * A {@link Context} which is marked as {@link UiContext} implies that the {@link Context} is also
- * a {@link DisplayContext}.
- * <p>
- * This kind of {@link Context} is usually an {@link Activity} or
- * created via {@link Context#createWindowContext(int, Bundle)}.
- * </p>
- * This is a marker annotation and has no specific attributes.
- *
- * @see Context#getDisplay()
- * @see Context#getSystemService(String)
- * @see Context#getSystemService(Class)
- * @see Context#createWindowContext(int, Bundle)
- * @see DisplayContext
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE, METHOD, PARAMETER, FIELD})
-public @interface UiContext {
-}
diff --git a/core/java/android/annotation/UiThread.java b/core/java/android/annotation/UiThread.java
deleted file mode 100644
index 6d7eedc7d2e2..000000000000
--- a/core/java/android/annotation/UiThread.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.os.Looper;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated method or constructor should only be called on the
- * UI thread. If the annotated element is a class, then all methods in the class
- * should be called on the UI thread.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- * &#64;UiThread
- * public abstract void setText(@NonNull String text) { ... }
- * </code>
- * </pre>
- *
- * @memberDoc This method must be called on the thread that originally created
- * this UI element. This is typically the
- * {@linkplain Looper#getMainLooper() main thread} of your app.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface UiThread {
-}
diff --git a/core/java/android/annotation/UptimeMillisLong.java b/core/java/android/annotation/UptimeMillisLong.java
deleted file mode 100644
index 8946eea0249c..000000000000
--- a/core/java/android/annotation/UptimeMillisLong.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import android.os.SystemClock;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * @memberDoc Value is a non-negative timestamp in the
- * {@link SystemClock#uptimeMillis()} time base.
- * @paramDoc Value is a non-negative timestamp in the
- * {@link SystemClock#uptimeMillis()} time base.
- * @returnDoc Value is a non-negative timestamp in the
- * {@link SystemClock#uptimeMillis()} time base.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface UptimeMillisLong {
-}
diff --git a/core/java/android/annotation/UserHandleAware.java b/core/java/android/annotation/UserHandleAware.java
deleted file mode 100644
index 7d3d20b31b2a..000000000000
--- a/core/java/android/annotation/UserHandleAware.java
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PACKAGE;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Indicates an API that uses {@code context.getUser} or {@code context.getUserId}
- * to operate across users (as the user associated with the context)
- * <p>
- * To create a {@link android.content.Context} associated with a different user,
- * use {@link android.content.Context#createContextAsUser} or
- * {@link android.content.Context#createPackageContextAsUser}
- * <p>
- * Example:
- * <pre>{@code
- * {@literal @}UserHandleAware
- * public abstract PackageInfo getPackageInfo({@literal @}NonNull String packageName,
- * {@literal @}PackageInfoFlags int flags) throws NameNotFoundException;
- * }</pre>
- *
- * @memberDoc This method uses {@linkplain android.content.Context#getUser}
- * or {@linkplain android.content.Context#getUserId} to execute across users.
- * @hide
- */
-@Retention(SOURCE)
-@Target({TYPE, METHOD, CONSTRUCTOR, PACKAGE})
-public @interface UserHandleAware {
-}
diff --git a/core/java/android/annotation/UserIdInt.java b/core/java/android/annotation/UserIdInt.java
deleted file mode 100644
index 7b9ce25e3f1a..000000000000
--- a/core/java/android/annotation/UserIdInt.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-/**
- * Denotes that the annotated element is a multi-user user ID. This is
- * <em>not</em> the same as a UID.
- *
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface UserIdInt {
-}
diff --git a/core/java/android/annotation/Widget.java b/core/java/android/annotation/Widget.java
deleted file mode 100644
index 6756cd73c5fe..000000000000
--- a/core/java/android/annotation/Widget.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.annotation;
-
-import java.lang.annotation.Target;
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Indicates a class is a widget usable by application developers to create UI.
- * <p>
- * This must be used in cases where:
- * <ul>
- * <li>The widget is not in the package <code>android.widget</code></li>
- * <li>The widget extends <code>android.view.ViewGroup</code></li>
- * </ul>
- * @hide
- */
-@Target({ ElementType.TYPE })
-@Retention(RetentionPolicy.SOURCE)
-public @interface Widget {
-}
diff --git a/core/java/android/annotation/WorkerThread.java b/core/java/android/annotation/WorkerThread.java
deleted file mode 100644
index 8c2a4d381ab1..000000000000
--- a/core/java/android/annotation/WorkerThread.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.CONSTRUCTOR;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.ElementType.TYPE;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that the annotated method should only be called on a worker thread.
- * If the annotated element is a class, then all methods in the class should be
- * called on a worker thread.
- * <p>
- * Example:
- *
- * <pre>
- * <code>
- * &#64;WorkerThread
- * protected abstract FilterResults performFiltering(CharSequence constraint);
- * </code>
- * </pre>
- *
- * @memberDoc This method may take several seconds to complete, so it should
- * only be called from a worker thread.
- * @hide
- */
-@Retention(SOURCE)
-@Target({METHOD,CONSTRUCTOR,TYPE,PARAMETER})
-public @interface WorkerThread {
-}
diff --git a/core/java/android/annotation/XmlRes.java b/core/java/android/annotation/XmlRes.java
deleted file mode 100644
index 5fb8a4a47127..000000000000
--- a/core/java/android/annotation/XmlRes.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.annotation;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-import static java.lang.annotation.ElementType.PARAMETER;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-/**
- * Denotes that an integer parameter, field or method return value is expected
- * to be an XML resource reference.
- *
- * {@hide}
- */
-@Documented
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD})
-public @interface XmlRes {
-}
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b3e656d30752..ff210e1c0ea6 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -5613,7 +5613,7 @@ public final class ActivityThread extends ClientTransactionHandler
}
/** Performs the activity relaunch locally vs. requesting from system-server. */
- private void handleRelaunchActivityLocally(IBinder token) {
+ public void handleRelaunchActivityLocally(IBinder token) {
final ActivityClientRecord r = mActivities.get(token);
if (r == null) {
Log.w(TAG, "Activity to relaunch no longer exists");
@@ -5977,20 +5977,6 @@ public final class ActivityThread extends ClientTransactionHandler
// Update all affected Resources objects to use new ResourcesImpl
mResourcesManager.applyNewResourceDirsLocked(ai, oldResDirs);
}
-
- ApplicationPackageManager.configurationChanged();
-
- // Trigger a regular Configuration change event, only with a different assetsSeq number
- // so that we actually call through to all components.
- // TODO(adamlesinski): Change this to make use of ActivityManager's upcoming ability to
- // store configurations per-process.
- final Configuration config = mConfigurationController.getConfiguration();
- Configuration newConfig = new Configuration();
- newConfig.assetsSeq = (config != null ? config.assetsSeq : 0) + 1;
- mConfigurationController.handleConfigurationChanged(newConfig, null /* compat */);
-
- // Preserve windows to avoid black flickers when overlays change.
- relaunchAllActivities(true /* preserveWindows */, "handleApplicationInfoChanged");
}
/**
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index efeef1b07c0e..75a38c2380b9 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -4723,8 +4723,8 @@ public class AppOpsManager {
}
/**
- * Flag for querying app op history: get only aggregate information and no
- * discrete accesses.
+ * Flag for querying app op history: get only aggregate information (counts of events) and no
+ * discret accesses information - specific accesses with timestamp.
*
* @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer)
*
@@ -4735,8 +4735,8 @@ public class AppOpsManager {
public static final int HISTORY_FLAG_AGGREGATE = 1 << 0;
/**
- * Flag for querying app op history: get only discrete information and no
- * aggregate accesses.
+ * Flag for querying app op history: get only discrete access information (only specific
+ * accesses with timestamps) and no aggregate information (counts over time).
*
* @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer)
*
@@ -4747,7 +4747,7 @@ public class AppOpsManager {
public static final int HISTORY_FLAG_DISCRETE = 1 << 1;
/**
- * Flag for querying app op history: get all types of historical accesses.
+ * Flag for querying app op history: get all types of historical access information.
*
* @see #getHistoricalOps(HistoricalOpsRequest, Executor, Consumer)
*
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index dba62b9d3b63..5a70f925fc02 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -881,7 +881,7 @@ public class ApplicationPackageManager extends PackageManager {
@Override
public void requestChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Type int required, @NonNull List<Certificate> trustedInstallers,
+ @Checksum.TypeMask int required, @NonNull List<Certificate> trustedInstallers,
@NonNull OnChecksumsReadyListener onChecksumsReadyListener)
throws CertificateEncodingException, NameNotFoundException {
Objects.requireNonNull(packageName);
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 7dc662abe0c1..609c014feb5b 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -5513,6 +5513,10 @@ public class DevicePolicyManager {
* This method requires the caller to be the device owner.
* <p>
* This proxy is only a recommendation and it is possible that some apps will ignore it.
+ * <p>
+ * Note: The device owner won't be able to set a global HTTP proxy if there are unaffiliated
+ * secondary users or profiles on the device. It's recommended that affiliation ids are set for
+ * new users as soon as possible after provisioning via {@link #setAffiliationIds}.
*
* @see ProxyInfo
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
@@ -12791,6 +12795,11 @@ public class DevicePolicyManager {
* <p>In this mode, the DNS subsystem will attempt a TLS handshake to the network-supplied
* resolver prior to attempting name resolution in cleartext.
*
+ * <p>Note: The device owner won't be able to set the global private DNS mode if there are
+ * unaffiliated secondary users or profiles on the device. It's recommended that affiliation
+ * ids are set for new users as soon as possible after provisioning via
+ * {@link #setAffiliationIds}.
+ *
* @param admin which {@link DeviceAdminReceiver} this request is associated with.
*
* @return {@code PRIVATE_DNS_SET_NO_ERROR} if the mode was set successfully, or
@@ -12826,6 +12835,11 @@ public class DevicePolicyManager {
* the ability to resolve hostnames as system traffic to the resolver may not go through the
* VPN.
*
+ * <p>Note: The device owner won't be able to set the global private DNS mode if there are
+ * unaffiliated secondary users or profiles on the device. It's recommended that affiliation
+ * ids are set for new users as soon as possible after provisioning via
+ * {@link #setAffiliationIds}.
+ *
* @param admin which {@link DeviceAdminReceiver} this request is associated with.
* @param privateDnsHost The hostname of a server that implements DNS over TLS (RFC7858).
*
diff --git a/core/java/android/app/people/PeopleSpaceTile.java b/core/java/android/app/people/PeopleSpaceTile.java
index de3eeee281ac..2dbbfdf660aa 100644
--- a/core/java/android/app/people/PeopleSpaceTile.java
+++ b/core/java/android/app/people/PeopleSpaceTile.java
@@ -43,6 +43,12 @@ import java.util.List;
*/
public class PeopleSpaceTile implements Parcelable {
+ public static final int SHOW_CONVERSATIONS = 1 << 0;
+ public static final int BLOCK_CONVERSATIONS = 1 << 1;
+ public static final int SHOW_IMPORTANT_CONVERSATIONS = 1 << 2;
+ public static final int SHOW_STARRED_CONTACTS = 1 << 3;
+ public static final int SHOW_CONTACTS = 1 << 4;
+
private String mId;
private CharSequence mUserName;
private Icon mUserIcon;
@@ -61,6 +67,11 @@ public class PeopleSpaceTile implements Parcelable {
private Intent mIntent;
private long mNotificationTimestamp;
private List<ConversationStatus> mStatuses;
+ private boolean mCanBypassDnd;
+ private boolean mIsPackageSuspended;
+ private boolean mIsUserQuieted;
+ private int mNotificationPolicyState;
+ private float mContactAffinity;
private PeopleSpaceTile(Builder b) {
mId = b.mId;
@@ -81,6 +92,11 @@ public class PeopleSpaceTile implements Parcelable {
mIntent = b.mIntent;
mNotificationTimestamp = b.mNotificationTimestamp;
mStatuses = b.mStatuses;
+ mCanBypassDnd = b.mCanBypassDnd;
+ mIsPackageSuspended = b.mIsPackageSuspended;
+ mIsUserQuieted = b.mIsUserQuieted;
+ mNotificationPolicyState = b.mNotificationPolicyState;
+ mContactAffinity = b.mContactAffinity;
}
public String getId() {
@@ -173,6 +189,41 @@ public class PeopleSpaceTile implements Parcelable {
return mStatuses;
}
+ /**
+ * Whether the app associated with the conversation can bypass DND.
+ */
+ public boolean canBypassDnd() {
+ return mCanBypassDnd;
+ }
+
+ /**
+ * Whether the app associated with the conversation is suspended.
+ */
+ public boolean isPackageSuspended() {
+ return mIsPackageSuspended;
+ }
+
+ /**
+ * Whether the user associated with the conversation is quieted.
+ */
+ public boolean isUserQuieted() {
+ return mIsUserQuieted;
+ }
+
+ /**
+ * Returns the state of notifications for the conversation.
+ */
+ public int getNotificationPolicyState() {
+ return mNotificationPolicyState;
+ }
+
+ /**
+ * Returns the contact affinity (whether the contact is starred).
+ */
+ public float getContactAffinity() {
+ return mContactAffinity;
+ }
+
/** Converts a {@link PeopleSpaceTile} into a {@link PeopleSpaceTile.Builder}. */
public Builder toBuilder() {
Builder builder =
@@ -192,6 +243,11 @@ public class PeopleSpaceTile implements Parcelable {
builder.setIntent(mIntent);
builder.setNotificationTimestamp(mNotificationTimestamp);
builder.setStatuses(mStatuses);
+ builder.setCanBypassDnd(mCanBypassDnd);
+ builder.setIsPackageSuspended(mIsPackageSuspended);
+ builder.setIsUserQuieted(mIsUserQuieted);
+ builder.setNotificationPolicyState(mNotificationPolicyState);
+ builder.setContactAffinity(mContactAffinity);
return builder;
}
@@ -215,6 +271,11 @@ public class PeopleSpaceTile implements Parcelable {
private Intent mIntent;
private long mNotificationTimestamp;
private List<ConversationStatus> mStatuses;
+ private boolean mCanBypassDnd;
+ private boolean mIsPackageSuspended;
+ private boolean mIsUserQuieted;
+ private int mNotificationPolicyState;
+ private float mContactAffinity;
/** Builder for use only if a shortcut is not available for the tile. */
public Builder(String id, CharSequence userName, Icon userIcon, Intent intent) {
@@ -223,6 +284,7 @@ public class PeopleSpaceTile implements Parcelable {
mUserIcon = userIcon;
mIntent = intent;
mPackageName = intent == null ? null : intent.getPackage();
+ mNotificationPolicyState = SHOW_CONVERSATIONS;
}
public Builder(ShortcutInfo info, LauncherApps launcherApps) {
@@ -232,6 +294,7 @@ public class PeopleSpaceTile implements Parcelable {
mUserHandle = info.getUserHandle();
mPackageName = info.getPackage();
mContactUri = getContactUri(info);
+ mNotificationPolicyState = SHOW_CONVERSATIONS;
}
public Builder(ConversationChannel channel, LauncherApps launcherApps) {
@@ -246,6 +309,9 @@ public class PeopleSpaceTile implements Parcelable {
mLastInteractionTimestamp = channel.getLastEventTimestamp();
mIsImportantConversation = channel.getParentNotificationChannel() != null
&& channel.getParentNotificationChannel().isImportantConversation();
+ mCanBypassDnd = channel.getParentNotificationChannel() != null
+ && channel.getParentNotificationChannel().canBypassDnd();
+ mNotificationPolicyState = SHOW_CONVERSATIONS;
}
/** Returns the Contact's Uri if present. */
@@ -366,6 +432,36 @@ public class PeopleSpaceTile implements Parcelable {
return this;
}
+ /** Sets whether the conversation channel can bypass DND. */
+ public Builder setCanBypassDnd(boolean canBypassDnd) {
+ mCanBypassDnd = canBypassDnd;
+ return this;
+ }
+
+ /** Sets whether the package is suspended. */
+ public Builder setIsPackageSuspended(boolean isPackageSuspended) {
+ mIsPackageSuspended = isPackageSuspended;
+ return this;
+ }
+
+ /** Sets whether the user has been quieted. */
+ public Builder setIsUserQuieted(boolean isUserQuieted) {
+ mIsUserQuieted = isUserQuieted;
+ return this;
+ }
+
+ /** Sets the state of blocked notifications for the conversation. */
+ public Builder setNotificationPolicyState(int notificationPolicyState) {
+ mNotificationPolicyState = notificationPolicyState;
+ return this;
+ }
+
+ /** Sets the contact's affinity. */
+ public Builder setContactAffinity(float contactAffinity) {
+ mContactAffinity = contactAffinity;
+ return this;
+ }
+
/** Builds a {@link PeopleSpaceTile}. */
@NonNull
public PeopleSpaceTile build() {
@@ -393,6 +489,11 @@ public class PeopleSpaceTile implements Parcelable {
mNotificationTimestamp = in.readLong();
mStatuses = new ArrayList<>();
in.readParcelableList(mStatuses, ConversationStatus.class.getClassLoader());
+ mCanBypassDnd = in.readBoolean();
+ mIsPackageSuspended = in.readBoolean();
+ mIsUserQuieted = in.readBoolean();
+ mNotificationPolicyState = in.readInt();
+ mContactAffinity = in.readFloat();
}
@Override
@@ -420,6 +521,11 @@ public class PeopleSpaceTile implements Parcelable {
dest.writeParcelable(mIntent, flags);
dest.writeLong(mNotificationTimestamp);
dest.writeParcelableList(mStatuses, flags);
+ dest.writeBoolean(mCanBypassDnd);
+ dest.writeBoolean(mIsPackageSuspended);
+ dest.writeBoolean(mIsUserQuieted);
+ dest.writeInt(mNotificationPolicyState);
+ dest.writeFloat(mContactAffinity);
}
public static final @android.annotation.NonNull
@@ -427,7 +533,6 @@ public class PeopleSpaceTile implements Parcelable {
public PeopleSpaceTile createFromParcel(Parcel source) {
return new PeopleSpaceTile(source);
}
-
public PeopleSpaceTile[] newArray(int size) {
return new PeopleSpaceTile[size];
}
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 114ad874d0c4..7e1df1b0e59c 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -1885,9 +1885,9 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
* in {@link android.provider.MediaStore.MediaColumns}.</p>
*
* @param uri The URI whose file is to be opened.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode Access mode for the file. May be "r" for read-only access,
+ * "rw" for read and write access, or "rwt" for read and write access
+ * that truncates any existing file.
*
* @return Returns a new ParcelFileDescriptor which you can use to access
* the file.
@@ -1948,9 +1948,10 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
* in {@link android.provider.MediaStore.MediaColumns}.</p>
*
* @param uri The URI whose file is to be opened.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode Access mode for the file. May be "r" for read-only access,
+ * "w" for write-only access, "rw" for read and write access, or
+ * "rwt" for read and write access that truncates any existing
+ * file.
* @param signal A signal to cancel the operation in progress, or
* {@code null} if none. For example, if you are downloading a
* file from the network to service a "rw" mode request, you
@@ -2010,9 +2011,11 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
* containing at least the columns specified by {@link android.provider.OpenableColumns}.</p>
*
* @param uri The URI whose file is to be opened.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode Access mode for the file. May be "r" for read-only access,
+ * "w" for write-only access (erasing whatever data is currently in
+ * the file), "wa" for write-only access to append to any existing data,
+ * "rw" for read and write access on any existing data, and "rwt" for read
+ * and write access that truncates any existing file.
*
* @return Returns a new AssetFileDescriptor which you can use to access
* the file.
@@ -2065,9 +2068,11 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
* containing at least the columns specified by {@link android.provider.OpenableColumns}.</p>
*
* @param uri The URI whose file is to be opened.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode Access mode for the file. May be "r" for read-only access,
+ * "w" for write-only access (erasing whatever data is currently in
+ * the file), "wa" for write-only access to append to any existing data,
+ * "rw" for read and write access on any existing data, and "rwt" for read
+ * and write access that truncates any existing file.
* @param signal A signal to cancel the operation in progress, or
* {@code null} if none. For example, if you are downloading a
* file from the network to service a "rw" mode request, you
@@ -2098,9 +2103,11 @@ public abstract class ContentProvider implements ContentInterface, ComponentCall
* by looking up a column named "_data" at the given URI.
*
* @param uri The URI to be opened.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode The file mode. May be "r" for read-only access,
+ * "w" for write-only access (erasing whatever data is currently in
+ * the file), "wa" for write-only access to append to any existing data,
+ * "rw" for read and write access on any existing data, and "rwt" for read
+ * and write access that truncates any existing file.
*
* @return Returns a new ParcelFileDescriptor that can be used by the
* client to access the file.
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 1132991a57f8..aec39da973f0 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -63,9 +63,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.system.ErrnoException;
import android.system.Int64Ref;
-import android.system.Os;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
@@ -78,10 +76,8 @@ import com.android.internal.util.MimeIconUtils;
import dalvik.system.CloseGuard;
import java.io.File;
-import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@@ -868,20 +864,6 @@ public abstract class ContentResolver implements ContentInterface {
return wrap((ContentInterface) wrapped);
}
- /**
- * Offer to locally truncate the given file when opened using the write-only
- * mode. This is typically used to preserve legacy compatibility behavior.
- */
- private static void maybeTruncate(FileDescriptor fd, String mode) throws FileNotFoundException {
- if ("w".equals(mode)) {
- try {
- Os.ftruncate(fd, 0);
- } catch (ErrnoException e) {
- throw new FileNotFoundException("Failed to truncate: " + e.getMessage());
- }
- }
- }
-
/** @hide */
@SuppressWarnings("HiddenAbstractMethod")
@UnsupportedAppUsage
@@ -1543,20 +1525,8 @@ public abstract class ContentResolver implements ContentInterface {
}
/**
- * Open a stream on to the content associated with a content URI. If there
- * is no data associated with the URI, FileNotFoundException is thrown.
- *
- * <h5>Accepts the following URI schemes:</h5>
- * <ul>
- * <li>content ({@link #SCHEME_CONTENT})</li>
- * <li>file ({@link #SCHEME_FILE})</li>
- * </ul>
- *
- * <p>See {@link #openAssetFileDescriptor(Uri, String)} for more information
- * on these schemes.
- *
- * <p>This method behaves like {@link FileOutputStream} and automatically
- * truncates any existing contents.
+ * Synonym for {@link #openOutputStream(Uri, String)
+ * openOutputStream(uri, "w")}.
*
* @param uri The desired URI.
* @return an OutputStream or {@code null} if the provider recently crashed.
@@ -1564,16 +1534,7 @@ public abstract class ContentResolver implements ContentInterface {
*/
public final @Nullable OutputStream openOutputStream(@NonNull Uri uri)
throws FileNotFoundException {
- AssetFileDescriptor fd = openAssetFileDescriptor(uri, "w", null);
- if (fd == null) return null;
- try {
- final FileOutputStream res = fd.createOutputStream();
- // Unconditionally truncate to mirror FileOutputStream behavior
- maybeTruncate(res.getFD(), "w");
- return res;
- } catch (IOException e) {
- throw new FileNotFoundException("Unable to create stream");
- }
+ return openOutputStream(uri, "w");
}
/**
@@ -1590,9 +1551,7 @@ public abstract class ContentResolver implements ContentInterface {
* on these schemes.
*
* @param uri The desired URI.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode May be "w", "wa", "rw", or "rwt".
* @return an OutputStream or {@code null} if the provider recently crashed.
* @throws FileNotFoundException if the provided URI could not be opened.
* @see #openAssetFileDescriptor(Uri, String)
@@ -1600,14 +1559,8 @@ public abstract class ContentResolver implements ContentInterface {
public final @Nullable OutputStream openOutputStream(@NonNull Uri uri, @NonNull String mode)
throws FileNotFoundException {
AssetFileDescriptor fd = openAssetFileDescriptor(uri, mode, null);
- if (fd == null) return null;
try {
- final FileOutputStream res = fd.createOutputStream();
- // Preserve legacy behavior by offering to truncate
- if (mTargetSdkVersion < Build.VERSION_CODES.Q) {
- maybeTruncate(res.getFD(), mode);
- }
- return res;
+ return fd != null ? fd.createOutputStream() : null;
} catch (IOException e) {
throw new FileNotFoundException("Unable to create stream");
}
@@ -1654,9 +1607,8 @@ public abstract class ContentResolver implements ContentInterface {
* provider, use {@link ParcelFileDescriptor#closeWithError(String)}.
*
* @param uri The desired URI to open.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode The file mode to use, as per {@link ContentProvider#openFile
+ * ContentProvider.openFile}.
* @return Returns a new ParcelFileDescriptor pointing to the file or {@code null} if the
* provider recently crashed. You own this descriptor and are responsible for closing it
* when done.
@@ -1698,9 +1650,8 @@ public abstract class ContentResolver implements ContentInterface {
* provider, use {@link ParcelFileDescriptor#closeWithError(String)}.
*
* @param uri The desired URI to open.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode The file mode to use, as per {@link ContentProvider#openFile
+ * ContentProvider.openFile}.
* @param cancellationSignal A signal to cancel the operation in progress,
* or null if none. If the operation is canceled, then
* {@link OperationCanceledException} will be thrown.
@@ -1793,9 +1744,8 @@ public abstract class ContentResolver implements ContentInterface {
* from any built-in data conversion that a provider implements.
*
* @param uri The desired URI to open.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile
+ * ContentProvider.openAssetFile}.
* @return Returns a new ParcelFileDescriptor pointing to the file or {@code null} if the
* provider recently crashed. You own this descriptor and are responsible for closing it
* when done.
@@ -1848,9 +1798,8 @@ public abstract class ContentResolver implements ContentInterface {
* from any built-in data conversion that a provider implements.
*
* @param uri The desired URI to open.
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt". See
- * {@link ParcelFileDescriptor#parseMode} for more details.
+ * @param mode The file mode to use, as per {@link ContentProvider#openAssetFile
+ * ContentProvider.openAssetFile}.
* @param cancellationSignal A signal to cancel the operation in progress, or null if
* none. If the operation is canceled, then
* {@link OperationCanceledException} will be thrown.
@@ -1886,10 +1835,6 @@ public abstract class ContentResolver implements ContentInterface {
} else if (SCHEME_FILE.equals(scheme)) {
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(
new File(uri.getPath()), ParcelFileDescriptor.parseMode(mode));
- // Preserve legacy behavior by offering to truncate
- if (mTargetSdkVersion < Build.VERSION_CODES.Q) {
- maybeTruncate(pfd.getFileDescriptor(), mode);
- }
return new AssetFileDescriptor(pfd, 0, -1);
} else {
if ("r".equals(mode)) {
@@ -1947,11 +1892,6 @@ public abstract class ContentResolver implements ContentInterface {
// ParcelFileDescriptorInner do that when it is closed.
stableProvider = null;
- // Preserve legacy behavior by offering to truncate
- if (mTargetSdkVersion < Build.VERSION_CODES.Q) {
- maybeTruncate(pfd.getFileDescriptor(), mode);
- }
-
return new AssetFileDescriptor(pfd, fd.getStartOffset(),
fd.getDeclaredLength());
diff --git a/core/java/android/content/pm/ApkChecksum.java b/core/java/android/content/pm/ApkChecksum.java
index eca48eca9e4b..d550f411f6f7 100644
--- a/core/java/android/content/pm/ApkChecksum.java
+++ b/core/java/android/content/pm/ApkChecksum.java
@@ -118,7 +118,7 @@ public final class ApkChecksum implements Parcelable {
- // Code below generated by codegen v1.0.15.
+ // Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -235,8 +235,8 @@ public final class ApkChecksum implements Parcelable {
};
@DataClass.Generated(
- time = 1601589269293L,
- codegenVersion = "1.0.15",
+ time = 1619810171079L,
+ codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/ApkChecksum.java",
inputSignatures = "private final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.NonNull android.content.pm.Checksum mChecksum\nprivate final @android.annotation.Nullable java.lang.String mInstallerPackageName\nprivate final @android.annotation.Nullable byte[] mInstallerCertificate\npublic @android.content.pm.Checksum.Type int getType()\npublic @android.annotation.NonNull byte[] getValue()\npublic @android.annotation.Nullable byte[] getInstallerCertificateBytes()\npublic @android.annotation.Nullable java.security.cert.Certificate getInstallerCertificate()\nclass ApkChecksum extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genHiddenConstructor=true)")
@Deprecated
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index e302f9e404fb..a3e0473e39cc 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -2141,22 +2141,57 @@ public class ApplicationInfo extends PackageItemInfo implements Parcelable {
}
/**
+ * Use default value for
+ * {@link android.R.styleable#AndroidManifestApplication_requestRawExternalStorageAccess}.
+ */
+ public static final int RAW_EXTERNAL_STORAGE_ACCESS_DEFAULT = 0;
+
+ /**
+ * Raw external storage was requested by this app.
+ */
+ public static final int RAW_EXTERNAL_STORAGE_ACCESS_REQUESTED = 1;
+
+ /**
+ * Raw external storage was not requested by this app.
+ */
+ public static final int RAW_EXTERNAL_STORAGE_ACCESS_NOT_REQUESTED = 2;
+
+ /**
+ * These constants need to match the value of
+ * {@link android.R.styleable#AndroidManifestApplication_requestRawExternalStorageAccess}.
+ * in application manifest.
+ * @hide
+ */
+ @IntDef(prefix = {"RAW_EXTERNAL_STORAGE_"}, value = {
+ RAW_EXTERNAL_STORAGE_ACCESS_DEFAULT,
+ RAW_EXTERNAL_STORAGE_ACCESS_REQUESTED,
+ RAW_EXTERNAL_STORAGE_ACCESS_NOT_REQUESTED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface RawExternalStorage {}
+
+ /**
* @return
* <ul>
- * <li>{@code true} if this app requested raw external storage access
- * <li>{@code false} if this app requests to disable raw external storage access.
- * <li>{@code null} if the app didn't specify
+ * <li>{@link ApplicationInfo#RAW_EXTERNAL_STORAGE_ACCESS_DEFAULT} if app didn't specify
* {@link android.R.styleable#AndroidManifestApplication_requestRawExternalStorageAccess}
- * in its manifest file.
- * </ul>
- *
- * @hide
+ * attribute in the manifest.
+ * <li>{@link ApplicationInfo#RAW_EXTERNAL_STORAGE_ACCESS_REQUESTED} if this app requested raw
+ * external storage access.
+ * <li>{@link ApplicationInfo#RAW_EXTERNAL_STORAGE_ACCESS_NOT_REQUESTED} if this app requests to
+ * disable raw external storage access
+ * </ul
+ * <p>
+ * Note that this doesn't give any hints on whether the app gets raw external storage access or
+ * not. Also, apps may get raw external storage access by default in some cases, see
+ * {@link android.R.styleable#AndroidManifestApplication_requestRawExternalStorageAccess}.
*/
- @SuppressWarnings("AutoBoxing")
- @SystemApi
- @Nullable
- public Boolean hasRequestRawExternalStorageAccess() {
- return requestRawExternalStorageAccess;
+ public @RawExternalStorage int getRequestRawExternalStorageAccess() {
+ if (requestRawExternalStorageAccess == null) {
+ return RAW_EXTERNAL_STORAGE_ACCESS_DEFAULT;
+ }
+ return requestRawExternalStorageAccess ? RAW_EXTERNAL_STORAGE_ACCESS_REQUESTED
+ : RAW_EXTERNAL_STORAGE_ACCESS_NOT_REQUESTED;
}
/**
diff --git a/core/java/android/content/pm/Checksum.java b/core/java/android/content/pm/Checksum.java
index 4f4898af278b..ff17496c7457 100644
--- a/core/java/android/content/pm/Checksum.java
+++ b/core/java/android/content/pm/Checksum.java
@@ -113,7 +113,7 @@ public final class Checksum implements Parcelable {
public static final int TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512 = 0x00000040;
/** @hide */
- @IntDef(flag = true, prefix = {"TYPE_"}, value = {
+ @IntDef(prefix = {"TYPE_"}, value = {
TYPE_WHOLE_MERKLE_ROOT_4K_SHA256,
TYPE_WHOLE_MD5,
TYPE_WHOLE_SHA1,
@@ -125,6 +125,19 @@ public final class Checksum implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}
+ /** @hide */
+ @IntDef(flag = true, prefix = {"TYPE_"}, value = {
+ TYPE_WHOLE_MERKLE_ROOT_4K_SHA256,
+ TYPE_WHOLE_MD5,
+ TYPE_WHOLE_SHA1,
+ TYPE_WHOLE_SHA256,
+ TYPE_WHOLE_SHA512,
+ TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256,
+ TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TypeMask {}
+
/**
* Serialize checksum to the stream in binary format.
* @hide
@@ -163,7 +176,7 @@ public final class Checksum implements Parcelable {
- // Code below generated by codegen v1.0.22.
+ // Code below generated by codegen v1.0.23.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -263,8 +276,8 @@ public final class Checksum implements Parcelable {
};
@DataClass.Generated(
- time = 1611601571576L,
- codegenVersion = "1.0.22",
+ time = 1619810358402L,
+ codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/content/pm/Checksum.java",
inputSignatures = "public static final int TYPE_WHOLE_MERKLE_ROOT_4K_SHA256\npublic static final @java.lang.Deprecated int TYPE_WHOLE_MD5\npublic static final @java.lang.Deprecated int TYPE_WHOLE_SHA1\npublic static final @java.lang.Deprecated int TYPE_WHOLE_SHA256\npublic static final @java.lang.Deprecated int TYPE_WHOLE_SHA512\npublic static final int TYPE_PARTIAL_MERKLE_ROOT_1M_SHA256\npublic static final int TYPE_PARTIAL_MERKLE_ROOT_1M_SHA512\nprivate final @android.content.pm.Checksum.Type int mType\nprivate final @android.annotation.NonNull byte[] mValue\npublic static void writeToStream(java.io.DataOutputStream,android.content.pm.Checksum)\npublic static @android.annotation.NonNull android.content.pm.Checksum readFromStream(java.io.DataInputStream)\nclass Checksum extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstDefs=false)")
@Deprecated
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 07d8478da553..a1d419e82174 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -8711,7 +8711,7 @@ public abstract class PackageManager {
* @throws NameNotFoundException if a package with the given name cannot be found on the system.
*/
public void requestChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Type int required, @NonNull List<Certificate> trustedInstallers,
+ @Checksum.TypeMask int required, @NonNull List<Certificate> trustedInstallers,
@NonNull OnChecksumsReadyListener onChecksumsReadyListener)
throws CertificateEncodingException, NameNotFoundException {
throw new UnsupportedOperationException("requestChecksums not implemented in subclass");
diff --git a/core/java/android/content/pm/parsing/ParsingPackageUtils.java b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
index 22d75ef93137..725576fda389 100644
--- a/core/java/android/content/pm/parsing/ParsingPackageUtils.java
+++ b/core/java/android/content/pm/parsing/ParsingPackageUtils.java
@@ -3069,6 +3069,13 @@ public class ParsingPackageUtils {
/**
* @hide
*/
+ public static void setCompatibilityModeEnabled(boolean compatibilityModeEnabled) {
+ sCompatibilityModeEnabled = compatibilityModeEnabled;
+ }
+
+ /**
+ * @hide
+ */
public static void readConfigUseRoundIcon(Resources r) {
if (r != null) {
sUseRoundIcon = r.getBoolean(com.android.internal.R.bool.config_useRoundIcon);
diff --git a/core/java/android/os/AggregateBatteryConsumer.java b/core/java/android/os/AggregateBatteryConsumer.java
index bcf41cce7e7c..449e3aeb6be6 100644
--- a/core/java/android/os/AggregateBatteryConsumer.java
+++ b/core/java/android/os/AggregateBatteryConsumer.java
@@ -25,17 +25,22 @@ import android.annotation.NonNull;
*/
public final class AggregateBatteryConsumer extends BatteryConsumer implements Parcelable {
+ private final double mConsumedPowerMah;
+
public AggregateBatteryConsumer(@NonNull Builder builder) {
super(builder.mPowerComponentsBuilder.build());
+ mConsumedPowerMah = builder.mConsumedPowerMah;
}
private AggregateBatteryConsumer(@NonNull Parcel source) {
super(new PowerComponents(source));
+ mConsumedPowerMah = source.readDouble();
}
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
super.writeToParcel(dest, flags);
+ dest.writeDouble(mConsumedPowerMah);
}
@Override
@@ -55,15 +60,30 @@ public final class AggregateBatteryConsumer extends BatteryConsumer implements P
}
};
+ @Override
+ public double getConsumedPower() {
+ return mConsumedPowerMah;
+ }
+
/**
* Builder for DeviceBatteryConsumer.
*/
public static final class Builder extends BaseBuilder<AggregateBatteryConsumer.Builder> {
+ private double mConsumedPowerMah;
+
public Builder(@NonNull String[] customPowerComponentNames, boolean includePowerModels) {
super(customPowerComponentNames, includePowerModels);
}
/**
+ * Sets the total power included in this aggregate.
+ */
+ public Builder setConsumedPower(double consumedPowerMah) {
+ mConsumedPowerMah = consumedPowerMah;
+ return this;
+ }
+
+ /**
* Creates a read-only object out of the Builder values.
*/
@NonNull
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 9ec6938de271..eec6810fa8bc 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -3234,6 +3234,11 @@ public abstract class BatteryStats implements Parcelable {
public abstract int getMaxLearnedBatteryCapacity() ;
/**
+ * @return The latest learned battery capacity in uAh.
+ */
+ public abstract int getLearnedBatteryCapacity();
+
+ /**
* Return the array of discharge step durations.
*/
public abstract LevelStepTracker getDischargeLevelStepTracker();
@@ -3925,7 +3930,9 @@ public abstract class BatteryStats implements Parcelable {
getStartClockTime(),
whichBatteryScreenOffRealtime / 1000, whichBatteryScreenOffUptime / 1000,
getEstimatedBatteryCapacity(),
- getMinLearnedBatteryCapacity(), getMaxLearnedBatteryCapacity(),
+ getLearnedBatteryCapacity(),
+ getMinLearnedBatteryCapacity(),
+ getMaxLearnedBatteryCapacity(),
screenDozeTime / 1000);
@@ -4688,22 +4695,31 @@ public abstract class BatteryStats implements Parcelable {
pw.println(sb.toString());
}
+ final int lastLearnedBatteryCapacity = getLearnedBatteryCapacity();
+ if (lastLearnedBatteryCapacity > 0) {
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Last learned battery capacity: ");
+ sb.append(BatteryStatsHelper.makemAh(lastLearnedBatteryCapacity / 1000));
+ sb.append(" mAh");
+ pw.println(sb.toString());
+ }
final int minLearnedBatteryCapacity = getMinLearnedBatteryCapacity();
if (minLearnedBatteryCapacity > 0) {
sb.setLength(0);
sb.append(prefix);
- sb.append(" Min learned battery capacity: ");
- sb.append(BatteryStatsHelper.makemAh(minLearnedBatteryCapacity / 1000));
- sb.append(" mAh");
+ sb.append(" Min learned battery capacity: ");
+ sb.append(BatteryStatsHelper.makemAh(minLearnedBatteryCapacity / 1000));
+ sb.append(" mAh");
pw.println(sb.toString());
}
final int maxLearnedBatteryCapacity = getMaxLearnedBatteryCapacity();
if (maxLearnedBatteryCapacity > 0) {
sb.setLength(0);
sb.append(prefix);
- sb.append(" Max learned battery capacity: ");
- sb.append(BatteryStatsHelper.makemAh(maxLearnedBatteryCapacity / 1000));
- sb.append(" mAh");
+ sb.append(" Max learned battery capacity: ");
+ sb.append(BatteryStatsHelper.makemAh(maxLearnedBatteryCapacity / 1000));
+ sb.append(" mAh");
pw.println(sb.toString());
}
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java
index e3af4834c341..6bc861f87e48 100644
--- a/core/java/android/os/BatteryUsageStats.java
+++ b/core/java/android/os/BatteryUsageStats.java
@@ -71,7 +71,6 @@ public final class BatteryUsageStats implements Parcelable {
public static final int AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT = 2;
- private final double mConsumedPower;
private final int mDischargePercentage;
private final long mStatsStartTimestampMs;
private final double mDischargedPowerLowerBound;
@@ -80,7 +79,6 @@ public final class BatteryUsageStats implements Parcelable {
private final long mChargeTimeRemainingMs;
private final String[] mCustomPowerComponentNames;
private final List<UidBatteryConsumer> mUidBatteryConsumers;
- private final List<SystemBatteryConsumer> mSystemBatteryConsumers;
private final List<UserBatteryConsumer> mUserBatteryConsumers;
private final AggregateBatteryConsumer[] mAggregateBatteryConsumers;
private final Parcel mHistoryBuffer;
@@ -97,14 +95,7 @@ public final class BatteryUsageStats implements Parcelable {
mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs;
mCustomPowerComponentNames = builder.mCustomPowerComponentNames;
- mAggregateBatteryConsumers =
- new AggregateBatteryConsumer[AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT];
- for (int i = 0; i < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; i++) {
- mAggregateBatteryConsumers[i] = builder.mAggregateBatteryConsumersBuilders[i].build();
- }
-
- double totalPower = 0;
-
+ double totalPowerMah = 0;
final int uidBatteryConsumerCount = builder.mUidBatteryConsumerBuilders.size();
mUidBatteryConsumers = new ArrayList<>(uidBatteryConsumerCount);
for (int i = 0; i < uidBatteryConsumerCount; i++) {
@@ -112,30 +103,28 @@ public final class BatteryUsageStats implements Parcelable {
builder.mUidBatteryConsumerBuilders.valueAt(i);
if (!uidBatteryConsumerBuilder.isExcludedFromBatteryUsageStats()) {
final UidBatteryConsumer consumer = uidBatteryConsumerBuilder.build();
- totalPower += consumer.getConsumedPower();
+ totalPowerMah += consumer.getConsumedPower();
mUidBatteryConsumers.add(consumer);
}
}
- final int systemBatteryConsumerCount = builder.mSystemBatteryConsumerBuilders.size();
- mSystemBatteryConsumers = new ArrayList<>(systemBatteryConsumerCount);
- for (int i = 0; i < systemBatteryConsumerCount; i++) {
- final SystemBatteryConsumer consumer =
- builder.mSystemBatteryConsumerBuilders.valueAt(i).build();
- totalPower += consumer.getConsumedPower() - consumer.getPowerConsumedByApps();
- mSystemBatteryConsumers.add(consumer);
- }
-
final int userBatteryConsumerCount = builder.mUserBatteryConsumerBuilders.size();
mUserBatteryConsumers = new ArrayList<>(userBatteryConsumerCount);
for (int i = 0; i < userBatteryConsumerCount; i++) {
final UserBatteryConsumer consumer =
builder.mUserBatteryConsumerBuilders.valueAt(i).build();
- totalPower += consumer.getConsumedPower();
+ totalPowerMah += consumer.getConsumedPower();
mUserBatteryConsumers.add(consumer);
}
- mConsumedPower = totalPower;
+ builder.getAggregateBatteryConsumerBuilder(AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
+ .setConsumedPower(totalPowerMah);
+
+ mAggregateBatteryConsumers =
+ new AggregateBatteryConsumer[AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT];
+ for (int i = 0; i < AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT; i++) {
+ mAggregateBatteryConsumers[i] = builder.mAggregateBatteryConsumersBuilders[i].build();
+ }
}
/**
@@ -147,6 +136,15 @@ public final class BatteryUsageStats implements Parcelable {
}
/**
+ * Total amount of battery charge drained since BatteryStats reset (e.g. due to being fully
+ * charged), in mAh
+ */
+ public double getConsumedPower() {
+ return mAggregateBatteryConsumers[AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE]
+ .getConsumedPower();
+ }
+
+ /**
* Portion of battery charge drained since BatteryStats reset (e.g. due to being fully
* charged), as percentage of the full charge in the range [0:100]
*/
@@ -182,14 +180,6 @@ public final class BatteryUsageStats implements Parcelable {
}
/**
- * Total amount of battery charge drained since BatteryStats reset (e.g. due to being fully
- * charged), in mAh
- */
- public double getConsumedPower() {
- return mConsumedPower;
- }
-
- /**
* Returns a battery consumer for the specified battery consumer type.
*/
public BatteryConsumer getAggregateBatteryConsumer(
@@ -203,11 +193,6 @@ public final class BatteryUsageStats implements Parcelable {
}
@NonNull
- public List<SystemBatteryConsumer> getSystemBatteryConsumers() {
- return mSystemBatteryConsumers;
- }
-
- @NonNull
public List<UserBatteryConsumer> getUserBatteryConsumers() {
return mUserBatteryConsumers;
}
@@ -232,7 +217,6 @@ public final class BatteryUsageStats implements Parcelable {
private BatteryUsageStats(@NonNull Parcel source) {
mStatsStartTimestampMs = source.readLong();
- mConsumedPower = source.readDouble();
mDischargePercentage = source.readInt();
mDischargedPowerLowerBound = source.readDouble();
mDischargedPowerUpperBound = source.readDouble();
@@ -254,14 +238,6 @@ public final class BatteryUsageStats implements Parcelable {
consumer.setCustomPowerComponentNames(mCustomPowerComponentNames);
mUidBatteryConsumers.add(consumer);
}
- int sysCount = source.readInt();
- mSystemBatteryConsumers = new ArrayList<>(sysCount);
- for (int i = 0; i < sysCount; i++) {
- final SystemBatteryConsumer consumer =
- SystemBatteryConsumer.CREATOR.createFromParcel(source);
- consumer.setCustomPowerComponentNames(mCustomPowerComponentNames);
- mSystemBatteryConsumers.add(consumer);
- }
int userCount = source.readInt();
mUserBatteryConsumers = new ArrayList<>(userCount);
for (int i = 0; i < userCount; i++) {
@@ -298,7 +274,6 @@ public final class BatteryUsageStats implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeLong(mStatsStartTimestampMs);
- dest.writeDouble(mConsumedPower);
dest.writeInt(mDischargePercentage);
dest.writeDouble(mDischargedPowerLowerBound);
dest.writeDouble(mDischargedPowerUpperBound);
@@ -312,10 +287,6 @@ public final class BatteryUsageStats implements Parcelable {
for (int i = mUidBatteryConsumers.size() - 1; i >= 0; i--) {
mUidBatteryConsumers.get(i).writeToParcel(dest, flags);
}
- dest.writeInt(mSystemBatteryConsumers.size());
- for (int i = mSystemBatteryConsumers.size() - 1; i >= 0; i--) {
- mSystemBatteryConsumers.get(i).writeToParcel(dest, flags);
- }
dest.writeInt(mUserBatteryConsumers.size());
for (int i = mUserBatteryConsumers.size() - 1; i >= 0; i--) {
mUserBatteryConsumers.get(i).writeToParcel(dest, flags);
@@ -367,8 +338,6 @@ public final class BatteryUsageStats implements Parcelable {
new AggregateBatteryConsumer.Builder[AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT];
private final SparseArray<UidBatteryConsumer.Builder> mUidBatteryConsumerBuilders =
new SparseArray<>();
- private final SparseArray<SystemBatteryConsumer.Builder> mSystemBatteryConsumerBuilders =
- new SparseArray<>();
private final SparseArray<UserBatteryConsumer.Builder> mUserBatteryConsumerBuilders =
new SparseArray<>();
private Parcel mHistoryBuffer;
@@ -483,22 +452,6 @@ public final class BatteryUsageStats implements Parcelable {
}
/**
- * Creates or returns a SystemBatteryConsumer, which represents battery attribution
- * data for a specific drain type.
- */
- @NonNull
- public SystemBatteryConsumer.Builder getOrCreateSystemBatteryConsumerBuilder(
- @SystemBatteryConsumer.DrainType int drainType) {
- SystemBatteryConsumer.Builder builder = mSystemBatteryConsumerBuilders.get(drainType);
- if (builder == null) {
- builder = new SystemBatteryConsumer.Builder(mCustomPowerComponentNames,
- mIncludePowerModels, drainType);
- mSystemBatteryConsumerBuilders.put(drainType, builder);
- }
- return builder;
- }
-
- /**
* Creates or returns a UserBatteryConsumer, which represents battery attribution
* data for an individual {@link UserHandle}.
*/
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index a06a8577a56a..f3e0ce9cd19e 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -1470,7 +1470,7 @@ public final class FileUtils {
return MediaStore.getOriginalMediaFormatFileDescriptor(context,
ParcelFileDescriptor.dup(fd));
} catch (Exception e) {
- Log.w(TAG, "Failed to convert to modern format file descriptor", e);
+ Log.d(TAG, "Failed to convert to modern format file descriptor", e);
return null;
}
}
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index 0c9ad1b17a7e..c0847872a45a 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -31,7 +31,6 @@ import static android.system.OsConstants.S_ISLNK;
import static android.system.OsConstants.S_ISREG;
import static android.system.OsConstants.S_IWOTH;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
import android.annotation.SystemApi;
@@ -64,8 +63,6 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.UncheckedIOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.net.DatagramSocket;
import java.net.Socket;
import java.nio.ByteOrder;
@@ -113,20 +110,6 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
private final CloseGuard mGuard = CloseGuard.get();
- /** @hide */
- @IntDef(prefix = {"MODE_"}, value = {
- MODE_WORLD_READABLE,
- MODE_WORLD_WRITEABLE,
- MODE_READ_ONLY,
- MODE_WRITE_ONLY,
- MODE_READ_WRITE,
- MODE_CREATE,
- MODE_TRUNCATE,
- MODE_APPEND,
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface Mode { }
-
/**
* For use with {@link #open}: if {@link #MODE_CREATE} has been supplied and
* this file doesn't already exist, then create the file with permissions
@@ -244,8 +227,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
* be opened with the requested mode.
* @see #parseMode(String)
*/
- public static ParcelFileDescriptor open(File file, @Mode int mode)
- throws FileNotFoundException {
+ public static ParcelFileDescriptor open(File file, int mode) throws FileNotFoundException {
final FileDescriptor fd = openInternal(file, mode);
if (fd == null) return null;
@@ -277,7 +259,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
// We can't accept a generic Executor here, since we need to use
// MessageQueue.addOnFileDescriptorEventListener()
@SuppressLint("ExecutorRegistration")
- public static ParcelFileDescriptor open(File file, @Mode int mode, Handler handler,
+ public static ParcelFileDescriptor open(File file, int mode, Handler handler,
final OnCloseListener listener) throws IOException {
if (handler == null) {
throw new IllegalArgumentException("Handler must not be null");
@@ -348,8 +330,7 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
return pfd;
}
- private static FileDescriptor openInternal(File file, @Mode int mode)
- throws FileNotFoundException {
+ private static FileDescriptor openInternal(File file, int mode) throws FileNotFoundException {
final int flags = FileUtils.translateModePfdToPosix(mode) | ifAtLeastQ(O_CLOEXEC);
int realMode = S_IRWXU | S_IRWXG;
@@ -642,36 +623,15 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
}
/**
- * Converts a string representing a file mode, such as "rw", into a bitmask
- * suitable for use with {@link #open}.
+ * Converts a string representing a file mode, such as "rw", into a bitmask suitable for use
+ * with {@link #open}.
* <p>
- * The argument must define at least one of the following base access modes:
- * <ul>
- * <li>"r" indicates the file should be opened in read-only mode, equivalent
- * to {@link OsConstants#O_RDONLY}.
- * <li>"w" indicates the file should be opened in write-only mode,
- * equivalent to {@link OsConstants#O_WRONLY}.
- * <li>"rw" indicates the file should be opened in read-write mode,
- * equivalent to {@link OsConstants#O_RDWR}.
- * </ul>
- * In addition to a base access mode, the following additional modes may
- * requested:
- * <ul>
- * <li>"a" indicates the file should be opened in append mode, equivalent to
- * {@link OsConstants#O_APPEND}. Before each write, the file offset is
- * positioned at the end of the file.
- * <li>"t" indicates the file should be opened in truncate mode, equivalent
- * to {@link OsConstants#O_TRUNC}. If the file already exists and is a
- * regular file and is opened for writing, it will be truncated to length 0.
- * </ul>
- *
- * @param mode The string representation of the file mode. Can be "r", "w",
- * "wt", "wa", "rw" or "rwt".
+ * @param mode The string representation of the file mode. Can be "r", "w", "wt", "wa", "rw"
+ * or "rwt".
* @return A bitmask representing the given file mode.
- * @throws IllegalArgumentException if the given string does not match a
- * known file mode.
+ * @throws IllegalArgumentException if the given string does not match a known file mode.
*/
- public static @Mode int parseMode(String mode) {
+ public static int parseMode(String mode) {
return FileUtils.translateModePosixToPfd(FileUtils.translateModeStringToPosix(mode));
}
diff --git a/core/java/android/os/SystemBatteryConsumer.java b/core/java/android/os/SystemBatteryConsumer.java
deleted file mode 100644
index 7618339260bd..000000000000
--- a/core/java/android/os/SystemBatteryConsumer.java
+++ /dev/null
@@ -1,198 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.os;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.util.Slog;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.List;
-
-
-/**
- * Contains power consumption data attributed to a system-wide drain type.
- *
- * {@hide}
- */
-public class SystemBatteryConsumer extends BatteryConsumer implements Parcelable {
- private static final String TAG = "SystemBatteryConsumer";
-
- // ****************
- // This list must be kept current with atoms.proto (frameworks/base/cmds/statsd/src/atoms.proto)
- // so the constant values must never change.
- // ****************
- @IntDef(prefix = {"DRAIN_TYPE_"}, value = {
- DRAIN_TYPE_AMBIENT_DISPLAY,
- // Reserved: APP
- DRAIN_TYPE_BLUETOOTH,
- DRAIN_TYPE_CAMERA,
- DRAIN_TYPE_MOBILE_RADIO,
- DRAIN_TYPE_FLASHLIGHT,
- DRAIN_TYPE_IDLE,
- DRAIN_TYPE_MEMORY,
- // Reserved: OVERCOUNTED,
- DRAIN_TYPE_PHONE,
- DRAIN_TYPE_SCREEN,
- // Reserved: UNACCOUNTED,
- // Reserved: USER,
- DRAIN_TYPE_WIFI,
- DRAIN_TYPE_CUSTOM,
- })
- @Retention(RetentionPolicy.SOURCE)
- public static @interface DrainType {
- }
-
- public static final int DRAIN_TYPE_AMBIENT_DISPLAY = 0;
- public static final int DRAIN_TYPE_BLUETOOTH = 2;
- public static final int DRAIN_TYPE_CAMERA = 3;
- public static final int DRAIN_TYPE_MOBILE_RADIO = 4;
- public static final int DRAIN_TYPE_FLASHLIGHT = 5;
- public static final int DRAIN_TYPE_IDLE = 6;
- public static final int DRAIN_TYPE_MEMORY = 7;
- public static final int DRAIN_TYPE_PHONE = 9;
- public static final int DRAIN_TYPE_SCREEN = 10;
- public static final int DRAIN_TYPE_WIFI = 13;
- public static final int DRAIN_TYPE_CUSTOM = 14;
-
- @DrainType
- private final int mDrainType;
-
- private final double mPowerConsumedByAppsMah;
-
- @DrainType
- public int getDrainType() {
- return mDrainType;
- }
-
- private SystemBatteryConsumer(@NonNull SystemBatteryConsumer.Builder builder) {
- super(builder.mPowerComponentsBuilder.build());
- mDrainType = builder.mDrainType;
- mPowerConsumedByAppsMah = builder.mPowerConsumedByAppsMah;
- if (mPowerConsumedByAppsMah > getConsumedPower()) {
- Slog.wtf(TAG,
- "Power attributed to apps exceeds total: drain type = " + mDrainType
- + " total consumed power = " + getConsumedPower()
- + " power consumed by apps = " + mPowerConsumedByAppsMah);
- }
- }
-
- private SystemBatteryConsumer(Parcel in) {
- super(new PowerComponents(in));
- mDrainType = in.readInt();
- mPowerConsumedByAppsMah = in.readDouble();
- }
-
- public double getPowerConsumedByApps() {
- return mPowerConsumedByAppsMah;
- }
-
- /**
- * Returns the amount of time this consumer was operating.
- */
- public long getUsageDurationMillis() {
- return mPowerComponents.getMaxComponentUsageDurationMillis();
- }
-
- /**
- * Writes the contents into a Parcel.
- */
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- dest.writeInt(mDrainType);
- dest.writeDouble(mPowerConsumedByAppsMah);
- }
-
- public static final Creator<SystemBatteryConsumer> CREATOR =
- new Creator<SystemBatteryConsumer>() {
- @Override
- public SystemBatteryConsumer createFromParcel(Parcel in) {
- return new SystemBatteryConsumer(in);
- }
-
- @Override
- public SystemBatteryConsumer[] newArray(int size) {
- return new SystemBatteryConsumer[size];
- }
- };
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- /**
- * Builder for SystemBatteryConsumer.
- */
- public static final class Builder extends BaseBuilder<Builder> {
- @DrainType
- private final int mDrainType;
- private double mPowerConsumedByAppsMah;
- private List<UidBatteryConsumer.Builder> mUidBatteryConsumers;
-
- Builder(@NonNull String[] customPowerComponentNames,
- boolean includePowerModels, @DrainType int drainType) {
- super(customPowerComponentNames, includePowerModels);
- mDrainType = drainType;
- }
-
- /**
- * Sets the amount of power used by this system component that is attributed to apps.
- * It should not exceed the total consumed power.
- */
- public Builder setPowerConsumedByApps(double powerConsumedByAppsMah) {
- mPowerConsumedByAppsMah = powerConsumedByAppsMah;
- return this;
- }
-
- /**
- * Add a UidBatteryConsumer to this SystemBatteryConsumer. For example,
- * the UidBatteryConsumer with the UID == {@link Process#BLUETOOTH_UID} should
- * be added to the SystemBatteryConsumer with the drain type == {@link
- * #DRAIN_TYPE_BLUETOOTH}.
- * <p>
- * Calculated power and duration components of the added battery consumers
- * are aggregated at the time the SystemBatteryConsumer is built by the {@link #build()}
- * method.
- * </p>
- */
- public void addUidBatteryConsumer(UidBatteryConsumer.Builder uidBatteryConsumerBuilder) {
- if (mUidBatteryConsumers == null) {
- mUidBatteryConsumers = new ArrayList<>();
- }
- mUidBatteryConsumers.add(uidBatteryConsumerBuilder);
- }
-
- /**
- * Creates a read-only object out of the Builder values.
- */
- @NonNull
- public SystemBatteryConsumer build() {
- if (mUidBatteryConsumers != null) {
- for (int i = mUidBatteryConsumers.size() - 1; i >= 0; i--) {
- UidBatteryConsumer.Builder uidBatteryConsumer = mUidBatteryConsumers.get(i);
- mPowerComponentsBuilder.addPowerAndDuration(
- uidBatteryConsumer.mPowerComponentsBuilder);
- }
- }
- return new SystemBatteryConsumer(this);
- }
- }
-}
diff --git a/core/java/android/os/VintfObject.java b/core/java/android/os/VintfObject.java
index 7af8f71aa4aa..bf0b655fe574 100644
--- a/core/java/android/os/VintfObject.java
+++ b/core/java/android/os/VintfObject.java
@@ -16,6 +16,7 @@
package android.os;
+import android.annotation.NonNull;
import android.annotation.TestApi;
import android.util.Slog;
@@ -112,6 +113,15 @@ public class VintfObject {
public static native String getSepolicyVersion();
/**
+ * @return the PLATFORM_SEPOLICY_VERSION build flag available in framework
+ * compatibility matrix.
+ *
+ * @hide
+ */
+ @TestApi
+ public static native @NonNull String getPlatformSepolicyVersion();
+
+ /**
* @return a list of VNDK snapshots supported by the framework, as
* specified in framework manifest. For example,
* [("27", ["libjpeg.so", "libbase.so"]),
diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java
index f6d525c10cc9..3cffeb0578d4 100644
--- a/core/java/android/view/FrameMetrics.java
+++ b/core/java/android/view/FrameMetrics.java
@@ -16,6 +16,8 @@
package android.view;
+import static android.graphics.FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED;
+
import android.annotation.IntDef;
import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build;
@@ -172,8 +174,6 @@ public final class FrameMetrics {
**/
public static final int DEADLINE = 13;
- private static final int FRAME_INFO_FLAG_FIRST_DRAW = 1 << 0;
-
/**
* Identifiers for metrics available for each frame.
*
@@ -343,7 +343,7 @@ public final class FrameMetrics {
}
if (id == FIRST_DRAW_FRAME) {
- return (mTimingData[Index.FLAGS] & FRAME_INFO_FLAG_FIRST_DRAW) != 0 ? 1 : 0;
+ return (mTimingData[Index.FLAGS] & FLAG_WINDOW_VISIBILITY_CHANGED) != 0 ? 1 : 0;
} else if (id == INTENDED_VSYNC_TIMESTAMP) {
return mTimingData[Index.INTENDED_VSYNC];
} else if (id == VSYNC_TIMESTAMP) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0958f3fbd771..a06f193255b2 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -2764,7 +2764,9 @@ public final class ViewRootImpl implements ViewParent,
// to resume them
mDirty.set(0, 0, mWidth, mHeight);
}
- mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED;
+ }
+ if (mFirst || viewVisibilityChanged) {
+ mViewFrameInfo.flags |= FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED;
}
relayoutResult = relayoutWindow(params, viewVisibility, insetsPending);
final boolean freeformResizing = (relayoutResult
diff --git a/core/java/android/view/translation/UiTranslationManager.java b/core/java/android/view/translation/UiTranslationManager.java
index 541b4941c62e..7726086a4787 100644
--- a/core/java/android/view/translation/UiTranslationManager.java
+++ b/core/java/android/view/translation/UiTranslationManager.java
@@ -315,6 +315,8 @@ public final class UiTranslationManager {
private static class UiTranslationStateRemoteCallback extends IRemoteCallback.Stub {
private final Executor mExecutor;
private final UiTranslationStateCallback mCallback;
+ private ULocale mSourceLocale;
+ private ULocale mTargetLocale;
UiTranslationStateRemoteCallback(Executor executor,
UiTranslationStateCallback callback) {
@@ -331,10 +333,12 @@ public final class UiTranslationManager {
int state = bundle.getInt(EXTRA_STATE);
switch (state) {
case STATE_UI_TRANSLATION_STARTED:
+ mSourceLocale = (ULocale) bundle.getSerializable(EXTRA_SOURCE_LOCALE);
+ mTargetLocale = (ULocale) bundle.getSerializable(EXTRA_TARGET_LOCALE);
+ mCallback.onStarted(mSourceLocale, mTargetLocale);
+ break;
case STATE_UI_TRANSLATION_RESUMED:
- mCallback.onStarted(
- (ULocale) bundle.getSerializable(EXTRA_SOURCE_LOCALE),
- (ULocale) bundle.getSerializable(EXTRA_TARGET_LOCALE));
+ mCallback.onStarted(mSourceLocale, mTargetLocale);
break;
case STATE_UI_TRANSLATION_PAUSED:
mCallback.onPaused();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index eb16cef15248..b3f848b4cf22 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -6614,27 +6614,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
/**
- * Returns the {@link EdgeEffect#getType()} for the edge effects.
- * @return the {@link EdgeEffect#getType()} for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- @EdgeEffect.EdgeEffectType
- public int getEdgeEffectType() {
- return mEdgeGlowTop.getType();
- }
-
- /**
- * Sets the {@link EdgeEffect#setType(int)} for the edge effects.
- * @param type The edge effect type to use for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) {
- mEdgeGlowTop.setType(type);
- mEdgeGlowBottom.setType(type);
- invalidate();
- }
-
- /**
* Sets the recycler listener to be notified whenever a View is set aside in
* the recycler for later reuse. This listener can be used to free resources
* associated to the View.
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 4d2d9e86f1a6..c11344ebaece 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -62,9 +62,7 @@ import java.lang.annotation.RetentionPolicy;
*/
public class EdgeEffect {
/**
- * This sets the default value for {@link #setType(int)} to {@link #TYPE_STRETCH} instead
- * of {@link #TYPE_GLOW}. The type can still be overridden by the theme, view attribute,
- * or by calling {@link #setType(int)}.
+ * This sets the edge effect to use stretch instead of glow.
*
* @hide
*/
@@ -73,34 +71,19 @@ public class EdgeEffect {
public static final long USE_STRETCH_EDGE_EFFECT_BY_DEFAULT = 171228096L;
/**
- * This sets the default value for {@link #setType(int)} to {@link #TYPE_STRETCH} instead
- * of {@link #TYPE_GLOW} for views that instantiate with
- * {@link #EdgeEffect(Context, AttributeSet)}, indicating use of S+ EdgeEffect support. The
- * type can still be overridden by the theme, view attribute, or by calling
- * {@link #setType(int)}.
- *
- * @hide
- */
- @ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.S)
- public static final long USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED = 178807038L;
-
- /**
* The default blend mode used by {@link EdgeEffect}.
*/
public static final BlendMode DEFAULT_BLEND_MODE = BlendMode.SRC_ATOP;
/**
- * Use a color edge glow for the edge effect. From XML, use
- * <code>android:edgeEffectType="glow"</code>.
+ * Use a color edge glow for the edge effect.
*/
- public static final int TYPE_GLOW = 0;
+ private static final int TYPE_GLOW = 0;
/**
- * Use a stretch for the edge effect. From XML, use
- * <code>android:edgeEffectType="stretch"</code>.
+ * Use a stretch for the edge effect.
*/
- public static final int TYPE_STRETCH = 1;
+ private static final int TYPE_STRETCH = 1;
/**
* The velocity threshold before the spring animation is considered settled.
@@ -221,7 +204,7 @@ public class EdgeEffect {
* @param context Context used to provide theming and resource information for the EdgeEffect
*/
public EdgeEffect(Context context) {
- this(context, null, Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT));
+ this(context, null);
}
/**
@@ -230,20 +213,12 @@ public class EdgeEffect {
* @param attrs The attributes of the XML tag that is inflating the view
*/
public EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs) {
- this(context, attrs,
- Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT)
- || Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED));
- }
-
- private EdgeEffect(@NonNull Context context, @Nullable AttributeSet attrs,
- boolean defaultStretch) {
final TypedArray a = context.obtainStyledAttributes(
attrs, com.android.internal.R.styleable.EdgeEffect);
final int themeColor = a.getColor(
com.android.internal.R.styleable.EdgeEffect_colorEdgeEffect, 0xff666666);
- mEdgeEffectType = a.getInt(
- com.android.internal.R.styleable.EdgeEffect_edgeEffectType,
- defaultStretch ? TYPE_STRETCH : TYPE_GLOW);
+ mEdgeEffectType = Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT)
+ ? TYPE_STRETCH : TYPE_GLOW;
a.recycle();
mPaint.setAntiAlias(true);
@@ -467,7 +442,6 @@ public class EdgeEffect {
if (mEdgeEffectType == TYPE_STRETCH) {
mState = STATE_RECEDE;
mVelocity = velocity * ON_ABSORB_VELOCITY_ADJUSTMENT;
- mDistance = 0;
mStartTime = AnimationUtils.currentAnimationTimeMillis();
} else {
mState = STATE_ABSORB;
@@ -506,17 +480,6 @@ public class EdgeEffect {
}
/**
- * Sets the edge effect type to use. The default without a theme attribute set is
- * {@link EdgeEffect#TYPE_GLOW}.
- *
- * @param type The edge effect type to use.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- public void setType(@EdgeEffectType int type) {
- mEdgeEffectType = type;
- }
-
- /**
* Set or clear the blend mode. A blend mode defines how source pixels
* (generated by a drawing command) are composited with the destination pixels
* (content of the render target).
@@ -542,16 +505,6 @@ public class EdgeEffect {
}
/**
- * Return the edge effect type to use.
- *
- * @return The edge effect type to use.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- public @EdgeEffectType int getType() {
- return mEdgeEffectType;
- }
-
- /**
* Returns the blend mode. A blend mode defines how source pixels
* (generated by a drawing command) are composited with the destination pixels
* (content of the render target).
@@ -568,7 +521,7 @@ public class EdgeEffect {
* Draw into the provided canvas. Assumes that the canvas has been rotated
* accordingly and the size has been set. The effect will be drawn the full
* width of X=0 to X=width, beginning from Y=0 and extending to some factor <
- * 1.f of height. The {@link #TYPE_STRETCH} effect will only be visible on a
+ * 1.f of height. The effect will only be visible on a
* hardware canvas, e.g. {@link RenderNode#beginRecording()}.
*
* @param canvas Canvas to draw into
@@ -686,7 +639,7 @@ public class EdgeEffect {
* @return The maximum height of the edge effect
*/
public int getMaxHeight() {
- return (int) (mBounds.height() * MAX_GLOW_SCALE + 0.5f);
+ return (int) mHeight;
}
private void update() {
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index e41893e37103..018cba7f95e5 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -308,27 +308,6 @@ public class HorizontalScrollView extends FrameLayout {
}
/**
- * Returns the {@link EdgeEffect#getType()} for the edge effects.
- * @return the {@link EdgeEffect#getType()} for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- @EdgeEffect.EdgeEffectType
- public int getEdgeEffectType() {
- return mEdgeGlowLeft.getType();
- }
-
- /**
- * Sets the {@link EdgeEffect#setType(int)} for the edge effects.
- * @param type The edge effect type to use for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) {
- mEdgeGlowRight.setType(type);
- mEdgeGlowLeft.setType(type);
- invalidate();
- }
-
- /**
* @return The maximum amount this scroll view will scroll in response to
* an arrow event.
*/
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 3610eb47edbc..693b13bbf224 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -340,27 +340,6 @@ public class ScrollView extends FrameLayout {
}
/**
- * Returns the {@link EdgeEffect#getType()} for the edge effects.
- * @return the {@link EdgeEffect#getType()} for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- @EdgeEffect.EdgeEffectType
- public int getEdgeEffectType() {
- return mEdgeGlowTop.getType();
- }
-
- /**
- * Sets the {@link EdgeEffect#setType(int)} for the edge effects.
- * @param type The edge effect type to use for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) {
- mEdgeGlowTop.setType(type);
- mEdgeGlowBottom.setType(type);
- invalidate();
- }
-
- /**
* @return The maximum amount this scroll view will scroll in response to
* an arrow event.
*/
@@ -368,7 +347,6 @@ public class ScrollView extends FrameLayout {
return (int) (MAX_SCROLL_FACTOR * (mBottom - mTop));
}
-
private void initScrollView() {
mScroller = new OverScroller(getContext());
setFocusable(true);
diff --git a/core/java/com/android/internal/annotations/CompositeRWLock.java b/core/java/com/android/internal/annotations/CompositeRWLock.java
deleted file mode 100644
index b6ddfc4d2cc4..000000000000
--- a/core/java/com/android/internal/annotations/CompositeRWLock.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Specifies a list of locks which are required for read/write operations on a data field.
- *
- * <p>
- * To annotate methods accessing the data field with the annotation {@link CompositeRWLock},
- * use {@link GuardedBy#value} to annotate method w/ write and/or read access to the data field,
- * use {@link GuardedBy#anyOf} to annotate method w/ read only access to the data field.
- * </p>
- *
- * <p>
- * When its {@link #value()} consists of multiple locks:
- * <ul>
- * <li>To write to the protected data, acquire <b>all</b> of the locks
- * in the order of the appearance in the {@link #value}.</li>
- * <li>To read from the protected data, acquire any of the locks in the {@link #value}.</li>
- * </ul>
- * </p>
- */
-@Target({FIELD})
-@Retention(RetentionPolicy.CLASS)
-public @interface CompositeRWLock {
- String[] value() default {};
-}
diff --git a/core/java/com/android/internal/annotations/GuardedBy.java b/core/java/com/android/internal/annotations/GuardedBy.java
deleted file mode 100644
index c05c4abd10e4..000000000000
--- a/core/java/com/android/internal/annotations/GuardedBy.java
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.annotations;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.ElementType.METHOD;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation type used to mark a method or field that can only be accessed when
- * holding the referenced locks.
- */
-@Target({FIELD, METHOD})
-@Retention(RetentionPolicy.CLASS)
-public @interface GuardedBy {
- /**
- * Specifies a list of locks to be held in order to access the field/method
- * annotated with this; when used in conjunction with the {@link CompositeRWLock}, locks
- * should be acquired in the order of the appearance in the {@link #value} here.
- *
- * <p>
- * If specified, {@link #anyOf()} must be null.
- * </p>
- *
- * @see CompositeRWLock
- */
- String[] value() default {};
-
- /**
- * Specifies a list of locks where at least one of them must be held in order to access
- * the field/method annotated with this; it should be <em>only</em> used in the conjunction
- * with the {@link CompositeRWLock}.
- *
- * <p>
- * If specified, {@link #allOf()} must be null.
- * </p>
- *
- * @see CompositeRWLock
- */
- String[] anyOf() default {};
-}
diff --git a/core/java/com/android/internal/annotations/Immutable.java b/core/java/com/android/internal/annotations/Immutable.java
deleted file mode 100644
index b424275f7a86..000000000000
--- a/core/java/com/android/internal/annotations/Immutable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- * Annotation type used to mark a class which is immutable.
- */
-@Target(ElementType.TYPE)
-@Retention(RetentionPolicy.CLASS)
-public @interface Immutable {
-}
diff --git a/core/java/com/android/internal/annotations/VisibleForNative.java b/core/java/com/android/internal/annotations/VisibleForNative.java
deleted file mode 100644
index e6a3fc67b7d3..000000000000
--- a/core/java/com/android/internal/annotations/VisibleForNative.java
+++ /dev/null
@@ -1,28 +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.internal.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that native code can access it.
- */
-@Retention(RetentionPolicy.CLASS)
-public @interface VisibleForNative {
-}
diff --git a/core/java/com/android/internal/annotations/VisibleForTesting.java b/core/java/com/android/internal/annotations/VisibleForTesting.java
deleted file mode 100644
index 99512ac68d5d..000000000000
--- a/core/java/com/android/internal/annotations/VisibleForTesting.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.annotations;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * Denotes that the class, method or field has its visibility relaxed so
- * that unit tests can access it.
- * <p/>
- * The <code>visibility</code> argument can be used to specific what the original
- * visibility should have been if it had not been made public or package-private for testing.
- * The default is to consider the element private.
- */
-@Retention(RetentionPolicy.CLASS)
-public @interface VisibleForTesting {
- /**
- * Intended visibility if the element had not been made public or package-private for
- * testing.
- */
- enum Visibility {
- /** The element should be considered protected. */
- PROTECTED,
- /** The element should be considered package-private. */
- PACKAGE,
- /** The element should be considered private. */
- PRIVATE
- }
-
- /**
- * Intended visibility if the element had not been made public or package-private for testing.
- * If not specified, one should assume the element originally intended to be private.
- */
- Visibility visibility() default Visibility.PRIVATE;
-}
diff --git a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java
index 100bf34203e7..0307268a28b5 100644
--- a/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java
+++ b/core/java/com/android/internal/os/AmbientDisplayPowerCalculator.java
@@ -20,7 +20,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UserHandle;
import android.util.SparseArray;
@@ -55,11 +54,6 @@ public class AmbientDisplayPowerCalculator extends PowerCalculator {
.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY, durationMs)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_AMBIENT_DISPLAY,
powerMah, powerModel);
-
- builder.getOrCreateSystemBatteryConsumerBuilder(
- SystemBatteryConsumer.DRAIN_TYPE_AMBIENT_DISPLAY)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, powerMah, powerModel)
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, durationMs);
}
/**
diff --git a/core/java/com/android/internal/os/BatteryChargeCalculator.java b/core/java/com/android/internal/os/BatteryChargeCalculator.java
index dc72f3267390..16f92efb922c 100644
--- a/core/java/com/android/internal/os/BatteryChargeCalculator.java
+++ b/core/java/com/android/internal/os/BatteryChargeCalculator.java
@@ -28,20 +28,28 @@ import java.util.List;
* Estimates the battery discharge amounts.
*/
public class BatteryChargeCalculator extends PowerCalculator {
- private final double mBatteryCapacity;
-
- public BatteryChargeCalculator(PowerProfile powerProfile) {
- mBatteryCapacity = powerProfile.getBatteryCapacity();
- }
@Override
public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
builder.setDischargePercentage(
- batteryStats.getDischargeAmount(BatteryStats.STATS_SINCE_CHARGED))
- .setDischargedPowerRange(
- batteryStats.getLowDischargeAmountSinceCharge() * mBatteryCapacity / 100,
- batteryStats.getHighDischargeAmountSinceCharge() * mBatteryCapacity / 100);
+ batteryStats.getDischargeAmount(BatteryStats.STATS_SINCE_CHARGED));
+
+ int batteryCapacityMah = batteryStats.getLearnedBatteryCapacity() / 1000;
+ if (batteryCapacityMah <= 0) {
+ batteryCapacityMah = batteryStats.getMinLearnedBatteryCapacity() / 1000;
+ if (batteryCapacityMah <= 0) {
+ batteryCapacityMah = batteryStats.getEstimatedBatteryCapacity();
+ }
+ }
+ final double dischargedPowerLowerBoundMah =
+ batteryStats.getLowDischargeAmountSinceCharge() * batteryCapacityMah / 100.0;
+ final double dischargedPowerUpperBoundMah =
+ batteryStats.getHighDischargeAmountSinceCharge() * batteryCapacityMah / 100.0;
+ builder.setDischargePercentage(
+ batteryStats.getDischargeAmount(BatteryStats.STATS_SINCE_CHARGED))
+ .setDischargedPowerRange(dischargedPowerLowerBoundMah,
+ dischargedPowerUpperBoundMah);
final long batteryTimeRemainingMs = batteryStats.computeBatteryTimeRemaining(rawRealtimeUs);
if (batteryTimeRemainingMs != -1) {
@@ -52,6 +60,11 @@ public class BatteryChargeCalculator extends PowerCalculator {
if (chargeTimeRemainingMs != -1) {
builder.setChargeTimeRemainingMs(chargeTimeRemainingMs / 1000);
}
+
+ builder.getAggregateBatteryConsumerBuilder(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+ .setConsumedPower(
+ (dischargedPowerLowerBoundMah + dischargedPowerUpperBoundMah) / 2);
}
@Override
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 02a290850b6f..db67bab25e78 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -161,7 +161,7 @@ public class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- static final int VERSION = 198;
+ static final int VERSION = 199;
// The maximum number of names wakelocks we will keep track of
// per uid; once the limit is reached, we batch the remaining wakelocks
@@ -1056,6 +1056,7 @@ public class BatteryStatsImpl extends BatteryStats {
private int mBatteryVoltageMv = -1;
private int mEstimatedBatteryCapacityMah = -1;
+ private int mLastLearnedBatteryCapacityUah = -1;
private int mMinLearnedBatteryCapacityUah = -1;
private int mMaxLearnedBatteryCapacityUah = -1;
@@ -1142,6 +1143,11 @@ public class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public int getLearnedBatteryCapacity() {
+ return mLastLearnedBatteryCapacityUah;
+ }
+
+ @Override
public int getMinLearnedBatteryCapacity() {
return mMinLearnedBatteryCapacityUah;
}
@@ -11199,6 +11205,7 @@ public class BatteryStatsImpl extends BatteryStats {
} else {
mEstimatedBatteryCapacityMah = -1;
}
+ mLastLearnedBatteryCapacityUah = -1;
mMinLearnedBatteryCapacityUah = -1;
mMaxLearnedBatteryCapacityUah = -1;
mInteractiveTimer.reset(false, elapsedRealtimeUs);
@@ -13799,6 +13806,7 @@ public class BatteryStatsImpl extends BatteryStats {
mRecordingHistory = DEBUG;
}
+ mLastLearnedBatteryCapacityUah = chargeFullUah;
if (mMinLearnedBatteryCapacityUah == -1) {
mMinLearnedBatteryCapacityUah = chargeFullUah;
} else {
@@ -15066,6 +15074,7 @@ public class BatteryStatsImpl extends BatteryStats {
mDischargeCurrentLevel = in.readInt();
mCurrentBatteryLevel = in.readInt();
mEstimatedBatteryCapacityMah = in.readInt();
+ mLastLearnedBatteryCapacityUah = in.readInt();
mMinLearnedBatteryCapacityUah = in.readInt();
mMaxLearnedBatteryCapacityUah = in.readInt();
mLowDischargeAmountSinceCharge = in.readInt();
@@ -15570,6 +15579,7 @@ public class BatteryStatsImpl extends BatteryStats {
out.writeInt(mDischargeCurrentLevel);
out.writeInt(mCurrentBatteryLevel);
out.writeInt(mEstimatedBatteryCapacityMah);
+ out.writeInt(mLastLearnedBatteryCapacityUah);
out.writeInt(mMinLearnedBatteryCapacityUah);
out.writeInt(mMaxLearnedBatteryCapacityUah);
out.writeInt(getLowDischargeAmountSinceCharge());
@@ -16071,6 +16081,7 @@ public class BatteryStatsImpl extends BatteryStats {
mRealtimeStartUs = in.readLong();
mOnBattery = in.readInt() != 0;
mEstimatedBatteryCapacityMah = in.readInt();
+ mLastLearnedBatteryCapacityUah = in.readInt();
mMinLearnedBatteryCapacityUah = in.readInt();
mMaxLearnedBatteryCapacityUah = in.readInt();
mOnBatteryInternal = false; // we are no longer really running.
@@ -16310,6 +16321,7 @@ public class BatteryStatsImpl extends BatteryStats {
out.writeLong(mRealtimeStartUs);
out.writeInt(mOnBattery ? 1 : 0);
out.writeInt(mEstimatedBatteryCapacityMah);
+ out.writeInt(mLastLearnedBatteryCapacityUah);
out.writeInt(mMinLearnedBatteryCapacityUah);
out.writeInt(mMaxLearnedBatteryCapacityUah);
mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
index babcea14d0ea..498955983ef2 100644
--- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
+++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java
@@ -54,7 +54,7 @@ public class BatteryUsageStatsProvider {
mPowerCalculators = new ArrayList<>();
// Power calculators are applied in the order of registration
- mPowerCalculators.add(new BatteryChargeCalculator(mPowerProfile));
+ mPowerCalculators.add(new BatteryChargeCalculator());
mPowerCalculators.add(new CpuPowerCalculator(mPowerProfile));
mPowerCalculators.add(new MemoryPowerCalculator(mPowerProfile));
mPowerCalculators.add(new WakelockPowerCalculator(mPowerProfile));
diff --git a/core/java/com/android/internal/os/BluetoothPowerCalculator.java b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
index 36f871b28655..6e99bbbf2331 100644
--- a/core/java/com/android/internal/os/BluetoothPowerCalculator.java
+++ b/core/java/com/android/internal/os/BluetoothPowerCalculator.java
@@ -21,7 +21,6 @@ import android.os.BatteryStats.ControllerActivityCounter;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Process;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.util.Log;
@@ -58,19 +57,11 @@ public class BluetoothPowerCalculator extends PowerCalculator {
final PowerAndDuration total = new PowerAndDuration();
- SystemBatteryConsumer.Builder systemBatteryConsumerBuilder =
- builder.getOrCreateSystemBatteryConsumerBuilder(
- SystemBatteryConsumer.DRAIN_TYPE_BLUETOOTH);
-
final SparseArray<UidBatteryConsumer.Builder> uidBatteryConsumerBuilders =
builder.getUidBatteryConsumerBuilders();
for (int i = uidBatteryConsumerBuilders.size() - 1; i >= 0; i--) {
final UidBatteryConsumer.Builder app = uidBatteryConsumerBuilders.valueAt(i);
calculateApp(app, total, query);
- if (app.getUid() == Process.BLUETOOTH_UID) {
- app.excludeFromBatteryUsageStats();
- systemBatteryConsumerBuilder.addUidBatteryConsumer(app);
- }
}
final long measuredChargeUC = batteryStats.getBluetoothMeasuredBatteryConsumptionUC();
@@ -87,12 +78,6 @@ public class BluetoothPowerCalculator extends PowerCalculator {
Log.d(TAG, "Bluetooth active: time=" + (systemComponentDurationMs)
+ " power=" + formatCharge(systemPowerMah));
}
- systemBatteryConsumerBuilder
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
- systemComponentDurationMs)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_BLUETOOTH,
- Math.max(systemPowerMah, total.powerMah), powerModel)
- .setPowerConsumedByApps(total.powerMah);
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
diff --git a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
index 9af11fe7614a..9b51a8ef6410 100644
--- a/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
+++ b/core/java/com/android/internal/os/CustomMeasuredPowerCalculator.java
@@ -20,7 +20,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.util.SparseArray;
@@ -47,15 +46,6 @@ public class CustomMeasuredPowerCalculator extends PowerCalculator {
final double[] customMeasuredPowerMah = calculateMeasuredEnergiesMah(
batteryStats.getCustomConsumerMeasuredBatteryConsumptionUC());
if (customMeasuredPowerMah != null) {
- final SystemBatteryConsumer.Builder systemBatteryConsumerBuilder =
- builder.getOrCreateSystemBatteryConsumerBuilder(
- SystemBatteryConsumer.DRAIN_TYPE_CUSTOM);
- for (int i = 0; i < customMeasuredPowerMah.length; i++) {
- systemBatteryConsumerBuilder.setConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + i,
- customMeasuredPowerMah[i]);
- }
-
final AggregateBatteryConsumer.Builder deviceBatteryConsumerBuilder =
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
diff --git a/core/java/com/android/internal/os/IdlePowerCalculator.java b/core/java/com/android/internal/os/IdlePowerCalculator.java
index cf68ab9a2066..d33a88deb9d7 100644
--- a/core/java/com/android/internal/os/IdlePowerCalculator.java
+++ b/core/java/com/android/internal/os/IdlePowerCalculator.java
@@ -20,7 +20,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UserHandle;
import android.util.Log;
import android.util.SparseArray;
@@ -53,9 +52,6 @@ public class IdlePowerCalculator extends PowerCalculator {
calculatePowerAndDuration(batteryStats, rawRealtimeUs, rawUptimeUs,
BatteryStats.STATS_SINCE_CHARGED);
if (mPowerMah != 0) {
- builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_IDLE)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE, mPowerMah)
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE, mDurationMs);
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE, mPowerMah)
diff --git a/core/java/com/android/internal/os/MemoryPowerCalculator.java b/core/java/com/android/internal/os/MemoryPowerCalculator.java
index 950d1ecec3b3..09fd85e42225 100644
--- a/core/java/com/android/internal/os/MemoryPowerCalculator.java
+++ b/core/java/com/android/internal/os/MemoryPowerCalculator.java
@@ -4,7 +4,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UserHandle;
import android.util.LongSparseArray;
import android.util.SparseArray;
@@ -31,9 +30,6 @@ public class MemoryPowerCalculator extends PowerCalculator {
BatteryStats.STATS_SINCE_CHARGED);
final double powerMah = calculatePower(batteryStats, rawRealtimeUs,
BatteryStats.STATS_SINCE_CHARGED);
- builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_MEMORY)
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MEMORY, durationMs)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MEMORY, powerMah);
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MEMORY, durationMs)
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index a1bab6eb21f6..eb5993dc2d61 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -19,7 +19,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.telephony.CellSignalStrength;
@@ -105,15 +104,6 @@ public class MobileRadioPowerCalculator extends PowerCalculator {
calculateRemaining(total, powerModel, batteryStats, rawRealtimeUs, consumptionUC);
if (total.remainingPowerMah != 0 || total.totalAppPowerMah != 0) {
- builder.getOrCreateSystemBatteryConsumerBuilder(
- SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO)
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
- total.durationMs)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
- total.remainingPowerMah + total.totalAppPowerMah,
- powerModel)
- .setPowerConsumedByApps(total.totalAppPowerMah);
-
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO,
diff --git a/core/java/com/android/internal/os/PhonePowerCalculator.java b/core/java/com/android/internal/os/PhonePowerCalculator.java
index f8997cbbd9c9..8dd463c0d5e1 100644
--- a/core/java/com/android/internal/os/PhonePowerCalculator.java
+++ b/core/java/com/android/internal/os/PhonePowerCalculator.java
@@ -20,7 +20,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UserHandle;
import android.util.SparseArray;
@@ -44,9 +43,6 @@ public class PhonePowerCalculator extends PowerCalculator {
BatteryStats.STATS_SINCE_CHARGED) / 1000;
final double phoneOnPower = mPowerEstimator.calculatePower(phoneOnTimeMs);
if (phoneOnPower != 0) {
- builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_PHONE)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnPower)
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnTimeMs);
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_PHONE, phoneOnPower)
diff --git a/core/java/com/android/internal/os/ScreenPowerCalculator.java b/core/java/com/android/internal/os/ScreenPowerCalculator.java
index 44bed2a54a10..1b3bc234fc0f 100644
--- a/core/java/com/android/internal/os/ScreenPowerCalculator.java
+++ b/core/java/com/android/internal/os/ScreenPowerCalculator.java
@@ -20,7 +20,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.text.format.DateUtils;
@@ -109,13 +108,6 @@ public class ScreenPowerCalculator extends PowerCalculator {
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
.setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN, totalAppPower, powerModel)
.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN, totalAppDuration);
-
- builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_SCREEN)
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN,
- totalPowerAndDuration.durationMs)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN,
- Math.max(totalPowerAndDuration.powerMah, totalAppPower), powerModel)
- .setPowerConsumedByApps(totalAppPower);
}
/**
diff --git a/core/java/com/android/internal/os/WifiPowerCalculator.java b/core/java/com/android/internal/os/WifiPowerCalculator.java
index 2dfc4ee69e14..776a70545df4 100644
--- a/core/java/com/android/internal/os/WifiPowerCalculator.java
+++ b/core/java/com/android/internal/os/WifiPowerCalculator.java
@@ -20,7 +20,6 @@ import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
import android.os.Process;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.util.Log;
@@ -79,10 +78,6 @@ public class WifiPowerCalculator extends PowerCalculator {
public void calculate(BatteryUsageStats.Builder builder, BatteryStats batteryStats,
long rawRealtimeUs, long rawUptimeUs, BatteryUsageStatsQuery query) {
- final SystemBatteryConsumer.Builder systemBatteryConsumerBuilder =
- builder.getOrCreateSystemBatteryConsumerBuilder(
- SystemBatteryConsumer.DRAIN_TYPE_WIFI);
-
long totalAppDurationMs = 0;
double totalAppPowerMah = 0;
final PowerDurationAndTraffic powerDurationAndTraffic = new PowerDurationAndTraffic();
@@ -104,11 +99,6 @@ public class WifiPowerCalculator extends PowerCalculator {
powerDurationAndTraffic.durationMs);
app.setConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI,
powerDurationAndTraffic.powerMah, powerModel);
-
- if (app.getUid() == Process.WIFI_UID) {
- systemBatteryConsumerBuilder.addUidBatteryConsumer(app);
- app.excludeFromBatteryUsageStats();
- }
}
final long consumptionUC = batteryStats.getWifiMeasuredBatteryConsumptionUC();
@@ -117,13 +107,6 @@ public class WifiPowerCalculator extends PowerCalculator {
BatteryStats.STATS_SINCE_CHARGED, batteryStats.hasWifiActivityReporting(),
totalAppDurationMs, totalAppPowerMah, consumptionUC);
- systemBatteryConsumerBuilder
- .setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI,
- powerDurationAndTraffic.durationMs)
- .setConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI,
- totalAppPowerMah + powerDurationAndTraffic.powerMah, powerModel)
- .setPowerConsumedByApps(totalAppPowerMah);
-
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
.setUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI,
diff --git a/core/java/com/android/internal/widget/RecyclerView.java b/core/java/com/android/internal/widget/RecyclerView.java
index 9ed5eb1d144e..be15a9bba107 100644
--- a/core/java/com/android/internal/widget/RecyclerView.java
+++ b/core/java/com/android/internal/widget/RecyclerView.java
@@ -16,16 +16,10 @@
package com.android.internal.widget;
-import static android.widget.EdgeEffect.TYPE_GLOW;
-import static android.widget.EdgeEffect.TYPE_STRETCH;
-import static android.widget.EdgeEffect.USE_STRETCH_EDGE_EFFECT_BY_DEFAULT;
-import static android.widget.EdgeEffect.USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED;
-
import android.annotation.CallSuper;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.compat.Compatibility;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.TypedArray;
@@ -466,8 +460,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
private final int[] mScrollConsumed = new int[2];
private final int[] mNestedOffsets = new int[2];
- private int mEdgeEffectType;
-
/**
* These are views that had their a11y importance changed during a layout. We defer these events
* until the end of the layout because a11y service may make sync calls back to the RV while
@@ -595,12 +587,8 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
}
- boolean defaultToStretch = Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_BY_DEFAULT)
- || Compatibility.isChangeEnabled(USE_STRETCH_EDGE_EFFECT_FOR_SUPPORTED);
TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.EdgeEffect);
- mEdgeEffectType = a.getInt(com.android.internal.R.styleable.EdgeEffect_edgeEffectType,
- defaultToStretch ? TYPE_STRETCH : TYPE_GLOW);
a.recycle();
// Re-set whether nested scrolling is enabled so that it is set on all API levels
@@ -626,28 +614,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
}
/**
- * Returns the {@link EdgeEffect#getType()} used for all EdgeEffects.
- *
- * @return @link EdgeEffect#getType()} used for all EdgeEffects.
- */
- @EdgeEffect.EdgeEffectType
- public int getEdgeEffectType() {
- return mEdgeEffectType;
- }
-
- /**
- * Sets the {@link EdgeEffect#getType()} used in all EdgeEffects.
- * Any existing over-scroll effects are cleared and new effects are created as needed.
- *
- * @param type the {@link EdgeEffect#getType()} used in all EdgeEffects.
- */
- public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) {
- mEdgeEffectType = type;
- invalidateGlows();
- invalidate();
- }
-
- /**
* Instantiate and set a LayoutManager, if specified in the attributes.
*/
private void createLayoutManager(Context context, String className, AttributeSet attrs,
@@ -2223,7 +2189,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
return;
}
mLeftGlow = new EdgeEffect(getContext());
- mLeftGlow.setType(mEdgeEffectType);
if (mClipToPadding) {
mLeftGlow.setSize(getMeasuredHeight() - getPaddingTop() - getPaddingBottom(),
getMeasuredWidth() - getPaddingLeft() - getPaddingRight());
@@ -2237,7 +2202,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
return;
}
mRightGlow = new EdgeEffect(getContext());
- mRightGlow.setType(mEdgeEffectType);
if (mClipToPadding) {
mRightGlow.setSize(getMeasuredHeight() - getPaddingTop() - getPaddingBottom(),
getMeasuredWidth() - getPaddingLeft() - getPaddingRight());
@@ -2251,7 +2215,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
return;
}
mTopGlow = new EdgeEffect(getContext());
- mTopGlow.setType(mEdgeEffectType);
if (mClipToPadding) {
mTopGlow.setSize(getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
getMeasuredHeight() - getPaddingTop() - getPaddingBottom());
@@ -2266,7 +2229,6 @@ public class RecyclerView extends ViewGroup implements ScrollingView, NestedScro
return;
}
mBottomGlow = new EdgeEffect(getContext());
- mBottomGlow.setType(mEdgeEffectType);
if (mClipToPadding) {
mBottomGlow.setSize(getMeasuredWidth() - getPaddingLeft() - getPaddingRight(),
getMeasuredHeight() - getPaddingTop() - getPaddingBottom());
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 93cde3ddb72d..1174db5b2cf7 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -387,28 +387,6 @@ public class ViewPager extends ViewGroup {
}
/**
- * Returns the {@link EdgeEffect#getType()} for the edge effects.
- * @return the {@link EdgeEffect#getType()} for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- @EdgeEffect.EdgeEffectType
- public int getEdgeEffectType() {
- // Both left and right edge have the same edge effect type
- return mLeftEdge.getType();
- }
-
- /**
- * Sets the {@link EdgeEffect#setType(int)} for the edge effects.
- * @param type The edge effect type to use for the edge effects.
- * @attr ref android.R.styleable#EdgeEffect_edgeEffectType
- */
- public void setEdgeEffectType(@EdgeEffect.EdgeEffectType int type) {
- mLeftEdge.setType(type);
- mRightEdge.setType(type);
- invalidate();
- }
-
- /**
* Set a PagerAdapter that will supply views for this pager as needed.
*
* @param adapter Adapter to use
diff --git a/core/jni/android_media_AudioAttributes.cpp b/core/jni/android_media_AudioAttributes.cpp
index b616ffc111a3..f1ae268f4c16 100644
--- a/core/jni/android_media_AudioAttributes.cpp
+++ b/core/jni/android_media_AudioAttributes.cpp
@@ -171,10 +171,6 @@ jint JNIAudioAttributeHelper::getJavaArray(
/*
* JNI registration.
*/
-static const JNINativeMethod gMethods[] = {
- // n/a
-};
-
int register_android_media_AudioAttributes(JNIEnv *env)
{
jclass audioAttributesClass = FindClassOrDie(env, kClassPathName);
@@ -218,5 +214,5 @@ int register_android_media_AudioAttributes(JNIEnv *env)
env->DeleteLocalRef(audioAttributesClass);
- return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
+ return 0;
}
diff --git a/core/jni/android_os_VintfObject.cpp b/core/jni/android_os_VintfObject.cpp
index 4bd33a9cbd3b..1baea2aecc3c 100644
--- a/core/jni/android_os_VintfObject.cpp
+++ b/core/jni/android_os_VintfObject.cpp
@@ -37,11 +37,13 @@ static jmethodID gLongValueOf;
namespace android {
+using vintf::CompatibilityMatrix;
using vintf::HalManifest;
using vintf::Level;
using vintf::SchemaType;
using vintf::to_string;
using vintf::toXml;
+using vintf::Version;
using vintf::VintfObject;
using vintf::Vndk;
@@ -119,6 +121,28 @@ static jstring android_os_VintfObject_getSepolicyVersion(JNIEnv* env, jclass) {
return env->NewStringUTF(cString.c_str());
}
+static jstring android_os_VintfObject_getPlatformSepolicyVersion(JNIEnv* env, jclass) {
+ std::shared_ptr<const CompatibilityMatrix> matrix =
+ VintfObject::GetFrameworkCompatibilityMatrix();
+ if (matrix == nullptr || matrix->type() != SchemaType::FRAMEWORK) {
+ jniThrowRuntimeException(env, "Cannot get framework compatibility matrix");
+ return nullptr;
+ }
+
+ auto versions = matrix->getSepolicyVersions();
+ if (versions.empty()) {
+ jniThrowRuntimeException(env,
+ "sepolicy_version in framework compatibility matrix is empty");
+ return nullptr;
+ }
+
+ Version latest;
+ for (const auto& range : versions) {
+ latest = std::max(latest, range.maxVer());
+ }
+ return env->NewStringUTF(to_string(latest).c_str());
+}
+
static jobject android_os_VintfObject_getVndkSnapshots(JNIEnv* env, jclass) {
std::shared_ptr<const HalManifest> manifest = VintfObject::GetFrameworkHalManifest();
if (manifest == nullptr || manifest->type() != SchemaType::FRAMEWORK) {
@@ -145,12 +169,17 @@ static jobject android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersi
// ----------------------------------------------------------------------------
static const JNINativeMethod gVintfObjectMethods[] = {
- {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
- {"verifyWithoutAvb", "()I", (void*)android_os_VintfObject_verifyWithoutAvb},
- {"getHalNamesAndVersions", "()[Ljava/lang/String;", (void*)android_os_VintfObject_getHalNamesAndVersions},
- {"getSepolicyVersion", "()Ljava/lang/String;", (void*)android_os_VintfObject_getSepolicyVersion},
- {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots},
- {"getTargetFrameworkCompatibilityMatrixVersion", "()Ljava/lang/Long;", (void*)android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion},
+ {"report", "()[Ljava/lang/String;", (void*)android_os_VintfObject_report},
+ {"verifyWithoutAvb", "()I", (void*)android_os_VintfObject_verifyWithoutAvb},
+ {"getHalNamesAndVersions", "()[Ljava/lang/String;",
+ (void*)android_os_VintfObject_getHalNamesAndVersions},
+ {"getSepolicyVersion", "()Ljava/lang/String;",
+ (void*)android_os_VintfObject_getSepolicyVersion},
+ {"getPlatformSepolicyVersion", "()Ljava/lang/String;",
+ (void*)android_os_VintfObject_getPlatformSepolicyVersion},
+ {"getVndkSnapshots", "()Ljava/util/Map;", (void*)android_os_VintfObject_getVndkSnapshots},
+ {"getTargetFrameworkCompatibilityMatrixVersion", "()Ljava/lang/Long;",
+ (void*)android_os_VintfObject_getTargetFrameworkCompatibilityMatrixVersion},
};
const char* const kVintfObjectPathName = "android/os/VintfObject";
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 4dc4bef10475..4b828ba4cb02 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3947,11 +3947,11 @@
<!-- This permission is required among systems services when accessing
tuner resource management related APIs or information.
- <p>Protection level: signature|privileged
- <p>Not for use by third-party applications.
+ <p>Protection level: signature|privileged|vendorPrivileged
+ <p>This should only be used by the OEM TvInputService.
@hide -->
<permission android:name="android.permission.TUNER_RESOURCE_ACCESS"
- android:protectionLevel="signature|privileged" />
+ android:protectionLevel="signature|privileged|vendorPrivileged" />
<!-- This permission is required by Media Resource Manager Service when
accessing its overridePid Api.
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 182fddce11b0..ff07d9b7ad7b 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"এপ্লিকেশ্বনৰ ব্ৰেণ্ডৰ প্ৰতিচ্ছবি"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"এক্সেছৰ ছেটিং পৰীক্ষা কৰক"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g>এ আপোনাৰ স্ক্ৰীনখন চাব আৰু পৰিচালনা কৰিব পাৰে। পৰ্যালোচনা কৰিবলৈ টিপক।"</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> অনুবাদ কৰা হ’ল।"</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"বাৰ্তাটো <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ৰ পৰা <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>লৈ অনুবাদ কৰা হ’ল।"</string>
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index a265821e5b09..a065f19e0b44 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"অ্যাপের ব্র্যান্ড ছবি"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"অ্যাক্সেস করার সেটিংস চেক করুন"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> আপনার স্ক্রিন দেখতে ও কন্ট্রোল করতে পারবে। পর্যালোচনা করতে ট্যাপ করুন।"</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> অনুবাদ করা হয়েছে।"</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"মেসেজ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> থেকে <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ভাষাতে অনুবাদ করা হয়েছে।"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 6a33a0a52f53..d277a80fe440 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"App-Branding-Hintergrundbild"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"Zugriffseinstellungen prüfen"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> kann deinen Bildschirm sehen und steuern. Zum Prüfen tippen."</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"„<xliff:g id="MESSAGE">%1$s</xliff:g>“ wurde übersetzt."</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"Nachricht wurde von <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> auf <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> übersetzt."</string>
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 17cff18dcd23..b7ecc0eb4676 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ઍપ્લિકેશનની બ્રાંડિંગ છબી"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"ઍક્સેસના સેટિંગ ચેક કરો"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> તમારી સ્ક્રીન જોઈ અને નિયંત્રિત કરી શકે છે. રિવ્યૂ કરવા માટે ટૅપ કરો."</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g>નો અનુવાદ કર્યો."</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>થી <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>માં સંદેશનો અનુવાદ કરવામાં આવ્યો."</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index aecd79bd6527..dd96815dc551 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -2355,8 +2355,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"תדמית המותג של האפליקציה"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"בדיקה של הגדרות הגישה"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"לשירות <xliff:g id="SERVICE_NAME">%s</xliff:g> יש הרשאה להצגת המסך ושליטה בו. אפשר להקיש כדי לבדוק."</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"ההודעה <xliff:g id="MESSAGE">%1$s</xliff:g> תורגמה."</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ההודעה תורגמה מ<xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ל<xliff:g id="TO_LANGUAGE">%2$s</xliff:g>."</string>
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 3a2a2b569f27..330147d6a131 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -2285,7 +2285,7 @@
<string name="sensor_privacy_notification_channel_label" msgid="936036783155261349">"सेन्सरसम्बन्धी गोपनीयता"</string>
<string name="splash_screen_view_icon_description" msgid="180638751260598187">"एप जनाउने आइकन"</string>
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"एपको ब्रान्डिङ फोटो"</string>
- <string name="view_and_control_notification_title" msgid="4300765399209912240">"हेराइ र नियन्त्रणसम्बन्धी सेटिङ जाँच्नुहोस्"</string>
+ <string name="view_and_control_notification_title" msgid="4300765399209912240">"भ्यु र नियन्त्रणसम्बन्धी सेटिङ जाँच्नुहोस्"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> तपाईंको स्क्रिन हेर्न र नियन्त्रण गर्न सक्छ। सेटिङ मिलाउन ट्याप गर्नुहोस्।"</string>
<!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
<skip />
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 5aa16e7e22de..cdd9f52aa322 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ଆପ୍ଲିକେସନ୍ ବ୍ରାଣ୍ଡିଂ ଛବି"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"ଆକ୍ସେସ୍ ସେଟିଂସକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ଆପଣଙ୍କ ସ୍କ୍ରିନକୁ ଦେଖିପାରିବ ଏବଂ ନିୟନ୍ତ୍ରଣ କରିପାରିବ। ସମୀକ୍ଷା କରିବାକୁ ଟାପ୍ କରନ୍ତୁ।"</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ଅନୁବାଦ କରାଯାଇଛି।"</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ମେସେଜ୍, <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g>ରୁ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>କୁ ଅନୁବାଦ କରାଯାଇଛି।"</string>
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index 6cc4f1998183..afd9c0c12496 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ਐਪਲੀਕੇਸ਼ਨ ਦਾ ਬ੍ਰਾਂਡ ਵਾਲਾ ਚਿੱਤਰ"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"ਪਹੁੰਚ ਸੈਟਿੰਗਾਂ ਦੀ ਜਾਂਚ ਕਰੋ"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> ਸੇਵਾ ਤੁਹਾਡੀ ਸਕ੍ਰੀਨ ਨੂੰ ਦੇਖ ਅਤੇ ਕੰਟਰੋਲ ਕਰ ਸਕਦੀ ਹੈ। ਸਮੀਖਿਆ ਲਈ ਟੈਪ ਕਰੋ।"</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> ਦਾ ਅਨੁਵਾਦ ਕੀਤਾ ਗਿਆ।"</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"ਸੁਨੇਹੇ ਦਾ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> ਤੋਂ <xliff:g id="TO_LANGUAGE">%2$s</xliff:g> ਵਿੱਚ ਅਨੁਵਾਦ ਕੀਤਾ ਗਿਆ।"</string>
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 49ea3638a160..e1998ddf0dfe 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"యాప్ బ్రాండింగ్ ఇమేజ్"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"యాక్సెస్ సెట్టింగ్‌లను చెక్ చేయండి"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"<xliff:g id="SERVICE_NAME">%s</xliff:g> మీ స్క్రీన్‌ను చూడవచ్చు, కంట్రోల్ చేయవచ్చు. రివ్యూ చేయడానికి ట్యాప్ చేయండి."</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> అనువదించబడింది."</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"మెసేజ్ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> నుండి <xliff:g id="TO_LANGUAGE">%2$s</xliff:g>‌కు అనువదించబడింది."</string>
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index 48208ac677cc..6d99dfb4563c 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -2287,8 +2287,6 @@
<string name="splash_screen_view_branding_description" msgid="7911129347402728216">"ایپلیکیشن کی برانڈنگ تصویر"</string>
<string name="view_and_control_notification_title" msgid="4300765399209912240">"رسائی کی ترتیبات چیک کریں"</string>
<string name="view_and_control_notification_content" msgid="8003766498562604034">"‫<xliff:g id="SERVICE_NAME">%s</xliff:g> آپ کی اسکرین کو دیکھ اور کنٹرول کر سکتی ہیں۔ جائزے کے لیے تھپتھپائیں۔"</string>
- <!-- no translation found for ui_translation_accessibility_translated_text (3197547218178944544) -->
- <skip />
- <!-- no translation found for ui_translation_accessibility_translation_finished (3057830947610088465) -->
- <skip />
+ <string name="ui_translation_accessibility_translated_text" msgid="3197547218178944544">"<xliff:g id="MESSAGE">%1$s</xliff:g> کا ترجمہ کیا گیا۔"</string>
+ <string name="ui_translation_accessibility_translation_finished" msgid="3057830947610088465">"پیغام کا ترجمہ <xliff:g id="FROM_LANGUAGE">%1$s</xliff:g> سے<xliff:g id="TO_LANGUAGE">%2$s</xliff:g> میں کیا گیا۔"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 480b47835100..f0c43ff18d36 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1179,15 +1179,6 @@
<!-- Color applied to effects. -->
<attr name="effectColor" format="color" />
- <!-- The type of the edge effect. The default is glow. -->
- <attr name="edgeEffectType">
- <!-- Use a colored glow at the edge. -->
- <enum name="glow" value="0" />
-
- <!-- Stretch the content. -->
- <enum name="stretch" value="1" />
- </attr>
-
<!-- =================== -->
<!-- Lighting properties -->
<!-- =================== -->
@@ -9257,7 +9248,6 @@
<!-- Used as a filter array on the theme to pull out only the EdgeEffect-relevant bits. -->
<declare-styleable name="EdgeEffect">
<attr name="colorEdgeEffect" />
- <attr name="edgeEffectType" />
</declare-styleable>
<!-- Use <code>tv-input</code> as the root tag of the XML resource that describes a
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 0e9526ab4e6c..482b112c0444 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -3064,7 +3064,6 @@
<public name="hotwordDetectionService" />
<public name="previewLayout" />
<public name="clipToOutline" />
- <public name="edgeEffectType" />
<public name="knownCerts" />
<public name="windowBackgroundBlurRadius"/>
<public name="windowSplashScreenBackground"/>
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
index da6dc76a68d2..24b164bcb8c0 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerData.java
@@ -19,7 +19,6 @@ package com.android.frameworks.core.batterystatsviewer;
import android.content.Context;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.util.DebugUtils;
@@ -133,11 +132,6 @@ public class BatteryConsumerData {
}
}
- for (BatteryConsumer consumer : batteryUsageStats.getSystemBatteryConsumers()) {
- if (batteryConsumerId(consumer).equals(batteryConsumerId)) {
- return consumer;
- }
- }
return null;
}
@@ -157,11 +151,25 @@ public class BatteryConsumerData {
private void computeTotalPower(BatteryUsageStats batteryUsageStats,
double[] powerByComponentMah) {
- for (BatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
- for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT;
- component++) {
- powerByComponentMah[component] += consumer.getConsumedPower(component);
- }
+ final BatteryConsumer consumer =
+ batteryUsageStats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+ for (int component = 0; component < BatteryConsumer.POWER_COMPONENT_COUNT; component++) {
+ powerByComponentMah[component] += consumer.getConsumedPower(component);
+ }
+ }
+
+ private void computeTotalPowerForCustomComponent(
+ BatteryUsageStats batteryUsageStats, double[] powerByComponentMah) {
+ final BatteryConsumer consumer =
+ batteryUsageStats.getAggregateBatteryConsumer(
+ BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE);
+ final int customComponentCount = consumer.getCustomPowerComponentCount();
+ for (int component = 0;
+ component < Math.min(customComponentCount, powerByComponentMah.length);
+ component++) {
+ powerByComponentMah[component] += consumer.getConsumedPowerForCustomComponent(
+ BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
}
}
@@ -175,19 +183,6 @@ public class BatteryConsumerData {
}
}
- private void computeTotalPowerForCustomComponent(
- BatteryUsageStats batteryUsageStats, double[] powerByComponentMah) {
- for (BatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
- final int customComponentCount = consumer.getCustomPowerComponentCount();
- for (int component = 0;
- component < Math.min(customComponentCount, powerByComponentMah.length);
- component++) {
- powerByComponentMah[component] += consumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + component);
- }
- }
- }
-
private void addEntry(String title, EntryType entryType, double amount, double totalAmount,
boolean isSystemBatteryConsumer) {
Entry entry = new Entry();
@@ -212,8 +207,6 @@ public class BatteryConsumerData {
return "APP|"
+ UserHandle.getUserId(((UidBatteryConsumer) consumer).getUid()) + "|"
+ ((UidBatteryConsumer) consumer).getUid();
- } else if (consumer instanceof SystemBatteryConsumer) {
- return ((SystemBatteryConsumer) consumer).getDrainType() + "|0|0";
} else {
return "";
}
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
index c37b48bb5e6a..f2d6bca28136 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerInfoHelper.java
@@ -23,7 +23,6 @@ import android.content.pm.PackageManager;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.os.Process;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.util.DebugUtils;
@@ -113,20 +112,6 @@ class BatteryConsumerInfoHelper {
// Won't happen
}
}
- } else if (batteryConsumer instanceof SystemBatteryConsumer) {
- final SystemBatteryConsumer systemBatteryConsumer =
- (SystemBatteryConsumer) batteryConsumer;
- final int drainType = systemBatteryConsumer.getDrainType();
- String name = DebugUtils.constantToString(SystemBatteryConsumer.class, "DRAIN_TYPE_",
- drainType);
- info.label = name.charAt(0) + name.substring(1).toLowerCase().replace('_', ' ');
- info.isSystemBatteryConsumer = true;
- try {
- info.iconInfo =
- packageManager.getApplicationInfo(SYSTEM_SERVER_PACKAGE_NAME, 0);
- } catch (PackageManager.NameNotFoundException nameNotFoundException) {
- // Won't happen
- }
} else {
for (int scope = 0;
scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
index 63a15d6c63b4..9e63a350df41 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerActivity.java
@@ -18,68 +18,60 @@ package com.android.frameworks.core.batterystatsviewer;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.os.BatteryStatsManager;
+import android.os.BatteryUsageStats;
import android.os.Bundle;
+import android.os.UidBatteryConsumer;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ImageView;
+import android.widget.TextView;
+import androidx.activity.ComponentActivity;
import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentActivity;
-import androidx.fragment.app.FragmentStatePagerAdapter;
-import androidx.viewpager.widget.ViewPager;
+import androidx.loader.app.LoaderManager;
+import androidx.loader.content.Loader;
+import androidx.recyclerview.widget.LinearLayoutManager;
+import androidx.recyclerview.widget.RecyclerView;
-import com.google.android.material.tabs.TabLayout;
+import com.android.settingslib.utils.AsyncLoaderCompat;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Locale;
/**
* Picker, showing a sorted lists of applications and other types of entities consuming power.
* Opens BatteryStatsViewerActivity upon item selection.
*/
-public class BatteryConsumerPickerActivity extends FragmentActivity {
+public class BatteryConsumerPickerActivity extends ComponentActivity {
private static final String PREF_SELECTED_BATTERY_CONSUMER = "batteryConsumerId";
+ private static final int BATTERY_STATS_REFRESH_RATE_MILLIS = 60 * 1000;
+ private BatteryConsumerListAdapter mBatteryConsumerListAdapter;
+ private RecyclerView mAppList;
+ private View mLoadingView;
+ private final Runnable mBatteryStatsRefresh = this::loadBatteryStats;
+
+ private interface OnBatteryConsumerSelectedListener {
+ void onBatteryConsumerSelected(String batteryConsumerId);
+ }
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
- setContentView(R.layout.battery_consumer_picker_activity_layout);
-
- ViewPager viewPager = findViewById(R.id.pager);
-
- FragmentStatePagerAdapter adapter = new FragmentStatePagerAdapter(
- getSupportFragmentManager()) {
-
- @Override
- public int getCount() {
- return 2;
- }
-
- @NonNull
- @Override
- public Fragment getItem(int position) {
- switch (position) {
- case 0:
- return new BatteryConsumerPickerFragment(
- BatteryConsumerPickerFragment.PICKER_TYPE_APP);
- case 1:
- default:
- return new BatteryConsumerPickerFragment(
- BatteryConsumerPickerFragment.PICKER_TYPE_DRAIN);
- }
- }
+ setContentView(R.layout.battery_consumer_picker_layout);
+ mLoadingView = findViewById(R.id.loading_view);
- @Override
- public CharSequence getPageTitle(int position) {
- switch (position) {
- case 0:
- return "Apps";
- case 1:
- return "Drains";
- }
- return null;
- }
- };
+ mAppList = findViewById(R.id.list_view);
+ mAppList.setLayoutManager(new LinearLayoutManager(this));
+ mBatteryConsumerListAdapter =
+ new BatteryConsumerListAdapter((this::setSelectedBatteryConsumer));
+ mAppList.setAdapter(mBatteryConsumerListAdapter);
- viewPager.setAdapter(adapter);
- TabLayout tabLayout = findViewById(R.id.tab_layout);
- tabLayout.setupWithViewPager(viewPager);
if (icicle == null) {
final String batteryConsumerId = getPreferences(Context.MODE_PRIVATE)
.getString(PREF_SELECTED_BATTERY_CONSUMER, null);
@@ -101,4 +93,183 @@ public class BatteryConsumerPickerActivity extends FragmentActivity {
.putExtra(BatteryStatsViewerActivity.EXTRA_BATTERY_CONSUMER, batteryConsumerId);
startActivity(intent);
}
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ loadBatteryStats();
+ }
+
+ @Override
+ protected void onPause() {
+ super.onPause();
+ getMainThreadHandler().removeCallbacks(mBatteryStatsRefresh);
+ }
+
+ private void loadBatteryStats() {
+ LoaderManager.getInstance(this).restartLoader(0, null,
+ new BatteryConsumerListLoaderCallbacks());
+ getMainThreadHandler().postDelayed(mBatteryStatsRefresh, BATTERY_STATS_REFRESH_RATE_MILLIS);
+ }
+
+ private static class BatteryConsumerListLoader extends
+ AsyncLoaderCompat<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> {
+ private final BatteryStatsManager mBatteryStatsManager;
+ private final PackageManager mPackageManager;
+
+ BatteryConsumerListLoader(Context context) {
+ super(context);
+ mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
+ mPackageManager = context.getPackageManager();
+ }
+
+ @Override
+ public List<BatteryConsumerInfoHelper.BatteryConsumerInfo> loadInBackground() {
+ final BatteryUsageStats batteryUsageStats = mBatteryStatsManager.getBatteryUsageStats();
+ List<BatteryConsumerInfoHelper.BatteryConsumerInfo> batteryConsumerList =
+ new ArrayList<>();
+
+ for (int scope = 0;
+ scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
+ scope++) {
+ batteryConsumerList.add(
+ BatteryConsumerInfoHelper.makeBatteryConsumerInfo(
+ batteryUsageStats.getAggregateBatteryConsumer(scope),
+ BatteryConsumerData.batteryConsumerId(scope),
+ mPackageManager));
+ }
+
+ for (UidBatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
+ batteryConsumerList.add(
+ BatteryConsumerInfoHelper.makeBatteryConsumerInfo(consumer,
+ BatteryConsumerData.batteryConsumerId(consumer),
+ mPackageManager));
+ }
+
+ batteryConsumerList.sort(
+ Comparator.comparing(
+ (BatteryConsumerInfoHelper.BatteryConsumerInfo a) -> a.powerMah)
+ .reversed());
+
+ return batteryConsumerList;
+ }
+
+ @Override
+ protected void onDiscardResult(List<BatteryConsumerInfoHelper.BatteryConsumerInfo> result) {
+ }
+ }
+
+ private class BatteryConsumerListLoaderCallbacks implements
+ LoaderManager.LoaderCallbacks<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> {
+
+ @NonNull
+ @Override
+ public Loader<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> onCreateLoader(int id,
+ Bundle args) {
+ return new BatteryConsumerListLoader(BatteryConsumerPickerActivity.this);
+ }
+
+ @Override
+ public void onLoadFinished(
+ @NonNull Loader<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> loader,
+ List<BatteryConsumerInfoHelper.BatteryConsumerInfo> batteryConsumerList) {
+ mBatteryConsumerListAdapter.setBatteryConsumerList(batteryConsumerList);
+ mAppList.setVisibility(View.VISIBLE);
+ mLoadingView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void onLoaderReset(
+ @NonNull Loader<List<BatteryConsumerInfoHelper.BatteryConsumerInfo>> loader) {
+ }
+ }
+
+ public class BatteryConsumerListAdapter
+ extends RecyclerView.Adapter<BatteryConsumerViewHolder> {
+ private final OnBatteryConsumerSelectedListener mListener;
+ private List<BatteryConsumerInfoHelper.BatteryConsumerInfo> mBatteryConsumerList;
+
+ public BatteryConsumerListAdapter(OnBatteryConsumerSelectedListener listener) {
+ mListener = listener;
+ }
+
+ void setBatteryConsumerList(
+ List<BatteryConsumerInfoHelper.BatteryConsumerInfo> batteryConsumerList) {
+ mBatteryConsumerList = batteryConsumerList;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getItemCount() {
+ return mBatteryConsumerList.size();
+ }
+
+ @NonNull
+ @Override
+ public BatteryConsumerViewHolder onCreateViewHolder(
+ @NonNull ViewGroup viewGroup,
+ int position) {
+ LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
+ View view = layoutInflater.inflate(R.layout.battery_consumer_info_layout, viewGroup,
+ false);
+ return new BatteryConsumerViewHolder(view, mListener);
+ }
+
+ @Override
+ public void onBindViewHolder(@NonNull BatteryConsumerViewHolder viewHolder, int position) {
+ BatteryConsumerInfoHelper.BatteryConsumerInfo item = mBatteryConsumerList.get(position);
+ viewHolder.id = item.id;
+ viewHolder.titleView.setText(item.label);
+ if (item.details != null) {
+ viewHolder.detailsView.setText(item.details);
+ viewHolder.detailsView.setVisibility(View.VISIBLE);
+ } else {
+ viewHolder.detailsView.setVisibility(View.GONE);
+ }
+ viewHolder.powerView.setText(
+ String.format(Locale.getDefault(), "%.1f mAh", item.powerMah));
+ if (item.iconInfo != null) {
+ viewHolder.iconView.setImageDrawable(
+ item.iconInfo.loadIcon(getPackageManager()));
+ } else {
+ viewHolder.iconView.setImageResource(R.drawable.gm_device_24);
+ }
+ if (item.packages != null) {
+ viewHolder.packagesView.setText(item.packages);
+ viewHolder.packagesView.setVisibility(View.VISIBLE);
+ } else {
+ viewHolder.packagesView.setVisibility(View.GONE);
+ }
+ }
+ }
+
+ // View Holder used when displaying apps
+ public static class BatteryConsumerViewHolder extends RecyclerView.ViewHolder
+ implements View.OnClickListener {
+ private final OnBatteryConsumerSelectedListener mListener;
+
+ public String id;
+ public TextView titleView;
+ public TextView detailsView;
+ public ImageView iconView;
+ public TextView packagesView;
+ public TextView powerView;
+
+ BatteryConsumerViewHolder(View view, OnBatteryConsumerSelectedListener listener) {
+ super(view);
+ mListener = listener;
+ view.setOnClickListener(this);
+ titleView = view.findViewById(android.R.id.title);
+ detailsView = view.findViewById(R.id.details);
+ iconView = view.findViewById(android.R.id.icon);
+ packagesView = view.findViewById(R.id.packages);
+ powerView = view.findViewById(R.id.power_mah);
+ powerView.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onClick(View v) {
+ mListener.onBatteryConsumerSelected(id);
+ }
+ }
}
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java
deleted file mode 100644
index daa6dae37f50..000000000000
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryConsumerPickerFragment.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Copyright (C) 2008 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.frameworks.core.batterystatsviewer;
-
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.os.BatteryStatsManager;
-import android.os.BatteryUsageStats;
-import android.os.Bundle;
-import android.os.SystemBatteryConsumer;
-import android.os.UidBatteryConsumer;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-import androidx.loader.app.LoaderManager;
-import androidx.loader.content.Loader;
-import androidx.recyclerview.widget.LinearLayoutManager;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.frameworks.core.batterystatsviewer.BatteryConsumerInfoHelper.BatteryConsumerInfo;
-import com.android.settingslib.utils.AsyncLoaderCompat;
-
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Locale;
-
-/**
- * Picker, showing a sorted lists of applications or other types of entities consuming power.
- * Returns the selected entity ID or null.
- */
-public class BatteryConsumerPickerFragment extends Fragment {
- private static final String TAG = "AppPicker";
-
- public static final String PICKER_TYPE = "pickertype";
-
- public static final int PICKER_TYPE_APP = 0;
- public static final int PICKER_TYPE_DRAIN = 1;
-
- private BatteryConsumerListAdapter mBatteryConsumerListAdapter;
- private RecyclerView mAppList;
- private View mLoadingView;
-
- private interface OnBatteryConsumerSelectedListener {
- void onBatteryConsumerSelected(String batteryConsumerId);
- }
-
- public BatteryConsumerPickerFragment(int pickerType) {
- Bundle args = new Bundle();
- args.putInt(PICKER_TYPE, pickerType);
- setArguments(args);
- }
-
- public BatteryConsumerPickerFragment() {
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.battery_consumer_picker_layout, container, false);
- mLoadingView = view.findViewById(R.id.loading_view);
-
- mAppList = view.findViewById(R.id.list_view);
- mAppList.setLayoutManager(new LinearLayoutManager(getContext()));
- mBatteryConsumerListAdapter = new BatteryConsumerListAdapter(
- BatteryConsumerPickerFragment.this::setSelectedBatteryConsumer);
- mAppList.setAdapter(mBatteryConsumerListAdapter);
-
- LoaderManager.getInstance(this).initLoader(0, getArguments(),
- new BatteryConsumerListLoaderCallbacks());
- return view;
- }
-
- public void setSelectedBatteryConsumer(String id) {
- ((BatteryConsumerPickerActivity) getActivity()).setSelectedBatteryConsumer(id);
- }
-
- private static class BatteryConsumerListLoader extends
- AsyncLoaderCompat<List<BatteryConsumerInfo>> {
- private final int mPickerType;
- private final BatteryStatsManager mBatteryStatsManager;
- private final PackageManager mPackageManager;
-
- BatteryConsumerListLoader(Context context, int pickerType) {
- super(context);
- mBatteryStatsManager = context.getSystemService(BatteryStatsManager.class);
- mPickerType = pickerType;
- mPackageManager = context.getPackageManager();
- }
-
- @Override
- public List<BatteryConsumerInfo> loadInBackground() {
- final BatteryUsageStats batteryUsageStats = mBatteryStatsManager.getBatteryUsageStats();
- List<BatteryConsumerInfo> batteryConsumerList = new ArrayList<>();
-
- for (int scope = 0;
- scope < BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_COUNT;
- scope++) {
- batteryConsumerList.add(
- BatteryConsumerInfoHelper.makeBatteryConsumerInfo(
- batteryUsageStats.getAggregateBatteryConsumer(scope),
- BatteryConsumerData.batteryConsumerId(scope),
- mPackageManager));
- }
-
- switch (mPickerType) {
- case PICKER_TYPE_APP:
- for (UidBatteryConsumer consumer : batteryUsageStats.getUidBatteryConsumers()) {
- batteryConsumerList.add(
- BatteryConsumerInfoHelper.makeBatteryConsumerInfo(consumer,
- BatteryConsumerData.batteryConsumerId(consumer),
- mPackageManager));
- }
- break;
- case PICKER_TYPE_DRAIN:
- default:
- for (SystemBatteryConsumer consumer :
- batteryUsageStats.getSystemBatteryConsumers()) {
- batteryConsumerList.add(
- BatteryConsumerInfoHelper.makeBatteryConsumerInfo(consumer,
- BatteryConsumerData.batteryConsumerId(consumer),
- mPackageManager));
- }
- break;
- }
-
- batteryConsumerList.sort(
- Comparator.comparing((BatteryConsumerInfo a) -> a.powerMah).reversed());
- return batteryConsumerList;
- }
-
- @Override
- protected void onDiscardResult(List<BatteryConsumerInfo> result) {
- }
- }
-
- private class BatteryConsumerListLoaderCallbacks implements
- LoaderManager.LoaderCallbacks<List<BatteryConsumerInfo>> {
-
- @NonNull
- @Override
- public Loader<List<BatteryConsumerInfo>> onCreateLoader(int id, Bundle args) {
- return new BatteryConsumerListLoader(getContext(), args.getInt(PICKER_TYPE));
- }
-
- @Override
- public void onLoadFinished(@NonNull Loader<List<BatteryConsumerInfo>> loader,
- List<BatteryConsumerInfo> batteryConsumerList) {
- mBatteryConsumerListAdapter.setBatteryConsumerList(batteryConsumerList);
- mAppList.setVisibility(View.VISIBLE);
- mLoadingView.setVisibility(View.GONE);
- }
-
- @Override
- public void onLoaderReset(
- @NonNull Loader<List<BatteryConsumerInfo>> loader) {
- }
- }
-
- public class BatteryConsumerListAdapter extends
- RecyclerView.Adapter<BatteryConsumerViewHolder> {
- private final OnBatteryConsumerSelectedListener mListener;
- private List<BatteryConsumerInfo> mBatteryConsumerList;
-
- public BatteryConsumerListAdapter(OnBatteryConsumerSelectedListener listener) {
- mListener = listener;
- }
-
- void setBatteryConsumerList(List<BatteryConsumerInfo> batteryConsumerList) {
- mBatteryConsumerList = batteryConsumerList;
- notifyDataSetChanged();
- }
-
- @Override
- public int getItemCount() {
- return mBatteryConsumerList.size();
- }
-
- @NonNull
- @Override
- public BatteryConsumerViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup,
- int position) {
- LayoutInflater layoutInflater = LayoutInflater.from(viewGroup.getContext());
- View view = layoutInflater.inflate(R.layout.battery_consumer_info_layout, viewGroup,
- false);
- return new BatteryConsumerViewHolder(view, mListener);
- }
-
- @Override
- public void onBindViewHolder(@NonNull BatteryConsumerViewHolder viewHolder, int position) {
- BatteryConsumerInfo item = mBatteryConsumerList.get(position);
- viewHolder.id = item.id;
- viewHolder.titleView.setText(item.label);
- if (item.details != null) {
- viewHolder.detailsView.setText(item.details);
- viewHolder.detailsView.setVisibility(View.VISIBLE);
- } else {
- viewHolder.detailsView.setVisibility(View.GONE);
- }
- viewHolder.powerView.setText(
- String.format(Locale.getDefault(), "%.1f mAh", item.powerMah));
- if (item.iconInfo != null) {
- viewHolder.iconView.setImageDrawable(
- item.iconInfo.loadIcon(getContext().getPackageManager()));
- } else {
- viewHolder.iconView.setImageResource(R.drawable.gm_device_24);
- }
- if (item.packages != null) {
- viewHolder.packagesView.setText(item.packages);
- viewHolder.packagesView.setVisibility(View.VISIBLE);
- } else {
- viewHolder.packagesView.setVisibility(View.GONE);
- }
- }
- }
-
- // View Holder used when displaying apps
- public static class BatteryConsumerViewHolder extends RecyclerView.ViewHolder
- implements View.OnClickListener {
- private final OnBatteryConsumerSelectedListener mListener;
-
- public String id;
- public TextView titleView;
- public TextView detailsView;
- public ImageView iconView;
- public TextView packagesView;
- public TextView powerView;
-
- BatteryConsumerViewHolder(View view, OnBatteryConsumerSelectedListener listener) {
- super(view);
- mListener = listener;
- view.setOnClickListener(this);
- titleView = view.findViewById(android.R.id.title);
- detailsView = view.findViewById(R.id.details);
- iconView = view.findViewById(android.R.id.icon);
- packagesView = view.findViewById(R.id.packages);
- powerView = view.findViewById(R.id.power_mah);
- powerView.setVisibility(View.VISIBLE);
- }
-
- @Override
- public void onClick(View v) {
- mListener.onBatteryConsumerSelected(id);
- }
- }
-}
diff --git a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
index f84e97a14297..bb75be4f5ba8 100644
--- a/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
+++ b/core/tests/batterystatstests/BatteryStatsViewer/src/com/android/frameworks/core/batterystatsviewer/BatteryStatsViewerActivity.java
@@ -51,7 +51,7 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
private static final int LOADER_BATTERY_USAGE_STATS = 1;
private BatteryStatsDataAdapter mBatteryStatsDataAdapter;
- private final Runnable mBatteryStatsRefresh = this::periodicBatteryStatsRefresh;
+ private final Runnable mBatteryStatsRefresh = this::loadBatteryStats;
private String mBatteryConsumerId;
private TextView mTitleView;
private TextView mDetailsView;
@@ -85,13 +85,15 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
mLoadingView = findViewById(R.id.loading_view);
mEmptyView = findViewById(R.id.empty_view);
- loadBatteryStats();
+ LoaderManager loaderManager = LoaderManager.getInstance(this);
+ loaderManager.restartLoader(LOADER_BATTERY_USAGE_STATS, null,
+ new BatteryUsageStatsLoaderCallbacks());
}
@Override
protected void onResume() {
super.onResume();
- periodicBatteryStatsRefresh();
+ loadBatteryStats();
}
@Override
@@ -100,15 +102,11 @@ public class BatteryStatsViewerActivity extends ComponentActivity {
getMainThreadHandler().removeCallbacks(mBatteryStatsRefresh);
}
- private void periodicBatteryStatsRefresh() {
- loadBatteryStats();
- getMainThreadHandler().postDelayed(mBatteryStatsRefresh, BATTERY_STATS_REFRESH_RATE_MILLIS);
- }
-
private void loadBatteryStats() {
LoaderManager loaderManager = LoaderManager.getInstance(this);
loaderManager.restartLoader(LOADER_BATTERY_USAGE_STATS, null,
new BatteryUsageStatsLoaderCallbacks());
+ getMainThreadHandler().postDelayed(mBatteryStatsRefresh, BATTERY_STATS_REFRESH_RATE_MILLIS);
}
private static class BatteryUsageStatsLoader extends
diff --git a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
index 2e2e6bd07539..6f17ea994699 100644
--- a/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
+++ b/core/tests/coretests/src/android/app/activity/ActivityThreadTest.java
@@ -185,15 +185,6 @@ public class ActivityThreadTest {
}
@Test
- public void testHandleActivity_assetsChanged() {
- relaunchActivityAndAssertPreserveWindow(activity -> {
- // Relaunches all activities.
- activity.getActivityThread().handleApplicationInfoChanged(
- activity.getApplicationInfo());
- });
- }
-
- @Test
public void testRecreateActivity() {
relaunchActivityAndAssertPreserveWindow(Activity::recreate);
}
diff --git a/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java b/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java
index 3e2c4e98e21a..5cee2c1389e4 100644
--- a/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java
+++ b/core/tests/coretests/src/android/app/people/PeopleSpaceTileTest.java
@@ -16,6 +16,9 @@
package android.app.people;
+import static android.app.people.PeopleSpaceTile.SHOW_CONVERSATIONS;
+import static android.app.people.PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
+
import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.assertFalse;
@@ -178,6 +181,71 @@ public class PeopleSpaceTileTest {
}
@Test
+ public void testUserQuieted() {
+ PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
+ new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
+ assertFalse(tile.isUserQuieted());
+
+ tile = new PeopleSpaceTile
+ .Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
+ .setIsUserQuieted(true)
+ .build();
+ assertTrue(tile.isUserQuieted());
+ }
+
+ @Test
+ public void testCanBypassDnd() {
+ PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
+ new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
+ assertFalse(tile.canBypassDnd());
+
+ tile = new PeopleSpaceTile
+ .Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
+ .setCanBypassDnd(true)
+ .build();
+ assertTrue(tile.canBypassDnd());
+ }
+
+ @Test
+ public void testNotificationPolicyState() {
+ PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
+ new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
+
+ tile = new PeopleSpaceTile
+ .Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
+ .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
+ .build();
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_IMPORTANT_CONVERSATIONS);
+ }
+
+ @Test
+ public void testPackageSuspended() {
+ PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
+ new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
+ assertFalse(tile.isPackageSuspended());
+
+ tile = new PeopleSpaceTile
+ .Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
+ .setIsPackageSuspended(true)
+ .build();
+ assertTrue(tile.isPackageSuspended());
+ }
+
+ @Test
+ public void testContactAffinity() {
+ PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
+ new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
+ assertThat(tile.getContactAffinity()).isEqualTo(0f);
+
+ tile = new PeopleSpaceTile
+ .Builder(new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps)
+ .setContactAffinity(1f)
+ .build();
+ assertThat(tile.getContactAffinity()).isEqualTo(1f);
+ }
+
+ @Test
public void testStatuses() {
PeopleSpaceTile tile = new PeopleSpaceTile.Builder(
new ShortcutInfo.Builder(mContext, "123").build(), mLauncherApps).build();
@@ -238,6 +306,11 @@ public class PeopleSpaceTileTest {
.setNotificationDataUri(Uri.parse("data"))
.setMessagesCount(2)
.setIntent(new Intent())
+ .setIsUserQuieted(true)
+ .setCanBypassDnd(false)
+ .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
+ .setIsPackageSuspended(true)
+ .setContactAffinity(1f)
.build();
Parcel parcel = Parcel.obtain();
@@ -261,6 +334,12 @@ public class PeopleSpaceTileTest {
assertThat(readTile.getNotificationDataUri()).isEqualTo(tile.getNotificationDataUri());
assertThat(readTile.getMessagesCount()).isEqualTo(tile.getMessagesCount());
assertThat(readTile.getIntent().toString()).isEqualTo(tile.getIntent().toString());
+ assertThat(readTile.isUserQuieted()).isEqualTo(tile.isUserQuieted());
+ assertThat(readTile.canBypassDnd()).isEqualTo(tile.canBypassDnd());
+ assertThat(readTile.getNotificationPolicyState()).isEqualTo(
+ tile.getNotificationPolicyState());
+ assertThat(readTile.isPackageSuspended()).isEqualTo(tile.isPackageSuspended());
+ assertThat(readTile.getContactAffinity()).isEqualTo(tile.getContactAffinity());
}
@Test
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryChargeCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryChargeCalculatorTest.java
index cf126c62dac7..23fc35d6ffa5 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryChargeCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryChargeCalculatorTest.java
@@ -36,18 +36,12 @@ public class BatteryChargeCalculatorTest {
@Rule
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule()
- .setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 4000.0);
+ .setAveragePower(PowerProfile.POWER_BATTERY_CAPACITY, 1234.0); // Should be ignored
@Test
public void testDischargeTotals() {
- BatteryChargeCalculator calculator =
- new BatteryChargeCalculator(mStatsRule.getPowerProfile());
-
final BatteryStatsImpl batteryStats = mStatsRule.getBatteryStats();
- mStatsRule.setTime(1000, 1000);
- batteryStats.resetAllStatsCmdLocked();
- batteryStats.setNoAutoReset(true);
batteryStats.setBatteryStateLocked(BatteryManager.BATTERY_STATUS_DISCHARGING, 100,
/* plugType */ 0, 90, 72, 3700, 3_600_000, 4_000_000, 0,
1_000_000, 1_000_000, 1_000_000);
@@ -58,8 +52,11 @@ public class BatteryChargeCalculatorTest {
/* plugType */ 0, 80, 72, 3700, 2_400_000, 4_000_000, 0,
2_000_000, 2_000_000, 2_000_000);
+ BatteryChargeCalculator calculator = new BatteryChargeCalculator();
BatteryUsageStats batteryUsageStats = mStatsRule.apply(calculator);
+ assertThat(batteryUsageStats.getConsumedPower())
+ .isWithin(PRECISION).of(380.0);
assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(10);
assertThat(batteryUsageStats.getDischargedPowerRange().getLower())
.isWithin(PRECISION).of(360.0);
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
index 4533fcb39cfe..1a6408ff7eb3 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java
@@ -27,7 +27,6 @@ import android.os.BatteryConsumer;
import android.os.BatteryStats;
import android.os.BatteryUsageStats;
import android.os.BatteryUsageStatsQuery;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.UserBatteryConsumer;
import android.util.SparseArray;
@@ -206,16 +205,6 @@ public class BatteryUsageStatsRule implements TestRule {
return null;
}
- public SystemBatteryConsumer getSystemBatteryConsumer(
- @SystemBatteryConsumer.DrainType int drainType) {
- for (SystemBatteryConsumer sbc : mBatteryUsageStats.getSystemBatteryConsumers()) {
- if (sbc.getDrainType() == drainType) {
- return sbc;
- }
- }
- return null;
- }
-
public UserBatteryConsumer getUserBatteryConsumer(int userId) {
for (UserBatteryConsumer ubc : mBatteryUsageStats.getUserBatteryConsumers()) {
if (ubc.getUserId() == userId) {
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
index ad9906b918d7..127cea84ba8c 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsTest.java
@@ -23,7 +23,6 @@ import static org.junit.Assert.fail;
import android.os.BatteryConsumer;
import android.os.BatteryUsageStats;
import android.os.Parcel;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import androidx.test.filters.SmallTest;
@@ -71,7 +70,6 @@ public class BatteryUsageStatsTest {
.setDischargePercentage(20)
.setDischargedPowerRange(1000, 2000)
.setStatsStartTimestamp(1000);
-
builder.getOrCreateUidBatteryConsumerBuilder(batteryStatsUid)
.setPackageWithHighestDrain("foo")
.setTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND, 1000)
@@ -87,17 +85,6 @@ public class BatteryUsageStatsTest {
.setUsageDurationForCustomComponentMillis(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 800);
- builder.getOrCreateSystemBatteryConsumerBuilder(SystemBatteryConsumer.DRAIN_TYPE_CAMERA)
- .setConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU, 10100)
- .setConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10200)
- .setUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU, 10300)
- .setUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID, 10400)
- .setPowerConsumedByApps(20000);
-
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS)
.setConsumedPower(
@@ -111,6 +98,7 @@ public class BatteryUsageStatsTest {
builder.getAggregateBatteryConsumerBuilder(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_DEVICE)
+ .setConsumedPower(30000)
.setConsumedPower(
BatteryConsumer.POWER_COMPONENT_CPU, 20100)
.setConsumedPowerForCustomComponent(
@@ -124,10 +112,7 @@ public class BatteryUsageStatsTest {
}
public void validateBatteryUsageStats(BatteryUsageStats batteryUsageStats) {
- // Camera: (10100 + 10200) - 20000 (consumed by apps) = 300
- // App: 300 + 400 + 500 = 1200
- // Total: 1500
- assertThat(batteryUsageStats.getConsumedPower()).isEqualTo(1500);
+ assertThat(batteryUsageStats.getConsumedPower()).isEqualTo(30000);
assertThat(batteryUsageStats.getDischargePercentage()).isEqualTo(20);
assertThat(batteryUsageStats.getDischargedPowerRange().getLower()).isEqualTo(1000);
assertThat(batteryUsageStats.getDischargedPowerRange().getUpper()).isEqualTo(2000);
@@ -161,30 +146,6 @@ public class BatteryUsageStatsTest {
}
}
- final List<SystemBatteryConsumer> systemBatteryConsumers =
- batteryUsageStats.getSystemBatteryConsumers();
- for (SystemBatteryConsumer systemBatteryConsumer : systemBatteryConsumers) {
- if (systemBatteryConsumer.getDrainType() == SystemBatteryConsumer.DRAIN_TYPE_CAMERA) {
- assertThat(systemBatteryConsumer.getConsumedPower(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10100);
- assertThat(systemBatteryConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(10200);
- assertThat(systemBatteryConsumer.getUsageDurationMillis(
- BatteryConsumer.POWER_COMPONENT_CPU)).isEqualTo(10300);
- assertThat(systemBatteryConsumer.getUsageDurationForCustomComponentMillis(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo(10400);
- assertThat(systemBatteryConsumer.getConsumedPower()).isEqualTo(20300);
- assertThat(systemBatteryConsumer.getPowerConsumedByApps()).isEqualTo(20000);
- assertThat(systemBatteryConsumer.getUsageDurationMillis())
- .isEqualTo(10400); // max
- assertThat(systemBatteryConsumer.getCustomPowerComponentCount()).isEqualTo(1);
- assertThat(systemBatteryConsumer.getCustomPowerComponentName(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID)).isEqualTo("FOO");
- } else {
- fail("Unexpected drain type " + systemBatteryConsumer.getDrainType());
- }
- }
-
final BatteryConsumer appsBatteryConsumer = batteryUsageStats.getAggregateBatteryConsumer(
BatteryUsageStats.AGGREGATE_BATTERY_CONSUMER_SCOPE_ALL_APPS);
assertThat(appsBatteryConsumer.getConsumedPower(
diff --git a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
index a0de6d3c4573..2de621c8fa6f 100644
--- a/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BluetoothPowerCalculatorTest.java
@@ -64,7 +64,9 @@ public class BluetoothPowerCalculatorTest {
mStatsRule.apply(BatteryUsageStatsRule.POWER_PROFILE_MODEL_ONLY, calculator);
- assertThat(mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID)).isNull();
+ assertBluetoothPowerAndDuration(
+ mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID),
+ 0.11388, 6000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
assertBluetoothPowerAndDuration(
mStatsRule.getUidBatteryConsumer(APP_UID),
0.24722, 15000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
@@ -95,7 +97,9 @@ public class BluetoothPowerCalculatorTest {
mStatsRule.apply(BatteryUsageStatsRule.POWER_PROFILE_MODEL_ONLY, calculator);
- assertThat(mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID)).isNull();
+ assertBluetoothPowerAndDuration(
+ mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID),
+ 0.1, 6000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
assertBluetoothPowerAndDuration(
mStatsRule.getUidBatteryConsumer(APP_UID),
0.2, 15000, BatteryConsumer.POWER_MODEL_POWER_PROFILE);
@@ -123,7 +127,9 @@ public class BluetoothPowerCalculatorTest {
mStatsRule.apply(new BatteryUsageStatsQuery.Builder().includePowerModels().build(),
calculator);
- assertThat(mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID)).isNull();
+ assertBluetoothPowerAndDuration(
+ mStatsRule.getUidBatteryConsumer(Process.BLUETOOTH_UID),
+ 0.10378, 3583, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
assertBluetoothPowerAndDuration(
mStatsRule.getUidBatteryConsumer(APP_UID),
0.22950, 8416, BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
diff --git a/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java
index 3fb274323720..f8c2bc6c3d80 100644
--- a/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/CustomMeasuredPowerCalculatorTest.java
@@ -20,7 +20,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.os.BatteryConsumer;
import android.os.Process;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.util.SparseLongArray;
@@ -68,15 +67,6 @@ public class CustomMeasuredPowerCalculatorTest {
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1))
.isWithin(PRECISION).of(33.33333);
- SystemBatteryConsumer systemConsumer = mStatsRule.getSystemBatteryConsumer(
- SystemBatteryConsumer.DRAIN_TYPE_CUSTOM);
- assertThat(systemConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID))
- .isWithin(PRECISION).of(27.77777);
- assertThat(systemConsumer.getConsumedPowerForCustomComponent(
- BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID + 1))
- .isWithin(PRECISION).of(55.55555);
-
final BatteryConsumer deviceBatteryConsumer = mStatsRule.getDeviceBatteryConsumer();
assertThat(deviceBatteryConsumer.getConsumedPowerForCustomComponent(
BatteryConsumer.FIRST_CUSTOM_POWER_COMPONENT_ID))
diff --git a/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java
index 159d53a4cf5b..67b1e516d704 100644
--- a/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/IdlePowerCalculatorTest.java
@@ -19,7 +19,6 @@ package com.android.internal.os;
import static com.google.common.truth.Truth.assertThat;
import android.os.BatteryConsumer;
-import android.os.SystemBatteryConsumer;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -46,13 +45,6 @@ public class IdlePowerCalculatorTest {
mStatsRule.apply(calculator);
- SystemBatteryConsumer consumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_IDLE);
- assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE))
- .isEqualTo(3000);
- assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_IDLE))
- .isWithin(PRECISION).of(0.7);
-
BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_IDLE))
.isEqualTo(3000);
diff --git a/core/tests/coretests/src/com/android/internal/os/MemoryPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/MemoryPowerCalculatorTest.java
index 94e760a4e2e2..4868d6a87228 100644
--- a/core/tests/coretests/src/com/android/internal/os/MemoryPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/MemoryPowerCalculatorTest.java
@@ -19,7 +19,6 @@ package com.android.internal.os;
import static com.google.common.truth.Truth.assertThat;
import android.os.BatteryConsumer;
-import android.os.SystemBatteryConsumer;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -53,8 +52,7 @@ public class MemoryPowerCalculatorTest {
mStatsRule.apply(calculator);
- SystemBatteryConsumer consumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_MEMORY);
+ BatteryConsumer consumer = mStatsRule.getDeviceBatteryConsumer();
assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_MEMORY))
.isEqualTo(3000);
assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MEMORY))
diff --git a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
index 4f5417fe7955..48a1da15d574 100644
--- a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
@@ -27,7 +27,6 @@ import android.net.NetworkCapabilities;
import android.net.NetworkStats;
import android.os.BatteryConsumer;
import android.os.Process;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.ModemActivityInfo;
@@ -100,17 +99,6 @@ public class MobileRadioPowerCalculatorTest {
mStatsRule.apply(BatteryUsageStatsRule.POWER_PROFILE_MODEL_ONLY, calculator);
- SystemBatteryConsumer consumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO);
- assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
- .isWithin(PRECISION).of(2.2444);
- assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
- .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
- assertThat(consumer.getConsumedPower())
- .isWithin(PRECISION).of(2.2444);
- assertThat(consumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(0.8);
-
UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
.isWithin(PRECISION).of(0.8);
@@ -171,17 +159,6 @@ public class MobileRadioPowerCalculatorTest {
mStatsRule.apply(calculator);
- SystemBatteryConsumer consumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_MOBILE_RADIO);
-
- // 100000000 uAs * (1 mA / 1000 uA) * (1 h / 3600 s) + 1.53934 (apps)= 4.31711 mAh
- assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
- .isWithin(PRECISION).of(4.31711);
- assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
- .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
- assertThat(consumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(1.53934);
-
UidBatteryConsumer uidConsumer = mStatsRule.getUidBatteryConsumer(APP_UID);
assertThat(uidConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
.isWithin(PRECISION).of(1.53934);
diff --git a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java
index 144da38e4cb3..4c29c204618a 100644
--- a/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/ScreenPowerCalculatorTest.java
@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.ActivityManager;
import android.os.BatteryConsumer;
import android.os.Process;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.view.Display;
@@ -82,21 +81,6 @@ public class ScreenPowerCalculatorTest {
mStatsRule.apply(calculator);
- SystemBatteryConsumer consumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_SCREEN);
- assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
- .isEqualTo(80 * MINUTE_IN_MS);
-
- // 600000000 uAs * (1 mA / 1000 uA) * (1 h / 3600 s) = 166.66666 mAh
- assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
- .isWithin(PRECISION).of(166.66666);
- assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
- .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
- assertThat(consumer.getConsumedPower())
- .isWithin(PRECISION).of(166.66666);
- assertThat(consumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(166.66666);
-
UidBatteryConsumer uid1 = mStatsRule.getUidBatteryConsumer(APP_UID1);
assertThat(uid1.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
.isEqualTo(20 * MINUTE_IN_MS);
@@ -130,8 +114,6 @@ public class ScreenPowerCalculatorTest {
.isWithin(PRECISION).of(166.66666);
assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
.isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
- assertThat(deviceConsumer.getConsumedPower())
- .isWithin(PRECISION).of(166.66666);
BatteryConsumer appsConsumer = mStatsRule.getAppsBatteryConsumer();
assertThat(appsConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
@@ -141,8 +123,6 @@ public class ScreenPowerCalculatorTest {
.isWithin(PRECISION).of(166.66666);
assertThat(appsConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
.isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
- assertThat(appsConsumer.getConsumedPower())
- .isWithin(PRECISION).of(166.66666);
}
@Test
@@ -174,19 +154,6 @@ public class ScreenPowerCalculatorTest {
mStatsRule.apply(BatteryUsageStatsRule.POWER_PROFILE_MODEL_ONLY, calculator);
- SystemBatteryConsumer consumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_SCREEN);
- assertThat(consumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
- .isEqualTo(80 * MINUTE_IN_MS);
- assertThat(consumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_SCREEN))
- .isWithin(PRECISION).of(92.0);
- assertThat(consumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_SCREEN))
- .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
- assertThat(consumer.getConsumedPower())
- .isWithin(PRECISION).of(92.0);
- assertThat(consumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(92.0);
-
UidBatteryConsumer uid1 = mStatsRule.getUidBatteryConsumer(APP_UID1);
assertThat(uid1.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_SCREEN))
.isEqualTo(20 * MINUTE_IN_MS);
diff --git a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
index f8655c5b89d2..fc44ddc216b4 100644
--- a/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/WifiPowerCalculatorTest.java
@@ -25,7 +25,6 @@ import android.net.NetworkCapabilities;
import android.net.NetworkStats;
import android.os.BatteryConsumer;
import android.os.Process;
-import android.os.SystemBatteryConsumer;
import android.os.UidBatteryConsumer;
import android.os.WorkSource;
import android.os.connectivity.WifiActivityEnergyInfo;
@@ -94,17 +93,6 @@ public class WifiPowerCalculatorTest {
assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
.isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
- SystemBatteryConsumer systemConsumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_WIFI);
- assertThat(systemConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(5577);
- assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isWithin(PRECISION).of(1.11153);
- assertThat(systemConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
- assertThat(systemConsumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(0.466333);
-
BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
.isEqualTo(4002);
@@ -139,18 +127,6 @@ public class WifiPowerCalculatorTest {
assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
.isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
- SystemBatteryConsumer systemConsumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_WIFI);
- assertThat(systemConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(5577);
- /* Same ratio as in testPowerControllerBasedModel_nonMeasured but scaled by 1_000_000uC. */
- assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isWithin(PRECISION).of(1.11153 / (0.2214666 + 0.645200) * 1_000_000 / 3600000);
- assertThat(systemConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
- assertThat(systemConsumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(0.14946);
-
BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
assertThat(deviceConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
.isEqualTo(4002);
@@ -196,17 +172,6 @@ public class WifiPowerCalculatorTest {
.isWithin(PRECISION).of(0.8231573);
assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
.isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
-
- SystemBatteryConsumer systemConsumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_WIFI);
- assertThat(systemConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(2222);
- assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isWithin(PRECISION).of(2.575000);
- assertThat(systemConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(BatteryConsumer.POWER_MODEL_POWER_PROFILE);
- assertThat(systemConsumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(1.69907);
}
@Test
@@ -228,17 +193,5 @@ public class WifiPowerCalculatorTest {
.isWithin(PRECISION).of(0.8231573 / (0.8231573 + 0.8759216) * 1_000_000 / 3600000);
assertThat(uidConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
.isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
-
- SystemBatteryConsumer systemConsumer =
- mStatsRule.getSystemBatteryConsumer(SystemBatteryConsumer.DRAIN_TYPE_WIFI);
- assertThat(systemConsumer.getUsageDurationMillis(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(2222);
- /* Same ratio as in testTimerBasedModel_nonMeasured but scaled by 1_000_000uC. */
- assertThat(systemConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isWithin(PRECISION).of(2.575000 / (0.8231573 + 0.8759216) * 1_000_000 / 3600000);
- assertThat(systemConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_WIFI))
- .isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
- assertThat(systemConsumer.getPowerConsumedByApps())
- .isWithin(PRECISION).of(0.277777);
}
}
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index b9393fff8896..b3615ff60bce 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -46,7 +46,7 @@ public final class FrameInfo {
public static final int FLAGS = 0;
// Is this the first-draw following a window layout?
- public static final long FLAG_WINDOW_LAYOUT_CHANGED = 1;
+ public static final long FLAG_WINDOW_VISIBILITY_CHANGED = 1;
// A renderer associated with just a Surface, not with a ViewRootImpl instance.
public static final long FLAG_SURFACE_CANVAS = 1 << 2;
@@ -56,7 +56,7 @@ public final class FrameInfo {
public static final long INVALID_VSYNC_ID = -1;
@LongDef(flag = true, value = {
- FLAG_WINDOW_LAYOUT_CHANGED, FLAG_SURFACE_CANVAS })
+ FLAG_WINDOW_VISIBILITY_CHANGED, FLAG_SURFACE_CANVAS })
@Retention(RetentionPolicy.SOURCE)
public @interface FrameInfoFlags {}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
index 1971ca97d426..55dfc12966a9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BadgedImageView.java
@@ -15,6 +15,7 @@
*/
package com.android.wm.shell.bubbles;
+import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static android.graphics.Paint.DITHER_FLAG;
import static android.graphics.Paint.FILTER_BITMAP_FLAG;
@@ -22,10 +23,10 @@ import android.annotation.Nullable;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.Path;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.PathParser;
import android.widget.ImageView;
@@ -75,13 +76,13 @@ public class BadgedImageView extends ImageView {
private BubbleViewProvider mBubble;
private BubblePositioner mPositioner;
+ private boolean mOnLeft;
private DotRenderer mDotRenderer;
private DotRenderer.DrawParams mDrawParams;
- private boolean mOnLeft;
-
private int mDotColor;
+ private Paint mPaint = new Paint(ANTI_ALIAS_FLAG);
private Rect mTempBounds = new Rect();
public BadgedImageView(Context context) {
@@ -305,7 +306,7 @@ public class BadgedImageView extends ImageView {
}
void showBadge() {
- Drawable badge = mBubble.getAppBadge();
+ Bitmap badge = mBubble.getAppBadge();
if (badge == null) {
setImageBitmap(mBubble.getBubbleIcon());
return;
@@ -318,13 +319,13 @@ public class BadgedImageView extends ImageView {
bubbleCanvas.setBitmap(bubble);
final int bubbleSize = bubble.getWidth();
final int badgeSize = (int) (ICON_BADGE_SCALE * bubbleSize);
+ Rect dest = new Rect();
if (mOnLeft) {
- badge.setBounds(0, bubbleSize - badgeSize, badgeSize, bubbleSize);
+ dest.set(0, bubbleSize - badgeSize, badgeSize, bubbleSize);
} else {
- badge.setBounds(bubbleSize - badgeSize, bubbleSize - badgeSize,
- bubbleSize, bubbleSize);
+ dest.set(bubbleSize - badgeSize, bubbleSize - badgeSize, bubbleSize, bubbleSize);
}
- badge.draw(bubbleCanvas);
+ bubbleCanvas.drawBitmap(badge, null /* src */, dest, mPaint);
bubbleCanvas.setBitmap(null);
setImageBitmap(bubble);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index f6e92ef0e8ea..afb40d1ff95c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -104,9 +104,10 @@ public class Bubble implements BubbleViewProvider {
}
private FlyoutMessage mFlyoutMessage;
- private Drawable mBadgeDrawable;
- // Bitmap with no badge, no dot
+ // The developer provided image for the bubble
private Bitmap mBubbleBitmap;
+ // The app badge for the bubble
+ private Bitmap mBadgeBitmap;
private int mDotColor;
private Path mDotPath;
private int mFlags;
@@ -242,8 +243,8 @@ public class Bubble implements BubbleViewProvider {
}
@Override
- public Drawable getAppBadge() {
- return mBadgeDrawable;
+ public Bitmap getAppBadge() {
+ return mBadgeBitmap;
}
@Override
@@ -398,7 +399,7 @@ public class Bubble implements BubbleViewProvider {
mAppName = info.appName;
mFlyoutMessage = info.flyoutMessage;
- mBadgeDrawable = info.badgeDrawable;
+ mBadgeBitmap = info.badgeBitmap;
mBubbleBitmap = info.bubbleBitmap;
mDotColor = info.dotColor;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index 696f705782c0..d8ec6508d77c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -395,7 +395,6 @@ public class BubbleExpandedView extends LinearLayout {
mPointerView.setBackground(mCurrentPointer);
}
-
private String getBubbleKey() {
return mBubble != null ? mBubble.getKey() : "null";
}
@@ -519,16 +518,11 @@ public class BubbleExpandedView extends LinearLayout {
+ " bubble=" + getBubbleKey());
}
mIsContentVisible = visibility;
-
- final float alpha = visibility ? 1f : 0f;
-
- mPointerView.setAlpha(alpha);
if (mTaskView != null && !mIsAlphaAnimating) {
- mTaskView.setAlpha(alpha);
+ mTaskView.setAlpha(visibility ? 1f : 0f);
}
}
-
@Nullable
TaskView getTaskView() {
return mTaskView;
@@ -673,26 +667,48 @@ public class BubbleExpandedView extends LinearLayout {
}
/**
- * Set the position that the tip of the triangle should point to.
+ * Sets the position of the pointer.
+ *
+ * When bubbles are showing "vertically" they display along the left / right sides of the
+ * screen with the expanded view beside them.
+ *
+ * If they aren't showing vertically they're positioned along the top of the screen with the
+ * expanded view below them.
+ *
+ * @param bubblePosition the x position of the bubble if showing on top, the y position of
+ * the bubble if showing vertically.
+ * @param onLeft whether the stack was on the left side of the screen when expanded.
*/
- public void setPointerPosition(float x, float y, boolean isLandscape, boolean onLeft) {
+ public void setPointerPosition(float bubblePosition, boolean onLeft) {
// Pointer gets drawn in the padding
- int paddingLeft = (isLandscape && onLeft) ? mPointerHeight : 0;
- int paddingRight = (isLandscape && !onLeft) ? mPointerHeight : 0;
- int paddingTop = isLandscape ? 0 : mExpandedViewPadding;
+ final boolean showVertically = mPositioner.showBubblesVertically();
+ final int paddingLeft = (showVertically && onLeft) ? mPointerHeight : 0;
+ final int paddingRight = (showVertically && !onLeft) ? mPointerHeight : 0;
+ final int paddingTop = showVertically ? 0 : mExpandedViewPadding;
setPadding(paddingLeft, paddingTop, paddingRight, 0);
- if (isLandscape) {
- // TODO: why setY vs setTranslationY ? linearlayout?
- mPointerView.setY(y - (mPointerWidth / 2f));
- mPointerView.setTranslationX(onLeft ? -mPointerHeight : x - mExpandedViewPadding);
- } else {
- mPointerView.setTranslationY(0f);
- mPointerView.setTranslationX(x - mExpandedViewPadding - (mPointerWidth / 2f));
- }
- mCurrentPointer = isLandscape ? onLeft ? mLeftPointer : mRightPointer : mTopPointer;
- updatePointerView();
- mPointerView.setVisibility(VISIBLE);
+ final float expandedViewY = mPositioner.getExpandedViewY();
+ final float bubbleSize = mPositioner.getBubbleBitmapSize();
+ final float bubbleCenter = showVertically
+ ? bubblePosition + (bubbleSize / 2f) - expandedViewY
+ : bubblePosition + (bubbleSize / 2f);
+ // Post because we need the width of the view
+ post(() -> {
+ float pointerY;
+ float pointerX;
+ if (showVertically) {
+ pointerY = bubbleCenter - (mPointerWidth / 2f);
+ pointerX = onLeft ? -mPointerHeight : getWidth() - mPaddingRight;
+ } else {
+ pointerY = 0;
+ pointerX = bubbleCenter - mPaddingLeft - (mPointerWidth / 2f);
+ }
+ mPointerView.setTranslationY(pointerY);
+ mPointerView.setTranslationX(pointerX);
+ mCurrentPointer = showVertically ? onLeft ? mLeftPointer : mRightPointer : mTopPointer;
+ updatePointerView();
+ mPointerView.setVisibility(VISIBLE);
+ });
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java
index e64ed6a0836c..b83feeedbf21 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleIconFactory.java
@@ -101,6 +101,12 @@ public class BubbleIconFactory extends BaseIconFactory {
userBadgedBitmap.getHeight(), userBadgedBitmap.getConfig());
Canvas c = new Canvas(badgeAndRing);
+ Paint ringPaint = new Paint();
+ ringPaint.setStyle(Paint.Style.FILL);
+ ringPaint.setColor(importantConversationColor);
+ ringPaint.setAntiAlias(true);
+ c.drawCircle(c.getWidth() / 2, c.getHeight() / 2, c.getWidth() / 2, ringPaint);
+
final int bitmapTop = (int) ringStrokeWidth;
final int bitmapLeft = (int) ringStrokeWidth;
final int bitmapWidth = c.getWidth() - 2 * (int) ringStrokeWidth;
@@ -110,14 +116,6 @@ public class BubbleIconFactory extends BaseIconFactory {
bitmapHeight, /* filter */ true);
c.drawBitmap(scaledBitmap, bitmapTop, bitmapLeft, /* paint */null);
- Paint ringPaint = new Paint();
- ringPaint.setStyle(Paint.Style.STROKE);
- ringPaint.setColor(importantConversationColor);
- ringPaint.setAntiAlias(true);
- ringPaint.setStrokeWidth(ringStrokeWidth);
- c.drawCircle(c.getWidth() / 2, c.getHeight() / 2, c.getWidth() / 2 - ringStrokeWidth,
- ringPaint);
-
shadowGenerator.recreateIcon(Bitmap.createBitmap(badgeAndRing), c);
return createIconBitmap(badgeAndRing);
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
index 51d63cff385a..36908b854842 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleOverflow.kt
@@ -24,7 +24,6 @@ import android.graphics.Matrix
import android.graphics.Path
import android.graphics.drawable.AdaptiveIconDrawable
import android.graphics.drawable.ColorDrawable
-import android.graphics.drawable.Drawable
import android.graphics.drawable.InsetDrawable
import android.util.PathParser
import android.util.TypedValue
@@ -151,7 +150,7 @@ class BubbleOverflow(
return dotColor
}
- override fun getAppBadge(): Drawable? {
+ override fun getAppBadge(): Bitmap? {
return null
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
index c4d33877f17d..07d16b57d675 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleStackView.java
@@ -2487,7 +2487,7 @@ public class BubbleStackView extends FrameLayout
// name and icon.
if (show && mBubbleData.hasBubbleInStackWithKey(mExpandedBubble.getKey())) {
final Bubble bubble = mBubbleData.getBubbleInStackWithKey(mExpandedBubble.getKey());
- mManageSettingsIcon.setImageDrawable(bubble.getAppBadge());
+ mManageSettingsIcon.setImageBitmap(bubble.getAppBadge());
mManageSettingsText.setText(getResources().getString(
R.string.bubbles_app_settings, bubble.getAppName()));
}
@@ -2683,7 +2683,7 @@ public class BubbleStackView extends FrameLayout
Log.d(TAG, "updateExpandedView: mIsExpanded=" + mIsExpanded);
}
boolean isOverflowExpanded = mExpandedBubble != null
- && mBubbleOverflow.KEY.equals(mExpandedBubble.getKey());
+ && BubbleOverflow.KEY.equals(mExpandedBubble.getKey());
int[] paddings = mPositioner.getExpandedViewPadding(
mStackAnimationController.isStackOnLeftSide(), isOverflowExpanded);
mExpandedViewContainer.setPadding(paddings[0], 0, paddings[1], 0);
@@ -2695,6 +2695,7 @@ public class BubbleStackView extends FrameLayout
mExpandedViewContainer.setTranslationX(0f);
mExpandedBubble.getExpandedView().updateView(
mExpandedViewContainer.getLocationOnScreen());
+ updatePointerPosition();
}
mStackOnLeftOrWillBe = mStackAnimationController.isStackOnLeftSide();
@@ -2732,27 +2733,7 @@ public class BubbleStackView extends FrameLayout
return;
}
float bubblePosition = mExpandedAnimationController.getBubbleXOrYForOrientation(index);
- float expandedViewY = mPositioner.getExpandedViewY();
- if (mPositioner.showBubblesVertically()) {
- float x = mStackOnLeftOrWillBe
- ? mPositioner.getAvailableRect().left
- : mPositioner.getAvailableRect().right
- - mExpandedViewContainer.getPaddingRight()
- - mPointerHeight;
- float bubbleCenter = bubblePosition - expandedViewY + (mBubbleSize / 2f);
- mExpandedBubble.getExpandedView().setPointerPosition(
- x,
- bubbleCenter,
- true,
- mStackOnLeftOrWillBe);
- } else {
- float bubbleCenter = bubblePosition + (mBubbleSize / 2f);
- mExpandedBubble.getExpandedView().setPointerPosition(
- bubbleCenter,
- expandedViewY,
- false,
- mStackOnLeftOrWillBe);
- }
+ mExpandedBubble.getExpandedView().setPointerPosition(bubblePosition, mStackOnLeftOrWillBe);
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
index fc53ef26dbd9..932f879caef8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewInfoTask.java
@@ -126,7 +126,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
ShortcutInfo shortcutInfo;
String appName;
Bitmap bubbleBitmap;
- Drawable badgeDrawable;
+ Bitmap badgeBitmap;
int dotColor;
Path dotPath;
Bubble.FlyoutMessage flyoutMessage;
@@ -188,7 +188,7 @@ public class BubbleViewInfoTask extends AsyncTask<Void, Void, BubbleViewInfoTask
BitmapInfo badgeBitmapInfo = iconFactory.getBadgeBitmap(badgedIcon,
b.isImportantConversation());
- info.badgeDrawable = badgedIcon;
+ info.badgeBitmap = badgeBitmapInfo.icon;
info.bubbleBitmap = iconFactory.createBadgedIconBitmap(bubbleDrawable,
null /* user */,
true /* shrinkNonAdaptiveIcons */).icon;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java
index da4259c42558..38b3ba9dfda0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleViewProvider.java
@@ -18,7 +18,6 @@ package com.android.wm.shell.bubbles;
import android.graphics.Bitmap;
import android.graphics.Path;
-import android.graphics.drawable.Drawable;
import android.view.View;
import androidx.annotation.Nullable;
@@ -48,7 +47,7 @@ public interface BubbleViewProvider {
Bitmap getBubbleIcon();
/** App badge drawable to draw above bubble icon. */
- @Nullable Drawable getAppBadge();
+ @Nullable Bitmap getAppBadge();
/** Path of normalized bubble icon to draw dot on. */
Path getDotPath();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAccessibilityUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAccessibilityUtil.java
index 130246177fdc..4892e6b1b30f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAccessibilityUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedAccessibilityUtil.java
@@ -82,7 +82,7 @@ public final class OneHandedAccessibilityUtil {
public void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "States: ");
+ pw.println(TAG);
pw.print(innerPrefix + "mPackageName=");
pw.println(mPackageName);
pw.print(innerPrefix + "mDescription=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
index 703eba9d6af7..481b94817385 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedBackgroundPanelOrganizer.java
@@ -203,7 +203,7 @@ public class OneHandedBackgroundPanelOrganizer extends DisplayAreaOrganizer
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "states: ");
+ pw.println(TAG);
pw.print(innerPrefix + "mIsShowing=");
pw.println(mIsShowing);
pw.print(innerPrefix + "mBkgBounds=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
index 04ec3917428e..ae7ab528ed0a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedController.java
@@ -630,7 +630,8 @@ public class OneHandedController implements RemoteCallable<OneHandedController>
public void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "States: ");
+ pw.println();
+ pw.println(TAG);
pw.print(innerPrefix + "mOffSetFraction=");
pw.println(mOffSetFraction);
pw.print(innerPrefix + "mLockedDisabled=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
index 1c24338db695..b8da37fd0c25 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedDisplayAreaOrganizer.java
@@ -305,7 +305,7 @@ public class OneHandedDisplayAreaOrganizer extends DisplayAreaOrganizer {
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "states: ");
+ pw.println(TAG);
pw.print(innerPrefix + "mDisplayLayout.rotation()=");
pw.println(mDisplayLayout.rotation());
pw.print(innerPrefix + "mDisplayAreaTokenMap=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
index 9e83a61667b2..03832294aaca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedGestureHandler.java
@@ -276,7 +276,7 @@ public class OneHandedGestureHandler implements OneHandedTransitionCallback {
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "States: ");
+ pw.println(TAG);
pw.print(innerPrefix + "mAllowGesture=");
pw.println(mAllowGesture);
pw.print(innerPrefix + "mIsEnabled=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
index 1b2fcdd6313e..2ab51f3f1313 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedSettingsUtil.java
@@ -137,8 +137,8 @@ public final class OneHandedSettingsUtil {
void dump(PrintWriter pw, String prefix, ContentResolver resolver,
int userId) {
- final String innerPrefix = prefix + " ";
- pw.println(innerPrefix + TAG);
+ final String innerPrefix = " ";
+ pw.println(TAG);
pw.print(innerPrefix + "isOneHandedModeEnable=");
pw.println(getSettingsOneHandedModeEnabled(resolver, userId));
pw.print(innerPrefix + "oneHandedTimeOut=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java
index cc874432be87..facc4bd2b6e8 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedState.java
@@ -90,7 +90,7 @@ public class OneHandedState {
/** Dumps internal state. */
public void dump(PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "states: ");
+ pw.println(TAG);
pw.println(innerPrefix + "sCurrentState=" + sCurrentState);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java
index 4a98941b7410..899c9ae748d0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTimeoutHandler.java
@@ -18,8 +18,6 @@ package com.android.wm.shell.onehanded;
import static com.android.wm.shell.onehanded.OneHandedSettingsUtil.ONE_HANDED_TIMEOUT_MEDIUM_IN_SECONDS;
-import android.os.Handler;
-
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
@@ -122,7 +120,7 @@ public class OneHandedTimeoutHandler {
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "states: ");
+ pw.println(TAG);
pw.print(innerPrefix + "sTimeout=");
pw.println(mTimeout);
pw.print(innerPrefix + "sListeners=");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java
index c7a49ff01d15..0f9b320791b9 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTouchHandler.java
@@ -156,7 +156,7 @@ public class OneHandedTouchHandler implements OneHandedTransitionCallback {
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + "states: ");
+ pw.println(TAG);
pw.print(innerPrefix + "mLastUpdatedBounds=");
pw.println(mLastUpdatedBounds);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
index c60e90315dfc..e8cee8a95c44 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/onehanded/OneHandedTutorialHandler.java
@@ -224,7 +224,7 @@ public class OneHandedTutorialHandler implements OneHandedTransitionCallback {
void dump(@NonNull PrintWriter pw) {
final String innerPrefix = " ";
- pw.println(TAG + " states: ");
+ pw.println(TAG);
pw.print(innerPrefix + "mTriggerState=");
pw.println(mTriggerState);
pw.print(innerPrefix + "mDisplayBounds=");
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedUiEventLoggerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedUiEventLoggerTest.java
index e29fc6a91933..aae1dd0f726f 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedUiEventLoggerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/onehanded/OneHandedUiEventLoggerTest.java
@@ -24,6 +24,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.testing.UiEventLoggerFake;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
@@ -51,6 +52,7 @@ public class OneHandedUiEventLoggerTest extends OneHandedTestCase {
}
@Test
+ @Ignore("b/184813408, go/wm-tests showing test flaky")
public void testLogEvent() {
if (mUiEvent != null) {
assertEquals(1, mUiEventLogger.numLogs());
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index 1e90b7c71376..17c1404c0d98 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -816,6 +816,11 @@ private:
uint32_t mSourceResourceId;
};
+static inline bool operator==(const android::ResXMLParser::ResXMLPosition& lhs,
+ const android::ResXMLParser::ResXMLPosition& rhs) {
+ return lhs.curNode == rhs.curNode;
+}
+
class DynamicRefTable;
/**
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index 2a134fa214e7..540a88b16dc9 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -68,7 +68,7 @@ extern const std::array<const char*, static_cast<int>(FrameInfoIndex::NumIndexes
namespace FrameInfoFlags {
enum {
- WindowLayoutChanged = 1 << 0,
+ WindowVisibilityChanged = 1 << 0,
RTAnimation = 1 << 1,
SurfaceCanvas = 1 << 2,
SkippedFrame = 1 << 3,
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java
index 11d20d4d6c80..bcd0eb0a9e39 100644
--- a/mime/java/android/content/type/DefaultMimeMapFactory.java
+++ b/mime/java/android/content/type/DefaultMimeMapFactory.java
@@ -96,7 +96,7 @@ public class DefaultMimeMapFactory {
specs.add(spec);
startIdx = endIdx + 1; // skip over the space
} while (startIdx < line.length());
- builder.put(specs.get(0), specs.subList(1, specs.size()));
+ builder.addMimeMapping(specs.get(0), specs.subList(1, specs.size()));
}
} catch (IOException | RuntimeException e) {
throw new RuntimeException("Failed to parse " + resourceName, e);
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
index 399cf1f5e0d6..33e5231acee5 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/DeleteStagedFileOnResult.java
@@ -42,10 +42,17 @@ public class DeleteStagedFileOnResult extends Activity {
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
- File sourceFile = new File(getIntent().getData().getPath());
- sourceFile.delete();
-
setResult(resultCode, data);
finish();
}
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+
+ if (isFinishing()) {
+ File sourceFile = new File(getIntent().getData().getPath());
+ new Thread(sourceFile::delete).start();
+ }
+ }
}
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 8b226c926c99..4f587ebba89c 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -50,13 +50,6 @@ java_library {
srcs: ["src/com/android/systemui/EventLogTags.logtags"],
}
-java_library {
- name: "SystemUI-sensors",
- srcs: [
- "src/com/android/systemui/util/sensors/ThresholdSensor.java",
- ],
-}
-
android_library {
name: "SystemUI-core",
srcs: [
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 173e95954014..d6989753f16e 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -62,11 +62,13 @@
<!-- Networking and telephony -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
- <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
- <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"
+ android:usesPermissionFlags="neverForLocation" />
+ <uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
+ android:usesPermissionFlags="neverForLocation" />
+ <uses-permission android:name="android.permission.BLUETOOTH_SCAN"
+ android:usesPermissionFlags="neverForLocation" />
<uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
- <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
diff --git a/packages/SystemUI/animation/Android.bp b/packages/SystemUI/animation/Android.bp
index ab9ab831157c..1b15d20d2c52 100644
--- a/packages/SystemUI/animation/Android.bp
+++ b/packages/SystemUI/animation/Android.bp
@@ -36,7 +36,6 @@ android_library {
static_libs: [
"PluginCoreLib",
- "SystemUI-sensors",
],
manifest: "AndroidManifest.xml",
diff --git a/packages/SystemUI/plugin/Android.bp b/packages/SystemUI/plugin/Android.bp
index 9f02fdbf3ec9..cafaaf854eed 100644
--- a/packages/SystemUI/plugin/Android.bp
+++ b/packages/SystemUI/plugin/Android.bp
@@ -34,7 +34,6 @@ java_library {
static_libs: [
"androidx.annotation_annotation",
"PluginCoreLib",
- "SystemUI-sensors",
"SystemUIAnimationLib",
],
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
index b75252b46785..5ac8961aceeb 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/FalsingManager.java
@@ -21,7 +21,6 @@ import android.net.Uri;
import android.view.MotionEvent;
import com.android.systemui.plugins.annotations.ProvidesInterface;
-import com.android.systemui.util.sensors.ThresholdSensor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -118,7 +117,7 @@ public interface FalsingManager {
void cleanup();
/** Call to report a ProximityEvent to the FalsingManager. */
- void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent);
+ void onProximityEvent(ProximityEvent proximityEvent);
/** Adds a {@link FalsingBeliefListener}. */
void addFalsingBeliefListener(FalsingBeliefListener listener);
@@ -141,4 +140,13 @@ public interface FalsingManager {
interface FalsingTapListener {
void onDoubleTapRequired();
}
+
+ /** Passed to {@link FalsingManager#onProximityEvent}. */
+ interface ProximityEvent {
+ /** Returns true when the proximity sensor was covered. */
+ boolean getCovered();
+
+ /** Returns when the proximity sensor was covered in nanoseconds. */
+ long getTimestampNs();
+ }
}
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
index 1a38585ea78d..ce63082868bb 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pattern_view.xml
@@ -40,7 +40,7 @@
android:clipToPadding="false">
<LinearLayout
- android:id="@+id/container"
+ android:id="@+id/pattern_container"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:orientation="vertical"
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
index 50ffbc802a7d..c64afd307f23 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_pin_view.xml
@@ -27,7 +27,7 @@
android:orientation="vertical"
>
<LinearLayout
- android:id="@+id/container"
+ android:id="@+id/pin_container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical"
diff --git a/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml b/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml
index 0e308d2f5bfb..da581061370b 100644
--- a/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_no_calling_sms.xml
@@ -1,12 +1,24 @@
+<!--
+ Copyright (C) 2021 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.0"
- android:viewportHeight="24.0">
+ android:width="16dp"
+ android:height="16dp"
+ android:viewportWidth="16.0"
+ android:viewportHeight="16.0">
<path
android:fillColor="#FF000000"
- android:pathData="M20.17,14.84l-3.26,-0.65c-0.33,-0.07 -0.67,0.04 -0.9,0.27l-2.62,2.62c-2.75,-1.49 -5.01,-3.75 -6.5,-6.5l2.62,-2.62c0.24,-0.24 0.34,-0.58 0.27,-0.9L9.13,3.8C9.04,3.34 8.63,3 8.15,3H4C3.44,3 2.97,3.47 3,4.03c0.17,2.91 1.04,5.63 2.43,8.01c1.57,2.69 3.81,4.93 6.5,6.5c2.38,1.39 5.1,2.26 8.01,2.43c0.56,0.03 1.03,-0.44 1.03,-1v-4.15C20.97,15.34 20.64,14.93 20.17,14.84z"/>
- <path
- android:fillColor="#FF000000"
- android:pathData="M22,3.41L20.59,2L18.5,4.09L16.41,2L15,3.41l2.09,2.09L15,7.59L16.41,9l2.09,-2.08L20.59,9L22,7.59L19.92,5.5L22,3.41z"/>
+ android:pathData="M6.52,11.37c0.46,0.37 0.94,0.7 1.45,0.99c1.59,0.93 3.4,1.51 5.34,1.62C13.69,14 14,13.69 14,13.31v-2.77c0,-0.32 -0.23,-0.59 -0.53,-0.65l-2.17,-0.43c-0.22,-0.05 -0.45,0.03 -0.6,0.18l-1.75,1.75c-0.52,-0.28 -1.01,-0.61 -1.48,-0.97l7.61,-7.61l-0.95,-0.94L1.87,14.13l0.94,0.94L6.52,11.37L6.52,11.37zM5.59,8.55C5.22,8.08 4.89,7.58 4.61,7.05l1.75,-1.75c0.16,-0.16 0.23,-0.39 0.18,-0.6L6.1,2.53C6.04,2.23 5.77,2 5.45,2H2.68C2.31,2 1.99,2.31 2.01,2.69c0.11,1.94 0.69,3.75 1.62,5.34c0.3,0.51 0.64,1.01 1.01,1.47L5.59,8.55L5.59,8.55z"/>
</vector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_media_button_background.xml b/packages/SystemUI/res/drawable/qs_media_button_background.xml
index 2241abf130e3..ed9bd263a79d 100644
--- a/packages/SystemUI/res/drawable/qs_media_button_background.xml
+++ b/packages/SystemUI/res/drawable/qs_media_button_background.xml
@@ -26,4 +26,5 @@
android:right="16dp"
android:top="8dp"
android:bottom="8dp" />
+ <solid android:color="@android:color/transparent" />
</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/media_carousel.xml b/packages/SystemUI/res/layout/media_carousel.xml
index 95cee66af536..87acfd088939 100644
--- a/packages/SystemUI/res/layout/media_carousel.xml
+++ b/packages/SystemUI/res/layout/media_carousel.xml
@@ -22,7 +22,7 @@
android:layout_height="wrap_content"
android:clipChildren="false"
android:clipToPadding="false"
- >
+ android:theme="@style/MediaPlayer">
<com.android.systemui.media.MediaScrollView
android:id="@+id/media_carousel_scroller"
android:layout_width="match_parent"
@@ -47,7 +47,7 @@
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_marginBottom="4dp"
- android:tint="?android:attr/textColorPrimary"
+ android:tint="?android:attr/textColor"
android:forceHasOverlappingRendering="false"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
index 1c4c89fb254a..8c54e2c1cec4 100644
--- a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
+++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
@@ -19,7 +19,6 @@
<com.android.systemui.util.animation.TransitionLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/media_recommendations"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -28,7 +27,8 @@
android:clipChildren="false"
android:clipToPadding="false"
android:forceHasOverlappingRendering="false"
- android:background="@drawable/qs_media_background">
+ android:background="@drawable/qs_media_background"
+ android:theme="@style/MediaPlayer">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/media_vertical_start_guideline"
@@ -37,12 +37,19 @@
android:orientation="vertical"
app:layout_constraintGuide_percent="0.25" />
- <ImageView
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/media_horizontal_center_guideline"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ app:layout_constraintGuide_percent="0.5" />
+
+ <com.android.internal.widget.CachingIconView
android:id="@+id/recommendation_card_icon"
android:layout_width="@dimen/qs_aa_media_rec_header_icon_size"
android:layout_height="@dimen/qs_aa_media_rec_header_icon_size"
android:src="@drawable/ic_headset"
- android:tint="?android:attr/colorPrimary" />
+ android:tint="?android:attr/textColor" />
<TextView
android:id="@+id/recommendation_card_text"
@@ -51,7 +58,6 @@
android:singleLine="true"
android:text="@string/controls_media_smartspace_rec_title"
android:fontFamily="google-sans-medium"
- android:textColor="?android:attr/colorPrimary"
android:textDirection="locale"
android:textSize="@dimen/qq_aa_media_rec_header_text_size" />
@@ -61,7 +67,7 @@
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ style="@style/MediaPlayer.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
@@ -69,7 +75,7 @@
android:id="@+id/media_logo1"
android:layout_width="@dimen/qs_media_icon_size"
android:layout_height="@dimen/qs_media_icon_size"
- android:background="@drawable/qs_media_icon_background" />
+ style="@style/MediaPlayer.AppIcon" />
<ImageView
android:id="@+id/media_cover2"
@@ -77,7 +83,7 @@
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ style="@style/MediaPlayer.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
@@ -85,7 +91,7 @@
android:id="@+id/media_logo2"
android:layout_width="@dimen/qs_media_icon_size"
android:layout_height="@dimen/qs_media_icon_size"
- android:background="@drawable/qs_media_icon_background" />
+ style="@style/MediaPlayer.AppIcon" />
<ImageView
android:id="@+id/media_cover3"
@@ -93,7 +99,7 @@
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ style="@style/MediaPlayer.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
@@ -101,7 +107,7 @@
android:id="@+id/media_logo3"
android:layout_width="@dimen/qs_media_icon_size"
android:layout_height="@dimen/qs_media_icon_size"
- android:background="@drawable/qs_media_icon_background" />
+ style="@style/MediaPlayer.AppIcon" />
<ImageView
android:id="@+id/media_cover4"
@@ -109,7 +115,7 @@
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ style="@style/MediaPlayer.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
@@ -117,7 +123,7 @@
android:id="@+id/media_logo4"
android:layout_width="@dimen/qs_media_icon_size"
android:layout_height="@dimen/qs_media_icon_size"
- android:background="@drawable/qs_media_icon_background" />
+ style="@style/MediaPlayer.AppIcon" />
<ImageView
android:id="@+id/media_cover5"
@@ -125,7 +131,7 @@
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ style="@style/MediaPlayer.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
@@ -133,7 +139,7 @@
android:id="@+id/media_logo5"
android:layout_width="@dimen/qs_media_icon_size"
android:layout_height="@dimen/qs_media_icon_size"
- android:background="@drawable/qs_media_icon_background" />
+ style="@style/MediaPlayer.AppIcon" />
<ImageView
android:id="@+id/media_cover6"
@@ -141,7 +147,7 @@
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
+ style="@style/MediaPlayer.Album"
android:clipToOutline="true"
android:scaleType="centerCrop"/>
@@ -149,7 +155,7 @@
android:id="@+id/media_logo6"
android:layout_width="@dimen/qs_media_icon_size"
android:layout_height="@dimen/qs_media_icon_size"
- android:background="@drawable/qs_media_icon_background" />
+ style="@style/MediaPlayer.AppIcon" />
<!-- Long press menu -->
<TextView
@@ -161,7 +167,6 @@
android:id="@+id/remove_text"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
- android:textColor="?android:attr/textColorPrimary"
android:text="@string/controls_media_close_session"
android:gravity="center_horizontal|top"
app:layout_constraintTop_toTopOf="parent"
@@ -186,9 +191,7 @@
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/qs_media_button_background"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/MediaPlayer.OutlineButton"
android:text="@string/controls_media_settings_button" />
</FrameLayout>
@@ -209,9 +212,7 @@
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/qs_media_button_background"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/MediaPlayer.OutlineButton"
android:text="@string/cancel" />
</FrameLayout>
@@ -232,9 +233,7 @@
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/qs_media_button_background"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/MediaPlayer.OutlineButton"
android:text="@string/controls_media_dismiss_button"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml
index cdced5a1be71..e9a24e284601 100644
--- a/packages/SystemUI/res/layout/media_view.xml
+++ b/packages/SystemUI/res/layout/media_view.xml
@@ -18,7 +18,6 @@
<!-- Layout for media controls inside QSPanel carousel -->
<com.android.systemui.util.animation.TransitionLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:id="@+id/qs_media_controls"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -26,7 +25,8 @@
android:clipToPadding="false"
android:gravity="center_horizontal|fill_vertical"
android:forceHasOverlappingRendering="false"
- android:background="@drawable/qs_media_background">
+ android:background="@drawable/qs_media_background"
+ android:theme="@style/MediaPlayer">
<androidx.constraintlayout.widget.Guideline
android:id="@+id/center_vertical_guideline"
@@ -55,7 +55,6 @@
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:fontFamily="@*android:string/config_bodyFontFamily"
- android:textColor="?android:attr/textColorPrimary"
android:gravity="start"
android:textSize="12sp" />
@@ -65,7 +64,6 @@
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:fontFamily="@*android:string/config_bodyFontFamily"
- android:textColor="?android:attr/textColorPrimary"
android:gravity="end"
android:textSize="12sp" />
</FrameLayout>
@@ -86,31 +84,31 @@
<ImageButton
android:id="@+id/action0"
- style="@style/MediaPlayer.Button"
+ style="@style/MediaPlayer.Action"
android:layout_width="48dp"
android:layout_height="48dp" />
<ImageButton
android:id="@+id/action1"
- style="@style/MediaPlayer.Button"
+ style="@style/MediaPlayer.Action"
android:layout_width="48dp"
android:layout_height="48dp" />
<ImageButton
android:id="@+id/action2"
- style="@style/MediaPlayer.Button"
+ style="@style/MediaPlayer.Action"
android:layout_width="48dp"
android:layout_height="48dp" />
<ImageButton
android:id="@+id/action3"
- style="@style/MediaPlayer.Button"
+ style="@style/MediaPlayer.Action"
android:layout_width="48dp"
android:layout_height="48dp" />
<ImageButton
android:id="@+id/action4"
- style="@style/MediaPlayer.Button"
+ style="@style/MediaPlayer.Action"
android:layout_width="48dp"
android:layout_height="48dp" />
@@ -120,8 +118,8 @@
android:layout_width="@dimen/qs_media_album_size"
android:layout_height="@dimen/qs_media_album_size"
android:layout_gravity="center_vertical"
+ style="@style/MediaPlayer.Album"
android:background="@drawable/qs_media_art_background"
- android:backgroundTint="?androidprv:attr/colorAccentSecondary"
android:clipToOutline="true" />
<!-- Seamless Output Switcher -->
@@ -138,6 +136,7 @@
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="@dimen/qs_seamless_height"
+ android:theme="@style/MediaPlayer.SolidButton"
android:background="@drawable/qs_media_seamless_background"
android:orientation="horizontal"
android:contentDescription="@string/quick_settings_media_device_label">
@@ -146,7 +145,6 @@
android:layout_width="@dimen/qs_seamless_icon_size"
android:layout_height="@dimen/qs_seamless_icon_size"
android:layout_gravity="center"
- android:tint="?android:attr/colorPrimary"
android:src="@*android:drawable/ic_media_seamless" />
<TextView
android:id="@+id/media_seamless_text"
@@ -157,7 +155,6 @@
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
android:text="@*android:string/ext_media_seamless_action"
- android:textColor="?android:attr/colorPrimary"
android:textDirection="locale"
android:textSize="12sp" />
</LinearLayout>
@@ -171,7 +168,7 @@
android:layout_marginBottom="@dimen/qs_media_padding"
android:layout_marginStart="@dimen/qs_center_guideline_padding"
android:layout_marginEnd="@dimen/qs_seamless_fallback_margin"
- android:tint="?android:attr/textColorPrimary"
+ android:tint="?android:attr/textColor"
android:src="@drawable/ic_cast_connected"
android:forceHasOverlappingRendering="false" />
@@ -179,17 +176,13 @@
<!-- As per Material Design on Biderectionality, this is forced to LTR in code -->
<SeekBar
android:id="@+id/media_progress_bar"
- style="@android:style/Widget.ProgressBar.Horizontal"
+ style="@style/MediaPlayer.ProgressBar"
android:layout_width="0dp"
android:layout_height="wrap_content"
- android:clickable="true"
android:maxHeight="@dimen/qs_media_enabled_seekbar_height"
android:paddingTop="@dimen/qs_media_enabled_seekbar_vertical_padding"
android:layout_marginTop="-22dp"
android:paddingBottom="0dp"
- android:thumbTint="?android:attr/textColorPrimary"
- android:progressTint="?android:attr/textColorPrimary"
- android:progressBackgroundTint="?android:attr/textColorTertiary"
android:splitTrack="false" />
<!-- Song name -->
@@ -199,7 +192,6 @@
android:layout_height="wrap_content"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
android:singleLine="true"
- android:textColor="?android:attr/textColorPrimary"
android:textSize="16sp" />
<!-- Artist name -->
@@ -209,16 +201,14 @@
android:layout_height="wrap_content"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
- android:textColor="?android:attr/textColorSecondary"
+ style="@style/MediaPlayer.Subtitle"
android:textSize="14sp" />
<com.android.internal.widget.CachingIconView
android:id="@+id/icon"
- android:tint="?android:attr/colorAccent"
+ style="@style/MediaPlayer.AppIcon"
android:layout_width="@dimen/qs_media_icon_size"
- android:layout_height="@dimen/qs_media_icon_size"
- android:background="@drawable/qs_media_icon_background"
- />
+ android:layout_height="@dimen/qs_media_icon_size" />
<!-- Long press menu -->
<TextView
@@ -230,7 +220,6 @@
android:id="@+id/remove_text"
android:fontFamily="@*android:string/config_headlineFontFamily"
android:singleLine="true"
- android:textColor="?android:attr/textColorPrimary"
android:text="@string/controls_media_close_session"
android:gravity="center_horizontal|top"
app:layout_constraintTop_toTopOf="parent"
@@ -255,9 +244,7 @@
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/qs_media_button_background"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/MediaPlayer.OutlineButton"
android:text="@string/controls_media_settings_button" />
</FrameLayout>
@@ -278,9 +265,7 @@
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/qs_media_button_background"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/MediaPlayer.OutlineButton"
android:text="@string/cancel" />
</FrameLayout>
@@ -301,9 +286,7 @@
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:background="@drawable/qs_media_button_background"
- android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="?android:attr/textColorPrimary"
+ style="@style/MediaPlayer.OutlineButton"
android:text="@string/controls_media_dismiss_button"
/>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml
index ea644cfca68a..c332f4cf7a39 100644
--- a/packages/SystemUI/res/layout/notification_conversation_info.xml
+++ b/packages/SystemUI/res/layout/notification_conversation_info.xml
@@ -254,7 +254,6 @@
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/notification_importance_button_description_top_margin"
android:visibility="gone"
- android:text="@string/notification_channel_summary_priority"
android:clickable="false"
android:focusable="false"
android:ellipsize="end"
diff --git a/packages/SystemUI/res/layout/people_tile_empty_layout.xml b/packages/SystemUI/res/layout/people_tile_empty_layout.xml
new file mode 100644
index 000000000000..7d3b919ce040
--- /dev/null
+++ b/packages/SystemUI/res/layout/people_tile_empty_layout.xml
@@ -0,0 +1,29 @@
+<!--
+ ~ Copyright (C) 2021 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.
+ -->
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:theme="@android:style/Theme.DeviceDefault.DayNight"
+ android:background="@drawable/people_space_tile_view_card"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <ImageView
+ android:id="@+id/item"
+ android:gravity="center"
+ android:layout_gravity="center"
+ android:padding="8dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+</FrameLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/priority_onboarding_half_shell.xml b/packages/SystemUI/res/layout/priority_onboarding_half_shell.xml
deleted file mode 100644
index 3f0e514a9af2..000000000000
--- a/packages/SystemUI/res/layout/priority_onboarding_half_shell.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<!--
- ~ Copyright (C) 2020 The Android Open Source Project
- ~
- ~ Licensed under the Apache License, Version 2.0 (the "License");
- ~ you may not use this file except in compliance with the License.
- ~ You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License
- -->
-
-<FrameLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/onboarding_half_shell_container"
- android:orientation="vertical"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|bottom"
- android:paddingStart="4dp"
- android:paddingEnd="4dp"
- >
-
- <LinearLayout
- android:id="@+id/half_shell"
- android:layout_width="@dimen/qs_panel_width"
- android:layout_height="wrap_content"
- android:paddingTop="16dp"
- android:paddingStart="16dp"
- android:paddingEnd="16dp"
- android:orientation="vertical"
- android:gravity="bottom"
- android:layout_gravity="center_horizontal|bottom"
- android:background="@drawable/rounded_bg_full"
- >
-
- <FrameLayout
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:clipChildren="false"
- android:clipToPadding="false"
- android:padding="12dp"
- android:layout_gravity="center_horizontal"
- >
-
- <!-- Big icon: 52x52, 12dp padding left + top, 16dp padding right -->
- <ImageView
- android:id="@+id/conversation_icon"
- android:layout_width="@*android:dimen/conversation_avatar_size"
- android:layout_height="@*android:dimen/conversation_avatar_size"
- android:scaleType="centerCrop"
- android:importantForAccessibility="no"
- />
-
- <FrameLayout
- android:id="@+id/conversation_icon_badge"
- android:layout_width="@*android:dimen/conversation_icon_size_badged"
- android:layout_height="@*android:dimen/conversation_icon_size_badged"
- android:layout_marginLeft="@*android:dimen/conversation_badge_side_margin"
- android:layout_marginTop="@*android:dimen/conversation_badge_side_margin"
- android:clipChildren="false"
- android:clipToPadding="false"
- >
- <ImageView
- android:id="@+id/conversation_icon_badge_bg"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:src="@*android:drawable/conversation_badge_background"
- android:forceHasOverlappingRendering="false"
- />
- <ImageView
- android:id="@+id/icon"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_margin="4dp"
- android:layout_gravity="center"
- android:forceHasOverlappingRendering="false"
- />
- <ImageView
- android:id="@+id/conversation_icon_badge_ring"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center"
- android:src="@*android:drawable/conversation_badge_ring"
- android:forceHasOverlappingRendering="false"
- android:clipToPadding="false"
- android:scaleType="center"
- />
- </FrameLayout>
- </FrameLayout>
-
- <TextView
- android:id="@+id/title"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:layout_marginTop="16dp"
- android:text="@string/priority_onboarding_title"
- style="@style/TextAppearance.NotificationImportanceChannel"
- />
-
- <View
- android:id="@+id/divider"
- android:layout_width="match_parent"
- android:layout_height="0.5dp"
- android:layout_marginTop="20dp"
- android:layout_marginBottom="20dp"
- android:background="@color/material_grey_300" />
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:text="@string/priority_onboarding_behavior"
- style="@style/TextAppearance.NotificationImportanceChannelGroup"
- />
-
- <TextView
- android:id="@+id/behaviors"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="start"
- android:layout_marginTop="8dp"
- style="@style/TextAppearance.NotificationImportanceChannelGroup"
- />
-
- <!-- Bottom button container -->
- <RelativeLayout
- android:id="@+id/button_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="32dp"
- android:orientation="horizontal"
- >
- <TextView
- android:id="@+id/settings_button"
- android:text="@string/priority_onboarding_settings_button_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentStart="true"
- android:gravity="start|center_vertical"
- android:minWidth="@dimen/notification_importance_toggle_size"
- android:minHeight="@dimen/notification_importance_toggle_size"
- android:maxWidth="125dp"
- style="@style/TextAppearance.NotificationInfo.Button"/>
- <TextView
- android:id="@+id/done_button"
- android:text="@string/priority_onboarding_done_button_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentEnd="true"
- android:gravity="end|center_vertical"
- android:minWidth="@dimen/notification_importance_toggle_size"
- android:minHeight="@dimen/notification_importance_toggle_size"
- android:maxWidth="125dp"
- style="@style/TextAppearance.NotificationInfo.Button"/>
-
- </RelativeLayout>
-
- </LinearLayout>
-</FrameLayout>
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 5bf691928300..bb540990ccb7 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -36,7 +36,7 @@
<include layout="@layout/quick_status_bar_header_date_privacy"/>
<RelativeLayout
- android:id="@+id/container"
+ android:id="@+id/qs_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="top"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index b94e9e8ae1c3..f17067a58b69 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Beweeg na regs onder"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Beweeg na rand en versteek"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Beweeg weg van rand en wys"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"wissel"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Toestelkontroles"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Voeg kontroles vir jou gekoppelde toestelle by"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Stel toestelkontroles op"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Maak toe"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervat"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellings"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Speel"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Onaktief, gaan program na"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fout, probeer tans weer …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nie gekry nie"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index d2ee53d54a46..d2ecd78df75c 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"ታችኛውን ቀኝ አንቀሳቅስ"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"ወደ ጠርዝ አንቀሳቅስ እና ደደብቅ"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"ጠርዙን ወደ ውጭ አንቀሳቅስ እና አሳይ"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ቀያይር"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"የመሣሪያ መቆጣጠሪያዎች"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"ለእርስዎ የተገናኙ መሣሪያዎች መቆጣጠሪያዎችን ያክሉ"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"የመሣሪያ መቆጣጠሪያዎችን ያቀናብሩ"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"አሰናብት"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ከቆመበት ቀጥል"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ቅንብሮች"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"አጫውት"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ንቁ ያልኾነ፣ መተግበሪያን ይፈትሹ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ስህተት፣ እንደገና በመሞከር ላይ…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"አልተገኘም"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index a32a55ce8101..bceb6c9250ae 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"তলৰ সোঁফালে নিয়ক"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"কাষলৈ নিয়ক আৰু লুকুৱাওক"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"কাষৰ বাহিৰলৈ নিয়ক আৰু দেখুৱাওক"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ট’গল কৰক"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহ"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"আপোনাৰ সংযোজিত ডিভাইচৰ বাবে নিয়ন্ত্ৰণ যোগ কৰক"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"ডিভাইচৰ নিয়ন্ত্ৰণসমূহ ছেট আপ কৰক"</string>
@@ -1087,15 +1086,12 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"অধিক চাবলৈ ছোৱাইপ কৰক"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"চুপাৰিছসমূহ ল’ড কৰি থকা হৈছে"</string>
<string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"এই মিডিয়াৰ ছেশ্বনটো লুকুৱাবনে?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"বৰ্তমানৰ মিডিয়াৰ ছেশ্বনটো লুকুৱাব নোৱাৰি।"</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"অগ্ৰাহ্য কৰক"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"পুনৰ আৰম্ভ কৰক"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ছেটিংসমূহ"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"প্লে’ কৰক"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"সক্ৰিয় নহয়, এপ্‌টো পৰীক্ষা কৰক"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"আসোঁৱাহ, পুনৰ চেষ্টা কৰি আছে…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"বিচাৰি পোৱা নগ’ল"</string>
@@ -1156,6 +1152,5 @@
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰ অক্ষম হৈ আছে"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"বিশ্বাসযোগ্যতা প্ৰমাণ কৰক"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইচ আনলক কৰক"</string>
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলিবলৈ ফিংগাৰপ্ৰিণ্ট ব্যৱহাৰ কৰক"</string>
</resources>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 9318906f4a49..466d24ef491d 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Aşağıya sağa köçürün"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"İçəri keçirib gizlədin"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Kənara daşıyıb göstərin"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"keçirin"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Cihaz idarəetmələri"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Qoşulmuş cihazlarınız üçün nizamlayıcılar əlavə edin"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz idarəetmələrini ayarlayın"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"İmtina edin"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davam edin"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Oxudun"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Aktiv deyil, tətbiqi yoxlayın"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Xəta, yenidən cəhd edilir…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Tapılmadı"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index eeb3061fe8e7..f1303ce06190 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -1049,8 +1049,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Premesti dole desno"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Premesti do ivice i sakrij"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Premesti izvan ivice i prikaži"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"uključite/isključite"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrole za povezane uređaje"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Podesite kontrole uređaja"</string>
@@ -1098,8 +1097,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Podešavanja"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Pusti"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno. Vidite aplikaciju"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Greška, pokušava se ponovo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 44f6ff96d323..e857489eff56 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Преместване долу вдясно"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Преместване в края и скриване"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Преместване в края и показване"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"превключване"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Контроли за устройството"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Добавяне на контроли за свързаните ви устройства"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Настройване на контролите за устройството"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Отхвърляне"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Възобновяване"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Настройки"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Google Play"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно, проверете прилож."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка. Извършва се нов опит…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Не е намерено"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 959f07b36b92..8f9953ba2a6d 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -1087,10 +1087,8 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"আরও দেখতে সোয়াইপ করুন"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"সাজেশন লোড করা হচ্ছে"</string>
<string name="controls_media_title" msgid="1746947284862928133">"মিডিয়া"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"এই মিডিয়া সেশন লুকিয়ে রাখতে চান?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"বর্তমান মিডিয়া সেশন লুকিয়ে রাখা যাবে না।"</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"খারিজ করুন"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"আবার চালু করুন"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"সেটিংস"</string>
@@ -1156,6 +1154,5 @@
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"ফিঙ্গারপ্রিন্ট সেন্সর বন্ধ করা আছে"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"যাচাই করিয়ে নিন"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ডিভাইস আনলক করুন"</string>
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"খুলতে ফিঙ্গারপ্রিন্ট ব্যবহার করুন"</string>
</resources>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 674f049849b0..482c8ad816f9 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -1049,8 +1049,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Pomjeranje dolje desno"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Pomjeranje do ivice i sakrivanje"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Pomjeranje izvan ivice i prikaz"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aktiviranje/deaktiviranje"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrole za povezane uređaje"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Postavite kontrole uređaja"</string>
@@ -1098,8 +1097,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Pokrenite"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, vidite aplikaciju"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Greška, ponovni pokušaj…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index b9e01021df59..ac86cfbba09e 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mou a baix a la dreta"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mou dins de les vores i amaga"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mou fora de les vores i mostra"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"commuta"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Controls de dispositius"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Afegeix controls per als teus dispositius connectats"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura els controls de dispositius"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignora"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprèn"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuració"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reprodueix"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiu; comprova l\'aplicació"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error. S\'està tornant a provar…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No s\'ha trobat"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 123b09fc1816..bf969a19d21e 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -1054,8 +1054,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Přesunout vpravo dolů"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Přesunout k okraji a skrýt"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Přesunout okraj ven a zobrazit"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"přepnout"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Ovládání zařízení"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Přidejte si ovládací prvky pro připojená zařízení"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavení ovládání zařízení"</string>
@@ -1104,8 +1103,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Zavřít"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovat"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavení"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Přehrát"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivní, zkontrolujte aplikaci"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Chyba. Nový pokus…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nenalezeno"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 5ccdbf38680a..abcb89e0de39 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Flyt ned til højre"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Flyt ud til kanten, og skjul"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Flyt ud til kanten, og vis"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"slå til/fra"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Enhedsstyring"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Tilføj styring af dine tilsluttede enheder"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhedsstyring"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Luk"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Genoptag"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Indstillinger"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Afspil"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Tjek appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fejl. Prøver igen…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ikke fundet"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 6885380b2cc5..2bc8a0392261 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -1087,10 +1087,8 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"Wischen, um weitere zu sehen"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"Empfehlungen werden geladen"</string>
<string name="controls_media_title" msgid="1746947284862928133">"Medien"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"Diese Mediensitzung ausblenden?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"Die Mediensitzung kann nicht ausgeblendet werden."</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ablehnen"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Fortsetzen"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Einstellungen"</string>
@@ -1156,6 +1154,5 @@
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"Fingerabdrucksensor ist deaktiviert"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"zu authentifizieren"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"das Gerät einzugeben"</string>
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Mit Fingerabdruck öffnen"</string>
</resources>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index f8420271d256..545d822c50ac 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Μετακίνηση κάτω δεξιά"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Μετακίν. στο άκρο και απόκρυψη"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Μετακ. εκτός άκρου και εμφάν."</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"εναλλαγή"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Στοιχεία ελέγχου συσκευής"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Προσθήκη στοιχείων ελέγχου για τις συνδεδεμένες συσκευές σας."</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Ρύθμιση στοιχείων ελέγχου συσκευής"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Παράβλεψη"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Συνέχιση"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ρυθμίσεις"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Play"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Ανενεργό, έλεγχος εφαρμογής"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Προέκυψε σφάλμα. Επανάληψη…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Δεν βρέθηκε."</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 21ed95421f1f..5292f8741446 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mover abajo a la derecha"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover fuera de borde y ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mover fuera de borde y mostrar"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar o desactivar"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Controles de dispositivos"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Agrega controles para los dispositivos conectados"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles de dispositivos"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Descartar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reproducir"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Verifica la app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hubo un error. Reintentando…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No se encontró"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index eaeaf0b6fbf8..d23f073d387f 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mover abajo a la derecha"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover al borde y ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mover al borde y mostrar"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Añade controles para tus dispositivos conectados"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar control de dispositivos"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Cerrar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reanudar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ajustes"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reproducir"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo, comprobar aplicación"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Error; reintentando…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"No se ha encontrado"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index ceaf3fcadb96..d227dcbfd225 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Teisalda alla paremale"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Teisalda serva ja kuva"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Teisalda servast eemale ja kuva"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"lülita"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Seadmete juhikud"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Lisage juhtelemendid ühendatud seadmete jaoks"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Seadmete juhtimisvidinate seadistamine"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Loobu"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Jätka"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Seaded"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Esitamine"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Passiivne, vaadake rakendust"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Viga, proovitakse uuesti …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ei leitud"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 3cb0b4398f4e..199107c2be56 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Eraman behealdera, eskuinetara"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Eraman ertzera eta ezkutatu"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Atera ertzetik eta erakutsi"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aldatu"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Gailuak kontrolatzeko widgetak"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Gehitu konektatutako gailuak kontrolatzeko widgetak"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguratu gailuak kontrolatzeko widgetak"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Baztertu"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Berrekin"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ezarpenak"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Erreproduzitu"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktibo; egiaztatu aplikazioa"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Errorea. Berriro saiatzen…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ez da aurkitu"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 7e9dabb4089a..d6b018df10b7 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"انتقال به پایین سمت چپ"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"انتقال به لبه و پنهان کردن"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"انتقال به خارج از لبه و نمایش"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"روشن/ خاموش کردن"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"کنترل‌های دستگاه"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"افزودن کنترل‌ها برای دستگاه‌های متصل"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"تنظیم کنترل‌های دستگاه"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"رد کردن"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ازسرگیری"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"تنظیمات"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"پخش"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"غیرفعال، برنامه را بررسی کنید"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"خطا، درحال تلاش مجدد…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"پیدا نشد"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 89566a6e6e29..d4da4597d56c 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Déplacer dans coin inf. droit"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Éloigner du bord et masquer"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Éloigner du bord et afficher"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"basculer"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajoutez des commandes pour vos appareils connectés"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes des appareils"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Fermer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Faire jouer"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifiez l\'appli"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erreur, nouvelle tentative…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 7f73bab04817..c17bf8ffe906 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Déplacer en bas à droite"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Rapprocher du bord et masquer"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Éloigner du bord et afficher"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activer/désactiver"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Commandes des appareils"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Ajouter des commandes pour vos appareils connectés"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurer les commandes des appareils"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Fermer"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reprendre"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Paramètres"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Lire"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Délai expiré, vérifier l\'appli"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erreur. Nouvelle tentative…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Introuvable"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 4a2a93ef0ec1..73d2de64d194 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mover á parte inferior dereita"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover ao bordo e ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mover fóra do bordo e mostrar"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"activar/desactivar"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Control de dispositivos"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Engade controis para os dispositivos conectados"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar o control de dispositivos"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignorar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configuración"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reproducir"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactivo. Comproba a app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando de novo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Non se atopou"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 25eb4163d3e9..4c5308bfc2fd 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -137,8 +137,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"ફોન"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"વૉઇસ સહાય"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"અનલૉક કરો"</string>
- <!-- no translation found for accessibility_lock_icon (661492842417875775) -->
- <skip />
+ <string name="accessibility_lock_icon" msgid="661492842417875775">"ડિવાઇસ લૉક કરેલું છે"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"ફિંગરપ્રિન્ટની રાહ જોઈ રહ્યાં છીએ"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"તમારી ફિંગરપ્રિન્ટનો ઉપયોગ કર્યા વગર અનલૉક કરો"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ચહેરો સ્કૅન કરવો"</string>
@@ -1088,10 +1087,8 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"વધુ જોવા માટે સ્વાઇપ કરો"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"સુઝાવ લોડ કરી રહ્યાં છીએ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"મીડિયા"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"શું આ મીડિયા સત્ર છુપાવીએ?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"હાલનું મીડિયા સત્ર છુપાવી શકાતું નથી."</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"છોડી દો"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ફરી શરૂ કરો"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"સેટિંગ"</string>
@@ -1153,14 +1150,9 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"તમારું બૅટરી મીટર વાંચવામાં સમસ્યા આવી"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"વધુ માહિતી માટે ટૅપ કરો"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"કોઈ અલાર્મ સેટ નથી"</string>
- <!-- no translation found for accessibility_fingerprint_label (5255731221854153660) -->
- <skip />
- <!-- no translation found for accessibility_udfps_disabled_button (4284034245130239384) -->
- <skip />
- <!-- no translation found for accessibility_authenticate_hint (798914151813205721) -->
- <skip />
- <!-- no translation found for accessibility_enter_hint (2617864063504824834) -->
- <skip />
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ફિંગરપ્રિન્ટ સેન્સર"</string>
+ <string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"ફિંગરપ્રિન્ટ સેન્સર બંધ કરેલું છે"</string>
+ <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ખાતરી કરો"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ડિવાઇસ અનલૉક કરો"</string>
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ખોલવા માટે ફિંગરપ્રિન્ટનો ઉપયોગ કરો"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 02e4a45751a8..6b03458b0f73 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"सबसे नीचे दाईं ओर ले जाएं"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"एज पर ले जाएं और छिपाएं"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"एज से निकालें और दिखाएं"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"टॉगल करें"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"डिवाइस कंट्रोल"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"कनेक्ट किए गए डिवाइस के लिए कंट्रोल जोड़ें"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"डिवाइस कंट्रोल सेट अप करें"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"खारिज करें"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"फिर से शुरू करें"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"सेटिंग"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"चलाएं"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"काम नहीं कर रहा, ऐप जांचें"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"कोई गड़बड़ी हुई, फिर से कोशिश की जा रही है…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"कंट्रोल नहीं है"</string>
@@ -1153,6 +1151,6 @@
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फ़िंगरप्रिंट सेंसर"</string>
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"फ़िंगरप्रिंट सेंसर बंद है"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"पुष्टि करें"</string>
- <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिवाइस अनलॉक करें"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिवाइस की होम स्क्रीन पर जाएं"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"खोलने के लिए, फ़िंगरप्रिंट का इस्तेमाल करें"</string>
</resources>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 39e628296126..3b4d034c8039 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -1049,8 +1049,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Premjesti u donji desni kut"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Premjesti na rub i sakrij"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Ukloni s ruba i prikaži"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"promijeni"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Kontrole uređaja"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Dodajte kontrole za povezane uređaje"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Postavljanje kontrola uređaja"</string>
@@ -1098,8 +1097,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Odbaci"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Nastavi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Postavke"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reprodukcija"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktivno, provjerite aplik."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Pogreška, pokušavamo ponovo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nije pronađeno"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 906b45fe13e9..1940cd5ef2ea 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Áthelyezés le és jobbra"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Áthelyezés a szélen kívül és elrejtés"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Áthelyezés a szélen kívül és mutatás"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"váltás"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Eszközvezérlők"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Vezérlők hozzáadása a csatlakoztatott eszközökhöz"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Eszközvezérlők beállítása"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Elvetés"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Folytatás"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Beállítások"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Játék"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktív, ellenőrizze az appot"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hiba, újrapróbálkozás…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nem található"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 630792f1ec4f..aaf2b5d8c31a 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Færa neðst til hægri"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Færa að jaðri og fela"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Færa að jaðri og birta"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"kveikja/slökkva"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Tækjastjórnun"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Bæta við stýringum fyrir tengd tæki"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Setja upp tækjastjórnun"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Hunsa"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Halda áfram"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Stillingar"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Spila"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Óvirkt, athugaðu forrit"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Villa, reynir aftur…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Fannst ekki"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index 0fd51ec1ad09..40294d5a32fe 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Sposta in basso a destra"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Sposta fino a bordo e nascondi"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Sposta fuori da bordo e mostra"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"attiva/disattiva"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Controllo dei dispositivi"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Aggiungi controlli per i dispositivi connessi"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configura il controllo dei dispositivi"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignora"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Riprendi"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Impostazioni"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Riproduci"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inattivo, controlla l\'app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Errore. Nuovo tentativo…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Controllo non trovato"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 98ae9d1ae9d4..0a9cceb32c5b 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -1099,10 +1099,8 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"יש להחליק כדי להציג עוד פריטים"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ההמלצות בטעינה"</string>
<string name="controls_media_title" msgid="1746947284862928133">"מדיה"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"להסתיר את סשן המדיה?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"לא ניתן להסתיר את סשן המדיה הנוכחי."</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"סגירה"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"המשך"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"הגדרות"</string>
@@ -1168,6 +1166,5 @@
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"חיישן טביעות האצבע מושבת"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"אימות"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"הזנת מכשיר"</string>
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"שימוש בטביעת אצבע כדי לפתוח"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index c3475017a066..97d94ab4d41c 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"右下に移動"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"端に移動して非表示"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"端から移動して表示"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"切り替え"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"デバイス コントロール"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"コネクテッド デバイスのコントロールを追加します"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"デバイス コントロールの設定"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"閉じる"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"再開"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"再生"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無効: アプリをご確認ください"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"エラー。再試行しています…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"見つかりませんでした"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index bc8abd42c929..0a181b43d1e7 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Төменгі оң жаққа жылжыту"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Шетке жылжыту және жасыру"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Шетке жылжыту және көрсету"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ауыстыру"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Құрылғыны басқару элементтері"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Жалғанған құрылғылар үшін басқару элементтерін қосу"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Құрылғыны басқару элементтерін реттеу"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Жабу"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Жалғастыру"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Параметрлер"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Ойнату"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Өшірулі. Қолданба тексеріңіз."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Қате, әрекет қайталануда…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Табылмады"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 48b80f684471..f872660aa1c8 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"ផ្លាស់ទីទៅខាងក្រោមផ្នែកខាងស្ដាំ"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"ផ្លាស់ទីទៅផ្នែកខាងចុង រួចលាក់"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"ផ្លាស់ទីចេញពីផ្នែកខាងចុង រួចបង្ហាញ"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"បិទ/បើក"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"ផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"បញ្ចូល​ផ្ទាំងគ្រប់គ្រង​សម្រាប់​ឧបករណ៍​ដែលអ្នកបានភ្ជាប់"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"រៀបចំ​ផ្ទាំងគ្រប់គ្រងឧបករណ៍"</string>
@@ -1094,8 +1093,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"ច្រាន​ចោល"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"បន្ត"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ការកំណត់"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ចាក់"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"អសកម្ម ពិនិត្យមើល​កម្មវិធី"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"បញ្ហា កំពុងព្យាយាម​ម្ដងទៀត…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"រកមិន​ឃើញទេ"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index f35c3b28b103..ffc634adbe4f 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -137,8 +137,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"ಫೋನ್"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"ಧ್ವನಿ ಸಹಾಯಕ"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"ಅನ್‌ಲಾಕ್"</string>
- <!-- no translation found for accessibility_lock_icon (661492842417875775) -->
- <skip />
+ <string name="accessibility_lock_icon" msgid="661492842417875775">"ಸಾಧನ ಲಾಕ್ ಆಗಿದೆ"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್‍‍ಗಾಗಿ ನಿರೀಕ್ಷಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"ನಿಮ್ಮ ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಬಳಸದೆಯೇ ಅನ್‌ಲಾಕ್ ಮಾಡಿ"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"ಮುಖವನ್ನು ಸ್ಕ್ಯಾನ್ ಮಾಡಲಾಗುತ್ತಿದೆ"</string>
@@ -1153,14 +1152,10 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"ನಿಮ್ಮ ಬ್ಯಾಟರಿ ಮೀಟರ್ ಓದುವಾಗ ಸಮಸ್ಯೆ ಎದುರಾಗಿದೆ"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"ಇನ್ನಷ್ಟು ಮಾಹಿತಿಗಾಗಿ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"ಅಲಾರಾಂ ಸೆಟ್ ಆಗಿಲ್ಲ"</string>
- <!-- no translation found for accessibility_fingerprint_label (5255731221854153660) -->
- <skip />
- <!-- no translation found for accessibility_udfps_disabled_button (4284034245130239384) -->
- <skip />
- <!-- no translation found for accessibility_authenticate_hint (798914151813205721) -->
- <skip />
- <!-- no translation found for accessibility_enter_hint (2617864063504824834) -->
- <skip />
+ <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್"</string>
+ <string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"ಫಿಂಗರ್‌ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
+ <string name="accessibility_authenticate_hint" msgid="798914151813205721">"ದೃಢೀಕರಿಸಿ"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"ಸಾಧನವನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 3c61f44beff2..7d27acba2fd0 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"오른쪽 하단으로 이동"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"가장자리로 옮겨서 숨기기"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"가장자리 바깥으로 옮겨서 표시"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"전환"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"기기 컨트롤"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"연결된 기기의 컨트롤을 추가하세요."</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"기기 컨트롤 설정"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"닫기"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"다시 시작"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"설정"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"재생"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"비활성. 앱을 확인하세요."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"오류 발생, 다시 시도 중…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"찾을 수 없음"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index a0d460b40599..54310c102821 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Баруун доош зөөх"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Ирмэг рүү зөөж, нуух"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Ирмэгээс гаргаж, харуулах"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"асаах/унтраах"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Төхөөрөмжийн хяналт"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Холбогдсон төхөөрөмжүүд дээрээ хяналт нэмэх"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Төхөөрөмжийн хяналтыг тохируулах"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Хаах"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Үргэлжлүүлэх"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Тохиргоо"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Тоглуулах"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Идэвхгүй байна, аппыг шалгана уу"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Алдаа, дахин оролдож байна…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Олдсонгүй"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 6bbeb52da831..3945370ca7b7 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Alihkan ke bawah sebelah kanan"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Alihkan ke tepi dan sorokkan"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Alihkan ke tepi dan tunjukkan"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"togol"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Kawalan peranti"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Tambah kawalan untuk peranti yang disambungkan"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Sediakan kawalan peranti"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Tolak"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Sambung semula"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Tetapan"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Main"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Tidak aktif, semak apl"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Ralat, mencuba semula…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Tidak ditemukan"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 649d7c509c65..3dcea65e7701 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Flytt til nederst til høyre"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Flytt til kanten og skjul"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Flytt ut kanten og vis"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"slå av/på"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyring"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Legg til kontroller for de tilkoblede enhetene dine"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurer enhetsstyring"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Lukk"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Gjenoppta"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Innstillinger"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Spill av"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv. Sjekk appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Feil. Prøver igjen …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ikke funnet"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 6258e4590a71..cd87cd5401d6 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -137,8 +137,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"फोन"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"आवाज सहायता"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"खोल्नुहोस्"</string>
- <!-- no translation found for accessibility_lock_icon (661492842417875775) -->
- <skip />
+ <string name="accessibility_lock_icon" msgid="661492842417875775">"यन्त्र लक गरिएको छ"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"फिंगरप्रिन्ट कुर्दै"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"आफ्नो फिंगरप्रिन्ट बिना नै अनलक गर्नुहोस्"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"अनुहार स्क्यान गर्दै"</string>
@@ -1153,14 +1152,10 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"डिभाइसको ब्याट्रीको मिटर रिडिङ क्रममा समस्या भयो"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"थप जानकारी प्राप्त गर्न ट्याप गर्नुहोस्"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"अलार्म राखिएको छैन"</string>
- <!-- no translation found for accessibility_fingerprint_label (5255731221854153660) -->
- <skip />
- <!-- no translation found for accessibility_udfps_disabled_button (4284034245130239384) -->
- <skip />
- <!-- no translation found for accessibility_authenticate_hint (798914151813205721) -->
- <skip />
- <!-- no translation found for accessibility_enter_hint (2617864063504824834) -->
- <skip />
+ <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"फिंगरप्रिन्ट सेन्सर"</string>
+ <string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"फिंगरप्रिन्ट सेन्सर असक्षम पारिएको छ"</string>
+ <string name="accessibility_authenticate_hint" msgid="798914151813205721">"प्रमाणित गर्नुहोस्"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"डिभाइस हाल्नुहोस्"</string>
<!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
<skip />
</resources>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 0bd3cd589401..d5d094684dd0 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Naar rechtsonder verplaatsen"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Naar rand verplaatsen en verbergen"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Over rand verplaatsen en tonen"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"schakelen"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Apparaatbediening"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Voeg bedieningselementen voor je gekoppelde apparaten toe"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Apparaatbediening instellen"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Sluiten"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Hervatten"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Instellingen"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Afspelen"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactief, check de app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fout. Opnieuw proberen…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Niet gevonden"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index e9371c60af14..95f1d3589ca4 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"ନିମ୍ନ ଡାହାଣକୁ ମୁଭ୍ କରନ୍ତୁ"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"ଧାରକୁ ମୁଭ୍ କରି ଲୁଚାନ୍ତୁ"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"ଧାର ବାହାରକୁ ମୁଭ୍ କରି ଦେଖାନ୍ତୁ"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ଟୋଗଲ୍ କରନ୍ତୁ"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"ଆପଣଙ୍କ ସଂଯୁକ୍ତ ଡିଭାଇସଗୁଡ଼ିକ ପାଇଁ ନିୟନ୍ତ୍ରଣ ଯୋଗ କରନ୍ତୁ"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"ଡିଭାଇସ୍ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ ସେଟ୍ ଅପ୍ କରନ୍ତୁ"</string>
@@ -1087,15 +1086,12 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ଅଧିକ ଦେଖିବାକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ସୁପାରିଶଗୁଡ଼ିକ ଲୋଡ୍ କରାଯାଉଛି"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ମିଡିଆ"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"ଏହି ମିଡିଆ ସେସନକୁ ଲୁଚାଇବେ?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"ବର୍ତ୍ତମାନର ମିଡିଆ ସେସନକୁ ଲୁଚାଯାଇପାରିବ ନାହିଁ।"</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"ଖାରଜ କରନ୍ତୁ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ପୁଣି ଆରମ୍ଭ କରନ୍ତୁ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ସେଟିଂସ୍"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"ଚଲାନ୍ତୁ"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ନିଷ୍କ୍ରିୟ ଅଛି, ଆପ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"ତ୍ରୁଟି, ପୁଣି ଚେଷ୍ଟା କରୁଛି…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ମିଳିଲା ନାହିଁ"</string>
@@ -1156,6 +1152,5 @@
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"ଟିପଚିହ୍ନ ସେନ୍ସରକୁ ଅକ୍ଷମ କରାଯାଇଛି"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ପ୍ରମାଣୀକରଣ କରନ୍ତୁ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ଡିଭାଇସ୍ ବିଷୟରେ ସୂଚନା ଲେଖନ୍ତୁ"</string>
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ଖୋଲିବାକୁ ଟିପଚିହ୍ନ ବ୍ୟବହାର କରନ୍ତୁ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index fdc20266c18a..e0e1b4f2f119 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -1087,10 +1087,8 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"ਹੋਰ ਦੇਖਣ ਲਈ ਸਵਾਈਪ ਕਰੋ"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"ਸਿਫ਼ਾਰਸ਼ਾਂ ਲੋਡ ਹੋ ਰਹੀਆਂ ਹਨ"</string>
<string name="controls_media_title" msgid="1746947284862928133">"ਮੀਡੀਆ"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"ਕੀ ਇਹ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਉਣਾ ਹੈ?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"ਮੌਜੂਦਾ ਮੀਡੀਆ ਸੈਸ਼ਨ ਲੁਕਾਇਆ ਨਹੀਂ ਜਾ ਸਕਦਾ।"</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"ਖਾਰਜ ਕਰੋ"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ਸੈਟਿੰਗਾਂ"</string>
@@ -1156,6 +1154,5 @@
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ਪ੍ਰਮਾਣਿਤ ਕਰੋ"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"ਡੀਵਾਈਸ ਵਿੱਚ ਦਾਖਲ ਹੋਵੋ"</string>
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"ਖੋਲ੍ਹਣ ਲਈ ਫਿੰਗਰਪ੍ਰਿੰਟ ਵਰਤੋ"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 4c6c15911a59..d95eabc8c35a 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -1165,6 +1165,6 @@
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Czytnik linii papilarnych"</string>
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"Czytnik linii papilarnych został wyłączony"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"uwierzytelnij"</string>
- <string name="accessibility_enter_hint" msgid="2617864063504824834">"dodaj urządzenie"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"otwórz urządzenie"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"By otworzyć, użyj odcisku palca"</string>
</resources>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index cc60b6a3719f..b786dfb46b03 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mover para o canto inferior direito"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover para a borda e ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mover para fora da borda e exibir"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Adiciona controles aos dispositivos conectados"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles do dispositivo"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dispensar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Iniciar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando novamente…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c38388d42b9b..496fcb21f838 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mover parte inferior direita"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover p/ extremidade e ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Retirar extremidade e mostrar"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ativar/desativar"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Controlos de dispositivos"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Adicione controlos para os dispositivos associados."</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configure os controlos de dispositivos"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ignorar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Definições"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Reproduzir"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativa. Consulte a app."</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. A tentar novamente…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index cc60b6a3719f..b786dfb46b03 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mover para o canto inferior direito"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mover para a borda e ocultar"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mover para fora da borda e exibir"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"alternar"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Controles do dispositivo"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Adiciona controles aos dispositivos conectados"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurar controles do dispositivo"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Dispensar"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Retomar"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Configurações"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Iniciar"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inativo, verifique o app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Erro. Tentando novamente…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Não encontrado"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 4e3fb127ee37..2100466e2cdf 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -1049,8 +1049,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Mutați în dreapta jos"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Mutați în afară și ascundeți"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Mutați în afară și afișați"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"Activați / dezactivați"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Comenzile dispozitivelor"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Adăugați comenzi pentru dispozitivele conectate"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Configurați comenzile dispozitivelor"</string>
@@ -1098,8 +1097,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Închideți"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Reia"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Setări"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Redați"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inactiv, verificați aplicația"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Eroare, se încearcă din nou…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nu s-a găsit"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index fe834484ab56..45abf9550ff3 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"පහළ දකුණට ගෙන යන්න"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"මායිමට ගෙන යන්න සහ සඟවන්න"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"මායිමෙන් පිටට ගන්න සහ පෙන්වන්න"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"ටොගල් කරන්න"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"උපාංග පාලන"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"ඔබේ සම්බන්ධිත උපාංග සඳහා පාලන එක් කරන්න"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"උපාංග පාලන පිහිටුවන්න"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"ඉවත ලන්න"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"නැවත පටන් ගන්න"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"සැකසීම්"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"වාදනය කරන්න"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"අක්‍රියයි, යෙදුම පරීක්ෂා කරන්න"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"දෝෂයකි, නැවත උත්සාහ කරමින්…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"හමු නොවිණි"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index d947376d1429..63c3b8bc5876 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -1054,8 +1054,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Presunúť doprava nadol"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Presunúť k okraju a skryť"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Presunúť z okraja a zobraziť"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"prepínač"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Ovládanie zariadení"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Pridajte si ovládače pripojených zariadení"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Nastavenie ovládania zariadení"</string>
@@ -1104,8 +1103,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Zavrieť"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Pokračovať"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Nastavenia"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Prehrať"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Neaktívne, preverte aplikáciu"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Chyba, skúša sa znova…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nenájdené"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index a0b5081c84ae..f1f7a7a63ff7 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Zhvendos poshtë djathtas"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Zhvendose te skaji dhe fshihe"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Zhvendose jashtë skajit dhe shfaqe"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aktivizo/çaktivizo"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Kontrollet e pajisjes"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Shto kontrolle për pajisjet e tua të lidhura"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfiguro kontrollet e pajisjes"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Hiq"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Vazhdo"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cilësimet"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Luaj"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Joaktive, kontrollo aplikacionin"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Gabim, po provohet përsëri"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Nuk u gjet"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index de323ecbffd1..22af16a5e242 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -1049,8 +1049,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Премести доле десно"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Премести до ивице и сакриј"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Премести изван ивице и прикажи"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"укључите/искључите"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Контроле уређаја"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Додајте контроле за повезане уређаје"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Подесите контроле уређаја"</string>
@@ -1098,8 +1097,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Одбаци"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Настави"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Подешавања"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Пусти"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Неактивно. Видите апликацију"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Грешка, покушава се поново…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Није пронађено"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index cc7adf5bd078..ebcae0f3ade8 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Flytta längst ned till höger"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Flytta till kanten och dölj"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Flytta från kanten och visa"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"aktivera och inaktivera"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Enhetsstyrning"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Lägg till snabbkontroller för anslutna enheter"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Konfigurera enhetsstyrning"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Stäng"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Återuppta"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Inställningar"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Spela upp"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Inaktiv, kolla appen"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Fel, försöker igen …"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hittades inte"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index afa23984d9e8..2a45ce5a0a33 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Sogeza chini kulia"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Sogeza kwenye ukingo kisha ufiche"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Sogeza nje ya ukingo kisha uonyeshe"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"geuza"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Vidhibiti vya vifaa"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Weka vidhibiti vya vifaa ulivyounganisha"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Weka mipangilio ya vidhibiti vya vifaa"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Ondoa"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Endelea"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mipangilio"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Cheza"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Haitumiki, angalia programu"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hitilafu, inajaribu tena…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hakipatikani"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index ad0e4c751900..63b4c3b8560d 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"கீழே வலதுபுறத்திற்கு நகர்த்து"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"ஓரத்திற்கு நகர்த்தி மறை"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"ஓரத்திற்கு நகர்த்தி, காட்டு"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"நிலைமாற்று"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"சாதனக் கட்டுப்பாடுகள்"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"இணைக்கப்பட்ட சாதனங்களில் கட்டுப்பாடுகளைச் சேர்க்கலாம்"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"சாதனக் கட்டுப்பாடுகளை அமைத்தல்"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"மூடுக"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"தொடர்க"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"அமைப்புகள்"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"இயக்குதல்"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"செயலில் இல்லை , சரிபார்க்கவும்"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"பிழை, மீண்டும் முயல்கிறது…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"இல்லை"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 0b030faa82e7..7b05e3620d9b 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -1087,10 +1087,8 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"మరిన్నింటిని చూడటం కోసం స్వైప్ చేయండి"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"సిఫార్సులు లోడ్ అవుతున్నాయి"</string>
<string name="controls_media_title" msgid="1746947284862928133">"మీడియా"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"ఈ మీడియా సెషన్‌ను దాచాలా?"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"ప్రస్తుత మీడియా సెషన్‌ను దాచడం సాధ్యం కాదు."</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"విస్మరించు"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"కొనసాగించండి"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"సెట్టింగ్‌లు"</string>
@@ -1156,6 +1154,5 @@
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"వేలిముద్ర సెన్సార్ డిజేబుల్ చేయబడింది"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"ప్రామాణీకరించండి"</string>
<string name="accessibility_enter_hint" msgid="2617864063504824834">"పరికరాన్ని ఎంటర్ చేయండి"</string>
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"తెరవడానికి వేలిముద్రను ఉపయోగించండి"</string>
</resources>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 578f8a11bf39..171ecd449b06 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"ย้ายไปด้านขาวล่าง"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"ย้ายไปที่ขอบและซ่อน"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"ย้ายออกจากขอบและแสดง"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"สลับ"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"ระบบควบคุมอุปกรณ์"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"เพิ่มตัวควบคุมของอุปกรณ์ที่เชื่อมต่อ"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"ตั้งค่าระบบควบคุมอุปกรณ์"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"ปิด"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"เล่นต่อ"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"การตั้งค่า"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"เล่น"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"ไม่มีการใช้งาน โปรดตรวจสอบแอป"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"มีข้อผิดพลาด กำลังลองอีกครั้ง…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"ไม่พบ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index 896eeade63fc..0490ff7ce286 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Ilipat sa kanan sa ibaba"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Ilipat sa sulok at itago"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Alisin sa sulok at ipakita"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"i-toggle"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Mga kontrol ng device"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Magdagdag ng kontrol para sa mga nakakonektang device"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"I-set up ang mga kontrol ng device"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"I-dismiss"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Ituloy"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Mga Setting"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"I-play"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Hindi aktibo, tingnan ang app"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Nagka-error, sinusubukan ulit…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Hindi nahanap"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index c584d31438b4..12cae9b93216 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Sağ alta taşı"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Kenara taşıyıp gizle"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Kenarın dışına taşıyıp göster"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"değiştir"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Cihaz denetimleri"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Bağlı cihazlarınız için denetimler ekleyin"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Cihaz denetimlerini kur"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Kapat"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Devam ettir"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Ayarlar"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Oynat"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Devre dışı, uygulamaya bakın"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Hata, yeniden deneniyor…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Bulunamadı"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 73d5e935a973..4e7de7110672 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -1165,6 +1165,6 @@
<string name="accessibility_fingerprint_label" msgid="5255731221854153660">"Сканер відбитків пальців"</string>
<string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"Сканер відбитків пальців вимкнено"</string>
<string name="accessibility_authenticate_hint" msgid="798914151813205721">"пройти автентифікацію"</string>
- <string name="accessibility_enter_hint" msgid="2617864063504824834">"виконати вхід на пристрої"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"відкрити пристрій"</string>
<string name="keyguard_try_fingerprint" msgid="2825130772993061165">"Щоб відкрити, використайте відбиток пальця"</string>
</resources>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 7e9cf556a9c8..702bc7efd36b 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -137,8 +137,7 @@
<string name="accessibility_phone_button" msgid="4256353121703100427">"فون"</string>
<string name="accessibility_voice_assist_button" msgid="6497706615649754510">"صوتی معاون"</string>
<string name="accessibility_unlock_button" msgid="122785427241471085">"غیر مقفل کریں"</string>
- <!-- no translation found for accessibility_lock_icon (661492842417875775) -->
- <skip />
+ <string name="accessibility_lock_icon" msgid="661492842417875775">"آلہ مقفل کر دیا گیا"</string>
<string name="accessibility_waiting_for_fingerprint" msgid="5209142744692162598">"فنگر پرنٹ کا انتظار ہے"</string>
<string name="accessibility_unlock_without_fingerprint" msgid="1811563723195375298">"فنگر پرنٹ استعمال کیے بغیرغیر مقفل کریں"</string>
<string name="accessibility_scanning_face" msgid="3093828357921541387">"اسکیننگ چہرہ"</string>
@@ -1088,10 +1087,8 @@
<string name="controls_structure_tooltip" msgid="4355922222944447867">"مزید دیکھنے کیلئے سوائپ کریں"</string>
<string name="controls_seeding_in_progress" msgid="3033855341410264148">"تجاویز لوڈ ہو رہی ہیں"</string>
<string name="controls_media_title" msgid="1746947284862928133">"میڈیا"</string>
- <!-- no translation found for controls_media_close_session (1193000643003066508) -->
- <skip />
- <!-- no translation found for controls_media_active_session (3146882316024153337) -->
- <skip />
+ <string name="controls_media_close_session" msgid="1193000643003066508">"اس میڈیا سیشن کو چھپائیں؟"</string>
+ <string name="controls_media_active_session" msgid="3146882316024153337">"میڈیا کے موجودہ سیشن کو چھپایا نہیں جا سکتا۔"</string>
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"برخاست کریں"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"دوبارہ شروع کریں"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"ترتیبات"</string>
@@ -1153,14 +1150,9 @@
<string name="battery_state_unknown_notification_title" msgid="8464703640483773454">"آپ کے بیٹری میٹر کو پڑھنے میں دشواری"</string>
<string name="battery_state_unknown_notification_text" msgid="13720937839460899">"مزید معلومات کے لیے تھپتھپائیں"</string>
<string name="qs_alarm_tile_no_alarm" msgid="4826472008616807923">"کوئی الارم سیٹ نہیں ہے"</string>
- <!-- no translation found for accessibility_fingerprint_label (5255731221854153660) -->
- <skip />
- <!-- no translation found for accessibility_udfps_disabled_button (4284034245130239384) -->
- <skip />
- <!-- no translation found for accessibility_authenticate_hint (798914151813205721) -->
- <skip />
- <!-- no translation found for accessibility_enter_hint (2617864063504824834) -->
- <skip />
- <!-- no translation found for keyguard_try_fingerprint (2825130772993061165) -->
- <skip />
+ <string name="accessibility_fingerprint_label" msgid="5255731221854153660">"فنگر پرنٹ سینسر"</string>
+ <string name="accessibility_udfps_disabled_button" msgid="4284034245130239384">"فنگر پرنٹ سینسر غیر فعال ہے"</string>
+ <string name="accessibility_authenticate_hint" msgid="798914151813205721">"تصدیق کریں"</string>
+ <string name="accessibility_enter_hint" msgid="2617864063504824834">"آلہ درج کریں"</string>
+ <string name="keyguard_try_fingerprint" msgid="2825130772993061165">"کھولنے کے لیے فنگر پرنٹ کا استعمال کریں"</string>
</resources>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index eb6a27214556..216a0944fcad 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Quyi oʻngga surish"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Chetiga olib borish va yashirish"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Chetidan qaytarish va koʻrsatish"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"oʻzgartirish"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Qurilmalarni boshqarish"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Ulangan qurilmalar uchun boshqaruv elementlari"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Qurilma boshqaruv elementlarini sozlash"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Yopish"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Davom etish"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Sozlamalar"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Ijro"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Nofaol. Ilovani tekshiring"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Xato, qayta urinilmoqda…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Topilmadi"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 237036f725c8..a6a9ace99e4c 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Chuyển tới dưới cùng bên phải"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Chuyển đến cạnh và ẩn"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Chuyển ra xa cạnh và hiển thị"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"bật/tắt"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Điều khiển thiết bị"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Thêm các nút điều khiển cho các thiết bị đã kết nối"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Thiết lập các tùy chọn điều khiển thiết bị"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Đóng"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Tiếp tục"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Cài đặt"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Phát"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Không hoạt động, hãy kiểm tra ứng dụng"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Lỗi, đang thử lại…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Không tìm thấy"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index aa5e4e2b1824..51b9a545721e 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"移去右下方"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"移到邊緣並隱藏"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"從邊緣移出並顯示"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"切換"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"為連接的裝置新增控制選項"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"關閉"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"播放"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"已停用,請檢查應用程式"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"發生錯誤,正在重試…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"找不到"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index ed44b087f0f8..8a93729c1e34 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"移到右下方"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"移到邊緣並隱藏"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"從邊緣移出並顯示"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"切換"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"裝置控制"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"新增已連結裝置的控制項"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"設定裝置控制項"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"關閉"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"繼續播放"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"設定"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"播放"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"無效,請查看應用程式"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"發生錯誤,正在重試…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"找不到控制項"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 01e0fca3a89e..674a7c843f5f 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -1044,8 +1044,7 @@
<string name="accessibility_floating_button_action_move_bottom_right" msgid="6196904373227440500">"Hamba phansi ngakwesokudla"</string>
<string name="accessibility_floating_button_action_move_to_edge_and_hide_to_half" msgid="662401168245782658">"Hamba onqenqemeni ufihle"</string>
<string name="accessibility_floating_button_action_move_out_edge_and_show" msgid="8354760891651663326">"Phuma onqenqemeni ubonise"</string>
- <!-- no translation found for accessibility_floating_button_action_double_tap_to_toggle (7976492639670692037) -->
- <skip />
+ <string name="accessibility_floating_button_action_double_tap_to_toggle" msgid="7976492639670692037">"guqula"</string>
<string name="quick_controls_title" msgid="6839108006171302273">"Izilawuli zezinsiza"</string>
<string name="quick_controls_subtitle" msgid="1667408093326318053">"Engeza izilawuli zedivayisi yakho exhunyiwe"</string>
<string name="quick_controls_setup_title" msgid="8901436655997849822">"Setha izilawuli zezinsiza"</string>
@@ -1092,8 +1091,7 @@
<string name="controls_media_dismiss_button" msgid="9081375542265132213">"Cashisa"</string>
<string name="controls_media_resume" msgid="1933520684481586053">"Qalisa kabusha"</string>
<string name="controls_media_settings_button" msgid="5815790345117172504">"Izilungiselelo"</string>
- <!-- no translation found for controls_media_smartspace_rec_title (1699818353932537407) -->
- <skip />
+ <string name="controls_media_smartspace_rec_title" msgid="1699818353932537407">"Dlala"</string>
<string name="controls_error_timeout" msgid="794197289772728958">"Akusebenzi, hlola uhlelo lokusebenza"</string>
<string name="controls_error_retryable" msgid="864025882878378470">"Iphutha, iyazama futhi…"</string>
<string name="controls_error_removed" msgid="6675638069846014366">"Ayitholakali"</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 13c285f12393..edd8486379a2 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1279,9 +1279,10 @@
<dimen name="qs_media_disabled_seekbar_vertical_padding">36dp</dimen>
<!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
- <dimen name="qs_aa_media_rec_header_icon_padding">10dp</dimen>
+ <dimen name="qs_aa_media_rec_header_icon_start_margin">10dp</dimen>
<dimen name="qs_aa_media_rec_header_icon_size">18dp</dimen>
<dimen name="qs_aa_media_rec_album_size">72dp</dimen>
+ <dimen name="qs_aa_media_rec_album_vertical_margin">8dp</dimen>
<dimen name="qq_aa_media_rec_header_text_size">16sp</dimen>
<!-- Window magnification -->
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 673a03ddac4e..d9cc24fa38ef 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1897,13 +1897,16 @@
<string name="notification_channel_summary_automatic_demoted">&lt;b>Status:&lt;/b> Ranked Lower</string>
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level summary -->
- <string name="notification_channel_summary_priority">Always shown at the top of your notifications, even when Priority mode is on</string>
+ <string name="notification_channel_summary_priority_baseline">Shows at the top of conversation notifications and as a profile picture on lock screen</string>
+ <string name="notification_channel_summary_priority_bubble">Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble</string>
+ <string name="notification_channel_summary_priority_dnd">Shows at the top of conversation notifications and as a profile picture on lock screen, interrupts Do Not Disturb</string>
+ <string name="notification_channel_summary_priority_all">Shows at the top of conversation notifications and as a profile picture on lock screen, appears as a bubble, interrupts Do Not Disturb</string>
<!--[CHAR LIMIT=30] Linkable text to Settings app -->
<string name="notification_conversation_channel_settings">Settings</string>
<!-- [CHAR LIMIT=150] Notification Importance title: important conversation level -->
- <string name="notification_priority_title">Priority conversations</string>
+ <string name="notification_priority_title">Priority</string>
<!-- Text shown in notification guts for conversation notifications that don't implement the full feature -->
<string name="no_shortcut"><xliff:g id="app_name" example="YouTube">%1$s</xliff:g> doesn\u2019t support conversation features</string>
@@ -2667,25 +2670,6 @@
<!-- Title of the overlay warning the user to interact with the device or it will go to sleep. [CHAR LIMIT=25] -->
<string name="inattentive_sleep_warning_title">Standby</string>
- <!-- Priority conversation onboarding screen -->
- <!-- title of priority onboarding [CHAR LIMIT=75] -->
- <string name="priority_onboarding_title">Conversation set to priority</string>
- <!-- Text explaining that the following actions are the behaviors of priority conversations.
- E.g. priority conversations will show at the top of the conversation section [CHAR LIMIT=75] -->
- <string name="priority_onboarding_behavior">Priority conversations</string>
- <!-- Text explaining that priority conversations show at the top of the conversation section [CHAR LIMIT=120] -->
- <string name="priority_onboarding_show_at_top_text">These conversations are shown at the top of your list and can always reach you when Priority mode is on</string>
- <!-- Text explaining that priority conversations show an avatar on the lock screen [CHAR LIMIT=120] -->
- <string name="priority_onboarding_show_avatar_text">Profile pictures are shown on the lock screen</string>
- <!-- Text explaining that priority conversations will appear as a bubble [CHAR LIMIT=120] -->
- <string name="priority_onboarding_appear_as_bubble_text">You can easily find these conversations in bubbles on your Home screen</string>
- <!-- Text explaining that priority conversations can interrupt DnD settings [CHAR LIMIT=120] -->
- <string name="priority_onboarding_ignores_dnd_text">Interrupt Do Not Disturb</string>
- <!-- Title for the affirmative button [CHAR LIMIT=50] -->
- <string name="priority_onboarding_done_button_title">Got it</string>
- <!-- Title for the settings button button [CHAR LIMIT=50] -->
- <string name="priority_onboarding_settings_button_title">Settings</string>
-
<!-- Window Magnification strings -->
<!-- Title for Magnification Window [CHAR LIMIT=NONE] -->
<string name="magnification_window_title">Magnification Window</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index ac9ced93f2df..aa1f954cb27a 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<resources xmlns:android="http://schemas.android.com/apk/res/android">
+<resources xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
<style name="ClearAllButtonDefaultMargins">
<item name="android:layout_marginStart">0dp</item>
<item name="android:layout_marginTop">0dp</item>
@@ -609,12 +610,54 @@
<item name="android:elevation">10dp</item>
</style>
- <style name="MediaPlayer.Button" parent="@android:style/Widget.Material.Button.Borderless.Small">
+ <!-- Media controls always have light background -->
+ <style name="MediaPlayer" parent="@*android:style/Theme.DeviceDefault.Light">
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:backgroundTint">@android:color/system_accent2_50</item>
+ </style>
+
+ <style name="MediaPlayer.ProgressBar" parent="@android:style/Widget.ProgressBar.Horizontal">
+ <item name="android:thumbTint">?android:attr/textColorPrimary</item>
+ <item name="android:progressTint">?android:attr/textColorPrimary</item>
+ <item name="android:progressBackgroundTint">?android:attr/textColorTertiary</item>
+ <item name="android:clickable">true</item>
+ <item name="android:splitTrack">false</item>
+ </style>
+
+ <style name="MediaPlayer.Subtitle" parent="MediaPlayer">
+ <item name="android:textColor">?android:attr/textColorSecondary</item>
+ </style>
+
+ <style name="MediaPlayer.Action" parent="@android:style/Widget.Material.Button.Borderless.Small">
<item name="android:background">@drawable/qs_media_light_source</item>
<item name="android:tint">?android:attr/textColorPrimary</item>
<item name="android:stateListAnimator">@anim/media_button_state_list_animator</item>
</style>
+ <style name="MediaPlayer.OutlineButton">
+ <item name="android:background">@drawable/qs_media_button_background</item>
+ <item name="android:textColor">?android:attr/textColorPrimary</item>
+ <item name="android:backgroundTint">?androidprv:attr/colorAccentPrimaryVariant</item>
+ <item name="android:fontFamily">@*android:string/config_headlineFontFamilyMedium</item>
+ </style>
+
+ <style name="MediaPlayer.SolidButton">
+ <item name="android:backgroundTint">?android:attr/colorAccent</item>
+ <item name="android:tint">?android:attr/colorPrimary</item>
+ <item name="android:textColor">?android:attr/colorPrimary</item>
+ </style>
+
+ <style name="MediaPlayer.AppIcon">
+ <item name="android:background">@drawable/qs_media_icon_background</item>
+ <item name="android:backgroundTint">?android:attr/colorPrimary</item>
+ <item name="android:tint">?android:attr/colorAccent</item>
+ </style>
+
+ <style name="MediaPlayer.Album">
+ <item name="android:backgroundTint">?androidprv:attr/colorAccentSecondary</item>
+
+ </style>
+
<!-- Used to style charging animation AVD animation -->
<style name="ChargingAnim" />
diff --git a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
index afd800b106c3..31a924cf4892 100644
--- a/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_collapsed.xml
@@ -22,8 +22,8 @@
android:id="@+id/recommendation_card_icon"
android:layout_width="@dimen/qs_aa_media_rec_header_icon_size"
android:layout_height="@dimen/qs_aa_media_rec_header_icon_size"
- android:layout_marginTop="@dimen/qs_aa_media_rec_header_icon_padding"
- android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_padding"
+ android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_start_margin"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/media_vertical_start_guideline"
@@ -33,7 +33,7 @@
android:id="@+id/recommendation_card_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_padding"
+ android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_start_margin"
app:layout_constraintTop_toBottomOf="@id/recommendation_card_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/media_vertical_start_guideline"
@@ -45,9 +45,12 @@
android:layout_height="@dimen/qs_aa_media_rec_album_size"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
+ android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginBottom="@dimen/qs_media_padding"
app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
app:layout_constraintEnd_toStartOf="@id/media_cover2"
app:layout_constraintHorizontal_chainStyle="spread"
+ app:layout_constraintVertical_chainStyle="spread"
android:visibility="gone" />
<Constraint
@@ -64,6 +67,8 @@
android:id="@+id/media_cover2"
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginBottom="@dimen/qs_media_padding"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/media_cover1"
@@ -85,6 +90,8 @@
android:id="@+id/media_cover3"
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginBottom="@dimen/qs_media_padding"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/media_cover2"
@@ -112,7 +119,6 @@
app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
app:layout_constraintEnd_toStartOf="@id/media_cover5"
app:layout_constraintHorizontal_chainStyle="spread"
- app:layout_constraintHorizontal_bias="1"
android:visibility="gone" />
<Constraint
@@ -134,7 +140,6 @@
app:layout_constraintStart_toEndOf="@+id/media_cover4"
app:layout_constraintEnd_toStartOf="@+id/media_cover6"
app:layout_constraintHorizontal_chainStyle="spread"
- app:layout_constraintHorizontal_bias="1"
android:visibility="gone" />
<Constraint
diff --git a/packages/SystemUI/res/xml/media_recommendation_expanded.xml b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
index 04a4877f8660..1411030a7431 100644
--- a/packages/SystemUI/res/xml/media_recommendation_expanded.xml
+++ b/packages/SystemUI/res/xml/media_recommendation_expanded.xml
@@ -23,7 +23,7 @@
android:layout_width="@dimen/qs_aa_media_rec_header_icon_size"
android:layout_height="@dimen/qs_aa_media_rec_header_icon_size"
android:layout_marginTop="@dimen/qs_media_padding"
- android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_padding"
+ android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_start_margin"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/media_vertical_start_guideline"
@@ -33,7 +33,7 @@
android:id="@+id/recommendation_card_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_padding"
+ android:layout_marginStart="@dimen/qs_aa_media_rec_header_icon_start_margin"
app:layout_constraintTop_toBottomOf="@id/recommendation_card_icon"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@id/media_vertical_start_guideline"
@@ -44,11 +44,14 @@
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginBottom="@dimen/qs_aa_media_rec_album_vertical_margin"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/media_cover4"
+ app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
app:layout_constraintEnd_toStartOf="@id/media_cover2"
app:layout_constraintHorizontal_chainStyle="spread"
+ app:layout_constraintVertical_chainStyle="spread"
+ app:layout_constraintVertical_bias="0"
android:visibility="gone" />
<Constraint
@@ -66,11 +69,14 @@
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginBottom="@dimen/qs_aa_media_rec_album_vertical_margin"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/media_cover5"
+ app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
app:layout_constraintStart_toEndOf="@id/media_cover1"
app:layout_constraintEnd_toStartOf="@id/media_cover3"
app:layout_constraintHorizontal_chainStyle="spread"
+ app:layout_constraintVertical_chainStyle="spread"
+ app:layout_constraintVertical_bias="0"
android:visibility="gone" />
<Constraint
@@ -88,12 +94,15 @@
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginBottom="@dimen/qs_aa_media_rec_album_vertical_margin"
app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@+id/media_cover6"
+ app:layout_constraintBottom_toTopOf="@+id/media_horizontal_center_guideline"
app:layout_constraintStart_toEndOf="@id/media_cover2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_bias="1"
+ app:layout_constraintVertical_chainStyle="spread"
+ app:layout_constraintVertical_bias="0"
android:visibility="gone" />
<Constraint
@@ -110,14 +119,15 @@
android:id="@+id/media_cover4"
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
- android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginTop="@dimen/qs_aa_media_rec_album_vertical_margin"
android:layout_marginBottom="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@+id/media_cover1"
+ app:layout_constraintTop_toBottomOf="@+id/media_horizontal_center_guideline"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/media_vertical_start_guideline"
app:layout_constraintEnd_toStartOf="@id/media_cover5"
app:layout_constraintHorizontal_chainStyle="spread"
- app:layout_constraintHorizontal_bias="1"
+ app:layout_constraintVertical_chainStyle="spread"
+ app:layout_constraintVertical_bias="1"
android:visibility="gone" />
<Constraint
@@ -134,14 +144,15 @@
android:id="@+id/media_cover5"
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
- android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginTop="@dimen/qs_aa_media_rec_album_vertical_margin"
android:layout_marginBottom="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@+id/media_cover2"
+ app:layout_constraintTop_toBottomOf="@+id/media_horizontal_center_guideline"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/media_cover4"
app:layout_constraintEnd_toStartOf="@+id/media_cover6"
app:layout_constraintHorizontal_chainStyle="spread"
- app:layout_constraintHorizontal_bias="1"
+ app:layout_constraintVertical_chainStyle="spread"
+ app:layout_constraintVertical_bias="1"
android:visibility="gone" />
<Constraint
@@ -158,14 +169,16 @@
android:id="@+id/media_cover6"
android:layout_width="@dimen/qs_aa_media_rec_album_size"
android:layout_height="@dimen/qs_aa_media_rec_album_size"
- android:layout_marginTop="@dimen/qs_media_padding"
+ android:layout_marginTop="@dimen/qs_aa_media_rec_album_vertical_margin"
android:layout_marginBottom="@dimen/qs_media_padding"
- app:layout_constraintTop_toBottomOf="@id/media_cover3"
+ app:layout_constraintTop_toBottomOf="@id/media_horizontal_center_guideline"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@id/media_cover5"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_chainStyle="spread"
app:layout_constraintHorizontal_bias="1"
+ app:layout_constraintVertical_chainStyle="spread"
+ app:layout_constraintVertical_bias="1"
android:visibility="gone" />
<Constraint
diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml
index cce27e71dbd2..aa24bb49d868 100644
--- a/packages/SystemUI/res/xml/people_space_widget_info.xml
+++ b/packages/SystemUI/res/xml/people_space_widget_info.xml
@@ -26,5 +26,5 @@
android:previewLayout="@layout/people_space_placeholder_layout"
android:resizeMode="horizontal|vertical"
android:configure="com.android.systemui.people.PeopleSpaceActivity"
- android:initialLayout="@layout/people_space_initial_layout">
+ android:initialLayout="@layout/people_tile_empty_layout">
</appwidget-provider>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
index b7a2c64dd107..2325b554d507 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPINView.java
@@ -76,7 +76,7 @@ public class KeyguardPINView extends KeyguardPinBasedInputView {
protected void onFinishInflate() {
super.onFinishInflate();
- mContainer = findViewById(R.id.container);
+ mContainer = findViewById(R.id.pin_container);
mRow0 = findViewById(R.id.row0);
mRow1 = findViewById(R.id.row1);
mRow2 = findViewById(R.id.row2);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
index d4513384c569..98e7fb48b7a6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardPatternView.java
@@ -97,7 +97,7 @@ public class KeyguardPatternView extends KeyguardInputView
mLockPatternView = findViewById(R.id.lockPatternView);
mEcaView = findViewById(R.id.keyguard_selector_fade_container);
- mContainer = findViewById(R.id.container);
+ mContainer = findViewById(R.id.pattern_container);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/Prefs.java b/packages/SystemUI/src/com/android/systemui/Prefs.java
index f28d1137f3e7..7f183798709c 100644
--- a/packages/SystemUI/src/com/android/systemui/Prefs.java
+++ b/packages/SystemUI/src/com/android/systemui/Prefs.java
@@ -73,8 +73,7 @@ public final class Prefs {
Key.TOUCHED_RINGER_TOGGLE,
Key.HAS_SEEN_ODI_CAPTIONS_TOOLTIP,
Key.HAS_SEEN_REVERSE_BOTTOM_SHEET,
- Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT,
- Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S
+ Key.CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT
})
// TODO: annotate these with their types so {@link PrefsCommandLine} can know how to set them
public @interface Key {
@@ -123,8 +122,6 @@ public final class Prefs {
String HAS_SEEN_ODI_CAPTIONS_TOOLTIP = "HasSeenODICaptionsTooltip";
String HAS_SEEN_REVERSE_BOTTOM_SHEET = "HasSeenReverseBottomSheet";
String CONTROLS_STRUCTURE_SWIPE_TOOLTIP_COUNT = "ControlsStructureSwipeTooltipCount";
- /** Tracks whether the user has seen the onboarding screen for priority conversations */
- String HAS_SEEN_PRIORITY_ONBOARDING_IN_S = "HasUserSeenPriorityOnboardingInS";
}
public static boolean getBoolean(Context context, @Key String key, boolean defaultValue) {
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
index 58881d9a33f4..c821d100f553 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/BrightLineFalsingManager.java
@@ -35,7 +35,6 @@ import com.android.systemui.dagger.qualifiers.TestHarness;
import com.android.systemui.dock.DockManager;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;
-import com.android.systemui.util.sensors.ThresholdSensor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -317,7 +316,7 @@ public class BrightLineFalsingManager implements FalsingManager {
}
@Override
- public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
+ public void onProximityEvent(ProximityEvent proximityEvent) {
// TODO: some of these classifiers might allow us to abort early, meaning we don't have to
// make these calls.
mClassifiers.forEach((classifier) -> classifier.onProximityEvent(proximityEvent));
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
index 81b9f66e9bc3..d75752841023 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingClassifier.java
@@ -18,7 +18,7 @@ package com.android.systemui.classifier;
import android.view.MotionEvent;
-import com.android.systemui.util.sensors.ProximitySensor;
+import com.android.systemui.plugins.FalsingManager;
import java.util.List;
@@ -110,7 +110,7 @@ public abstract class FalsingClassifier {
/**
* Called when a ProximityEvent occurs (change in near/far).
*/
- void onProximityEvent(ProximitySensor.ThresholdSensorEvent proximityEvent) {}
+ void onProximityEvent(FalsingManager.ProximityEvent proximityEvent) {}
/**
* The phone screen has turned on and we need to begin falsing detection.
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
index 94e5c8ad1536..0f202b085851 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingCollectorImpl.java
@@ -361,7 +361,7 @@ class FalsingCollectorImpl implements FalsingCollector {
private void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
// TODO: some of these classifiers might allow us to abort early, meaning we don't have to
// make these calls.
- mFalsingManager.onProximityEvent(proximityEvent);
+ mFalsingManager.onProximityEvent(new ProximityEventImpl(proximityEvent));
}
@@ -374,4 +374,21 @@ class FalsingCollectorImpl implements FalsingCollector {
Log.d(TAG, msg, throwable);
}
}
+
+ private static class ProximityEventImpl implements FalsingManager.ProximityEvent {
+ private ThresholdSensor.ThresholdSensorEvent mThresholdSensorEvent;
+
+ ProximityEventImpl(ThresholdSensor.ThresholdSensorEvent thresholdSensorEvent) {
+ mThresholdSensorEvent = thresholdSensorEvent;
+ }
+ @Override
+ public boolean getCovered() {
+ return mThresholdSensorEvent.getBelow();
+ }
+
+ @Override
+ public long getTimestampNs() {
+ return mThresholdSensorEvent.getTimestampNs();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
index e8445d40836e..ee69e277cc46 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerFake.java
@@ -20,7 +20,6 @@ import android.net.Uri;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.plugins.FalsingManager;
-import com.android.systemui.util.sensors.ThresholdSensor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -133,7 +132,7 @@ public class FalsingManagerFake implements FalsingManager {
}
@Override
- public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
+ public void onProximityEvent(ProximityEvent proximityEvent) {
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index 6b819fbbbcf1..ee0dba0a5087 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -31,7 +31,6 @@ import com.android.systemui.plugins.FalsingPlugin;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.util.DeviceConfigProxy;
-import com.android.systemui.util.sensors.ThresholdSensor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -186,7 +185,7 @@ public class FalsingManagerProxy implements FalsingManager, Dumpable {
}
@Override
- public void onProximityEvent(ThresholdSensor.ThresholdSensorEvent proximityEvent) {
+ public void onProximityEvent(ProximityEvent proximityEvent) {
mInternalFalsingManager.onProximityEvent(proximityEvent);
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
index 72d4303dc0ef..32d9ca59951d 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
@@ -25,8 +25,8 @@ import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import android.provider.DeviceConfig;
import android.view.MotionEvent;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.util.DeviceConfigProxy;
-import com.android.systemui.util.sensors.ProximitySensor;
import java.util.Locale;
@@ -107,11 +107,11 @@ class ProximityClassifier extends FalsingClassifier {
@Override
public void onProximityEvent(
- ProximitySensor.ThresholdSensorEvent proximityEvent) {
- boolean near = proximityEvent.getBelow();
+ FalsingManager.ProximityEvent proximityEvent) {
+ boolean covered = proximityEvent.getCovered();
long timestampNs = proximityEvent.getTimestampNs();
- logDebug("Sensor is: " + near + " at time " + timestampNs);
- update(near, timestampNs);
+ logDebug("Sensor is: " + covered + " at time " + timestampNs);
+ update(covered, timestampNs);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
index 2a7023a58637..0cf3333d12a6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DefaultBroadcastReceiverBinder.java
@@ -20,6 +20,7 @@ import android.content.BroadcastReceiver;
import com.android.systemui.media.dialog.MediaOutputDialogReceiver;
import com.android.systemui.people.widget.PeopleSpaceWidgetPinnedReceiver;
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
import com.android.systemui.screenshot.ActionProxyReceiver;
import com.android.systemui.screenshot.DeleteScreenshotReceiver;
import com.android.systemui.screenshot.SmartActionsReceiver;
@@ -79,4 +80,13 @@ public abstract class DefaultBroadcastReceiverBinder {
public abstract BroadcastReceiver bindPeopleSpaceWidgetPinnedReceiver(
PeopleSpaceWidgetPinnedReceiver broadcastReceiver);
+ /**
+ *
+ */
+ @Binds
+ @IntoMap
+ @ClassKey(PeopleSpaceWidgetProvider.class)
+ public abstract BroadcastReceiver bindPeopleSpaceWidgetProvider(
+ PeopleSpaceWidgetProvider broadcastReceiver);
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
index 8e4e3081aff2..c04201caa182 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SysUIComponent.java
@@ -23,6 +23,7 @@ import com.android.systemui.InitController;
import com.android.systemui.SystemUIAppComponentFactory;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.keyguard.KeyguardSliceProvider;
+import com.android.systemui.people.PeopleProvider;
import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.util.InjectionInflationController;
import com.android.wm.shell.ShellCommandHandler;
@@ -156,4 +157,9 @@ public interface SysUIComponent {
* Member injection into the supplied argument.
*/
void inject(ClockOptionsProvider clockOptionsProvider);
+
+ /**
+ * Member injection into the supplied argument.
+ */
+ void inject(PeopleProvider peopleProvider);
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 8d9a4be30ab6..24503675ae36 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -3,7 +3,6 @@ package com.android.systemui.media
import android.app.smartspace.SmartspaceTarget
import android.content.Context
import android.content.Intent
-import android.content.res.ColorStateList
import android.content.res.Configuration
import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS
import android.util.Log
@@ -20,6 +19,7 @@ import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.qs.PageIndicator
+import com.android.systemui.shared.system.SysUiStatsLog
import com.android.systemui.statusbar.notification.collection.legacy.VisualStabilityManager
import com.android.systemui.statusbar.policy.ConfigurationController
import com.android.systemui.util.Utils
@@ -115,7 +115,6 @@ class MediaCarouselController @Inject constructor(
private var needsReordering: Boolean = false
private var keysNeedRemoval = mutableSetOf<String>()
private var bgColor = getBackgroundColor()
- private var fgColor = getForegroundColor()
private var isRtl: Boolean = false
set(value) {
if (value != field) {
@@ -156,6 +155,13 @@ class MediaCarouselController @Inject constructor(
}
}
+ var visibleToUser: Boolean = false
+ set(value) {
+ if (field != value) {
+ field = value
+ }
+ }
+
init {
mediaFrame = inflateMediaCarousel()
mediaCarousel = mediaFrame.requireViewById(R.id.media_carousel_scroller)
@@ -203,6 +209,9 @@ class MediaCarouselController @Inject constructor(
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
Log.d(TAG, "My Smartspace media update is here")
addSmartspaceMediaRecommendations(key, data)
+ if (visibleToUser) {
+ logSmartspaceImpression()
+ }
}
override fun onMediaDataRemoved(key: String) {
@@ -265,10 +274,6 @@ class MediaCarouselController @Inject constructor(
}
private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData) {
- data.actions.forEach {
- it.icon?.setTintList(ColorStateList.valueOf(fgColor))
- }
- data.appIcon?.setTintList(ColorStateList.valueOf(fgColor))
val dataCopy = data.copy(backgroundColor = bgColor)
val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey)
if (existingPlayer == null) {
@@ -317,7 +322,7 @@ class MediaCarouselController @Inject constructor(
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
- newRecs.bindRecommendation(data, fgColor, bgColor)
+ newRecs.bindRecommendation(data, bgColor)
MediaPlayerData.addMediaPlayer(key, newRecs)
updatePlayerToState(newRecs, noAnimation = true)
reorderAllPlayers()
@@ -357,8 +362,6 @@ class MediaCarouselController @Inject constructor(
private fun recreatePlayers() {
bgColor = getBackgroundColor()
- fgColor = getForegroundColor()
- pageIndicator.tintList = ColorStateList.valueOf(fgColor)
MediaPlayerData.mediaData().forEach { (key, data) ->
removePlayer(key, dismissMediaData = false)
@@ -370,11 +373,6 @@ class MediaCarouselController @Inject constructor(
return context.getColor(android.R.color.system_accent2_50)
}
- private fun getForegroundColor(): Int {
- return com.android.settingslib.Utils.getColorAttr(context,
- com.android.internal.R.attr.textColorPrimary).defaultColor
- }
-
private fun updatePageIndicator() {
val numPages = mediaContent.getChildCount()
pageIndicator.setNumPages(numPages)
@@ -567,6 +565,29 @@ class MediaCarouselController @Inject constructor(
mediaCarouselScrollHandler.playerWidthPlusPadding = playerWidthPlusPadding
}
}
+
+ /**
+ * Log the user impression for media card.
+ */
+ fun logSmartspaceImpression() {
+ MediaPlayerData.players().forEach {
+ // Log every impression of media recommendation card since it will only be shown
+ // for 1 minute after each connection.
+ if (it.recommendationViewHolder?.recommendations?.visibility == View.VISIBLE) {
+ /* ktlint-disable max-line-length */
+ SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
+ 800, // SMARTSPACE_CARD_SEEN
+ it.getInstanceId(),
+ SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__HEADPHONE_MEDIA_RECOMMENDATIONS,
+ it.getSurfaceForSmartspaceLogging(),
+ /* rank */ 0,
+ /* cardinality */ 1)
+ /* ktlint-disable max-line-length */
+ }
+
+ // TODO(shijieru): add logging for media control card
+ }
+ }
}
@VisibleForTesting
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index c713b229670d..1e9cc8cb08cc 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -55,6 +55,7 @@ import com.android.systemui.shared.system.SysUiStatsLog;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
import com.android.systemui.util.animation.TransitionLayout;
+import java.net.URISyntaxException;
import java.util.List;
import java.util.concurrent.Executor;
@@ -69,6 +70,9 @@ public class MediaControlPanel {
private static final String TAG = "MediaControlPanel";
private static final float DISABLED_ALPHA = 0.38f;
private static final String EXTRAS_MEDIA_SOURCE_PACKAGE_NAME = "package_name";
+ private static final String EXTRAS_SMARTSPACE_INTENT =
+ "com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT";
+ private static final String KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND";
private static final int MEDIA_RECOMMENDATION_ITEMS_PER_ROW = 3;
private static final int MEDIA_RECOMMENDATION_MAX_NUM = 6;
@@ -100,6 +104,8 @@ public class MediaControlPanel {
private int mBackgroundColor;
private int mDevicePadding;
private int mAlbumArtSize;
+ // Instance id for logging purpose.
+ private int mInstanceId;
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
/**
@@ -259,9 +265,6 @@ public class MediaControlPanel {
ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
- mPlayerViewHolder.getPlayer().setBackgroundTintList(
- ColorStateList.valueOf(mBackgroundColor));
-
// Click action
PendingIntent clickIntent = data.getClickIntent();
if (clickIntent != null) {
@@ -459,15 +462,12 @@ public class MediaControlPanel {
/** Bind this recommendation view based on the data given. */
public void bindRecommendation(
@NonNull SmartspaceTarget target,
- @NonNull int primaryColor,
@NonNull int backgroundColor) {
if (mRecommendationViewHolder == null) {
return;
}
- mRecommendationViewHolder.getCardIcon().setColorFilter(primaryColor);
- mRecommendationViewHolder.getCardText().setTextColor(primaryColor);
-
+ mInstanceId = target.getSmartspaceTargetId().hashCode();
mRecommendationViewHolder.getRecommendations()
.setBackgroundTintList(ColorStateList.valueOf(backgroundColor));
mBackgroundColor = backgroundColor;
@@ -486,8 +486,10 @@ public class MediaControlPanel {
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
MEDIA_RECOMMENDATION_MAX_NUM);
- for (int i = 0; i < mediaRecommendationNum; i++) {
- SmartspaceAction recommendation = mediaRecommendationList.get(i);
+ for (int itemIndex = 0, uiComponentIndex = 0;
+ itemIndex < mediaRecommendationNum && uiComponentIndex < mediaRecommendationNum;
+ itemIndex++) {
+ SmartspaceAction recommendation = mediaRecommendationList.get(itemIndex);
if (recommendation.getIcon() == null) {
Log.w(TAG, "No media cover is provided. Skipping this item...");
continue;
@@ -511,31 +513,38 @@ public class MediaControlPanel {
}
// Set up media source app's logo.
- ImageView mediaSourceLogoImageView = mediaLogoItems.get(i);
+ ImageView mediaSourceLogoImageView = mediaLogoItems.get(uiComponentIndex);
mediaSourceLogoImageView.setImageDrawable(icon);
// TODO(b/186699032): Tint the app logo using the accent color.
mediaSourceLogoImageView.setColorFilter(backgroundColor, PorterDuff.Mode.XOR);
// Set up media item cover.
- ImageView mediaCoverImageView = mediaCoverItems.get(i);
+ ImageView mediaCoverImageView = mediaCoverItems.get(uiComponentIndex);
mediaCoverImageView.setImageIcon(recommendation.getIcon());
// Set up the click listener if applicable.
setSmartspaceRecItemOnClickListener(
mediaCoverImageView,
recommendation,
- target.getSmartspaceTargetId(),
null);
- if (i < MEDIA_RECOMMENDATION_ITEMS_PER_ROW) {
- setVisibleAndAlpha(collapsedSet, mediaCoverItemsResIds.get(i), true);
- setVisibleAndAlpha(collapsedSet, mediaLogoItemsResIds.get(i), true);
+ if (uiComponentIndex < MEDIA_RECOMMENDATION_ITEMS_PER_ROW) {
+ setVisibleAndAlpha(collapsedSet,
+ mediaCoverItemsResIds.get(uiComponentIndex), true);
+ setVisibleAndAlpha(collapsedSet,
+ mediaLogoItemsResIds.get(uiComponentIndex), true);
} else {
- setVisibleAndAlpha(collapsedSet, mediaCoverItemsResIds.get(i), false);
- setVisibleAndAlpha(collapsedSet, mediaLogoItemsResIds.get(i), false);
+ setVisibleAndAlpha(collapsedSet,
+ mediaCoverItemsResIds.get(uiComponentIndex), false);
+ setVisibleAndAlpha(collapsedSet,
+ mediaLogoItemsResIds.get(uiComponentIndex), false);
}
- setVisibleAndAlpha(expandedSet, mediaCoverItemsResIds.get(i), true);
- setVisibleAndAlpha(expandedSet, mediaLogoItemsResIds.get(i), true);
+ setVisibleAndAlpha(expandedSet,
+ mediaCoverItemsResIds.get(uiComponentIndex), true);
+ setVisibleAndAlpha(expandedSet,
+ mediaLogoItemsResIds.get(uiComponentIndex), true);
+
+ uiComponentIndex++;
}
// Set up long press to show guts setting panel.
@@ -635,7 +644,6 @@ public class MediaControlPanel {
private void setSmartspaceRecItemOnClickListener(
@NonNull View view,
@NonNull SmartspaceAction action,
- @NonNull String targetId,
@Nullable View.OnClickListener callback) {
if (view == null || action == null || action.getIntent() == null) {
Log.e(TAG, "No tap action can be set up");
@@ -646,24 +654,60 @@ public class MediaControlPanel {
// When media recommendation card is shown, there could be only one card.
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
760, // SMARTSPACE_CARD_CLICK
- targetId.hashCode(),
+ mInstanceId,
SysUiStatsLog
.SMART_SPACE_CARD_REPORTED__CARD_TYPE__HEADPHONE_MEDIA_RECOMMENDATIONS,
- getSurfaceForSmartspaceLogging(mMediaViewController.getCurrentEndLocation()),
- /* rank */ 1,
+ getSurfaceForSmartspaceLogging(),
+ /* rank */ 0,
/* cardinality */ 1);
- mActivityStarter.postStartActivityDismissingKeyguard(
- action.getIntent(),
- 0 /* delay */,
- buildLaunchAnimatorController(mRecommendationViewHolder.getRecommendations()));
+ if (shouldSmartspaceRecItemOpenInForeground(action)) {
+ // Request to unlock the device if the activity needs to be opened in foreground.
+ mActivityStarter.postStartActivityDismissingKeyguard(
+ action.getIntent(),
+ 0 /* delay */,
+ buildLaunchAnimatorController(
+ mRecommendationViewHolder.getRecommendations()));
+ } else {
+ // Otherwise, open the activity in background directly.
+ view.getContext().startActivity(action.getIntent());
+ }
+
if (callback != null) {
callback.onClick(v);
}
});
}
- private int getSurfaceForSmartspaceLogging(int currentEndLocation) {
+ /** Returns if the Smartspace action will open the activity in foreground. */
+ private boolean shouldSmartspaceRecItemOpenInForeground(SmartspaceAction action) {
+ if (action == null || action.getIntent() == null
+ || action.getIntent().getExtras() == null) {
+ return false;
+ }
+
+ String intentString = action.getIntent().getExtras().getString(EXTRAS_SMARTSPACE_INTENT);
+ if (intentString == null) {
+ return false;
+ }
+
+ try {
+ Intent wrapperIntent = Intent.parseUri(intentString, Intent.URI_INTENT_SCHEME);
+ return wrapperIntent.getBooleanExtra(KEY_SMARTSPACE_OPEN_IN_FOREGROUND, false);
+ } catch (URISyntaxException e) {
+ Log.wtf(TAG, "Failed to create intent from URI: " + intentString);
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ /**
+ * Get the surface given the current end location for MediaViewController
+ * @return surface used for Smartspace logging
+ */
+ protected int getSurfaceForSmartspaceLogging() {
+ int currentEndLocation = mMediaViewController.getCurrentEndLocation();
if (currentEndLocation == MediaHierarchyManager.LOCATION_QQS
|| currentEndLocation == MediaHierarchyManager.LOCATION_QS) {
return SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE;
@@ -672,4 +716,8 @@ public class MediaControlPanel {
}
return SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__DEFAULT_SURFACE;
}
+
+ protected int getInstanceId() {
+ return mInstanceId;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
index 30bc8c1733bc..a80a410d32db 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
@@ -38,6 +38,7 @@ import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.animation.UniqueObjectHostView
import javax.inject.Inject
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
/**
* Similarly to isShown but also excludes views that have 0 alpha
@@ -73,7 +74,8 @@ class MediaHierarchyManager @Inject constructor(
private val bypassController: KeyguardBypassController,
private val mediaCarouselController: MediaCarouselController,
private val notifLockscreenUserManager: NotificationLockscreenUserManager,
- wakefulnessLifecycle: WakefulnessLifecycle
+ wakefulnessLifecycle: WakefulnessLifecycle,
+ private val statusBarKeyguardViewManager: StatusBarKeyguardViewManager
) {
/**
* The root overlay of the hierarchy. This is where the media notification is attached to
@@ -162,6 +164,26 @@ class MediaHierarchyManager @Inject constructor(
}
/**
+ * Is quick setting expanded?
+ */
+ var qsExpanded: Boolean = false
+ set(value) {
+ if (field != value) {
+ field = value
+ }
+ // Pull down shade from lock screen (exclude the case when shade is brought out by
+ // tapping twice on lock screen)
+ if (value && isLockScreenShadeVisibleToUser()) {
+ mediaCarouselController.logSmartspaceImpression()
+ }
+ // Release shade and back to lock screen
+ if (isLockScreenVisibleToUser()) {
+ mediaCarouselController.logSmartspaceImpression()
+ }
+ mediaCarouselController.visibleToUser = isVisibleToUser()
+ }
+
+ /**
* Is the shade currently collapsing from the expanded qs? If we're on the lockscreen and in qs,
* we wouldn't want to transition in that case.
*/
@@ -231,6 +253,11 @@ class MediaHierarchyManager @Inject constructor(
override fun onStateChanged(newState: Int) {
updateTargetState()
+ // Enters shade from lock screen
+ if (newState == StatusBarState.SHADE_LOCKED && isLockScreenShadeVisibleToUser()) {
+ mediaCarouselController.logSmartspaceImpression()
+ }
+ mediaCarouselController.visibleToUser = isVisibleToUser()
}
override fun onDozeAmountChanged(linear: Float, eased: Float) {
@@ -240,9 +267,27 @@ class MediaHierarchyManager @Inject constructor(
override fun onDozingChanged(isDozing: Boolean) {
if (!isDozing) {
dozeAnimationRunning = false
+ // Enters lock screen from screen off
+ if (isLockScreenVisibleToUser()) {
+ mediaCarouselController.logSmartspaceImpression()
+ }
} else {
updateDesiredLocation()
+ qsExpanded = false
}
+ mediaCarouselController.visibleToUser = isVisibleToUser()
+ }
+
+ override fun onExpandedChanged(isExpanded: Boolean) {
+ // Enters shade from home screen
+ if (isHomeScreenShadeVisibleToUser()) {
+ mediaCarouselController.logSmartspaceImpression()
+ }
+ // Back to lock screen from bouncer
+ if (isLockScreenVisibleToUser()) {
+ mediaCarouselController.logSmartspaceImpression()
+ }
+ mediaCarouselController.visibleToUser = isVisibleToUser()
}
})
@@ -622,6 +667,36 @@ class MediaHierarchyManager @Inject constructor(
return location
}
+ /**
+ * Returns true when the media card could be visible to the user if existed.
+ */
+ private fun isVisibleToUser(): Boolean {
+ return isLockScreenVisibleToUser() || isLockScreenShadeVisibleToUser() ||
+ isHomeScreenShadeVisibleToUser()
+ }
+
+ private fun isLockScreenVisibleToUser(): Boolean {
+ return !statusBarStateController.isDozing &&
+ !statusBarKeyguardViewManager.isBouncerShowing &&
+ statusBarStateController.state == StatusBarState.KEYGUARD &&
+ notifLockscreenUserManager.shouldShowLockscreenNotifications() &&
+ statusBarStateController.isExpanded &&
+ !qsExpanded
+ }
+
+ private fun isLockScreenShadeVisibleToUser(): Boolean {
+ return !statusBarStateController.isDozing &&
+ !statusBarKeyguardViewManager.isBouncerShowing &&
+ (statusBarStateController.state == StatusBarState.SHADE_LOCKED ||
+ (statusBarStateController.state == StatusBarState.KEYGUARD && qsExpanded))
+ }
+
+ private fun isHomeScreenShadeVisibleToUser(): Boolean {
+ return !statusBarStateController.isDozing &&
+ statusBarStateController.state == StatusBarState.SHADE &&
+ statusBarStateController.isExpanded
+ }
+
companion object {
/**
* Attached in expanded quick settings
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
index a9640566d531..0f6645641dda 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleProvider.java
@@ -30,12 +30,15 @@ import android.widget.RemoteViews;
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.shared.system.PeopleProviderUtils;
+import javax.inject.Inject;
+
/** API that returns a People Tile preview. */
public class PeopleProvider extends ContentProvider {
private static final String TAG = "PeopleProvider";
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
private static final String EMPTY_STRING = "";
+ @Inject
PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
@Override
@@ -76,7 +79,8 @@ public class PeopleProvider extends ContentProvider {
}
if (mPeopleSpaceWidgetManager == null) {
- mPeopleSpaceWidgetManager = new PeopleSpaceWidgetManager(getContext());
+ Log.e(TAG, "Could not initialize people widget manager");
+ return null;
}
RemoteViews view =
mPeopleSpaceWidgetManager.getPreview(shortcutId, userHandle, packageName, extras);
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index 99a17ffbe77a..a6c6103ae4c5 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -23,11 +23,11 @@ import static com.android.systemui.people.NotificationHelper.hasReadContactsPerm
import static com.android.systemui.people.NotificationHelper.isMissedCall;
import static com.android.systemui.people.NotificationHelper.shouldMatchNotificationByUri;
+import android.annotation.Nullable;
import android.app.Notification;
import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
import android.app.people.PeopleSpaceTile;
-import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
@@ -40,13 +40,11 @@ import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
-import android.os.Bundle;
import android.os.UserManager;
import android.provider.ContactsContract;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
-import android.widget.RemoteViews;
import androidx.preference.PreferenceManager;
@@ -56,7 +54,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.internal.util.ArrayUtils;
import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.R;
-import com.android.systemui.people.widget.AppWidgetOptionsHelper;
+import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -76,45 +74,17 @@ import java.util.stream.Stream;
public class PeopleSpaceUtils {
/** Turns on debugging information about People Space. */
public static final boolean DEBUG = true;
- private static final String TAG = "PeopleSpaceUtils";
public static final String PACKAGE_NAME = "package_name";
public static final String USER_ID = "user_id";
public static final String SHORTCUT_ID = "shortcut_id";
-
public static final String EMPTY_STRING = "";
public static final int INVALID_USER_ID = -1;
-
public static final PeopleTileKey EMPTY_KEY =
new PeopleTileKey(EMPTY_STRING, INVALID_USER_ID, EMPTY_STRING);
-
- /** Represents whether {@link StatusBarNotification} was posted or removed. */
- public enum NotificationAction {
- POSTED,
- REMOVED
- }
-
- /**
- * The UiEvent enums that this class can log.
- */
- public enum PeopleSpaceWidgetEvent implements UiEventLogger.UiEventEnum {
- @UiEvent(doc = "People space widget deleted")
- PEOPLE_SPACE_WIDGET_DELETED(666),
- @UiEvent(doc = "People space widget added")
- PEOPLE_SPACE_WIDGET_ADDED(667),
- @UiEvent(doc = "People space widget clicked to launch conversation")
- PEOPLE_SPACE_WIDGET_CLICKED(668);
-
- private final int mId;
-
- PeopleSpaceWidgetEvent(int id) {
- mId = id;
- }
-
- @Override
- public int getId() {
- return mId;
- }
- }
+ static final float STARRED_CONTACT = 1f;
+ static final float VALID_CONTACT = .5f;
+ static final float DEFAULT_AFFINITY = 0f;
+ private static final String TAG = "PeopleSpaceUtils";
/** Returns stored widgets for the conversation specified. */
public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) {
@@ -127,6 +97,10 @@ public class PeopleSpaceUtils {
/** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
int appWidgetId, Uri contactUri) {
+ if (!key.isValid()) {
+ Log.e(TAG, "Not storing for invalid key");
+ return;
+ }
// Write relevant persisted storage.
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
Context.MODE_PRIVATE);
@@ -201,7 +175,7 @@ public class PeopleSpaceUtils {
.collect(Collectors.toList());
}
- /** Returns the total messages in {@code notificationEntries}.*/
+ /** Returns the total messages in {@code notificationEntries}. */
public static int getMessagesCount(Set<NotificationEntry> notificationEntries) {
if (DEBUG) {
Log.d(TAG, "Calculating messages count from " + notificationEntries.size()
@@ -247,19 +221,34 @@ public class PeopleSpaceUtils {
* {@code messagesCount}.
*/
public static PeopleSpaceTile augmentTileFromNotification(Context context, PeopleSpaceTile tile,
- PeopleTileKey key, NotificationEntry notificationEntry, int messagesCount) {
+ PeopleTileKey key, NotificationEntry notificationEntry, int messagesCount,
+ Optional<Integer> appWidgetId) {
if (notificationEntry == null || notificationEntry.getSbn().getNotification() == null) {
if (DEBUG) Log.d(TAG, "Tile key: " + key.toString() + ". Notification is null");
return removeNotificationFields(tile);
}
Notification notification = notificationEntry.getSbn().getNotification();
+
+ PeopleSpaceTile.Builder updatedTile = tile.toBuilder();
+ String uriFromNotification = getContactUri(notificationEntry.getSbn());
+ if (appWidgetId.isPresent() && tile.getContactUri() == null && !TextUtils.isEmpty(
+ uriFromNotification)) {
+ if (DEBUG) Log.d(TAG, "Add uri from notification to tile: " + uriFromNotification);
+ Uri contactUri = Uri.parse(uriFromNotification);
+ // Update storage.
+ setSharedPreferencesStorageForTile(context, new PeopleTileKey(tile), appWidgetId.get(),
+ contactUri);
+ // Update cached tile in-memory.
+ updatedTile.setContactUri(contactUri);
+ }
+
boolean isMissedCall = isMissedCall(notification);
List<Notification.MessagingStyle.Message> messages =
getMessagingStyleMessages(notification);
if (!isMissedCall && ArrayUtils.isEmpty(messages)) {
if (DEBUG) Log.d(TAG, "Tile key: " + key.toString() + ". Notification has no content");
- return removeNotificationFields(tile);
+ return removeNotificationFields(updatedTile.build());
}
// messages are in chronological order from most recent to least.
@@ -276,8 +265,7 @@ public class PeopleSpaceUtils {
}
CharSequence sender = getSenderIfGroupConversation(notification, message);
- return tile
- .toBuilder()
+ return updatedTile
.setNotificationKey(notificationEntry.getSbn().getKey())
.setNotificationCategory(notification.category)
.setNotificationContent(content)
@@ -378,17 +366,18 @@ public class PeopleSpaceUtils {
context.getString(R.string.birthday_status));
}
- /** Calls to retrieve birthdays on a background thread. */
- public static void getBirthdaysOnBackgroundThread(Context context,
- AppWidgetManager appWidgetManager,
+ /** Calls to retrieve birthdays & contact affinity on a background thread. */
+ public static void getDataFromContactsOnBackgroundThread(Context context,
+ PeopleSpaceWidgetManager manager,
Map<Integer, PeopleSpaceTile> peopleSpaceTiles, int[] appWidgetIds) {
ThreadUtils.postOnBackgroundThread(
- () -> getBirthdays(context, appWidgetManager, peopleSpaceTiles, appWidgetIds));
+ () -> getDataFromContacts(context, manager, peopleSpaceTiles, appWidgetIds));
}
- /** Queries the Contacts DB for any birthdays today. */
+ /** Queries the Contacts DB for any birthdays today & updates contact affinity. */
@VisibleForTesting
- public static void getBirthdays(Context context, AppWidgetManager appWidgetManager,
+ public static void getDataFromContacts(Context context,
+ PeopleSpaceWidgetManager peopleSpaceWidgetManager,
Map<Integer, PeopleSpaceTile> widgetIdToTile, int[] appWidgetIds) {
if (DEBUG) Log.d(TAG, "Get birthdays");
if (appWidgetIds.length == 0) return;
@@ -397,28 +386,37 @@ public class PeopleSpaceUtils {
PeopleSpaceTile storedTile = widgetIdToTile.get(appWidgetId);
if (storedTile == null || storedTile.getContactUri() == null) {
if (DEBUG) Log.d(TAG, "No contact uri for: " + storedTile);
- removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
- continue;
- }
- if (lookupKeysWithBirthdaysToday.isEmpty()) {
- if (DEBUG) Log.d(TAG, "No birthdays today");
- removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
+ updateTileContactFields(peopleSpaceWidgetManager, context, storedTile,
+ appWidgetId, DEFAULT_AFFINITY, /* birthdayString= */ null);
continue;
}
- updateTileWithBirthday(context, appWidgetManager, lookupKeysWithBirthdaysToday,
+ updateTileWithBirthdayAndUpdateAffinity(context, peopleSpaceWidgetManager,
+ lookupKeysWithBirthdaysToday,
storedTile,
appWidgetId);
}
}
- /** Removes the birthday status if present in {@code storedTile} and pushes the update. */
- private static void removeBirthdayStatusIfPresent(AppWidgetManager appWidgetManager,
- Context context, PeopleSpaceTile storedTile, int appWidgetId) {
- if (hasBirthdayStatus(storedTile, context)) {
- if (DEBUG) Log.d(TAG, "Remove " + storedTile.getUserName() + "'s birthday");
- updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId,
+ /**
+ * Updates the {@code storedTile} with {@code affinity} & {@code birthdayString} if
+ * necessary.
+ */
+ private static void updateTileContactFields(PeopleSpaceWidgetManager manager,
+ Context context, PeopleSpaceTile storedTile, int appWidgetId, float affinity,
+ @Nullable String birthdayString) {
+ boolean outdatedBirthdayStatus = hasBirthdayStatus(storedTile, context)
+ && birthdayString == null;
+ boolean addBirthdayStatus = !hasBirthdayStatus(storedTile, context)
+ && birthdayString != null;
+ boolean shouldUpdate =
+ storedTile.getContactAffinity() != affinity || outdatedBirthdayStatus
+ || addBirthdayStatus;
+ if (shouldUpdate) {
+ if (DEBUG) Log.d(TAG, "Update " + storedTile.getUserName() + " from contacts");
+ manager.updateAppWidgetOptionsAndView(appWidgetId,
storedTile.toBuilder()
- .setBirthdayText(null)
+ .setBirthdayText(birthdayString)
+ .setContactAffinity(affinity)
.build());
}
}
@@ -427,7 +425,8 @@ public class PeopleSpaceUtils {
* Update {@code storedTile} if the contact has a lookup key matched to any {@code
* lookupKeysWithBirthdays}.
*/
- private static void updateTileWithBirthday(Context context, AppWidgetManager appWidgetManager,
+ private static void updateTileWithBirthdayAndUpdateAffinity(Context context,
+ PeopleSpaceWidgetManager manager,
List<String> lookupKeysWithBirthdaysToday, PeopleSpaceTile storedTile,
int appWidgetId) {
Cursor cursor = null;
@@ -437,14 +436,16 @@ public class PeopleSpaceUtils {
while (cursor != null && cursor.moveToNext()) {
String storedLookupKey = cursor.getString(
cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.LOOKUP_KEY));
+ float affinity = getContactAffinity(cursor);
if (!storedLookupKey.isEmpty() && lookupKeysWithBirthdaysToday.contains(
storedLookupKey)) {
if (DEBUG) Log.d(TAG, storedTile.getUserName() + "'s birthday today!");
- updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId,
- storedTile.toBuilder()
- .setBirthdayText(context.getString(R.string.birthday_status))
- .build());
- return;
+ updateTileContactFields(manager, context, storedTile, appWidgetId,
+ affinity, /* birthdayString= */
+ context.getString(R.string.birthday_status));
+ } else {
+ updateTileContactFields(manager, context, storedTile, appWidgetId,
+ affinity, /* birthdayString= */ null);
}
}
} catch (SQLException e) {
@@ -454,51 +455,20 @@ public class PeopleSpaceUtils {
cursor.close();
}
}
- removeBirthdayStatusIfPresent(appWidgetManager, context, storedTile, appWidgetId);
- }
-
- /** Updates the current widget view with provided {@link PeopleSpaceTile}. */
- public static void updateAppWidgetViews(AppWidgetManager appWidgetManager,
- Context context, int appWidgetId, PeopleSpaceTile tile, Bundle options) {
- if (tile == null) {
- if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + ". Tile is null, skipping update");
- return;
- }
- if (DEBUG) {
- Log.d(TAG, "Widget: " + appWidgetId + ", " + tile.getUserName() + ", "
- + tile.getPackageName() + ". Updating app widget view.");
- }
- RemoteViews views = new PeopleTileViewHelper(context, tile, appWidgetId,
- options).getViews();
-
- // Tell the AppWidgetManager to perform an update on the current app widget.
- appWidgetManager.updateAppWidget(appWidgetId, views);
- }
-
- /** Updates tile in app widget options and the current view. */
- public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
- Context context, int appWidgetId, PeopleSpaceTile tile) {
- if (tile == null) {
- if (DEBUG) {
- Log.w(TAG, "Widget: " + appWidgetId + "Tile is null, skipping storage and update.");
- }
- return;
- }
- Bundle options = AppWidgetOptionsHelper.setPeopleTile(appWidgetManager, appWidgetId, tile);
- updateAppWidgetViews(appWidgetManager, context, appWidgetId, tile, options);
}
- /** Wrapper around {@link #updateAppWidgetOptionsAndView} with optional tile as a parameter. */
- public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
- Context context, int appWidgetId, Optional<PeopleSpaceTile> optionalTile) {
- if (!optionalTile.isPresent()) {
- if (DEBUG) {
- Log.w(TAG, "Widget: " + appWidgetId
- + "Optional tile is not present, skipping storage and update.");
+ /** Pulls the contact affinity from {@code cursor}. */
+ private static float getContactAffinity(Cursor cursor) {
+ float affinity = VALID_CONTACT;
+ int starIdx = cursor.getColumnIndex(ContactsContract.Contacts.STARRED);
+ if (starIdx >= 0) {
+ boolean isStarred = cursor.getInt(starIdx) != 0;
+ if (isStarred) {
+ affinity = Math.max(affinity, STARRED_CONTACT);
}
- return;
}
- updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId, optionalTile.get());
+ if (DEBUG) Log.d(TAG, "Affinity is: " + affinity);
+ return affinity;
}
/**
@@ -546,4 +516,33 @@ public class PeopleSpaceUtils {
public static int getUserId(PeopleSpaceTile tile) {
return tile.getUserHandle().getIdentifier();
}
+
+ /** Represents whether {@link StatusBarNotification} was posted or removed. */
+ public enum NotificationAction {
+ POSTED,
+ REMOVED
+ }
+
+ /**
+ * The UiEvent enums that this class can log.
+ */
+ public enum PeopleSpaceWidgetEvent implements UiEventLogger.UiEventEnum {
+ @UiEvent(doc = "People space widget deleted")
+ PEOPLE_SPACE_WIDGET_DELETED(666),
+ @UiEvent(doc = "People space widget added")
+ PEOPLE_SPACE_WIDGET_ADDED(667),
+ @UiEvent(doc = "People space widget clicked to launch conversation")
+ PEOPLE_SPACE_WIDGET_CLICKED(668);
+
+ private final int mId;
+
+ PeopleSpaceWidgetEvent(int id) {
+ mId = id;
+ }
+
+ @Override
+ public int getId() {
+ return mId;
+ }
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
index a23db63a70fc..6980d723583b 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleTileViewHelper.java
@@ -30,6 +30,8 @@ import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MAX_WIDTH;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_HEIGHT;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
+import static com.android.systemui.people.PeopleSpaceUtils.STARRED_CONTACT;
+import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT;
import static com.android.systemui.people.PeopleSpaceUtils.convertDrawableToBitmap;
import static com.android.systemui.people.PeopleSpaceUtils.getUserId;
@@ -39,6 +41,8 @@ import android.app.people.ConversationStatus;
import android.app.people.PeopleSpaceTile;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
@@ -48,6 +52,7 @@ import android.icu.util.Measure;
import android.icu.util.MeasureUnit;
import android.net.Uri;
import android.os.Bundle;
+import android.os.UserHandle;
import android.text.TextUtils;
import android.util.IconDrawableFactory;
import android.util.Log;
@@ -57,6 +62,8 @@ import android.widget.RemoteViews;
import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.launcher3.icons.FastBitmapDrawable;
+import com.android.settingslib.Utils;
import com.android.systemui.R;
import com.android.systemui.people.widget.LaunchConversationActivity;
import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
@@ -142,7 +149,9 @@ public class PeopleTileViewHelper {
private int mMediumVerticalPadding;
private Context mContext;
+ @Nullable
private PeopleSpaceTile mTile;
+ private PeopleTileKey mKey;
private float mDensity;
private int mAppWidgetId;
private int mWidth;
@@ -152,10 +161,11 @@ public class PeopleTileViewHelper {
private Locale mLocale;
private NumberFormat mIntegerFormat;
- public PeopleTileViewHelper(Context context, PeopleSpaceTile tile,
- int appWidgetId, Bundle options) {
+ public PeopleTileViewHelper(Context context, @Nullable PeopleSpaceTile tile,
+ int appWidgetId, Bundle options, PeopleTileKey key) {
mContext = context;
mTile = tile;
+ mKey = key;
mAppWidgetId = appWidgetId;
mDensity = mContext.getResources().getDisplayMetrics().density;
int display = mContext.getResources().getConfiguration().orientation;
@@ -184,8 +194,19 @@ public class PeopleTileViewHelper {
* content, then birthdays, then the most recent status, and finally last interaction.
*/
private RemoteViews getViewForTile() {
- PeopleTileKey key = new PeopleTileKey(mTile);
- if (DEBUG) Log.d(TAG, "Creating view for tile key: " + key.toString());
+ if (DEBUG) Log.d(TAG, "Creating view for tile key: " + mKey.toString());
+ if (mTile == null || mTile.isPackageSuspended() || mTile.isUserQuieted()) {
+ if (DEBUG) Log.d(TAG, "Create empty view: " + mTile);
+ return createEmptyView();
+ }
+
+ boolean dndBlockingTileData = isDndBlockingTileData(mTile);
+ if (dndBlockingTileData) {
+ if (DEBUG) Log.d(TAG, "Create DND view: " + mTile.getNotificationPolicyState());
+ // TODO: Create DND view.
+ return createEmptyView();
+ }
+
if (Objects.equals(mTile.getNotificationCategory(), CATEGORY_MISSED_CALL)) {
if (DEBUG) Log.d(TAG, "Create missed call view");
return createMissedCallRemoteViews();
@@ -217,6 +238,58 @@ public class PeopleTileViewHelper {
return createLastInteractionRemoteViews();
}
+ private boolean isDndBlockingTileData(PeopleSpaceTile tile) {
+ int notificationPolicyState = tile.getNotificationPolicyState();
+ if ((notificationPolicyState & PeopleSpaceTile.SHOW_CONVERSATIONS) != 0) {
+ // Not in DND, or all conversations
+ if (DEBUG) Log.d(TAG, "Tile can show all data: " + tile.getUserName());
+ return false;
+ }
+ if ((notificationPolicyState & PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS) != 0
+ && tile.isImportantConversation()) {
+ if (DEBUG) Log.d(TAG, "Tile can show important: " + tile.getUserName());
+ return false;
+ }
+ if ((notificationPolicyState & PeopleSpaceTile.SHOW_STARRED_CONTACTS) != 0
+ && tile.getContactAffinity() == STARRED_CONTACT) {
+ if (DEBUG) Log.d(TAG, "Tile can show starred: " + tile.getUserName());
+ return false;
+ }
+ if ((notificationPolicyState & PeopleSpaceTile.SHOW_CONTACTS) != 0
+ && (tile.getContactAffinity() == VALID_CONTACT
+ || tile.getContactAffinity() == STARRED_CONTACT)) {
+ if (DEBUG) Log.d(TAG, "Tile can show contacts: " + tile.getUserName());
+ return false;
+ }
+ if (DEBUG) Log.d(TAG, "Tile can show if can bypass DND: " + tile.getUserName());
+ return !tile.canBypassDnd();
+ }
+
+ private RemoteViews createEmptyView() {
+ RemoteViews views = new RemoteViews(mContext.getPackageName(),
+ R.layout.people_tile_empty_layout);
+ Drawable appIcon = getAppBadge(mKey.getPackageName(), mKey.getUserId());
+ Bitmap appIconAsBitmap = convertDrawableToBitmap(appIcon);
+ FastBitmapDrawable drawable = new FastBitmapDrawable(
+ appIconAsBitmap);
+ drawable.setIsDisabled(true);
+ Bitmap convertedBitmap = convertDrawableToBitmap(drawable);
+ views.setImageViewBitmap(R.id.item, convertedBitmap);
+ return views;
+ }
+
+ private Drawable getAppBadge(String packageName, int userId) {
+ Drawable badge = null;
+ try {
+ final ApplicationInfo appInfo = mContext.getPackageManager().getApplicationInfoAsUser(
+ packageName, PackageManager.GET_META_DATA, userId);
+ badge = Utils.getBadgedIcon(mContext, appInfo);
+ } catch (PackageManager.NameNotFoundException e) {
+ badge = mContext.getPackageManager().getDefaultActivityIcon();
+ }
+ return badge;
+ }
+
private void setMaxLines(RemoteViews views, boolean showSender) {
int textSize = mLayoutSize == LAYOUT_LARGE ? getSizeInDp(
R.dimen.content_text_size_for_medium)
@@ -337,6 +410,9 @@ public class PeopleTileViewHelper {
private RemoteViews setCommonRemoteViewsFields(RemoteViews views,
int maxAvatarSize) {
try {
+ if (mTile == null) {
+ return views;
+ }
boolean isAvailable =
mTile.getStatuses() != null && mTile.getStatuses().stream().anyMatch(
c -> c.getAvailability() == AVAILABILITY_AVAILABLE);
@@ -367,13 +443,16 @@ public class PeopleTileViewHelper {
| Intent.FLAG_ACTIVITY_CLEAR_TASK
| Intent.FLAG_ACTIVITY_NO_HISTORY
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
- activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, mTile.getId());
+ activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_TILE_ID, mKey.getShortcutId());
activityIntent.putExtra(
- PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, mTile.getPackageName());
+ PeopleSpaceWidgetProvider.EXTRA_PACKAGE_NAME, mKey.getPackageName());
activityIntent.putExtra(PeopleSpaceWidgetProvider.EXTRA_USER_HANDLE,
- mTile.getUserHandle());
- activityIntent.putExtra(
- PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY, mTile.getNotificationKey());
+ new UserHandle(mKey.getUserId()));
+ if (mTile != null) {
+ activityIntent.putExtra(
+ PeopleSpaceWidgetProvider.EXTRA_NOTIFICATION_KEY,
+ mTile.getNotificationKey());
+ }
views.setOnClickPendingIntent(R.id.item, PendingIntent.getActivity(
mContext,
mAppWidgetId,
@@ -727,6 +806,9 @@ public class PeopleTileViewHelper {
c -> c.getActivity() == ACTIVITY_NEW_STORY);
Icon icon = tile.getUserIcon();
+ if (icon == null) {
+ return null;
+ }
PeopleStoryIconFactory storyIcon = new PeopleStoryIconFactory(context,
context.getPackageManager(),
IconDrawableFactory.newInstance(context, false),
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 64a6509ea0aa..ea1724f96669 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -17,6 +17,12 @@
package com.android.systemui.people.widget;
import static android.Manifest.permission.READ_CONTACTS;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.content.Intent.ACTION_BOOT_COMPLETED;
+import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
import static com.android.systemui.people.NotificationHelper.getContactUri;
import static com.android.systemui.people.NotificationHelper.getHighestPriorityNotification;
@@ -30,13 +36,12 @@ import static com.android.systemui.people.PeopleSpaceUtils.augmentTileFromNotifi
import static com.android.systemui.people.PeopleSpaceUtils.getMessagesCount;
import static com.android.systemui.people.PeopleSpaceUtils.getNotificationsByUri;
import static com.android.systemui.people.PeopleSpaceUtils.removeNotificationFields;
-import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
-import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.NotificationChannel;
+import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Person;
import android.app.people.ConversationChannel;
@@ -44,8 +49,11 @@ import android.app.people.IPeopleManager;
import android.app.people.PeopleManager;
import android.app.people.PeopleSpaceTile;
import android.appwidget.AppWidgetManager;
+import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -60,6 +68,8 @@ import android.preference.PreferenceManager;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
+import android.service.notification.ZenModeConfig;
+import android.text.TextUtils;
import android.util.Log;
import android.widget.RemoteViews;
@@ -67,8 +77,9 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
-import com.android.settingslib.utils.ThreadUtils;
-import com.android.systemui.Dependency;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.dagger.SysUISingleton;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.people.NotificationHelper;
import com.android.systemui.people.PeopleSpaceUtils;
import com.android.systemui.people.PeopleTileViewHelper;
@@ -85,15 +96,15 @@ import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.Executor;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.inject.Inject;
-import javax.inject.Singleton;
/** Manager for People Space widget. */
-@Singleton
+@SysUISingleton
public class PeopleSpaceWidgetManager {
private static final String TAG = "PeopleSpaceWidgetMgr";
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
@@ -107,12 +118,15 @@ public class PeopleSpaceWidgetManager {
private PeopleManager mPeopleManager;
private NotificationEntryManager mNotificationEntryManager;
private PackageManager mPackageManager;
- private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider;
private INotificationManager mINotificationManager;
private UserManager mUserManager;
+ private PeopleSpaceWidgetManager mManager;
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
+ private NotificationManager mNotificationManager;
+ private BroadcastDispatcher mBroadcastDispatcher;
+ private Executor mBgExecutor;
@GuardedBy("mLock")
- public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
+ public static Map<PeopleTileKey, TileConversationListener>
mListeners = new HashMap<>();
@GuardedBy("mLock")
@@ -120,46 +134,91 @@ public class PeopleSpaceWidgetManager {
// This is required because on notification removal, the contact Uri field is stripped and we
// only have the notification key to determine which widget IDs should be updated.
private Map<String, Set<String>> mNotificationKeyToWidgetIdsMatchedByUri = new HashMap<>();
- private boolean mIsForTesting;
+ private boolean mRegisteredReceivers;
@Inject
- public PeopleSpaceWidgetManager(Context context) {
+ public PeopleSpaceWidgetManager(Context context, LauncherApps launcherApps,
+ NotificationEntryManager notificationEntryManager,
+ PackageManager packageManager, UserManager userManager,
+ NotificationManager notificationManager, BroadcastDispatcher broadcastDispatcher,
+ @Background Executor bgExecutor) {
if (DEBUG) Log.d(TAG, "constructor");
mContext = context;
mAppWidgetManager = AppWidgetManager.getInstance(context);
mIPeopleManager = IPeopleManager.Stub.asInterface(
ServiceManager.getService(Context.PEOPLE_SERVICE));
- mLauncherApps = context.getSystemService(LauncherApps.class);
+ mLauncherApps = launcherApps;
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
- mPeopleManager = mContext.getSystemService(PeopleManager.class);
- mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
- mPackageManager = mContext.getPackageManager();
- mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider();
+ mPeopleManager = context.getSystemService(PeopleManager.class);
+ mNotificationEntryManager = notificationEntryManager;
+ mPackageManager = packageManager;
mINotificationManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
- mUserManager = context.getSystemService(UserManager.class);
+ mUserManager = userManager;
+ mNotificationManager = notificationManager;
+ mManager = this;
+ mBroadcastDispatcher = broadcastDispatcher;
+ mBgExecutor = bgExecutor;
+ }
+
+ /** Initializes {@PeopleSpaceWidgetManager}. */
+ public void init() {
+ synchronized (mLock) {
+ if (!mRegisteredReceivers) {
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
+ filter.addAction(ACTION_BOOT_COMPLETED);
+ filter.addAction(Intent.ACTION_LOCALE_CHANGED);
+ filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+ filter.addAction(Intent.ACTION_PACKAGES_SUSPENDED);
+ filter.addAction(Intent.ACTION_PACKAGES_UNSUSPENDED);
+ filter.addAction(Intent.ACTION_MANAGED_PROFILE_AVAILABLE);
+ filter.addAction(Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE);
+ filter.addAction(Intent.ACTION_USER_UNLOCKED);
+ mBroadcastDispatcher.registerReceiver(mBaseBroadcastReceiver, filter,
+ null /* executor */, UserHandle.ALL);
+ mRegisteredReceivers = true;
+ }
+ }
+ }
+
+ /** Listener for the shortcut data changes. */
+ public class TileConversationListener implements PeopleManager.ConversationListener {
+
+ @Override
+ public void onConversationUpdate(@NonNull ConversationChannel conversation) {
+ if (DEBUG) {
+ Log.d(TAG,
+ "Received updated conversation: "
+ + conversation.getShortcutInfo().getLabel());
+ }
+ updateWidgetsWithConversationChanged(conversation);
+ }
}
/**
- * AppWidgetManager setter used for testing.
+ * PeopleSpaceWidgetManager setter used for testing.
*/
@VisibleForTesting
- public void setAppWidgetManager(
+ PeopleSpaceWidgetManager(Context context,
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
PeopleManager peopleManager, LauncherApps launcherApps,
NotificationEntryManager notificationEntryManager, PackageManager packageManager,
- boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider,
- UserManager userManager, INotificationManager notificationManager) {
+ UserManager userManager, INotificationManager iNotificationManager,
+ NotificationManager notificationManager, @Background Executor executor) {
+ mContext = context;
mAppWidgetManager = appWidgetManager;
mIPeopleManager = iPeopleManager;
mPeopleManager = peopleManager;
mLauncherApps = launcherApps;
mNotificationEntryManager = notificationEntryManager;
mPackageManager = packageManager;
- mIsForTesting = isForTesting;
- mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider;
mUserManager = userManager;
- mINotificationManager = notificationManager;
+ mINotificationManager = iNotificationManager;
+ mNotificationManager = notificationManager;
+ mManager = this;
+ mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
+ mBgExecutor = executor;
}
/**
@@ -173,7 +232,7 @@ public class PeopleSpaceWidgetManager {
return;
}
- if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets");
+ if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets: " + widgetIds);
synchronized (mLock) {
updateSingleConversationWidgets(widgetIds);
}
@@ -191,16 +250,47 @@ public class PeopleSpaceWidgetManager {
for (int appWidgetId : appWidgetIds) {
PeopleSpaceTile tile = getTileForExistingWidget(appWidgetId);
if (tile == null) {
- if (DEBUG) Log.d(TAG, "Matching conversation not found for shortcut ID");
- //TODO: Delete app widget id when crash is fixed (b/172932636)
- continue;
+ Log.e(TAG, "Matching conversation not found for shortcut ID");
}
Bundle options = mAppWidgetManager.getAppWidgetOptions(appWidgetId);
- updateAppWidgetViews(mAppWidgetManager, mContext, appWidgetId, tile, options);
+ updateAppWidgetViews(appWidgetId, tile, options);
widgetIdToTile.put(appWidgetId, tile);
+ if (tile != null) {
+ registerConversationListenerIfNeeded(appWidgetId,
+ new PeopleTileKey(tile));
+ }
+ }
+ PeopleSpaceUtils.getDataFromContactsOnBackgroundThread(
+ mContext, mManager, widgetIdToTile, appWidgetIds);
+ }
+
+ /** Updates the current widget view with provided {@link PeopleSpaceTile}. */
+ private void updateAppWidgetViews(int appWidgetId, PeopleSpaceTile tile, Bundle options) {
+ PeopleTileKey key = getKeyFromStorageByWidgetId(appWidgetId);
+ if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + " for: " + key.toString());
+ if (!key.isValid()) {
+ Log.e(TAG, "Cannot update invalid widget");
+ return;
+ }
+ RemoteViews views = new PeopleTileViewHelper(mContext, tile, appWidgetId,
+ options, key).getViews();
+
+ // Tell the AppWidgetManager to perform an update on the current app widget.
+ mAppWidgetManager.updateAppWidget(appWidgetId, views);
+ }
+
+ /** Updates tile in app widget options and the current view. */
+ public void updateAppWidgetOptionsAndViewOptional(int appWidgetId,
+ Optional<PeopleSpaceTile> tile) {
+ if (tile.isPresent()) {
+ updateAppWidgetOptionsAndView(appWidgetId, tile.get());
}
- PeopleSpaceUtils.getBirthdaysOnBackgroundThread(
- mContext, mAppWidgetManager, widgetIdToTile, appWidgetIds);
+ }
+
+ /** Updates tile in app widget options and the current view. */
+ public void updateAppWidgetOptionsAndView(int appWidgetId, PeopleSpaceTile tile) {
+ Bundle options = AppWidgetOptionsHelper.setPeopleTile(mAppWidgetManager, appWidgetId, tile);
+ updateAppWidgetViews(appWidgetId, tile, options);
}
/**
@@ -226,7 +316,7 @@ public class PeopleSpaceWidgetManager {
widgetSp.getInt(USER_ID, INVALID_USER_ID),
widgetSp.getString(PACKAGE_NAME, EMPTY_STRING));
- return getTileFromPersistentStorage(key);
+ return getTileFromPersistentStorage(key, appWidgetId);
}
/**
@@ -234,7 +324,7 @@ public class PeopleSpaceWidgetManager {
* If a {@link PeopleTileKey} is not provided, fetch one from {@link SharedPreferences}.
*/
@Nullable
- public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key) {
+ public PeopleSpaceTile getTileFromPersistentStorage(PeopleTileKey key, int appWidgetId) {
if (!key.isValid()) {
Log.e(TAG, "PeopleTileKey invalid: " + key.toString());
return null;
@@ -254,7 +344,22 @@ public class PeopleSpaceWidgetManager {
return null;
}
- return new PeopleSpaceTile.Builder(channel, mLauncherApps).build();
+ // Get tile from shortcut & conversation storage.
+ PeopleSpaceTile.Builder storedTile = new PeopleSpaceTile.Builder(channel,
+ mLauncherApps);
+ if (storedTile == null) {
+ return storedTile.build();
+ }
+
+ // Supplement with our storage.
+ String contactUri = mSharedPrefs.getString(String.valueOf(appWidgetId), null);
+ if (contactUri != null && storedTile.build().getContactUri() == null) {
+ if (DEBUG) Log.d(TAG, "Restore contact uri from storage: " + contactUri);
+ storedTile.setContactUri(Uri.parse(contactUri));
+ }
+
+ // Add current state.
+ return updateWithCurrentState(storedTile.build(), ACTION_BOOT_COMPLETED);
} catch (Exception e) {
Log.e(TAG, "Failed to retrieve conversation for tile: " + e);
return null;
@@ -275,11 +380,7 @@ public class PeopleSpaceWidgetManager {
Log.d(TAG, "Notification removed, key: " + sbn.getKey());
}
}
- if (mIsForTesting) {
- updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction);
- return;
- }
- ThreadUtils.postOnBackgroundThread(
+ mBgExecutor.execute(
() -> updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction));
}
@@ -331,8 +432,7 @@ public class PeopleSpaceWidgetManager {
.collect(Collectors.toMap(
Function.identity(),
id -> getAugmentedTileForExistingWidget(id, groupedNotifications)))
- .forEach((id, tile) ->
- updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, id, tile));
+ .forEach((id, tile) -> updateAppWidgetOptionsAndViewOptional(id, tile));
} catch (Exception e) {
Log.e(TAG, "Exception updating widgets: " + e);
}
@@ -341,16 +441,20 @@ public class PeopleSpaceWidgetManager {
/**
* Augments {@code tile} based on notifications returned from {@code notificationEntryManager}.
*/
- public PeopleSpaceTile augmentTileFromNotificationEntryManager(PeopleSpaceTile tile) {
+ public PeopleSpaceTile augmentTileFromNotificationEntryManager(PeopleSpaceTile tile,
+ Optional<Integer> appWidgetId) {
PeopleTileKey key = new PeopleTileKey(tile);
- Log.d(TAG, "Augmenting tile from NotificationEntryManager widget: " + key.toString());
+ if (DEBUG) {
+ Log.d(TAG,
+ "Augmenting tile from NotificationEntryManager widget: " + key.toString());
+ }
Map<PeopleTileKey, Set<NotificationEntry>> notifications =
getGroupedConversationNotifications();
String contactUri = null;
if (tile.getContactUri() != null) {
contactUri = tile.getContactUri().toString();
}
- return augmentTileFromNotifications(tile, key, contactUri, notifications);
+ return augmentTileFromNotifications(tile, key, contactUri, notifications, appWidgetId);
}
/** Returns active and pending notifications grouped by {@link PeopleTileKey}. */
@@ -380,9 +484,11 @@ public class PeopleSpaceWidgetManager {
/** Augments {@code tile} based on {@code notifications}, matching {@code contactUri}. */
public PeopleSpaceTile augmentTileFromNotifications(PeopleSpaceTile tile, PeopleTileKey key,
- String contactUri, Map<PeopleTileKey, Set<NotificationEntry>> notifications) {
+ String contactUri,
+ Map<PeopleTileKey, Set<NotificationEntry>> notifications,
+ Optional<Integer> appWidgetId) {
if (DEBUG) Log.d(TAG, "Augmenting tile from notifications. Tile key: " + key.toString());
- boolean hasReadContactsPermission = mPackageManager.checkPermission(READ_CONTACTS,
+ boolean hasReadContactsPermission = mPackageManager.checkPermission(READ_CONTACTS,
tile.getPackageName()) == PackageManager.PERMISSION_GRANTED;
List<NotificationEntry> notificationsByUri = new ArrayList<>();
@@ -413,7 +519,8 @@ public class PeopleSpaceWidgetManager {
NotificationEntry highestPriority = getHighestPriorityNotification(allNotifications);
if (DEBUG) Log.d(TAG, "Augmenting tile from notification, key: " + key.toString());
- return augmentTileFromNotification(mContext, tile, key, highestPriority, messagesCount);
+ return augmentTileFromNotification(mContext, tile, key, highestPriority, messagesCount,
+ appWidgetId);
}
/** Returns an augmented tile for an existing widget. */
@@ -434,7 +541,8 @@ public class PeopleSpaceWidgetManager {
PeopleTileKey key = new PeopleTileKey(tile);
if (DEBUG) Log.d(TAG, "Existing widget: " + widgetId + ". Tile key: " + key.toString());
return Optional.ofNullable(
- augmentTileFromNotifications(tile, key, contactUriString, notifications));
+ augmentTileFromNotifications(tile, key, contactUriString, notifications,
+ Optional.of(widgetId)));
}
/** Returns stored widgets for the conversation specified. */
@@ -552,10 +660,8 @@ public class PeopleSpaceWidgetManager {
.setStatuses(conversation.getStatuses())
.setLastInteractionTimestamp(conversation.getLastEventTimestamp())
.setIsImportantConversation(conversation.getParentNotificationChannel() != null
- && conversation.getParentNotificationChannel().isImportantConversation())
- .build();
- updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, appWidgetId,
- updatedTile.build());
+ && conversation.getParentNotificationChannel().isImportantConversation());
+ updateAppWidgetOptionsAndView(appWidgetId, updatedTile.build());
}
/**
@@ -640,11 +746,11 @@ public class PeopleSpaceWidgetManager {
/** Adds a widget based on {@code key} mapped to {@code appWidgetId}. */
public void addNewWidget(int appWidgetId, PeopleTileKey key) {
if (DEBUG) Log.d(TAG, "addNewWidget called with key for appWidgetId: " + appWidgetId);
- PeopleSpaceTile tile = getTileFromPersistentStorage(key);
+ PeopleSpaceTile tile = getTileFromPersistentStorage(key, appWidgetId);
if (tile == null) {
return;
}
- tile = augmentTileFromNotificationEntryManager(tile);
+ tile = augmentTileFromNotificationEntryManager(tile, Optional.of(appWidgetId));
PeopleTileKey existingKeyIfStored;
synchronized (mLock) {
@@ -665,6 +771,8 @@ public class PeopleSpaceWidgetManager {
PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId,
tile.getContactUri());
}
+ if (DEBUG) Log.d(TAG, "Ensure listener is registered for widget: " + appWidgetId);
+ registerConversationListenerIfNeeded(appWidgetId, key);
try {
if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + key.toString());
mLauncherApps.cacheShortcuts(tile.getPackageName(),
@@ -674,23 +782,17 @@ public class PeopleSpaceWidgetManager {
Log.w(TAG, "Exception caching shortcut:" + e);
}
- PeopleSpaceUtils.updateAppWidgetOptionsAndView(
- mAppWidgetManager, mContext, appWidgetId, tile);
- mPeopleSpaceWidgetProvider.onUpdate(mContext, mAppWidgetManager, new int[]{appWidgetId});
+ updateAppWidgetOptionsAndView(appWidgetId, tile);
}
/** Registers a conversation listener for {@code appWidgetId} if not already registered. */
- public void registerConversationListenerIfNeeded(int widgetId,
- PeopleSpaceWidgetProvider.TileConversationListener newListener) {
+ public void registerConversationListenerIfNeeded(int widgetId, PeopleTileKey key) {
// Retrieve storage needed for registration.
- PeopleTileKey key;
- synchronized (mLock) {
- key = getKeyFromStorageByWidgetId(widgetId);
- if (!key.isValid()) {
- if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
- return;
- }
+ if (!key.isValid()) {
+ if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId);
+ return;
}
+ TileConversationListener newListener = new TileConversationListener();
synchronized (mListeners) {
if (mListeners.containsKey(key)) {
if (DEBUG) Log.d(TAG, "Already registered listener");
@@ -760,7 +862,7 @@ public class PeopleSpaceWidgetManager {
/** Unregisters the conversation listener for {@code appWidgetId}. */
private void unregisterConversationListener(PeopleTileKey key, int appWidgetId) {
- PeopleSpaceWidgetProvider.TileConversationListener registeredListener;
+ TileConversationListener registeredListener;
synchronized (mListeners) {
registeredListener = mListeners.get(key);
if (registeredListener == null) {
@@ -875,9 +977,153 @@ public class PeopleSpaceWidgetManager {
return null;
}
- PeopleSpaceTile augmentedTile = augmentTileFromNotificationEntryManager(tile);
+ PeopleSpaceTile augmentedTile = augmentTileFromNotificationEntryManager(tile,
+ Optional.empty());
if (DEBUG) Log.i(TAG, "Returning tile preview for shortcutId: " + shortcutId);
- return new PeopleTileViewHelper(mContext, augmentedTile, 0, options).getViews();
+ return new PeopleTileViewHelper(mContext, augmentedTile, 0, options,
+ new PeopleTileKey(augmentedTile)).getViews();
+ }
+
+ protected final BroadcastReceiver mBaseBroadcastReceiver = new BroadcastReceiver() {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (DEBUG) Log.d(TAG, "Update widgets from: " + action);
+ mBgExecutor.execute(() -> updateWidgetsOnStateChange(action));
+ }
+ };
+
+ /** Updates any app widget based on the current state. */
+ @VisibleForTesting
+ void updateWidgetsOnStateChange(String entryPoint) {
+ int[] appWidgetIds = mAppWidgetManager.getAppWidgetIds(
+ new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
+ if (appWidgetIds == null) {
+ return;
+ }
+ synchronized (mLock) {
+ for (int appWidgetId : appWidgetIds) {
+ PeopleSpaceTile tile = getTileForExistingWidget(appWidgetId);
+ if (tile == null) {
+ Log.e(TAG, "Matching conversation not found for shortcut ID");
+ } else {
+ tile = updateWithCurrentState(tile, entryPoint);
+ }
+ updateAppWidgetOptionsAndView(appWidgetId, tile);
+ }
+ }
+ }
+
+ /** Checks the current state of {@code tile} dependencies, updating fields as necessary. */
+ @Nullable
+ private PeopleSpaceTile updateWithCurrentState(PeopleSpaceTile tile,
+ String entryPoint) {
+ PeopleSpaceTile.Builder updatedTile = tile.toBuilder();
+ try {
+ switch (entryPoint) {
+ case NotificationManager
+ .ACTION_INTERRUPTION_FILTER_CHANGED:
+ updatedTile.setNotificationPolicyState(getNotificationPolicyState());
+ break;
+ case Intent.ACTION_PACKAGES_SUSPENDED:
+ case Intent.ACTION_PACKAGES_UNSUSPENDED:
+ updatedTile.setIsPackageSuspended(getPackageSuspended(tile));
+ break;
+ case Intent.ACTION_MANAGED_PROFILE_AVAILABLE:
+ case Intent.ACTION_MANAGED_PROFILE_UNAVAILABLE:
+ case Intent.ACTION_USER_UNLOCKED:
+ updatedTile.setIsUserQuieted(getUserQuieted(tile));
+ break;
+ case Intent.ACTION_LOCALE_CHANGED:
+ break;
+ case ACTION_BOOT_COMPLETED:
+ default:
+ updatedTile.setIsUserQuieted(getUserQuieted(tile)).setIsPackageSuspended(
+ getPackageSuspended(tile)).setNotificationPolicyState(
+ getNotificationPolicyState());
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Package no longer found for tile: " + tile.toString() + e);
+ return null;
+ }
+ return updatedTile.build();
+ }
+
+ private boolean getPackageSuspended(PeopleSpaceTile tile) throws Exception {
+ boolean packageSuspended = !TextUtils.isEmpty(tile.getPackageName())
+ && mPackageManager.isPackageSuspended(tile.getPackageName());
+ if (DEBUG) Log.d(TAG, "Package suspended: " + packageSuspended);
+ return packageSuspended;
+ }
+
+ private boolean getUserQuieted(PeopleSpaceTile tile) {
+ boolean workProfileQuieted =
+ tile.getUserHandle() != null && mUserManager.isQuietModeEnabled(
+ tile.getUserHandle());
+ if (DEBUG) Log.d(TAG, "Work profile quiet: " + workProfileQuieted);
+ return workProfileQuieted;
+ }
+
+ private int getNotificationPolicyState() {
+ NotificationManager.Policy policy = mNotificationManager.getNotificationPolicy();
+ boolean suppressVisualEffects =
+ NotificationManager.Policy.areAllVisualEffectsSuppressed(
+ policy.suppressedVisualEffects);
+ int notificationPolicyState = 0;
+ switch (mNotificationManager.getCurrentInterruptionFilter()) {
+ case INTERRUPTION_FILTER_ALL:
+ if (DEBUG) Log.d(TAG, "All interruptions allowed");
+ return PeopleSpaceTile.SHOW_CONVERSATIONS;
+ case INTERRUPTION_FILTER_PRIORITY:
+ if (policy.allowConversations()) {
+ // If the user sees notifications in DND, show notifications in tiles in DND.
+ if (!suppressVisualEffects) {
+ if (DEBUG) Log.d(TAG, "Visual effects not suppressed.");
+ return PeopleSpaceTile.SHOW_CONVERSATIONS;
+ }
+ if (policy.priorityConversationSenders == CONVERSATION_SENDERS_ANYONE) {
+ if (DEBUG) Log.d(TAG, "All conversations allowed");
+ // We only show conversations, so we can show everything.
+ return PeopleSpaceTile.SHOW_CONVERSATIONS;
+ } else if (policy.priorityConversationSenders
+ == NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT) {
+ if (DEBUG) Log.d(TAG, "Important conversations allowed");
+ notificationPolicyState |= PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
+ }
+ }
+ if (policy.allowMessages()) {
+ switch (policy.allowMessagesFrom()) {
+ case ZenModeConfig.SOURCE_CONTACT:
+ if (DEBUG) Log.d(TAG, "All contacts allowed");
+ notificationPolicyState |= PeopleSpaceTile.SHOW_CONTACTS;
+ return notificationPolicyState;
+ case ZenModeConfig.SOURCE_STAR:
+ if (DEBUG) Log.d(TAG, "Starred contacts allowed");
+ notificationPolicyState |= PeopleSpaceTile.SHOW_STARRED_CONTACTS;
+ return notificationPolicyState;
+ case ZenModeConfig.SOURCE_ANYONE:
+ default:
+ if (DEBUG) Log.d(TAG, "All messages allowed");
+ return PeopleSpaceTile.SHOW_CONVERSATIONS;
+ }
+ }
+ if (notificationPolicyState != 0) {
+ if (DEBUG) Log.d(TAG, "Return block state: " + notificationPolicyState);
+ return notificationPolicyState;
+ }
+ // If only alarms or nothing can bypass DND, the tile shouldn't show conversations.
+ case INTERRUPTION_FILTER_NONE:
+ case INTERRUPTION_FILTER_ALARMS:
+ default:
+ // If the user sees notifications in DND, show notifications in tiles in DND.
+ if (!suppressVisualEffects) {
+ if (DEBUG) Log.d(TAG, "Visual effects not suppressed.");
+ return PeopleSpaceTile.SHOW_CONVERSATIONS;
+ }
+ if (DEBUG) Log.d(TAG, "Block conversations");
+ return PeopleSpaceTile.BLOCK_CONVERSATIONS;
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
index 3bc5b29bd05d..3522b76e6460 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetProvider.java
@@ -16,9 +16,6 @@
package com.android.systemui.people.widget;
-import android.annotation.NonNull;
-import android.app.people.ConversationChannel;
-import android.app.people.PeopleManager;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
@@ -28,6 +25,8 @@ import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.people.PeopleSpaceUtils;
+import javax.inject.Inject;
+
/** People Space Widget Provider class. */
public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
private static final String TAG = "PeopleSpaceWidgetPvd";
@@ -38,25 +37,11 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
public static final String EXTRA_USER_HANDLE = "extra_user_handle";
public static final String EXTRA_NOTIFICATION_KEY = "extra_notification_key";
- public PeopleSpaceWidgetManager peopleSpaceWidgetManager;
-
- /** Listener for the shortcut data changes. */
- public class TileConversationListener implements PeopleManager.ConversationListener {
+ public PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
- @Override
- public void onConversationUpdate(@NonNull ConversationChannel conversation) {
- if (DEBUG) {
- Log.d(TAG,
- "Received updated conversation: "
- + conversation.getShortcutInfo().getLabel());
- }
- if (peopleSpaceWidgetManager == null) {
- // This shouldn't happen since onUpdate is called at reboot.
- Log.e(TAG, "Skipping conversation update: WidgetManager uninitialized");
- return;
- }
- peopleSpaceWidgetManager.updateWidgetsWithConversationChanged(conversation);
- }
+ @Inject
+ PeopleSpaceWidgetProvider(PeopleSpaceWidgetManager peopleSpaceWidgetManager) {
+ mPeopleSpaceWidgetManager = peopleSpaceWidgetManager;
}
/** Called when widget updates. */
@@ -65,15 +50,8 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
super.onUpdate(context, appWidgetManager, appWidgetIds);
if (DEBUG) Log.d(TAG, "onUpdate called");
- ensurePeopleSpaceWidgetManagerInitialized(context);
- peopleSpaceWidgetManager.updateWidgets(appWidgetIds);
- for (int appWidgetId : appWidgetIds) {
- if (DEBUG) Log.d(TAG, "Ensure listener is registered for widget: " + appWidgetId);
- PeopleSpaceWidgetProvider.TileConversationListener
- newListener = new PeopleSpaceWidgetProvider.TileConversationListener();
- peopleSpaceWidgetManager.registerConversationListenerIfNeeded(appWidgetId,
- newListener);
- }
+ ensurePeopleSpaceWidgetManagerInitialized();
+ mPeopleSpaceWidgetManager.updateWidgets(appWidgetIds);
}
/** Called when widget updates. */
@@ -81,25 +59,23 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, Bundle newOptions) {
super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions);
- ensurePeopleSpaceWidgetManagerInitialized(context);
- peopleSpaceWidgetManager.onAppWidgetOptionsChanged(appWidgetId, newOptions);
+ ensurePeopleSpaceWidgetManagerInitialized();
+ mPeopleSpaceWidgetManager.onAppWidgetOptionsChanged(appWidgetId, newOptions);
}
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
- ensurePeopleSpaceWidgetManagerInitialized(context);
- peopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
+ ensurePeopleSpaceWidgetManagerInitialized();
+ mPeopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
}
- private void ensurePeopleSpaceWidgetManagerInitialized(Context context) {
- if (peopleSpaceWidgetManager == null) {
- peopleSpaceWidgetManager = new PeopleSpaceWidgetManager(context);
- }
+ private void ensurePeopleSpaceWidgetManagerInitialized() {
+ mPeopleSpaceWidgetManager.init();
}
@VisibleForTesting
public void setPeopleSpaceWidgetManager(PeopleSpaceWidgetManager manager) {
- peopleSpaceWidgetManager = manager;
+ mPeopleSpaceWidgetManager = manager;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index c552e89a3625..aa4fb712090b 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -7,7 +7,6 @@ import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.content.Context;
import android.content.res.Configuration;
-import android.content.res.Resources;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
@@ -333,11 +332,6 @@ public class PagedTileLayout extends ViewPager implements QSTileLayout {
@Override
public boolean updateResources() {
- // Update bottom padding, useful for removing extra space once the panel page indicator is
- // hidden.
- Resources res = getContext().getResources();
- setPageMargin(res.getDimensionPixelOffset(R.dimen.qs_tile_margin_horizontal));
-
setPadding(0, 0, 0,
getContext().getResources().getDimensionPixelSize(
R.dimen.qs_paged_tile_layout_padding_bottom));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index f486c535d9e2..3b436769a456 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -207,11 +207,12 @@ public class QSContainerImpl extends FrameLayout {
mContext.getResources().getDimensionPixelSize(R.dimen.qs_container_bottom_padding)
);
- mSideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
+ int sideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
int padding = getResources().getDimensionPixelSize(
R.dimen.notification_shade_content_margin_horizontal);
- boolean marginsChanged = padding != mContentPadding;
+ boolean marginsChanged = padding != mContentPadding || sideMargins != mSideMargins;
mContentPadding = padding;
+ mSideMargins = sideMargins;
if (marginsChanged) {
updatePaddingsAndMargins(qsPanelController, quickStatusBarHeaderController);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
index e3f00f42d2ca..c69956f90c67 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeader.java
@@ -55,9 +55,13 @@ public class QuickStatusBarHeader extends FrameLayout {
private TouchAnimator mAlphaAnimator;
private TouchAnimator mTranslationAnimator;
+ private TouchAnimator mIconsAlphaAnimator;
+ private TouchAnimator mIconsAlphaAnimatorFixed;
protected QuickQSPanel mHeaderQsPanel;
private View mDatePrivacyView;
+ private View mDateView;
+ private View mSecurityHeaderView;
private View mClockIconsView;
private View mContainer;
@@ -66,7 +70,7 @@ public class QuickStatusBarHeader extends FrameLayout {
private Space mSpace;
private BatteryMeterView mBatteryRemainingIcon;
private StatusIconContainer mIconContainer;
-
+ private View mPrivacyChip;
private TintedIconManager mTintedIconManager;
private QSExpansionPathInterpolator mQSExpansionPathInterpolator;
@@ -79,7 +83,6 @@ public class QuickStatusBarHeader extends FrameLayout {
private int mCutOutPaddingLeft;
private int mCutOutPaddingRight;
private float mClockIconsAlpha = 1.0f;
- private float mDatePrivacyAlpha = 1.0f;
private float mKeyguardExpansionFraction;
private int mTextColorPrimary = Color.TRANSPARENT;
private int mTopViewMeasureHeight;
@@ -111,8 +114,11 @@ public class QuickStatusBarHeader extends FrameLayout {
mDatePrivacyView = findViewById(R.id.quick_status_bar_date_privacy);
mClockIconsView = findViewById(R.id.quick_qs_status_icons);
mQSCarriers = findViewById(R.id.carrier_group);
- mContainer = findViewById(R.id.container);
+ mContainer = findViewById(R.id.qs_container);
mIconContainer = findViewById(R.id.statusIcons);
+ mPrivacyChip = findViewById(R.id.privacy_chip);
+ mDateView = findViewById(R.id.date);
+ mSecurityHeaderView = findViewById(R.id.header_text_container);
mClockView = findViewById(R.id.clock);
mSpace = findViewById(R.id.space);
@@ -126,6 +132,11 @@ public class QuickStatusBarHeader extends FrameLayout {
// QS will always show the estimate, and BatteryMeterView handles the case where
// it's unavailable or charging
mBatteryRemainingIcon.setPercentShowMode(BatteryMeterView.MODE_ESTIMATE);
+
+ mIconsAlphaAnimatorFixed = new TouchAnimator.Builder()
+ .addFloat(mIconContainer, "alpha", 0, 1)
+ .addFloat(mBatteryRemainingIcon, "alpha", 0, 1)
+ .build();
}
void onAttach(TintedIconManager iconManager,
@@ -226,8 +237,12 @@ public class QuickStatusBarHeader extends FrameLayout {
StatusBarIconView callStrengthIcon =
((StatusBarIconView) mIconContainer.getViewForSlot(mCallStrengthSlotName));
TouchAnimator.Builder builder = new TouchAnimator.Builder()
- .addFloat(mQSCarriers, "alpha", 0, 1)
- .addFloat(mDatePrivacyView, "alpha", 0, mDatePrivacyAlpha);
+ // The following two views have to be hidden manually, so as not to hide the
+ // Privacy chip in QQS
+ .addFloat(mDateView, "alpha", 0, 1)
+ .addFloat(mSecurityHeaderView, "alpha", 0, 1)
+ .addFloat(mQSCarriers, "alpha", 0, 1);
+
if (noCallingIcon != null || callStrengthIcon != null) {
if (noCallingIcon != null) {
builder.addFloat(noCallingIcon, "alpha", 1, 0);
@@ -259,6 +274,20 @@ public class QuickStatusBarHeader extends FrameLayout {
mAlphaAnimator = builder.build();
}
+ void setChipVisibility(boolean visibility) {
+ mPrivacyChip.setVisibility(visibility ? View.VISIBLE : View.GONE);
+ if (visibility) {
+ // Animates the icons and battery indicator from alpha 0 to 1, when the chip is visible
+ mIconsAlphaAnimator = mIconsAlphaAnimatorFixed;
+ mIconsAlphaAnimator.setPosition(mKeyguardExpansionFraction);
+ } else {
+ mIconsAlphaAnimator = null;
+ mIconContainer.setAlpha(1);
+ mBatteryRemainingIcon.setAlpha(1);
+ }
+
+ }
+
/** */
public void setExpanded(boolean expanded, QuickQSPanelController quickQSPanelController) {
if (mExpanded == expanded) return;
@@ -285,6 +314,9 @@ public class QuickStatusBarHeader extends FrameLayout {
if (mTranslationAnimator != null) {
mTranslationAnimator.setPosition(keyguardExpansionFraction);
}
+ if (mIconsAlphaAnimator != null) {
+ mIconsAlphaAnimator.setPosition(keyguardExpansionFraction);
+ }
// If forceExpanded (we are opening QS from lockscreen), the animators have been set to
// position = 1f.
if (forceExpanded) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
index 3aafea98ff2a..617b067be891 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickStatusBarHeaderController.java
@@ -225,7 +225,6 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
private void setChipVisibility(boolean chipVisible) {
if (chipVisible && getChipEnabled()) {
- mPrivacyChip.setVisibility(View.VISIBLE);
mPrivacyLogger.logChipVisible(true);
// Makes sure that the chip is logged as viewed at most once each time QS is opened
// mListening makes sure that the callback didn't return after the user closed QS
@@ -235,8 +234,8 @@ class QuickStatusBarHeaderController extends ViewController<QuickStatusBarHeader
}
} else {
mPrivacyLogger.logChipVisible(false);
- mPrivacyChip.setVisibility(View.GONE);
}
+ mView.setChipVisibility(chipVisible);
}
private List<String> getIgnoredIconSlots() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index f078ccd9d382..1ec785d4712e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -213,7 +213,9 @@ public class OverviewProxyService extends CurrentUserTracker implements
// TODO move this logic to message queue
mStatusBarOptionalLazy.ifPresent(statusBarLazy -> {
StatusBar statusBar = statusBarLazy.get();
- statusBar.getPanelController().startExpandLatencyTracking();
+ if (event.getActionMasked() == ACTION_DOWN) {
+ statusBar.getPanelController().startExpandLatencyTracking();
+ }
mHandler.post(()-> {
int action = event.getActionMasked();
if (action == ACTION_DOWN) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 5437ce63475e..7f31fddbfb6c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar;
import static com.android.systemui.statusbar.RemoteInputController.processForRemoteInput;
import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
+import static com.android.systemui.statusbar.phone.StatusBar.DEBUG;
import android.annotation.NonNull;
import android.annotation.SuppressLint;
@@ -34,7 +35,6 @@ import android.util.Log;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.dagger.StatusBarModule;
import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins;
-import com.android.systemui.statusbar.phone.StatusBar;
import java.util.ArrayList;
import java.util.List;
@@ -46,7 +46,6 @@ import java.util.List;
@SuppressLint("OverrideAbstract")
public class NotificationListener extends NotificationListenerWithPlugins {
private static final String TAG = "NotificationListener";
- private static final boolean DEBUG = StatusBar.DEBUG;
private final Context mContext;
private final NotificationManager mNotificationManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt b/packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt
index 1da42a705311..78e85f1e6f73 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt
@@ -168,7 +168,6 @@ private class PrefsCommand(val context: Context) : Command {
when (topLevel) {
"list-prefs" -> listPrefs(pw)
- "set-pref" -> setPref(pw, args.drop(1))
else -> help(pw)
}
}
@@ -180,25 +179,4 @@ private class PrefsCommand(val context: Context) : Command {
pw.println(field.get(Prefs.Key::class.java))
}
}
-
- /**
- * Sets a preference from [Prefs]
- */
- private fun setPref(pw: PrintWriter, args: List<String>) {
- if (args.isEmpty()) {
- pw.println("invalid arguments: $args")
- return
- }
- val pref = args[0]
-
- when (pref) {
- Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S -> {
- val value = Integer.parseInt(args[1])
- Prefs.putBoolean(context, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, value != 0)
- }
- else -> {
- pw.println("Cannot set pref ($pref)")
- }
- }
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
index 5ab71bc62fe6..b3f7ca6f2630 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
@@ -29,6 +29,8 @@ import com.android.systemui.animation.Interpolators
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
+import com.android.systemui.statusbar.phone.StatusBarLocationPublisher
+import com.android.systemui.statusbar.phone.StatusBarMarginUpdatedListener
import java.lang.IllegalStateException
import java.util.concurrent.Executor
@@ -51,8 +53,9 @@ import javax.inject.Inject
@SysUISingleton
class PrivacyDotViewController @Inject constructor(
- @Main val mainExecutor: Executor,
- val animationScheduler: SystemStatusAnimationScheduler
+ @Main private val mainExecutor: Executor,
+ private val locationPublisher: StatusBarLocationPublisher,
+ private val animationScheduler: SystemStatusAnimationScheduler
) {
private var rotation = 0
private var leftSize = 0
@@ -80,12 +83,21 @@ class PrivacyDotViewController @Inject constructor(
private val views: Sequence<View>
get() = if (!this::tl.isInitialized) sequenceOf() else sequenceOf(tl, tr, br, bl)
+ init {
+ locationPublisher.addCallback(object : StatusBarMarginUpdatedListener {
+ override fun onStatusBarMarginUpdated(marginLeft: Int, marginRight: Int) {
+ setStatusBarMargins(marginLeft, marginRight)
+ }
+ })
+ }
+
fun setUiExecutor(e: Executor) {
uiExecutor = e
}
@UiThread
fun updateRotation(rot: Int) {
+ dlog("updateRotation: ")
if (rot == rotation) {
return
}
@@ -248,7 +260,7 @@ class PrivacyDotViewController @Inject constructor(
* @param left the space between the status bar contents and the left side of the screen
* @param right space between the status bar contents and the right side of the screen
*/
- fun setStatusBarMargins(left: Int, right: Int) {
+ private fun setStatusBarMargins(left: Int, right: Int) {
leftSize = left
rightSize = right
@@ -262,6 +274,7 @@ class PrivacyDotViewController @Inject constructor(
}
private fun doUpdates(rot: Boolean, height: Boolean, width: Boolean) {
+ dlog("doUpdates: ")
var newDesignatedCorner: View? = null
if (rot) {
@@ -324,12 +337,19 @@ class PrivacyDotViewController @Inject constructor(
}
}
+private fun dlog(s: String) {
+ if (DEBUG) {
+ Log.d(TAG, s)
+ }
+}
+
const val TOP_LEFT = 0
const val TOP_RIGHT = 1
const val BOTTOM_RIGHT = 2
const val BOTTOM_LEFT = 3
private const val DURATION = 160L
private const val TAG = "PrivacyDotViewController"
+private const val DEBUG = false
private fun Int.toGravity(): Int {
return when (this) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
index 620963060b49..b861c1db9b8b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
@@ -27,6 +27,7 @@ import android.widget.FrameLayout
import com.android.systemui.R
import com.android.systemui.statusbar.SuperStatusBarViewFactory
+import com.android.systemui.statusbar.phone.StatusBarLocationPublisher
import com.android.systemui.statusbar.phone.StatusBarWindowController
import com.android.systemui.statusbar.phone.StatusBarWindowView
@@ -39,7 +40,8 @@ import javax.inject.Inject
class SystemEventChipAnimationController @Inject constructor(
private val context: Context,
private val statusBarViewFactory: SuperStatusBarViewFactory,
- private val statusBarWindowController: StatusBarWindowController
+ private val statusBarWindowController: StatusBarWindowController,
+ private val locationPublisher: StatusBarLocationPublisher
) : SystemStatusChipAnimationCallback {
var showPersistentDot = false
set(value) {
@@ -64,13 +66,15 @@ class SystemEventChipAnimationController @Inject constructor(
if (state == ANIMATING_IN) {
currentAnimatedView = viewCreator(context)
- animationWindowView.addView(currentAnimatedView, layoutParamsDefault)
+ animationWindowView.addView(currentAnimatedView, layoutParamsDefault())
// We are animating IN; chip comes in from View.END
currentAnimatedView?.apply {
- translationX = width.toFloat()
+ val translation = width.toFloat()
+ translationX = if (isLayoutRtl) -translation else translation
alpha = 0f
visibility = View.VISIBLE
+ setPadding(locationPublisher.marginLeft, 0, locationPublisher.marginRight, 0)
}
} else {
// We are animating away
@@ -109,7 +113,7 @@ class SystemEventChipAnimationController @Inject constructor(
val w = width
val translation = (1 - amt) * w
- translationX = translation
+ translationX = if (isLayoutRtl) -translation else translation
}
}
@@ -131,7 +135,13 @@ class SystemEventChipAnimationController @Inject constructor(
statusBarWindowView.addView(animationWindowView, lp)
}
- private val layoutParamsDefault = FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).also {
- it.gravity = Gravity.END or Gravity.CENTER_VERTICAL
+ private fun start() = if (animationWindowView.isLayoutRtl) right() else left()
+ private fun right() = locationPublisher.marginRight
+ private fun left() = locationPublisher.marginLeft
+
+ private fun layoutParamsDefault(): FrameLayout.LayoutParams =
+ FrameLayout.LayoutParams(WRAP_CONTENT, WRAP_CONTENT).also {
+ it.gravity = Gravity.END or Gravity.CENTER_VERTICAL
+ it.marginStart = start()
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
index 1e071312065b..40049373610c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
@@ -127,7 +127,6 @@ class SystemStatusAnimationScheduler @Inject constructor(
}
private fun isTooEarly(): Boolean {
- Log.d(TAG, "time=> ${systemClock.uptimeMillis() - Process.getStartUptimeMillis()}")
return systemClock.uptimeMillis() - Process.getStartUptimeMillis() < MIN_UPTIME
}
@@ -339,4 +338,4 @@ private const val ENTRANCE_ANIM_LENGTH = 500L
private const val CHIP_ANIM_LENGTH = 500L
private const val MIN_UPTIME: Long = 5 * 1000
-private const val DEBUG = false \ No newline at end of file
+private const val DEBUG = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
index d95c265c1460..d6356de5ea51 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/legacy/NotificationGroupManagerLegacy.java
@@ -16,9 +16,7 @@
package com.android.systemui.statusbar.notification.collection.legacy;
-import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.Notification;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.Log;
@@ -33,7 +31,6 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.render.GroupExpansionManager;
import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
import com.android.systemui.statusbar.notification.people.PeopleNotificationIdentifier;
-import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import com.android.wm.shell.bubbles.Bubbles;
@@ -42,12 +39,10 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
-import java.util.TreeSet;
import javax.inject.Inject;
@@ -63,21 +58,13 @@ import dagger.Lazy;
public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener, StateListener,
GroupMembershipManager, GroupExpansionManager, Dumpable {
- private static final String TAG = "NotifGroupManager";
- private static final boolean DEBUG = StatusBar.DEBUG;
- private static final boolean SPEW = StatusBar.SPEW;
- /**
- * The maximum amount of time (in ms) between the posting of notifications that can be
- * considered part of the same update batch.
- */
- private static final long POST_BATCH_MAX_AGE = 5000;
+ private static final String TAG = "NotificationGroupManager";
private final HashMap<String, NotificationGroup> mGroupMap = new HashMap<>();
private final ArraySet<OnGroupExpansionChangeListener> mExpansionChangeListeners =
new ArraySet<>();
private final ArraySet<OnGroupChangeListener> mGroupChangeListeners = new ArraySet<>();
private final Lazy<PeopleNotificationIdentifier> mPeopleNotificationIdentifier;
private final Optional<Bubbles> mBubblesOptional;
- private final EventBuffer mEventBuffer = new EventBuffer();
private int mBarState = -1;
private HashMap<String, StatusBarNotification> mIsolatedEntries = new HashMap<>();
private HeadsUpManager mHeadsUpManager;
@@ -147,14 +134,8 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
* When we want to remove an entry from being tracked for grouping
*/
public void onEntryRemoved(NotificationEntry removed) {
- if (SPEW) {
- Log.d(TAG, "onEntryRemoved: entry=" + removed);
- }
onEntryRemovedInternal(removed, removed.getSbn());
- StatusBarNotification oldSbn = mIsolatedEntries.remove(removed.getKey());
- if (oldSbn != null) {
- updateSuppression(mGroupMap.get(oldSbn.getGroupKey()));
- }
+ mIsolatedEntries.remove(removed.getKey());
}
/**
@@ -181,9 +162,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
// the close future. See b/23676310 for reference.
return;
}
- if (SPEW) {
- Log.d(TAG, "onEntryRemovedInternal: entry=" + removed + " group=" + group.groupKey);
- }
if (isGroupChild(removed.getKey(), isGroup, isGroupSummary)) {
group.children.remove(removed.getKey());
} else {
@@ -204,9 +182,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
* Notify the group manager that a new entry was added
*/
public void onEntryAdded(final NotificationEntry added) {
- if (SPEW) {
- Log.d(TAG, "onEntryAdded: entry=" + added);
- }
updateIsolation(added);
onEntryAddedInternal(added);
}
@@ -220,16 +195,13 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
String groupKey = getGroupKey(sbn);
NotificationGroup group = mGroupMap.get(groupKey);
if (group == null) {
- group = new NotificationGroup(groupKey);
+ group = new NotificationGroup();
mGroupMap.put(groupKey, group);
for (OnGroupChangeListener listener : mGroupChangeListeners) {
listener.onGroupCreated(group, groupKey);
}
}
- if (SPEW) {
- Log.d(TAG, "onEntryAddedInternal: entry=" + added + " group=" + group.groupKey);
- }
if (isGroupChild) {
NotificationEntry existing = group.children.get(added.getKey());
if (existing != null && existing != added) {
@@ -241,11 +213,9 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
+ " added removed" + added.isRowRemoved(), new Throwable());
}
group.children.put(added.getKey(), added);
- addToPostBatchHistory(group, added);
updateSuppression(group);
} else {
group.summary = added;
- addToPostBatchHistory(group, added);
group.expanded = added.areChildrenExpanded();
updateSuppression(group);
if (!group.children.isEmpty()) {
@@ -261,27 +231,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
}
}
- private void addToPostBatchHistory(NotificationGroup group, @Nullable NotificationEntry entry) {
- if (entry == null) {
- return;
- }
- boolean didAdd = group.postBatchHistory.add(new PostRecord(entry));
- if (didAdd) {
- trimPostBatchHistory(group.postBatchHistory);
- }
- }
-
- /** remove all history that's too old to be in the batch. */
- private void trimPostBatchHistory(@NonNull TreeSet<PostRecord> postBatchHistory) {
- if (postBatchHistory.size() <= 1) {
- return;
- }
- long batchStartTime = postBatchHistory.last().postTime - POST_BATCH_MAX_AGE;
- while (!postBatchHistory.isEmpty() && postBatchHistory.first().postTime < batchStartTime) {
- postBatchHistory.pollFirst();
- }
- }
-
private void onEntryBecomingChild(NotificationEntry entry) {
updateIsolation(entry);
}
@@ -290,9 +239,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
if (group == null) {
return;
}
- NotificationEntry prevAlertOverride = group.alertOverride;
- group.alertOverride = getPriorityConversationAlertOverride(group);
-
int childCount = 0;
boolean hasBubbles = false;
for (NotificationEntry entry : group.children.values()) {
@@ -309,146 +255,16 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
group.suppressed = group.summary != null && !group.expanded
&& (childCount == 1
|| (childCount == 0
- && group.summary.getSbn().getNotification().isGroupSummary()
- && (hasIsolatedChildren(group) || hasBubbles)));
-
- boolean alertOverrideChanged = prevAlertOverride != group.alertOverride;
- boolean suppressionChanged = prevSuppressed != group.suppressed;
- if (alertOverrideChanged || suppressionChanged) {
- if (DEBUG && alertOverrideChanged) {
- Log.d(TAG, group + " alertOverride was=" + prevAlertOverride + " now="
- + group.alertOverride);
- }
- if (DEBUG && suppressionChanged) {
- Log.d(TAG, group + " suppressed changed to " + group.suppressed);
- }
- if (!mIsUpdatingUnchangedGroup) {
- if (alertOverrideChanged) {
- mEventBuffer.notifyAlertOverrideChanged(group, prevAlertOverride);
- }
- if (suppressionChanged) {
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupSuppressionChanged(group, group.suppressed);
- }
- }
- mEventBuffer.notifyGroupsChanged();
- } else {
- if (DEBUG) {
- Log.d(TAG, group + " did not notify listeners of above change(s)");
- }
- }
- }
- }
-
- /**
- * Finds the isolated logical child of this group which is should be alerted instead.
- *
- * Notifications from priority conversations are isolated from their groups to make them more
- * prominent, however apps may post these with a GroupAlertBehavior that has the group receiving
- * the alert. This would lead to the group alerting even though the conversation that was
- * updated was not actually a part of that group. This method finds the best priority
- * conversation in this situation, if there is one, so they can be set as the alertOverride of
- * the group.
- *
- * @param group the group to check
- * @return the entry which should receive the alert instead of the group, if any.
- */
- @Nullable
- private NotificationEntry getPriorityConversationAlertOverride(NotificationGroup group) {
- // GOAL: if there is a priority child which wouldn't alert based on its groupAlertBehavior,
- // but which should be alerting (because priority conversations are isolated), find it.
- if (group == null || group.summary == null) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: null group or summary");
- }
- return null;
- }
- if (isIsolated(group.summary.getKey())) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: isolated group");
- }
- return null;
- }
-
- // Precondiions:
- // * Only necessary when all notifications in the group use GROUP_ALERT_SUMMARY
- // * Only necessary when at least one notification in the group is on a priority channel
- if (group.summary.getSbn().getNotification().getGroupAlertBehavior()
- != Notification.GROUP_ALERT_SUMMARY) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: summary != GROUP_ALERT_SUMMARY");
- }
- return null;
- }
-
- // Get the important children first, copy the keys for the final importance check,
- // then add the non-isolated children to the map for unified lookup.
- HashMap<String, NotificationEntry> children = getImportantConversations(group);
- if (children == null || children.isEmpty()) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: no important conversations");
- }
- return null;
- }
- HashSet<String> importantChildKeys = new HashSet<>(children.keySet());
- children.putAll(group.children);
-
- // Ensure all children have GROUP_ALERT_SUMMARY
- for (NotificationEntry child : children.values()) {
- if (child.getSbn().getNotification().getGroupAlertBehavior()
- != Notification.GROUP_ALERT_SUMMARY) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: "
- + "child != GROUP_ALERT_SUMMARY");
- }
- return null;
- }
- }
-
- // Create a merged post history from all the children
- TreeSet<PostRecord> combinedHistory = new TreeSet<>(group.postBatchHistory);
- for (String importantChildKey : importantChildKeys) {
- NotificationGroup importantChildGroup = mGroupMap.get(importantChildKey);
- combinedHistory.addAll(importantChildGroup.postBatchHistory);
- }
- trimPostBatchHistory(combinedHistory);
-
- // This is a streamlined implementation of the following idea:
- // * From the subset of notifications in the latest 'batch' of updates. A batch is:
- // * Notifs posted less than POST_BATCH_MAX_AGE before the most recently posted.
- // * Only including notifs newer than the second-to-last post of any notification.
- // * Find the newest child in the batch -- the with the largest 'when' value.
- // * If the newest child is a priority conversation, set that as the override.
- HashSet<String> batchKeys = new HashSet<>();
- long newestChildWhen = -1;
- NotificationEntry newestChild = null;
- // Iterate backwards through the post history, tracking the child with the smallest sort key
- for (PostRecord record : combinedHistory.descendingSet()) {
- if (batchKeys.contains(record.key)) {
- // Once you see a notification again, the batch has ended
- break;
- }
- batchKeys.add(record.key);
- NotificationEntry child = children.get(record.key);
- if (child != null) {
- long childWhen = child.getSbn().getNotification().when;
- if (newestChild == null || childWhen > newestChildWhen) {
- newestChildWhen = childWhen;
- newestChild = child;
+ && group.summary.getSbn().getNotification().isGroupSummary()
+ && (hasIsolatedChildren(group) || hasBubbles)));
+ if (prevSuppressed != group.suppressed) {
+ for (OnGroupChangeListener listener : mGroupChangeListeners) {
+ if (!mIsUpdatingUnchangedGroup) {
+ listener.onGroupSuppressionChanged(group, group.suppressed);
+ listener.onGroupsChanged();
}
}
}
- if (newestChild != null && importantChildKeys.contains(newestChild.getKey())) {
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: result=" + newestChild);
- }
- return newestChild;
- }
- if (SPEW) {
- Log.d(TAG, "getPriorityConversationAlertOverride: result=null, newestChild="
- + newestChild);
- }
- return null;
}
private boolean hasIsolatedChildren(NotificationGroup group) {
@@ -465,33 +281,12 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
return count;
}
- @Nullable
- private HashMap<String, NotificationEntry> getImportantConversations(NotificationGroup group) {
- String groupKey = group.summary.getSbn().getGroupKey();
- HashMap<String, NotificationEntry> result = null;
- for (StatusBarNotification sbn : mIsolatedEntries.values()) {
- if (sbn.getGroupKey().equals(groupKey)) {
- NotificationEntry entry = mGroupMap.get(sbn.getKey()).summary;
- if (isImportantConversation(entry)) {
- if (result == null) {
- result = new HashMap<>();
- }
- result.put(sbn.getKey(), entry);
- }
- }
- }
- return result;
- }
-
/**
* Update an entry's group information
* @param entry notification entry to update
* @param oldNotification previous notification info before this update
*/
public void onEntryUpdated(NotificationEntry entry, StatusBarNotification oldNotification) {
- if (SPEW) {
- Log.d(TAG, "onEntryUpdated: entry=" + entry);
- }
onEntryUpdated(entry, oldNotification.getGroupKey(), oldNotification.isGroup(),
oldNotification.getNotification().isGroupSummary());
}
@@ -530,17 +325,7 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
* Whether the given notification is the summary of a group that is being suppressed
*/
public boolean isSummaryOfSuppressedGroup(StatusBarNotification sbn) {
- return sbn.getNotification().isGroupSummary() && isGroupSuppressed(getGroupKey(sbn));
- }
-
- /**
- * If the given notification is a summary, get the group for it.
- */
- public NotificationGroup getGroupForSummary(StatusBarNotification sbn) {
- if (sbn.getNotification().isGroupSummary()) {
- return mGroupMap.get(getGroupKey(sbn));
- }
- return null;
+ return isGroupSuppressed(getGroupKey(sbn)) && sbn.getNotification().isGroupSummary();
}
private boolean isOnlyChild(StatusBarNotification sbn) {
@@ -760,7 +545,9 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
if (!sbn.isGroup() || sbn.getNotification().isGroupSummary()) {
return false;
}
- if (isImportantConversation(entry)) {
+ int peopleNotificationType =
+ mPeopleNotificationIdentifier.get().getPeopleNotificationType(entry);
+ if (peopleNotificationType == PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON) {
return true;
}
if (mHeadsUpManager != null && !mHeadsUpManager.isAlerting(entry.getKey())) {
@@ -773,25 +560,18 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
|| isGroupNotFullyVisible(notificationGroup));
}
- private boolean isImportantConversation(NotificationEntry entry) {
- int peopleNotificationType =
- mPeopleNotificationIdentifier.get().getPeopleNotificationType(entry);
- return peopleNotificationType == PeopleNotificationIdentifier.TYPE_IMPORTANT_PERSON;
- }
-
/**
* Isolate a notification from its group so that it visually shows as its own group.
*
* @param entry the notification to isolate
*/
private void isolateNotification(NotificationEntry entry) {
- if (SPEW) {
- Log.d(TAG, "isolateNotification: entry=" + entry);
- }
+ StatusBarNotification sbn = entry.getSbn();
+
// We will be isolated now, so lets update the groups
onEntryRemovedInternal(entry, entry.getSbn());
- mIsolatedEntries.put(entry.getKey(), entry.getSbn());
+ mIsolatedEntries.put(sbn.getKey(), sbn);
onEntryAddedInternal(entry);
// We also need to update the suppression of the old group, because this call comes
@@ -808,14 +588,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
* Update the isolation of an entry, splitting it from the group.
*/
public void updateIsolation(NotificationEntry entry) {
- // We need to buffer a few events because we do isolation changes in 3 steps:
- // removeInternal, update mIsolatedEntries, addInternal. This means that often the
- // alertOverride will update on the removal, however processing the event in that case can
- // cause problems because the mIsolatedEntries map is not in its final state, so the event
- // listener may be unable to correctly determine the true state of the group. By delaying
- // the alertOverride change until after the add phase, we can ensure that listeners only
- // have to handle a consistent state.
- mEventBuffer.startBuffering();
boolean isIsolated = isIsolated(entry.getSbn().getKey());
if (shouldIsolate(entry)) {
if (!isIsolated) {
@@ -824,7 +596,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
} else if (isIsolated) {
stopIsolatingNotification(entry);
}
- mEventBuffer.flushAndStopBuffering();
}
/**
@@ -833,15 +604,15 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
* @param entry the notification to un-isolate
*/
private void stopIsolatingNotification(NotificationEntry entry) {
- if (SPEW) {
- Log.d(TAG, "stopIsolatingNotification: entry=" + entry);
- }
- // not isolated anymore, we need to update the groups
- onEntryRemovedInternal(entry, entry.getSbn());
- mIsolatedEntries.remove(entry.getKey());
- onEntryAddedInternal(entry);
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupsChanged();
+ StatusBarNotification sbn = entry.getSbn();
+ if (isIsolated(sbn.getKey())) {
+ // not isolated anymore, we need to update the groups
+ onEntryRemovedInternal(entry, entry.getSbn());
+ mIsolatedEntries.remove(sbn.getKey());
+ onEntryAddedInternal(entry);
+ for (OnGroupChangeListener listener : mGroupChangeListeners) {
+ listener.onGroupsChanged();
+ }
}
}
@@ -877,154 +648,33 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
}
/**
- * A record of a notification being posted, containing the time of the post and the key of the
- * notification entry. These are stored in a TreeSet by the NotificationGroup and used to
- * calculate a batch of notifications.
- */
- public static class PostRecord implements Comparable<PostRecord> {
- public final long postTime;
- public final String key;
-
- /** constructs a record containing the post time and key from the notification entry */
- public PostRecord(@NonNull NotificationEntry entry) {
- this.postTime = entry.getSbn().getPostTime();
- this.key = entry.getKey();
- }
-
- @Override
- public int compareTo(PostRecord o) {
- int postTimeComparison = Long.compare(this.postTime, o.postTime);
- return postTimeComparison == 0
- ? String.CASE_INSENSITIVE_ORDER.compare(this.key, o.key)
- : postTimeComparison;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- PostRecord that = (PostRecord) o;
- return postTime == that.postTime && key.equals(that.key);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(postTime, key);
- }
- }
-
- /**
* Represents a notification group in the notification shade.
*/
public static class NotificationGroup {
- public final String groupKey;
public final HashMap<String, NotificationEntry> children = new HashMap<>();
- public final TreeSet<PostRecord> postBatchHistory = new TreeSet<>();
public NotificationEntry summary;
public boolean expanded;
/**
* Is this notification group suppressed, i.e its summary is hidden
*/
public boolean suppressed;
- /**
- * The child (which is isolated from this group) to which the alert should be transferred,
- * due to priority conversations.
- */
- public NotificationEntry alertOverride;
-
- NotificationGroup(String groupKey) {
- this.groupKey = groupKey;
- }
@Override
public String toString() {
- StringBuilder sb = new StringBuilder();
- sb.append(" groupKey: ").append(groupKey);
- sb.append("\n summary:");
- appendEntry(sb, summary);
- sb.append("\n children size: ").append(children.size());
+ String result = " summary:\n "
+ + (summary != null ? summary.getSbn() : "null")
+ + (summary != null && summary.getDebugThrowable() != null
+ ? Log.getStackTraceString(summary.getDebugThrowable())
+ : "");
+ result += "\n children size: " + children.size();
for (NotificationEntry child : children.values()) {
- appendEntry(sb, child);
- }
- sb.append("\n alertOverride:");
- appendEntry(sb, alertOverride);
- sb.append("\n summary suppressed: ").append(suppressed);
- return sb.toString();
- }
-
- private void appendEntry(StringBuilder sb, NotificationEntry entry) {
- sb.append("\n ").append(entry != null ? entry.getSbn() : "null");
- if (entry != null && entry.getDebugThrowable() != null) {
- sb.append(Log.getStackTraceString(entry.getDebugThrowable()));
- }
- }
- }
-
- /**
- * This class is a toggleable buffer for a subset of events of {@link OnGroupChangeListener}.
- * When buffering, instead of notifying the listeners it will set internal state that will allow
- * it to notify listeners of those events later
- */
- private class EventBuffer {
- private final HashMap<String, NotificationEntry> mOldAlertOverrideByGroup = new HashMap<>();
- private boolean mIsBuffering = false;
- private boolean mDidGroupsChange = false;
-
- void notifyAlertOverrideChanged(NotificationGroup group,
- NotificationEntry oldAlertOverride) {
- if (mIsBuffering) {
- // The value in this map is the override before the event. If there is an entry
- // already in the map, then we are effectively coalescing two events, which means
- // we need to preserve the original initial value.
- mOldAlertOverrideByGroup.putIfAbsent(group.groupKey, oldAlertOverride);
- } else {
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupAlertOverrideChanged(group, oldAlertOverride,
- group.alertOverride);
- }
- }
- }
-
- void notifyGroupsChanged() {
- if (mIsBuffering) {
- mDidGroupsChange = true;
- } else {
- for (OnGroupChangeListener listener : mGroupChangeListeners) {
- listener.onGroupsChanged();
- }
- }
- }
-
- void startBuffering() {
- mIsBuffering = true;
- }
-
- void flushAndStopBuffering() {
- // stop buffering so that we can call our own helpers
- mIsBuffering = false;
- // alert all group alert override changes for groups that were not removed
- for (Map.Entry<String, NotificationEntry> entry : mOldAlertOverrideByGroup.entrySet()) {
- NotificationGroup group = mGroupMap.get(entry.getKey());
- if (group == null) {
- // The group can be null if this alertOverride changed before the group was
- // permanently removed, meaning that there's no guarantee that listeners will
- // that field clear.
- continue;
- }
- NotificationEntry oldAlertOverride = entry.getValue();
- if (group.alertOverride == oldAlertOverride) {
- // If the final alertOverride equals the initial, it means we coalesced two
- // events which undid the change, so we can drop it entirely.
- continue;
- }
- notifyAlertOverrideChanged(group, oldAlertOverride);
- }
- mOldAlertOverrideByGroup.clear();
- // alert that groups changed
- if (mDidGroupsChange) {
- notifyGroupsChanged();
- mDidGroupsChange = false;
+ result += "\n " + child.getSbn()
+ + (child.getDebugThrowable() != null
+ ? Log.getStackTraceString(child.getDebugThrowable())
+ : "");
}
+ result += "\n summary suppressed: " + suppressed;
+ return result;
}
}
@@ -1064,18 +714,6 @@ public class NotificationGroupManagerLegacy implements OnHeadsUpChangedListener,
boolean suppressed) {}
/**
- * The alert override of a group has changed.
- *
- * @param group the group that has changed
- * @param oldAlertOverride the previous notification to which the group's alerts were sent
- * @param newAlertOverride the notification to which the group's alerts should now be sent
- */
- default void onGroupAlertOverrideChanged(
- NotificationGroup group,
- @Nullable NotificationEntry oldAlertOverride,
- @Nullable NotificationEntry newAlertOverride) {}
-
- /**
* A group of children just received a summary notification and should therefore become
* children of it.
*
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
index 617dadb42594..e2a37f647bf5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationsModule.java
@@ -69,7 +69,6 @@ import com.android.systemui.statusbar.notification.logging.NotificationPanelLogg
import com.android.systemui.statusbar.notification.row.ChannelEditorDialogController;
import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.row.OnUserInteractionCallback;
-import com.android.systemui.statusbar.notification.row.PriorityOnboardingDialogController;
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager;
import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm;
import com.android.systemui.statusbar.phone.ShadeController;
@@ -141,7 +140,6 @@ public interface NotificationsModule {
ShortcutManager shortcutManager,
ChannelEditorDialogController channelEditorDialogController,
UserContextProvider contextTracker,
- Provider<PriorityOnboardingDialogController.Builder> builderProvider,
AssistantFeedbackController assistantFeedbackController,
Optional<BubblesManager> bubblesManagerOptional,
UiEventLogger uiEventLogger,
@@ -161,7 +159,6 @@ public interface NotificationsModule {
shortcutManager,
channelEditorDialogController,
contextTracker,
- builderProvider,
assistantFeedbackController,
bubblesManagerOptional,
uiEventLogger,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
index 40be4bfa47dc..1f4f3caea517 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfo.java
@@ -22,6 +22,8 @@ import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_LOW;
import static android.app.NotificationManager.IMPORTANCE_UNSPECIFIED;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
import static com.android.systemui.animation.Interpolators.FAST_OUT_SLOW_IN;
@@ -34,7 +36,6 @@ import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
-import android.app.NotificationManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -55,7 +56,6 @@ import android.transition.TransitionManager;
import android.transition.TransitionSet;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.LayoutInflater;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
@@ -64,7 +64,6 @@ import android.widget.TextView;
import com.android.internal.annotations.VisibleForTesting;
import com.android.settingslib.notification.ConversationIconFactory;
-import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.dagger.qualifiers.Main;
@@ -78,8 +77,6 @@ import com.android.systemui.wmshell.BubblesManager;
import java.lang.annotation.Retention;
import java.util.Optional;
-import javax.inject.Provider;
-
/**
* The guts of a conversation notification revealed when performing a long press.
*/
@@ -107,7 +104,6 @@ public class NotificationConversationInfo extends LinearLayout implements
private StatusBarNotification mSbn;
@Nullable private Notification.BubbleMetadata mBubbleMetadata;
private Context mUserContext;
- private Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider;
private boolean mIsDeviceProvisioned;
private int mAppBubble;
@@ -172,13 +168,9 @@ public class NotificationConversationInfo extends LinearLayout implements
private OnClickListener mOnDone = v -> {
mPressedApply = true;
- // If the user selected Priority, maybe show the priority onboarding.
// If the user selected Priority and the previous selection was not priority, show a
- // People Tile add request. If showing the priority onboarding, however, delay the request
- // to when the onboarding dialog closes.
- if (mSelectedAction == ACTION_FAVORITE && shouldShowPriorityOnboarding()) {
- showPriorityOnboarding();
- } else if (mSelectedAction == ACTION_FAVORITE && getPriority() != mSelectedAction) {
+ // People Tile add request.
+ if (mSelectedAction == ACTION_FAVORITE && getPriority() != mSelectedAction) {
mShadeController.animateCollapsePanels();
mPeopleSpaceWidgetManager.requestPinAppWidget(mShortcutInfo, new Bundle());
}
@@ -229,7 +221,6 @@ public class NotificationConversationInfo extends LinearLayout implements
OnSnoozeClickListener onSnoozeClickListener,
ConversationIconFactory conversationIconFactory,
Context userContext,
- Provider<PriorityOnboardingDialogController.Builder> builderProvider,
boolean isDeviceProvisioned,
@Main Handler mainHandler,
@Background Handler bgHandler,
@@ -258,7 +249,6 @@ public class NotificationConversationInfo extends LinearLayout implements
mBubbleMetadata = bubbleMetadata;
mBubblesManagerOptional = bubblesManagerOptional;
mShadeController = shadeController;
- mBuilderProvider = builderProvider;
mMainHandler = mainHandler;
mBgHandler = bgHandler;
mShortcutManager = shortcutManager;
@@ -342,6 +332,18 @@ public class NotificationConversationInfo extends LinearLayout implements
// bindName();
bindPackage();
bindIcon(mNotificationChannel.isImportantConversation());
+
+ mPriorityDescriptionView = findViewById(R.id.priority_summary);
+ if (willShowAsBubble() && willBypassDnd()) {
+ mPriorityDescriptionView.setText(R.string.notification_channel_summary_priority_all);
+ } else if (willShowAsBubble()) {
+ mPriorityDescriptionView.setText(R.string.notification_channel_summary_priority_bubble);
+ } else if (willBypassDnd()) {
+ mPriorityDescriptionView.setText(R.string.notification_channel_summary_priority_dnd);
+ } else {
+ mPriorityDescriptionView.setText(
+ R.string.notification_channel_summary_priority_baseline);
+ }
}
private void bindIcon(boolean important) {
@@ -428,7 +430,6 @@ public class NotificationConversationInfo extends LinearLayout implements
protected void onFinishInflate() {
super.onFinishInflate();
- mPriorityDescriptionView = findViewById(R.id.priority_summary);
mDefaultDescriptionView = findViewById(R.id.default_summary);
mSilentDescriptionView = findViewById(R.id.silence_summary);
}
@@ -552,51 +553,22 @@ public class NotificationConversationInfo extends LinearLayout implements
StackStateAnimator.ANIMATION_DURATION_STANDARD);
}
- private boolean shouldShowPriorityOnboarding() {
- return !Prefs.getBoolean(mUserContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, false);
- }
-
- private void showPriorityOnboarding() {
- View onboardingView = LayoutInflater.from(mContext)
- .inflate(R.layout.priority_onboarding_half_shell, null);
-
- boolean ignoreDnd = false;
+ private boolean willBypassDnd() {
+ boolean bypassesDnd = false;
try {
- ignoreDnd = mINotificationManager
- .getConsolidatedNotificationPolicy().priorityConversationSenders ==
- NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
+ int allowedSenders = mINotificationManager
+ .getConsolidatedNotificationPolicy().priorityConversationSenders;
+ bypassesDnd = allowedSenders == CONVERSATION_SENDERS_IMPORTANT
+ || allowedSenders == CONVERSATION_SENDERS_ANYONE;
} catch (RemoteException e) {
Log.e(TAG, "Could not check conversation senders", e);
}
+ return bypassesDnd;
+ }
- boolean showAsBubble = mBubbleMetadata != null
- && mBubbleMetadata.getAutoExpandBubble()
+ private boolean willShowAsBubble() {
+ return mBubbleMetadata != null
&& BubblesManager.areBubblesEnabled(mContext, mSbn.getUser());
-
- Drawable person = mIconFactory.getBaseIconDrawable(mShortcutInfo);
- if (person == null) {
- person = mContext.getDrawable(R.drawable.ic_person).mutate();
- TypedArray ta = mContext.obtainStyledAttributes(new int[]{android.R.attr.colorAccent});
- int colorAccent = ta.getColor(0, 0);
- ta.recycle();
- person.setTint(colorAccent);
- }
-
- PriorityOnboardingDialogController controller = mBuilderProvider.get()
- .setContext(mUserContext)
- .setView(onboardingView)
- .setIgnoresDnd(ignoreDnd)
- .setShowsAsBubble(showAsBubble)
- .setIcon(person)
- .setBadge(mIconFactory.getAppBadge(
- mPackageName, UserHandle.getUserId(mSbn.getUid())))
- .setOnSettingsClick(mOnConversationSettingsClickListener)
- .setPeopleSpaceWidgetManager(mPeopleSpaceWidgetManager)
- .setShadeController(mShadeController)
- .build();
-
- controller.init(mShortcutInfo);
- controller.show();
}
@Override
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 1a7f5b0bf5af..59b88a53b45e 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
@@ -129,7 +129,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
private final LauncherApps mLauncherApps;
private final ShortcutManager mShortcutManager;
private final UserContextProvider mContextTracker;
- private final Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider;
private final UiEventLogger mUiEventLogger;
private final ShadeController mShadeController;
private final AppWidgetManager mAppWidgetManager;
@@ -150,7 +149,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
ShortcutManager shortcutManager,
ChannelEditorDialogController channelEditorDialogController,
UserContextProvider contextTracker,
- Provider<PriorityOnboardingDialogController.Builder> builderProvider,
AssistantFeedbackController assistantFeedbackController,
Optional<BubblesManager> bubblesManagerOptional,
UiEventLogger uiEventLogger,
@@ -168,7 +166,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
mLauncherApps = launcherApps;
mShortcutManager = shortcutManager;
mContextTracker = contextTracker;
- mBuilderProvider = builderProvider;
mChannelEditorDialogController = channelEditorDialogController;
mAssistantFeedbackController = assistantFeedbackController;
mBubblesManagerOptional = bubblesManagerOptional;
@@ -503,7 +500,6 @@ public class NotificationGutsManager implements Dumpable, NotificationLifetimeEx
onSnoozeClickListener,
iconFactoryLoader,
mContextTracker.getUserContext(),
- mBuilderProvider,
mDeviceProvisionedController.isDeviceProvisioned(),
mMainHandler,
mBgHandler,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
deleted file mode 100644
index 270721ffa4b8..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/PriorityOnboardingDialogController.kt
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.notification.row
-
-import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
-import android.animation.AnimatorSet
-import android.animation.ValueAnimator
-import android.app.Dialog
-import android.content.Context
-import android.content.pm.ShortcutInfo
-import android.graphics.Color
-import android.graphics.PixelFormat
-import android.graphics.drawable.ColorDrawable
-import android.graphics.drawable.Drawable
-import android.graphics.drawable.GradientDrawable
-import android.os.Bundle
-import android.text.SpannableStringBuilder
-import android.text.style.BulletSpan
-import android.view.Gravity
-import android.view.View
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.view.Window
-import android.view.WindowInsets.Type.statusBars
-import android.view.WindowManager
-import android.view.animation.Interpolator
-import android.view.animation.PathInterpolator
-import android.widget.ImageView
-import android.widget.TextView
-import com.android.systemui.Prefs
-import com.android.systemui.R
-import com.android.systemui.animation.Interpolators.LINEAR_OUT_SLOW_IN
-import com.android.systemui.people.widget.PeopleSpaceWidgetManager
-import com.android.systemui.statusbar.notification.row.NotificationConversationInfo.OnConversationSettingsClickListener
-import com.android.systemui.statusbar.phone.ShadeController
-import javax.inject.Inject
-
-/**
- * Controller to handle presenting the priority conversations onboarding dialog
- */
-class PriorityOnboardingDialogController @Inject constructor(
- val view: View,
- val context: Context,
- private val ignoresDnd: Boolean,
- private val showsAsBubble: Boolean,
- val icon: Drawable,
- private val onConversationSettingsClickListener: OnConversationSettingsClickListener,
- val badge: Drawable,
- private val peopleSpaceWidgetManager: PeopleSpaceWidgetManager,
- private val shadeController: ShadeController
-) {
-
- private lateinit var dialog: Dialog
- private lateinit var shortcutInfo: ShortcutInfo
- private val OVERSHOOT: Interpolator = PathInterpolator(0.4f, 0f, 0.2f, 1.4f)
- private val IMPORTANCE_ANIM_DELAY = 150L
- private val IMPORTANCE_ANIM_GROW_DURATION = 250L
- private val IMPORTANCE_ANIM_SHRINK_DURATION = 200L
- private val IMPORTANCE_ANIM_SHRINK_DELAY = 25L
-
- fun init(info: ShortcutInfo) {
- shortcutInfo = info
- initDialog()
- }
-
- fun show() {
- dialog.show()
- }
-
- private fun done() {
- // Log that the user has seen the onboarding
- Prefs.putBoolean(context, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, true)
- dialog.dismiss()
- shadeController.animateCollapsePanels()
- peopleSpaceWidgetManager.requestPinAppWidget(shortcutInfo, Bundle())
- }
-
- private fun settings() {
- // Log that the user has seen the onboarding
- Prefs.putBoolean(context, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, true)
- dialog.dismiss()
- onConversationSettingsClickListener?.onClick()
- }
-
- class Builder @Inject constructor() {
- private lateinit var view: View
- private lateinit var context: Context
- private var ignoresDnd = false
- private var showAsBubble = false
- private lateinit var icon: Drawable
- private lateinit var onConversationSettingsClickListener:
- OnConversationSettingsClickListener
- private lateinit var badge: Drawable
- private lateinit var peopleSpaceWidgetManager: PeopleSpaceWidgetManager
- private lateinit var shadeController: ShadeController
-
- fun setView(v: View): Builder {
- view = v
- return this
- }
-
- fun setContext(c: Context): Builder {
- context = c
- return this
- }
-
- fun setIgnoresDnd(ignore: Boolean): Builder {
- ignoresDnd = ignore
- return this
- }
-
- fun setShowsAsBubble(bubble: Boolean): Builder {
- showAsBubble = bubble
- return this
- }
-
- fun setIcon(draw: Drawable): Builder {
- icon = draw
- return this
- }
- fun setBadge(badge: Drawable): Builder {
- this.badge = badge
- return this
- }
-
- fun setOnSettingsClick(onClick: OnConversationSettingsClickListener): Builder {
- onConversationSettingsClickListener = onClick
- return this
- }
-
- fun setShadeController(shadeController: ShadeController): Builder {
- this.shadeController = shadeController
- return this
- }
-
- fun setPeopleSpaceWidgetManager(peopleSpaceWidgetManager: PeopleSpaceWidgetManager):
- Builder {
- this.peopleSpaceWidgetManager = peopleSpaceWidgetManager
- return this
- }
-
- fun build(): PriorityOnboardingDialogController {
- val controller = PriorityOnboardingDialogController(
- view, context, ignoresDnd, showAsBubble, icon,
- onConversationSettingsClickListener, badge, peopleSpaceWidgetManager,
- shadeController)
- return controller
- }
- }
-
- private fun initDialog() {
- dialog = Dialog(context)
-
- if (dialog.window == null) {
- throw IllegalStateException("Need a window for the onboarding dialog to show")
- }
-
- dialog.window?.requestFeature(Window.FEATURE_NO_TITLE)
- // Prevent a11y readers from reading the first element in the dialog twice
- dialog.setTitle("\u00A0")
- dialog.apply {
- setContentView(view)
- setCanceledOnTouchOutside(true)
-
- findViewById<TextView>(R.id.done_button)?.setOnClickListener {
- done()
- }
-
- findViewById<TextView>(R.id.settings_button)?.setOnClickListener {
- settings()
- }
-
- findViewById<ImageView>(R.id.conversation_icon)?.setImageDrawable(icon)
- findViewById<ImageView>(R.id.icon)?.setImageDrawable(badge)
- val mImportanceRingView = findViewById<ImageView>(R.id.conversation_icon_badge_ring)
- val conversationIconBadgeBg = findViewById<ImageView>(R.id.conversation_icon_badge_bg)
-
- val ring: GradientDrawable = mImportanceRingView.drawable as GradientDrawable
- ring.mutate()
- val bg = conversationIconBadgeBg.drawable as GradientDrawable
- bg.mutate()
- val ringColor = context.getResources()
- .getColor(com.android.internal.R.color.conversation_important_highlight)
- val standardThickness = context.resources.getDimensionPixelSize(
- com.android.internal.R.dimen.importance_ring_stroke_width)
- val largeThickness = context.resources.getDimensionPixelSize(
- com.android.internal.R.dimen.importance_ring_anim_max_stroke_width)
- val standardSize = context.resources.getDimensionPixelSize(
- com.android.internal.R.dimen.importance_ring_size)
- val baseSize = standardSize - standardThickness * 2
- val largeSize = baseSize + largeThickness * 2
- val bgSize = context.resources.getDimensionPixelSize(
- com.android.internal.R.dimen.conversation_icon_size_badged)
-
- val animatorUpdateListener: ValueAnimator.AnimatorUpdateListener =
- ValueAnimator.AnimatorUpdateListener { animation ->
- val strokeWidth = animation.animatedValue as Int
- ring.setStroke(strokeWidth, ringColor)
- val newSize = baseSize + strokeWidth * 2
- ring.setSize(newSize, newSize)
- mImportanceRingView.invalidate()
- }
-
- val growAnimation: ValueAnimator = ValueAnimator.ofInt(0, largeThickness)
- growAnimation.interpolator = LINEAR_OUT_SLOW_IN
- growAnimation.duration = IMPORTANCE_ANIM_GROW_DURATION
- growAnimation.addUpdateListener(animatorUpdateListener)
-
- val shrinkAnimation: ValueAnimator =
- ValueAnimator.ofInt(largeThickness, standardThickness)
- shrinkAnimation.duration = IMPORTANCE_ANIM_SHRINK_DURATION
- shrinkAnimation.startDelay = IMPORTANCE_ANIM_SHRINK_DELAY
- shrinkAnimation.interpolator = OVERSHOOT
- shrinkAnimation.addUpdateListener(animatorUpdateListener)
- shrinkAnimation.addListener(object : AnimatorListenerAdapter() {
- override fun onAnimationStart(animation: Animator?) {
- // Shrink the badge bg so that it doesn't peek behind the animation
- bg.setSize(baseSize, baseSize)
- conversationIconBadgeBg.invalidate()
- }
-
- override fun onAnimationEnd(animation: Animator?) {
- // Reset bg back to normal size
- bg.setSize(bgSize, bgSize)
- conversationIconBadgeBg.invalidate()
- }
- })
-
- val anims = AnimatorSet()
- anims.startDelay = IMPORTANCE_ANIM_DELAY
- anims.playSequentially(growAnimation, shrinkAnimation)
-
- val gapWidth = dialog.context.getResources().getDimensionPixelSize(
- R.dimen.conversation_onboarding_bullet_gap_width)
- val description = SpannableStringBuilder()
- description.append(context.getText(R.string.priority_onboarding_show_at_top_text),
- BulletSpan(gapWidth), /* flags */0)
- description.append(System.lineSeparator())
- description.append(context.getText(R.string.priority_onboarding_show_avatar_text),
- BulletSpan(gapWidth), /* flags */0)
- if (showsAsBubble) {
- description.append(System.lineSeparator())
- description.append(context.getText(
- R.string.priority_onboarding_appear_as_bubble_text),
- BulletSpan(gapWidth), /* flags */0)
- }
- if (ignoresDnd) {
- description.append(System.lineSeparator())
- description.append(context.getText(R.string.priority_onboarding_ignores_dnd_text),
- BulletSpan(gapWidth), /* flags */0)
- }
- findViewById<TextView>(R.id.behaviors).setText(description)
-
- window?.apply {
- setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
- addFlags(wmFlags)
- setType(WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL)
- setWindowAnimations(com.android.internal.R.style.Animation_InputMethod)
-
- attributes = attributes.apply {
- format = PixelFormat.TRANSLUCENT
- title = PriorityOnboardingDialogController::class.java.simpleName
- gravity = Gravity.BOTTOM or Gravity.CENTER_HORIZONTAL
- fitInsetsTypes = attributes.fitInsetsTypes and statusBars().inv()
- width = MATCH_PARENT
- height = WRAP_CONTENT
- }
- }
- anims.start()
- }
- }
-
- private val wmFlags = (WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS
- or WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
- or WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED)
-}
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 b81619317b95..506d8a185adc 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
@@ -1000,7 +1000,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
mAmbientState.setCurrentScrollVelocity(mScroller.isFinished()
? 0
: mScroller.getCurrVelocity());
- mAmbientState.setScrollY(mOwnScrollY);
mStackScrollAlgorithm.resetViewStates(mAmbientState, getSpeedBumpIndex());
if (!isCurrentlyAnimating() && !mNeedsAnimation) {
applyCurrentState();
@@ -1143,16 +1142,18 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
*/
private void updateStackPosition() {
// Consider interpolating from an mExpansionStartY for use on lockscreen and AOD
- final float stackY = MathUtils.lerp(0, mTopPadding, mAmbientState.getExpansionFraction());
+ final float fraction = mAmbientState.getExpansionFraction();
+ final float stackY = MathUtils.lerp(0, mTopPadding, fraction);
mAmbientState.setStackY(stackY);
if (mOnStackYChanged != null) {
mOnStackYChanged.run();
}
- final float shadeBottom = getHeight() - getEmptyBottomMargin();
- mAmbientState.setStackEndHeight(shadeBottom - mTopPadding);
+ final float stackEndHeight = getHeight() - getEmptyBottomMargin() - mTopPadding;
+ mAmbientState.setStackEndHeight(stackEndHeight);
mAmbientState.setStackHeight(
- MathUtils.lerp(0, shadeBottom - mTopPadding, mAmbientState.getExpansionFraction()));
+ MathUtils.lerp(stackEndHeight * StackScrollAlgorithm.START_FRACTION,
+ stackEndHeight, fraction));
}
void setOnStackYChanged(Runnable onStackYChanged) {
@@ -2439,18 +2440,6 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
}
@ShadeViewRefactor(RefactorComponent.COORDINATOR)
- public int getPeekHeight() {
- final ExpandableView firstChild = getFirstChildNotGone();
- final int firstChildMinHeight = firstChild != null ? firstChild.getCollapsedHeight()
- : mCollapsedSize;
- int shelfHeight = 0;
- if (getLastVisibleSection() != null && mShelf.getVisibility() != GONE) {
- shelfHeight = mShelf.getIntrinsicHeight();
- }
- return mIntrinsicPadding + firstChildMinHeight + shelfHeight;
- }
-
- @ShadeViewRefactor(RefactorComponent.COORDINATOR)
private int clampPadding(int desiredPadding) {
return Math.max(desiredPadding, mIntrinsicPadding);
}
@@ -4542,7 +4531,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements Dumpable
// We still want to call the normal scrolled changed for accessibility reasons
onScrollChanged(mScrollX, ownScrollY, mScrollX, mOwnScrollY);
mOwnScrollY = ownScrollY;
- updateChildren();
+ mAmbientState.setScrollY(mOwnScrollY);
updateOnScrollChange();
updateStackPosition();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index b039df3f32af..f7eb574feac3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -1061,10 +1061,6 @@ public class NotificationStackScrollLayoutController {
mView.setUnlockHintRunning(running);
}
- public float getPeekHeight() {
- return mView.getPeekHeight();
- }
-
public boolean isFooterViewNotGone() {
return mView.isFooterViewNotGone();
}
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 c1a5f148d4ca..413048d6ce54 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
@@ -42,6 +42,8 @@ import java.util.List;
*/
public class StackScrollAlgorithm {
+ public static final float START_FRACTION = 0.3f;
+
private static final String LOG_TAG = "StackScrollAlgorithm";
private final ViewGroup mHostView;
@@ -442,7 +444,8 @@ public class StackScrollAlgorithm {
maxViewHeight = algorithmState.viewHeightBeforeShelf;
}
}
- viewState.height = (int) MathUtils.lerp(0, maxViewHeight, expansionFraction);
+ viewState.height = (int) MathUtils.lerp(maxViewHeight * START_FRACTION, maxViewHeight,
+ expansionFraction);
}
currentYPosition += viewState.height + expansionFraction * mPaddingBetweenElements;
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 76657ad5ab07..16bed6f3f38d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragment.java
@@ -43,7 +43,6 @@ import com.android.systemui.animation.Interpolators;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.statusbar.events.SystemStatusAnimationCallback;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.StatusBarIconController.DarkIconManager;
@@ -92,7 +91,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
private CommandQueue mCommandQueue;
private OngoingCallController mOngoingCallController;
private final SystemStatusAnimationScheduler mAnimationScheduler;
- private final PrivacyDotViewController mDotViewController;
+ private final StatusBarLocationPublisher mLocationPublisher;
private NotificationIconAreaController mNotificationIconAreaController;
private List<String> mBlockedIcons = new ArrayList<>();
@@ -120,12 +119,12 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
public CollapsedStatusBarFragment(
OngoingCallController ongoingCallController,
SystemStatusAnimationScheduler animationScheduler,
- PrivacyDotViewController dotViewController,
+ StatusBarLocationPublisher locationPublisher,
NotificationIconAreaController notificationIconAreaController
) {
mOngoingCallController = ongoingCallController;
mAnimationScheduler = animationScheduler;
- mDotViewController = dotViewController;
+ mLocationPublisher = locationPublisher;
mNotificationIconAreaController = notificationIconAreaController;
}
@@ -540,7 +539,7 @@ public class CollapsedStatusBarFragment extends Fragment implements CommandQueue
int leftMargin = left - mStatusBar.getLeft();
int rightMargin = mStatusBar.getRight() - right;
- mDotViewController.setStatusBarMargins(leftMargin, rightMargin);
+ mLocationPublisher.updateStatusBarMargin(leftMargin, rightMargin);
}
// Listen for view end changes of PhoneStatusBarView and publish that to the privacy dot
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 0b747f94e935..42f301d2f222 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -118,7 +118,6 @@ public class HeadsUpTouchHelper implements Gefingerpoken {
mPanel.setPanelScrimMinFraction(maxPanelHeight > 0f
? (float) startHeight / maxPanelHeight : 0f);
mPanel.startExpandMotion(x, y, true /* startTracking */, startHeight);
- mPanel.startExpandingFromPeek();
// This call needs to be after the expansion start otherwise we will get a
// flicker of one frame as it's not expanded yet.
mHeadsUpManager.unpinAll(true);
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 9787a9446019..3181f520dca2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelper.java
@@ -22,12 +22,12 @@ import android.app.Notification;
import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
-import android.util.Log;
import com.android.internal.statusbar.NotificationVisibility;
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.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -41,21 +41,17 @@ import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
import java.util.ArrayList;
-import java.util.List;
import java.util.Objects;
/**
* A helper class dealing with the alert interactions between {@link NotificationGroupManagerLegacy}
* and {@link HeadsUpManager}. In particular, this class deals with keeping
- * the correct notification in a group alerting based off the group suppression and alertOverride.
+ * the correct notification in a group alerting based off the group suppression.
*/
public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedListener,
StateListener {
private static final long ALERT_TRANSFER_TIMEOUT = 300;
- private static final String TAG = "NotifGroupAlertTransfer";
- private static final boolean DEBUG = StatusBar.DEBUG;
- private static final boolean SPEW = StatusBar.SPEW;
/**
* The list of entries containing group alert metadata for each group. Keyed by group key.
@@ -146,98 +142,41 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
@Override
public void onGroupSuppressionChanged(NotificationGroup group, boolean suppressed) {
- if (DEBUG) {
- Log.d(TAG, "!! onGroupSuppressionChanged: group.summary=" + group.summary
- + " suppressed=" + suppressed);
- }
- NotificationEntry oldAlertOverride = group.alertOverride;
- onGroupChanged(group, oldAlertOverride);
- }
-
- @Override
- public void onGroupAlertOverrideChanged(NotificationGroup group,
- @Nullable NotificationEntry oldAlertOverride,
- @Nullable NotificationEntry newAlertOverride) {
- if (DEBUG) {
- Log.d(TAG, "!! onGroupAlertOverrideChanged: group.summary=" + group.summary
- + " oldAlertOverride=" + oldAlertOverride
- + " newAlertOverride=" + newAlertOverride);
- }
- onGroupChanged(group, oldAlertOverride);
- }
- };
-
- /**
- * Called when either the suppressed or alertOverride fields of the group changed
- *
- * @param group the group which changed
- * @param oldAlertOverride the previous value of group.alertOverride
- */
- private void onGroupChanged(NotificationGroup group,
- NotificationEntry oldAlertOverride) {
- // Group summary can be null if we are no longer suppressed because the summary was
- // removed. In that case, we don't need to alert the summary.
- if (group.summary == null) {
- if (DEBUG) {
- Log.d(TAG, "onGroupChanged: summary is null");
- }
- return;
- }
- if (group.suppressed || group.alertOverride != null) {
- checkForForwardAlertTransfer(group.summary, oldAlertOverride);
- } else {
- if (DEBUG) {
- Log.d(TAG, "onGroupChanged: maybe transfer back");
- }
- GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(mGroupManager.getGroupKey(
- group.summary.getSbn()));
- // Group is no longer suppressed or overridden.
- // We should check if we need to transfer the alert back to the summary.
- if (groupAlertEntry.mAlertSummaryOnNextAddition) {
- if (!mHeadsUpManager.isAlerting(group.summary.getKey())) {
- alertNotificationWhenPossible(group.summary);
+ if (suppressed) {
+ if (mHeadsUpManager.isAlerting(group.summary.getKey())) {
+ handleSuppressedSummaryAlerted(group.summary, mHeadsUpManager);
}
- groupAlertEntry.mAlertSummaryOnNextAddition = false;
} else {
- checkShouldTransferBack(groupAlertEntry);
+ // Group summary can be null if we are no longer suppressed because the summary was
+ // removed. In that case, we don't need to alert the summary.
+ if (group.summary == null) {
+ return;
+ }
+ GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(mGroupManager.getGroupKey(
+ group.summary.getSbn()));
+ // 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 (!mHeadsUpManager.isAlerting(group.summary.getKey())) {
+ alertNotificationWhenPossible(group.summary, mHeadsUpManager);
+ }
+ groupAlertEntry.mAlertSummaryOnNextAddition = false;
+ } else {
+ checkShouldTransferBack(groupAlertEntry);
+ }
}
}
- }
+ };
@Override
public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
- if (DEBUG) {
- Log.d(TAG, "!! onHeadsUpStateChanged: entry=" + entry + " isHeadsUp=" + isHeadsUp);
- }
- if (isHeadsUp && entry.getSbn().getNotification().isGroupSummary()) {
- // a group summary is alerting; trigger the forward transfer checks
- checkForForwardAlertTransfer(entry, /* oldAlertOverride */ null);
- }
+ onAlertStateChanged(entry, isHeadsUp, mHeadsUpManager);
}
- /**
- * Handles changes in a group's suppression or alertOverride, but where at least one of those
- * conditions is still true (either the group is suppressed, the group has an alertOverride,
- * or both). The method determined which kind of child needs to receive the alert, finds the
- * entry currently alerting, and makes the transfer.
- *
- * Internally, this is handled with two main cases: the override needs the alert, or there is
- * no override but the summary is suppressed (so an isolated child needs the alert).
- *
- * @param summary the notification entry of the summary of the logical group.
- * @param oldAlertOverride the former value of group.alertOverride, before whatever event
- * required us to check for for a transfer condition.
- */
- private void checkForForwardAlertTransfer(NotificationEntry summary,
- NotificationEntry oldAlertOverride) {
- if (DEBUG) {
- Log.d(TAG, "checkForForwardAlertTransfer: enter");
- }
- NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn());
- if (group != null && group.alertOverride != null) {
- handleOverriddenSummaryAlerted(summary);
- } else if (mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn())) {
- handleSuppressedSummaryAlerted(summary, oldAlertOverride);
+ private void onAlertStateChanged(NotificationEntry entry, boolean isAlerting,
+ AlertingNotificationManager alertManager) {
+ if (isAlerting && mGroupManager.isSummaryOfSuppressedGroup(entry.getSbn())) {
+ handleSuppressedSummaryAlerted(entry, alertManager);
}
}
@@ -247,16 +186,9 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
// see as early as we can if we need to abort a transfer.
@Override
public void onPendingEntryAdded(NotificationEntry entry) {
- if (DEBUG) {
- Log.d(TAG, "!! onPendingEntryAdded: entry=" + entry);
- }
String groupKey = mGroupManager.getGroupKey(entry.getSbn());
GroupAlertEntry groupAlertEntry = mGroupAlertEntries.get(groupKey);
- if (groupAlertEntry != null && groupAlertEntry.mGroup.alertOverride == null) {
- // new pending group entries require us to transfer back from the child to the
- // group, but alertOverrides are only present in very limited circumstances, so
- // while it's possible the group should ALSO alert, the previous detection which set
- // this alertOverride won't be invalidated by this notification added to this group.
+ if (groupAlertEntry != null) {
checkShouldTransferBack(groupAlertEntry);
}
}
@@ -330,128 +262,43 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
}
/**
- * Handles the scenario where a summary that has been suppressed is itself, or has a former
- * alertOverride (in the form of an isolated logical child) which was alerted. A suppressed
+ * Handles the scenario where a summary that has been suppressed is alerted. A suppressed
* summary should for all intents and purposes be invisible to the user and as a result should
* not alert. When this is the case, it is our responsibility to pass the alert to the
* appropriate child which will be the representative notification alerting for the group.
*
- * @param summary the summary that is suppressed and (potentially) alerting
- * @param oldAlertOverride the alertOverride before whatever event triggered this method. If
- * the alert override was removed, this will be the entry that should
- * be transferred back from.
+ * @param summary the summary that is suppressed and alerting
+ * @param alertManager the alert manager that manages the alerting summary
*/
private void handleSuppressedSummaryAlerted(@NonNull NotificationEntry summary,
- NotificationEntry oldAlertOverride) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: summary=" + summary);
- }
+ @NonNull AlertingNotificationManager alertManager) {
+ StatusBarNotification sbn = summary.getSbn();
GroupAlertEntry groupAlertEntry =
- mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn()));
-
+ mGroupAlertEntries.get(mGroupManager.getGroupKey(sbn));
if (!mGroupManager.isSummaryOfSuppressedGroup(summary.getSbn())
+ || !alertManager.isAlerting(sbn.getKey())
|| groupAlertEntry == null) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: invalid state");
- }
- return;
- }
- boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey());
- boolean priorityIsAlerting = oldAlertOverride != null
- && mHeadsUpManager.isAlerting(oldAlertOverride.getKey());
- if (!summaryIsAlerting && !priorityIsAlerting) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: no summary or override alerting");
- }
return;
}
if (pendingInflationsWillAddChildren(groupAlertEntry.mGroup)) {
// New children will actually be added to this group, let's not transfer the alert.
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: pending inflations");
- }
return;
}
NotificationEntry child =
mGroupManager.getLogicalChildren(summary.getSbn()).iterator().next();
- if (summaryIsAlerting) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: transfer summary -> child");
- }
- tryTransferAlertState(summary, /*from*/ summary, /*to*/ child, groupAlertEntry);
- return;
- }
- // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure
- // it's not too late to transfer back, then transfer the alert from the oldAlertOverride to
- // the isolated child which should receive the alert.
- if (!canStillTransferBack(groupAlertEntry)) {
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: transfer from override: too late");
- }
- return;
- }
-
- if (DEBUG) {
- Log.d(TAG, "handleSuppressedSummaryAlerted: transfer override -> child");
- }
- tryTransferAlertState(summary, /*from*/ oldAlertOverride, /*to*/ child, groupAlertEntry);
- }
-
- /**
- * Checks for and handles the scenario where the given entry is the summary of a group which
- * has an alertOverride, and either the summary itself or one of its logical isolated children
- * is currently alerting (which happens if the summary is suppressed).
- */
- private void handleOverriddenSummaryAlerted(NotificationEntry summary) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: summary=" + summary);
- }
- GroupAlertEntry groupAlertEntry =
- mGroupAlertEntries.get(mGroupManager.getGroupKey(summary.getSbn()));
- NotificationGroup group = mGroupManager.getGroupForSummary(summary.getSbn());
- if (group == null || group.alertOverride == null || groupAlertEntry == null) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: invalid state");
- }
- return;
- }
- boolean summaryIsAlerting = mHeadsUpManager.isAlerting(summary.getKey());
- if (summaryIsAlerting) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: transfer summary -> override");
- }
- tryTransferAlertState(summary, /*from*/ summary, group.alertOverride, groupAlertEntry);
- return;
- }
- // Summary didn't have the alert, so we're in "transfer back" territory. First, make sure
- // it's not too late to transfer back, then remove the alert from any of the logical
- // children, and if one of them was alerting, we can alert the override.
- if (!canStillTransferBack(groupAlertEntry)) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: transfer from child: too late");
- }
- return;
- }
- List<NotificationEntry> children = mGroupManager.getLogicalChildren(summary.getSbn());
- if (children == null) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: no children");
- }
- return;
- }
- children.remove(group.alertOverride); // do not release the alert on our desired destination
- boolean releasedChild = releaseChildAlerts(children);
- if (releasedChild) {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: transfer child -> override");
+ if (child != null) {
+ if (child.getRow().keepInParent()
+ || child.isRowRemoved()
+ || child.isRowDismissed()) {
+ // The notification is actually already removed. No need to alert it.
+ return;
}
- tryTransferAlertState(summary, /*from*/ null, group.alertOverride, groupAlertEntry);
- } else {
- if (DEBUG) {
- Log.d(TAG, "handleOverriddenSummaryAlerted: no child alert released");
+ if (!alertManager.isAlerting(child.getKey()) && onlySummaryAlerts(summary)) {
+ groupAlertEntry.mLastAlertTransferTime = SystemClock.elapsedRealtime();
}
+ transferAlertState(summary, child, alertManager);
}
}
@@ -460,37 +307,14 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
* immediately to have the incorrect one up as short as possible. The second should alert
* when possible.
*
- * @param summary entry of the summary
* @param fromEntry entry to transfer alert from
* @param toEntry entry to transfer to
+ * @param alertManager alert manager for the alert type
*/
- private void tryTransferAlertState(
- NotificationEntry summary,
- NotificationEntry fromEntry,
- NotificationEntry toEntry,
- GroupAlertEntry groupAlertEntry) {
- if (toEntry != null) {
- if (toEntry.getRow().keepInParent()
- || toEntry.isRowRemoved()
- || toEntry.isRowDismissed()) {
- // The notification is actually already removed. No need to alert it.
- return;
- }
- if (!mHeadsUpManager.isAlerting(toEntry.getKey()) && onlySummaryAlerts(summary)) {
- groupAlertEntry.mLastAlertTransferTime = SystemClock.elapsedRealtime();
- }
- if (DEBUG) {
- Log.d(TAG, "transferAlertState: fromEntry=" + fromEntry + " toEntry=" + toEntry);
- }
- transferAlertState(fromEntry, toEntry);
- }
- }
- private void transferAlertState(@Nullable NotificationEntry fromEntry,
- @NonNull NotificationEntry toEntry) {
- if (fromEntry != null) {
- mHeadsUpManager.removeNotification(fromEntry.getKey(), true /* releaseImmediately */);
- }
- alertNotificationWhenPossible(toEntry);
+ private void transferAlertState(@NonNull NotificationEntry fromEntry, @NonNull NotificationEntry toEntry,
+ @NonNull AlertingNotificationManager alertManager) {
+ alertManager.removeNotification(fromEntry.getKey(), true /* releaseImmediately */);
+ alertNotificationWhenPossible(toEntry, alertManager);
}
/**
@@ -502,13 +326,11 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
* more children are coming. Thus, if a child is added within a certain timeframe after we
* transfer, we back out and alert the summary again.
*
- * An alert can only transfer back within a small window of time after a transfer away from the
- * summary to a child happened.
- *
* @param groupAlertEntry group alert entry to check
*/
private void checkShouldTransferBack(@NonNull GroupAlertEntry groupAlertEntry) {
- if (canStillTransferBack(groupAlertEntry)) {
+ if (SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime
+ < ALERT_TRANSFER_TIMEOUT) {
NotificationEntry summary = groupAlertEntry.mGroup.summary;
if (!onlySummaryAlerts(summary)) {
@@ -516,17 +338,30 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
}
ArrayList<NotificationEntry> children = mGroupManager.getLogicalChildren(
summary.getSbn());
- int numActiveChildren = children.size();
+ int numChildren = children.size();
int numPendingChildren = getPendingChildrenNotAlerting(groupAlertEntry.mGroup);
- int numChildren = numActiveChildren + numPendingChildren;
+ numChildren += numPendingChildren;
if (numChildren <= 1) {
return;
}
- boolean releasedChild = releaseChildAlerts(children);
+ boolean releasedChild = false;
+ for (int i = 0; i < children.size(); i++) {
+ NotificationEntry entry = children.get(i);
+ if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.getKey())) {
+ releasedChild = true;
+ mHeadsUpManager.removeNotification(
+ entry.getKey(), true /* releaseImmediately */);
+ }
+ if (mPendingAlerts.containsKey(entry.getKey())) {
+ // This is the child that would've been removed if it was inflated.
+ releasedChild = true;
+ mPendingAlerts.get(entry.getKey()).mAbortOnInflation = true;
+ }
+ }
if (releasedChild && !mHeadsUpManager.isAlerting(summary.getKey())) {
- boolean notifyImmediately = numActiveChildren > 1;
+ boolean notifyImmediately = (numChildren - numPendingChildren) > 1;
if (notifyImmediately) {
- alertNotificationWhenPossible(summary);
+ alertNotificationWhenPossible(summary, mHeadsUpManager);
} else {
// Should wait until the pending child inflates before alerting.
groupAlertEntry.mAlertSummaryOnNextAddition = true;
@@ -536,61 +371,25 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
}
}
- private boolean canStillTransferBack(@NonNull GroupAlertEntry groupAlertEntry) {
- return SystemClock.elapsedRealtime() - groupAlertEntry.mLastAlertTransferTime
- < ALERT_TRANSFER_TIMEOUT;
- }
-
- private boolean releaseChildAlerts(List<NotificationEntry> children) {
- boolean releasedChild = false;
- if (SPEW) {
- Log.d(TAG, "releaseChildAlerts: numChildren=" + children.size());
- }
- for (int i = 0; i < children.size(); i++) {
- NotificationEntry entry = children.get(i);
- if (SPEW) {
- Log.d(TAG, "releaseChildAlerts: checking i=" + i + " entry=" + entry
- + " onlySummaryAlerts=" + onlySummaryAlerts(entry)
- + " isAlerting=" + mHeadsUpManager.isAlerting(entry.getKey())
- + " isPendingAlert=" + mPendingAlerts.containsKey(entry.getKey()));
- }
- if (onlySummaryAlerts(entry) && mHeadsUpManager.isAlerting(entry.getKey())) {
- releasedChild = true;
- mHeadsUpManager.removeNotification(
- entry.getKey(), true /* releaseImmediately */);
- }
- if (mPendingAlerts.containsKey(entry.getKey())) {
- // This is the child that would've been removed if it was inflated.
- releasedChild = true;
- mPendingAlerts.get(entry.getKey()).mAbortOnInflation = true;
- }
- }
- if (SPEW) {
- Log.d(TAG, "releaseChildAlerts: didRelease=" + releasedChild);
- }
- return releasedChild;
- }
-
/**
* Tries to alert the notification. If its content view is not inflated, we inflate and continue
* when the entry finishes inflating the view.
*
* @param entry entry to show
+ * @param alertManager alert manager for the alert type
*/
- private void alertNotificationWhenPossible(@NonNull NotificationEntry entry) {
- @InflationFlag int contentFlag = mHeadsUpManager.getContentFlag();
+ private void alertNotificationWhenPossible(@NonNull NotificationEntry entry,
+ @NonNull AlertingNotificationManager alertManager) {
+ @InflationFlag int contentFlag = alertManager.getContentFlag();
final RowContentBindParams params = mRowContentBindStage.getStageParams(entry);
if ((params.getContentViews() & contentFlag) == 0) {
- if (DEBUG) {
- Log.d(TAG, "alertNotificationWhenPossible: async requestRebind entry=" + entry);
- }
mPendingAlerts.put(entry.getKey(), new PendingAlertInfo(entry));
params.requireContentViews(contentFlag);
mRowContentBindStage.requestRebind(entry, en -> {
PendingAlertInfo alertInfo = mPendingAlerts.remove(entry.getKey());
if (alertInfo != null) {
if (alertInfo.isStillValid()) {
- alertNotificationWhenPossible(entry);
+ alertNotificationWhenPossible(entry, mHeadsUpManager);
} else {
// The transfer is no longer valid. Free the content.
mRowContentBindStage.getStageParams(entry).markContentViewsFreeable(
@@ -601,16 +400,10 @@ public class NotificationGroupAlertTransferHelper implements OnHeadsUpChangedLis
});
return;
}
- if (mHeadsUpManager.isAlerting(entry.getKey())) {
- if (DEBUG) {
- Log.d(TAG, "alertNotificationWhenPossible: continue alerting entry=" + entry);
- }
- mHeadsUpManager.updateNotification(entry.getKey(), true /* alert */);
+ if (alertManager.isAlerting(entry.getKey())) {
+ alertManager.updateNotification(entry.getKey(), true /* alert */);
} else {
- if (DEBUG) {
- Log.d(TAG, "alertNotificationWhenPossible: start alerting entry=" + entry);
- }
- mHeadsUpManager.showNotification(entry);
+ alertManager.showNotification(entry);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index c79e503379bd..20b37e26dcee 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -22,7 +22,6 @@ import static androidx.constraintlayout.widget.ConstraintSet.END;
import static androidx.constraintlayout.widget.ConstraintSet.PARENT_ID;
import static androidx.constraintlayout.widget.ConstraintSet.START;
-import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_NOTIFICATION_SHADE_QS_EXPAND_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
@@ -1730,7 +1729,6 @@ public class NotificationPanelViewController extends PanelViewController {
return;
}
mExpectingSynthesizedDown = true;
- InteractionJankMonitor.getInstance().begin(mView, CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
onTrackingStarted();
updatePanelExpanded();
}
@@ -2075,20 +2073,18 @@ public class NotificationPanelViewController extends PanelViewController {
setQsExpansionEnabled(mAmbientState.getScrollY() == 0);
int radius = mScrimCornerRadius;
- if (visible || !mShouldUseSplitNotificationShade) {
- if (!mShouldUseSplitNotificationShade) {
- top = (int) Math.min(qsPanelBottomY, notificationTop);
- bottom = getView().getBottom();
- left = getView().getLeft();
- right = getView().getRight();
- radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius,
- Math.min(top / (float) mScrimCornerRadius, 1f));
- } else {
- top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding);
- bottom = mNotificationStackScrollLayoutController.getHeight();
- left = mNotificationStackScrollLayoutController.getLeft();
- right = mNotificationStackScrollLayoutController.getRight();
- }
+ if (!mShouldUseSplitNotificationShade) {
+ top = (int) Math.min(qsPanelBottomY, notificationTop);
+ bottom = getView().getBottom();
+ left = getView().getLeft();
+ right = getView().getRight();
+ radius = (int) MathUtils.lerp(mScreenCornerRadius, mScrimCornerRadius,
+ Math.min(top / (float) mScrimCornerRadius, 1f));
+ } else if (qsPanelBottomY > 0) { // so bounds are empty on lockscreen
+ top = Math.min(qsPanelBottomY, mSplitShadeNotificationsTopPadding);
+ bottom = mNotificationStackScrollLayoutController.getHeight();
+ left = mNotificationStackScrollLayoutController.getLeft();
+ right = mNotificationStackScrollLayoutController.getRight();
}
// Fancy clipping for quick settings
@@ -2698,6 +2694,7 @@ public class NotificationPanelViewController extends PanelViewController {
mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
mIsExpanding = false;
mMediaHierarchyManager.setCollapsingShadeFromQS(false);
+ mMediaHierarchyManager.setQsExpanded(mQsExpanded);
if (isFullyCollapsed()) {
DejankUtils.postAfterTraversal(new Runnable() {
@Override
@@ -2834,15 +2831,6 @@ public class NotificationPanelViewController extends PanelViewController {
}
@Override
- protected float getPeekHeight() {
- if (mNotificationStackScrollLayoutController.getNotGoneChildCount() > 0) {
- return mNotificationStackScrollLayoutController.getPeekHeight();
- } else {
- return mQsMinExpansionHeight;
- }
- }
-
- @Override
protected boolean shouldUseDismissingAnimation() {
return mBarState != StatusBarState.SHADE && (mKeyguardStateController.canDismissLockScreen()
|| !isTracking());
@@ -3709,6 +3697,12 @@ public class NotificationPanelViewController extends PanelViewController {
@Override
public void flingTopOverscroll(float velocity, boolean open) {
+ // in split shade mode we want to expand/collapse QS only when touch happens within QS
+ if (mShouldUseSplitNotificationShade
+ && (mInitialTouchX < mQsFrame.getX()
+ || mInitialTouchX > mQsFrame.getX() + mQsFrame.getWidth())) {
+ return;
+ }
mLastOverscroll = 0f;
mQsExpansionFromOverscroll = false;
setQsExpansion(mQsExpansionHeight);
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 28cfe214dd3a..64e2c1c5d268 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -212,7 +212,6 @@ public abstract class PanelBar extends FrameLayout {
} else {
pv.resetViews(false /* animate */);
pv.setExpandedFraction(0); // just in case
- pv.cancelPeek();
}
if (DEBUG) LOG("collapsePanel: animate=%s waiting=%s", animate, waiting);
if (!waiting && mState != STATE_CLOSED) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index d0bdf40d1f0b..f9a644fe2def 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -68,8 +68,6 @@ import java.util.ArrayList;
public abstract class PanelViewController {
public static final boolean DEBUG = PanelBar.DEBUG;
public static final String TAG = PanelView.class.getSimpleName();
- private static final int INITIAL_OPENING_PEEK_DURATION = 200;
- private static final int PEEK_ANIMATION_DURATION = 360;
private static final int NO_FIXED_DURATION = -1;
private static final long SHADE_OPEN_SPRING_OUT_DURATION = 350L;
private static final long SHADE_OPEN_SPRING_BACK_DURATION = 200L;
@@ -96,7 +94,6 @@ public abstract class PanelViewController {
protected HeadsUpManagerPhone mHeadsUpManager;
protected final StatusBarTouchableRegionManager mStatusBarTouchableRegionManager;
- private float mPeekHeight;
private float mHintDistance;
private float mInitialOffsetOnTouch;
private boolean mCollapsedAndHeadsUpOnDown;
@@ -106,8 +103,6 @@ public abstract class PanelViewController {
private boolean mHasLayoutedSinceDown;
private float mUpdateFlingVelocity;
private boolean mUpdateFlingOnLayout;
- private boolean mPeekTouching;
- private boolean mJustPeeked;
private boolean mClosing;
protected boolean mTracking;
private boolean mTouchSlopExceeded;
@@ -125,7 +120,6 @@ public abstract class PanelViewController {
private boolean mHandlingPointerUp;
private ValueAnimator mHeightAnimator;
- private ObjectAnimator mPeekAnimator;
private final VelocityTracker mVelocityTracker = VelocityTracker.obtain();
private FlingAnimationUtils mFlingAnimationUtils;
private FlingAnimationUtils mFlingAnimationUtilsClosing;
@@ -195,40 +189,6 @@ public abstract class PanelViewController {
}
}
- private void runPeekAnimation(long duration, float peekHeight, boolean collapseWhenFinished) {
- mPeekHeight = peekHeight;
- if (DEBUG) logf("peek to height=%.1f", mPeekHeight);
- if (mHeightAnimator != null) {
- return;
- }
- if (mPeekAnimator != null) {
- mPeekAnimator.cancel();
- }
- mPeekAnimator = ObjectAnimator.ofFloat(this, "expandedHeight", mPeekHeight).setDuration(
- duration);
- mPeekAnimator.setInterpolator(Interpolators.LINEAR_OUT_SLOW_IN);
- mPeekAnimator.addListener(new AnimatorListenerAdapter() {
- private boolean mCancelled;
-
- @Override
- public void onAnimationCancel(Animator animation) {
- mCancelled = true;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- mPeekAnimator = null;
- if (!mCancelled && collapseWhenFinished) {
- mView.postOnAnimation(mPostCollapseRunnable);
- }
-
- }
- });
- notifyExpandingStarted();
- mPeekAnimator.start();
- mJustPeeked = true;
- }
-
protected AmbientState getAmbientState() {
return mAmbientState;
}
@@ -336,8 +296,6 @@ public abstract class PanelViewController {
}
private void startOpening(MotionEvent event) {
- runPeekAnimation(INITIAL_OPENING_PEEK_DURATION, getOpeningHeight(),
- false /* collapseWhenFinished */);
notifyBarPanelExpansionChanged();
maybeVibrateOnOpening();
@@ -375,10 +333,6 @@ public abstract class PanelViewController {
return Math.abs(yDiff) >= Math.abs(xDiff);
}
- protected void startExpandingFromPeek() {
- mStatusBar.handlePeekToExpandTransistion();
- }
-
protected void startExpandMotion(float newX, float newY, boolean startTracking,
float expandedHeight) {
if (!mHandlingPointerUp) {
@@ -442,18 +396,6 @@ public abstract class PanelViewController {
if (mUpdateFlingOnLayout) {
mUpdateFlingVelocity = vel;
}
- } else if (mPanelClosedOnDown && !mHeadsUpManager.hasPinnedHeadsUp() && !mTracking
- && !mStatusBar.isBouncerShowing()
- && !mKeyguardStateController.isKeyguardFadingAway()) {
- long timePassed = SystemClock.uptimeMillis() - mDownTime;
- if (timePassed < ViewConfiguration.getLongPressTimeout()) {
- // Let's show the user that they can actually expand the panel
- runPeekAnimation(
- PEEK_ANIMATION_DURATION, getPeekHeight(), true /* collapseWhenFinished */);
- } else {
- // We need to collapse the panel since we peeked to the small height.
- mView.postOnAnimation(mPostCollapseRunnable);
- }
} else if (!mStatusBar.isBouncerShowing()
&& !mStatusBarKeyguardViewManager.isShowingAlternateAuthOrAnimating()) {
boolean expands = onEmptySpaceClick(mInitialTouchX);
@@ -461,7 +403,6 @@ public abstract class PanelViewController {
}
mVelocityTracker.clear();
- mPeekTouching = false;
}
protected float getCurrentExpandVelocity() {
@@ -582,7 +523,6 @@ public abstract class PanelViewController {
protected void fling(float vel, boolean expand, float collapseSpeedUpFactor,
boolean expandBecauseOfFalsing) {
- cancelPeek();
float target = expand ? getMaxPanelHeight() : 0;
if (!expand) {
mClosing = true;
@@ -638,6 +578,12 @@ public abstract class PanelViewController {
private boolean mCancelled;
@Override
+ public void onAnimationStart(Animator animation) {
+ InteractionJankMonitor.getInstance()
+ .begin(mView, CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+ }
+
+ @Override
public void onAnimationCancel(Animator animation) {
mCancelled = true;
}
@@ -718,10 +664,6 @@ public abstract class PanelViewController {
return;
}
- if (mPeekAnimator != null || mPeekTouching) {
- return;
- }
-
if (mTracking && !isTrackingBlocked()) {
return;
}
@@ -884,20 +826,6 @@ public abstract class PanelViewController {
}
};
- public void cancelPeek() {
- boolean cancelled = false;
- if (mPeekAnimator != null) {
- cancelled = true;
- mPeekAnimator.cancel();
- }
-
- if (cancelled) {
- // When peeking, we already tell mBar that we expanded ourselves. Make sure that we also
- // notify mBar that we might have closed ourselves.
- notifyBarPanelExpansionChanged();
- }
- }
-
public void expand(final boolean animate) {
if (!isFullyCollapsed() && !isCollapsing()) {
return;
@@ -907,7 +835,6 @@ public abstract class PanelViewController {
mAnimateAfterExpanding = animate;
mUpdateFlingOnLayout = false;
abortAnimations();
- cancelPeek();
if (mTracking) {
onTrackingStopped(true /* expands */); // The panel is expanded after this call.
}
@@ -958,7 +885,6 @@ public abstract class PanelViewController {
}
private void abortAnimations() {
- cancelPeek();
cancelHeightAnimator();
mView.removeCallbacks(mPostCollapseRunnable);
mView.removeCallbacks(mFlingCollapseRunnable);
@@ -976,7 +902,6 @@ public abstract class PanelViewController {
if (mHeightAnimator != null || mTracking) {
return;
}
- cancelPeek();
notifyExpandingStarted();
startUnlockHintAnimationPhase1(() -> {
notifyExpandingFinished();
@@ -1079,7 +1004,7 @@ public abstract class PanelViewController {
if (mBar != null) {
mBar.panelExpansionChanged(
mExpandedFraction,
- mExpandedFraction > 0f || mPeekAnimator != null || mInstantExpanding
+ mExpandedFraction > 0f || mInstantExpanding
|| isPanelVisibleBecauseOfHeadsUp() || mTracking
|| mHeightAnimator != null);
}
@@ -1119,19 +1044,16 @@ public abstract class PanelViewController {
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(String.format("[PanelView(%s): expandedHeight=%f maxPanelHeight=%d closing=%s"
- + " tracking=%s justPeeked=%s peekAnim=%s%s timeAnim=%s%s "
+ + " tracking=%s timeAnim=%s%s "
+ "touchDisabled=%s" + "]",
this.getClass().getSimpleName(), getExpandedHeight(), getMaxPanelHeight(),
- mClosing ? "T" : "f", mTracking ? "T" : "f", mJustPeeked ? "T" : "f", mPeekAnimator,
- ((mPeekAnimator != null && mPeekAnimator.isStarted()) ? " (started)" : ""),
- mHeightAnimator,
+ mClosing ? "T" : "f", mTracking ? "T" : "f", mHeightAnimator,
((mHeightAnimator != null && mHeightAnimator.isStarted()) ? " (started)" : ""),
mTouchDisabled ? "T" : "f"));
}
public abstract void resetViews(boolean animate);
- protected abstract float getPeekHeight();
/**
* @return whether "Clear all" button will be visible when the panel is fully expanded
@@ -1206,10 +1128,8 @@ public abstract class PanelViewController {
mAnimatingOnDown = mHeightAnimator != null;
mMinExpandHeight = 0.0f;
mDownTime = SystemClock.uptimeMillis();
- if (mAnimatingOnDown && mClosing && !mHintAnimationRunning
- || mPeekAnimator != null) {
+ if (mAnimatingOnDown && mClosing && !mHintAnimationRunning) {
cancelHeightAnimator();
- cancelPeek();
mTouchSlopExceeded = true;
return true;
}
@@ -1217,7 +1137,6 @@ public abstract class PanelViewController {
mInitialTouchX = x;
mTouchStartedInEmptyArea = !isInContentBounds(x, y);
mTouchSlopExceeded = mTouchSlopExceededBeforeDown;
- mJustPeeked = false;
mMotionAborted = false;
mPanelClosedOnDown = isFullyCollapsed();
mCollapsedAndHeadsUpOnDown = false;
@@ -1296,8 +1215,6 @@ public abstract class PanelViewController {
* We capture touch events here and update the expand height here in case according to
* the users fingers. This also handles multi-touch.
*
- * If the user just clicks shortly, we show a quick peek of the shade.
- *
* Flinging is also enabled in order to open or close the shade.
*/
@@ -1317,25 +1234,22 @@ public abstract class PanelViewController {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
- mJustPeeked = false;
mMinExpandHeight = 0.0f;
mPanelClosedOnDown = isFullyCollapsed();
mHasLayoutedSinceDown = false;
mUpdateFlingOnLayout = false;
mMotionAborted = false;
- mPeekTouching = mPanelClosedOnDown;
mDownTime = SystemClock.uptimeMillis();
mTouchAboveFalsingThreshold = false;
mCollapsedAndHeadsUpOnDown =
isFullyCollapsed() && mHeadsUpManager.hasPinnedHeadsUp();
addMovement(event);
if (!mGestureWaitForTouchSlop || (mHeightAnimator != null
- && !mHintAnimationRunning) || mPeekAnimator != null) {
+ && !mHintAnimationRunning)) {
mTouchSlopExceeded =
(mHeightAnimator != null && !mHintAnimationRunning)
- || mPeekAnimator != null || mTouchSlopExceededBeforeDown;
+ || mTouchSlopExceededBeforeDown;
cancelHeightAnimator();
- cancelPeek();
onTrackingStarted();
}
if (isFullyCollapsed() && !mHeadsUpManager.hasPinnedHeadsUp()
@@ -1375,7 +1289,7 @@ public abstract class PanelViewController {
|| mIgnoreXTouchSlop)) {
mTouchSlopExceeded = true;
if (mGestureWaitForTouchSlop && !mTracking && !mCollapsedAndHeadsUpOnDown) {
- if (!mJustPeeked && mInitialOffsetOnTouch != 0f) {
+ if (mInitialOffsetOnTouch != 0f) {
startExpandMotion(x, y, false /* startTracking */, mExpandedHeight);
h = 0;
}
@@ -1384,26 +1298,12 @@ public abstract class PanelViewController {
}
}
float newHeight = Math.max(0, h + mInitialOffsetOnTouch);
- if (newHeight > mPeekHeight) {
- if (mPeekAnimator != null) {
- mPeekAnimator.cancel();
- }
- mJustPeeked = false;
- } else if (mPeekAnimator == null && mJustPeeked) {
- // The initial peek has finished, but we haven't dragged as far yet, lets
- // speed it up by starting at the peek height.
- mInitialOffsetOnTouch = mExpandedHeight;
- mInitialTouchY = y;
- mMinExpandHeight = mExpandedHeight;
- mJustPeeked = false;
- }
newHeight = Math.max(newHeight, mMinExpandHeight);
if (-h >= getFalsingThreshold()) {
mTouchAboveFalsingThreshold = true;
mUpwardsWhenThresholdReached = isDirectionUpwards(x, y);
}
- if (!mJustPeeked && (!mGestureWaitForTouchSlop || mTracking)
- && !isTrackingBlocked()) {
+ if ((!mGestureWaitForTouchSlop || mTracking) && !isTrackingBlocked()) {
setExpandedHeightInternal(newHeight);
}
break;
@@ -1412,11 +1312,14 @@ public abstract class PanelViewController {
case MotionEvent.ACTION_CANCEL:
addMovement(event);
endMotionEvent(event, x, y, false /* forceCancel */);
- InteractionJankMonitor monitor = InteractionJankMonitor.getInstance();
- if (event.getActionMasked() == MotionEvent.ACTION_UP) {
- monitor.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
- } else {
- monitor.cancel(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+ // mHeightAnimator is null, there is no remaining frame, ends instrumenting.
+ if (mHeightAnimator == null) {
+ InteractionJankMonitor monitor = InteractionJankMonitor.getInstance();
+ if (event.getActionMasked() == MotionEvent.ACTION_UP) {
+ monitor.end(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+ } else {
+ monitor.cancel(CUJ_NOTIFICATION_SHADE_EXPAND_COLLAPSE);
+ }
}
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index c09293115492..a952db2a6073 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -163,7 +163,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private final float mDefaultScrimAlpha;
// Assuming the shade is expanded during initialization
- private float mExpansionFraction = 1f;
+ private float mPanelExpansion = 1f;
private float mQsExpansion;
private boolean mQsBottomVisible;
@@ -487,8 +487,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
if (isNaN(fraction)) {
throw new IllegalArgumentException("Fraction should not be NaN");
}
- if (mExpansionFraction != fraction) {
- mExpansionFraction = fraction;
+ if (mPanelExpansion != fraction) {
+ mPanelExpansion = fraction;
boolean relevantState = (mState == ScrimState.UNLOCKED
|| mState == ScrimState.KEYGUARD
@@ -641,7 +641,12 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
mBehindTint = Color.BLACK;
} else {
mBehindAlpha = backAlpha;
- mNotificationsAlpha = Math.max(1.0f - getInterpolatedFraction(), mQsExpansion);
+ if (mState == ScrimState.SHADE_LOCKED) {
+ // going from KEYGUARD to SHADE_LOCKED state
+ mNotificationsAlpha = getInterpolatedFraction();
+ } else {
+ mNotificationsAlpha = Math.max(1.0f - getInterpolatedFraction(), mQsExpansion);
+ }
mBehindTint = backTint;
}
}
@@ -805,7 +810,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
}
private float getInterpolatedFraction() {
- float frac = mExpansionFraction;
+ float frac = mPanelExpansion;
// let's start this 20% of the way down the screen
frac = frac * 1.2f - 0.2f;
if (frac <= 0) {
@@ -1165,7 +1170,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
pw.print(" mDefaultScrimAlpha=");
pw.println(mDefaultScrimAlpha);
pw.print(" mExpansionFraction=");
- pw.println(mExpansionFraction);
+ pw.println(mPanelExpansion);
}
public void setWallpaperSupportsAmbientMode(boolean wallpaperSupportsAmbientMode) {
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 aaef739af8c4..bd17d00063d7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -209,7 +209,6 @@ import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.charging.WiredChargingRippleController;
-import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationActivityStarter;
@@ -429,7 +428,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private NotificationsController mNotificationsController;
private final OngoingCallController mOngoingCallController;
private final SystemStatusAnimationScheduler mAnimationScheduler;
- private final PrivacyDotViewController mDotViewController;
+ private final StatusBarLocationPublisher mStatusBarLocationPublisher;
// expanded notifications
// the sliding/resizing panel within the notification window
@@ -799,7 +798,7 @@ public class StatusBar extends SystemUI implements DemoMode,
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
SystemStatusAnimationScheduler animationScheduler,
- PrivacyDotViewController dotViewController,
+ StatusBarLocationPublisher locationPublisher,
FeatureFlags featureFlags,
KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
super(context);
@@ -882,7 +881,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mChargingRippleAnimationController = chargingRippleAnimationController;
mOngoingCallController = ongoingCallController;
mAnimationScheduler = animationScheduler;
- mDotViewController = dotViewController;
+ mStatusBarLocationPublisher = locationPublisher;
mFeatureFlags = featureFlags;
mExpansionChangedListeners = new ArrayList<>();
@@ -1175,7 +1174,7 @@ public class StatusBar extends SystemUI implements DemoMode,
new CollapsedStatusBarFragment(
mOngoingCallController,
mAnimationScheduler,
- mDotViewController,
+ mStatusBarLocationPublisher,
mNotificationIconAreaController),
CollapsedStatusBarFragment.TAG)
.commit();
@@ -3095,19 +3094,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- void handlePeekToExpandTransistion() {
- try {
- // consider the transition from peek to expanded to be a panel open,
- // but not one that clears notification effects.
- int notificationLoad = mNotificationsController.getActiveNotificationsCount();
- mBarService.onPanelRevealed(false, notificationLoad);
- } catch (RemoteException ex) {
- // Won't fail unless the world has ended.
- }
- }
-
// Visibility reporting
-
void handleVisibleToUserChangedImpl(boolean visibleToUser) {
if (visibleToUser) {
/* The LEDs are turned off when the notification panel is shown, even just a little bit.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt
new file mode 100644
index 000000000000..4e5ecfe3f623
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2021 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 com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.policy.CallbackController
+import java.lang.ref.WeakReference
+import javax.inject.Inject
+
+/**
+ * Publishes updates to the status bar's margins.
+ *
+ * While the status bar view consumes the entire width of the device, the status bar
+ * contents are laid out with margins for rounded corners, padding from the absolute
+ * edges, and potentially display cutouts in the corner.
+ */
+@SysUISingleton
+class StatusBarLocationPublisher @Inject constructor()
+: CallbackController<StatusBarMarginUpdatedListener> {
+ private val listeners = mutableSetOf<WeakReference<StatusBarMarginUpdatedListener>>()
+
+ var marginLeft: Int = 0
+ private set
+ var marginRight: Int = 0
+ private set
+
+ override fun addCallback(listener: StatusBarMarginUpdatedListener) {
+ listeners.add(WeakReference(listener))
+ }
+
+ override fun removeCallback(listener: StatusBarMarginUpdatedListener) {
+ var toRemove: WeakReference<StatusBarMarginUpdatedListener>? = null
+ for (l in listeners) {
+ if (l.get() == listener) {
+ toRemove = l
+ }
+ }
+
+ if (toRemove != null) {
+ listeners.remove(toRemove)
+ }
+ }
+
+ fun updateStatusBarMargin(left: Int, right: Int) {
+ marginLeft = left
+ marginRight = right
+
+ notifyListeners()
+ }
+
+ private fun notifyListeners() {
+ var listenerList: List<WeakReference<StatusBarMarginUpdatedListener>>
+ synchronized(this) {
+ listenerList = listeners.toList()
+ }
+
+ listenerList.forEach { wrapper ->
+ if (wrapper.get() == null) {
+ listeners.remove(wrapper)
+ }
+
+ wrapper.get()?.onStatusBarMarginUpdated(marginLeft, marginRight)
+ }
+ }
+}
+
+interface StatusBarMarginUpdatedListener {
+ fun onStatusBarMarginUpdated(marginLeft: Int, marginRight: Int)
+} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
index 66e1c2e1b571..ae11a74748cd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/dagger/StatusBarPhoneModule.java
@@ -62,7 +62,6 @@ import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.charging.WiredChargingRippleController;
-import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
@@ -91,6 +90,7 @@ import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarIconController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
+import com.android.systemui.statusbar.phone.StatusBarLocationPublisher;
import com.android.systemui.statusbar.phone.StatusBarNotificationActivityStarter;
import com.android.systemui.statusbar.phone.StatusBarTouchableRegionManager;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
@@ -212,7 +212,7 @@ public interface StatusBarPhoneModule {
WiredChargingRippleController chargingRippleAnimationController,
OngoingCallController ongoingCallController,
SystemStatusAnimationScheduler animationScheduler,
- PrivacyDotViewController dotViewController,
+ StatusBarLocationPublisher locationPublisher,
FeatureFlags featureFlags,
KeyguardUnlockAnimationController keyguardUnlockAnimationController) {
return new StatusBar(
@@ -298,7 +298,7 @@ public interface StatusBarPhoneModule {
chargingRippleAnimationController,
ongoingCallController,
animationScheduler,
- dotViewController,
+ locationPublisher,
featureFlags,
keyguardUnlockAnimationController);
}
diff --git a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
index b95545576e56..10c4a55ad240 100644
--- a/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
+++ b/packages/SystemUI/src/com/android/systemui/wmshell/BubblesManager.java
@@ -675,7 +675,6 @@ public class BubblesManager implements Dumpable {
}
try {
int flags = Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION;
- flags |= Notification.BubbleMetadata.FLAG_AUTO_EXPAND_BUBBLE;
mBarService.onNotificationBubbleChanged(entry.getKey(), true, flags);
} catch (RemoteException e) {
Log.e(TAG, e.getMessage());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
index 60786f6afe99..1c3922a57368 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/classifier/ProximityClassifierTest.java
@@ -29,8 +29,8 @@ import android.view.MotionEvent;
import androidx.test.filters.SmallTest;
+import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.util.DeviceConfigProxyFake;
-import com.android.systemui.util.sensors.ProximitySensor;
import org.junit.After;
import org.junit.Before;
@@ -149,8 +149,17 @@ public class ProximityClassifierTest extends ClassifierTest {
motionEvent.recycle();
}
- private ProximitySensor.ThresholdSensorEvent createSensorEvent(
- boolean covered, long timestampMs) {
- return new ProximitySensor.ThresholdSensorEvent(covered, timestampMs * NS_PER_MS);
+ private FalsingManager.ProximityEvent createSensorEvent(boolean covered, long timestampMs) {
+ return new FalsingManager.ProximityEvent() {
+ @Override
+ public boolean getCovered() {
+ return covered;
+ }
+
+ @Override
+ public long getTimestampNs() {
+ return timestampMs * NS_PER_MS;
+ }
+ };
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index 94252d2b8331..800daa1e96aa 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -17,7 +17,6 @@
package com.android.systemui.media
import android.content.Intent
-import android.content.res.ColorStateList
import android.graphics.Color
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.RippleDrawable
@@ -222,17 +221,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
}
@Test
- fun bindBackgroundColor() {
- player.attachPlayer(holder)
- val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
- emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
- player.bindPlayer(state, PACKAGE)
- val list = ArgumentCaptor.forClass(ColorStateList::class.java)
- verify(view).setBackgroundTintList(list.capture())
- assertThat(list.value).isEqualTo(ColorStateList.valueOf(BG_COLOR))
- }
-
- @Test
fun bindDevice() {
player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
index d86dfa5fa5f7..406f40c75735 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
@@ -28,6 +28,7 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.SysuiStatusBarStateController
import com.android.systemui.statusbar.phone.KeyguardBypassController
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.animation.UniqueObjectHostView
import org.junit.Assert.assertNotNull
@@ -73,6 +74,8 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
private lateinit var mediaCarouselController: MediaCarouselController
@Mock
private lateinit var wakefulnessLifecycle: WakefulnessLifecycle
+ @Mock
+ private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
@Captor
private lateinit var wakefullnessObserver: ArgumentCaptor<(WakefulnessLifecycle.Observer)>
@JvmField
@@ -90,7 +93,8 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
bypassController,
mediaCarouselController,
notificationLockscreenUserManager,
- wakefulnessLifecycle)
+ wakefulnessLifecycle,
+ statusBarKeyguardViewManager)
verify(wakefulnessLifecycle).addObserver(wakefullnessObserver.capture())
setupHost(lockHost, MediaHierarchyManager.LOCATION_LOCKSCREEN)
setupHost(qsHost, MediaHierarchyManager.LOCATION_QS)
@@ -98,7 +102,6 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
`when`(statusBarStateController.state).thenReturn(StatusBarState.SHADE)
// We'll use the viewmanager to verify a few calls below, let's reset this.
clearInvocations(mediaCarouselController)
-
}
private fun setupHost(host: MediaHost, location: Int) {
@@ -125,7 +128,8 @@ class MediaHierarchyManagerTest : SysuiTestCase() {
observer.onStartedGoingToSleep()
clearInvocations(mediaCarouselController)
mediaHiearchyManager.qsExpansion = 0.0f
- verify(mediaCarouselController, times(0)).onDesiredLocationChanged(ArgumentMatchers.anyInt(),
+ verify(mediaCarouselController, times(0))
+ .onDesiredLocationChanged(ArgumentMatchers.anyInt(),
any(MediaHostState::class.java), anyBoolean(), anyLong(), anyLong())
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
index cc322620eb57..0dd1f6816787 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java
@@ -24,7 +24,6 @@ import static com.google.common.truth.Truth.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
@@ -59,6 +58,7 @@ import androidx.test.filters.SmallTest;
import com.android.internal.appwidget.IAppWidgetService;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
import com.android.systemui.people.widget.PeopleTileKey;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -73,6 +73,7 @@ import org.mockito.MockitoAnnotations;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
@RunWith(AndroidTestingRunner.class)
@SmallTest
@@ -188,6 +189,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
private PackageManager mPackageManager;
@Mock
private NotificationEntryManager mNotificationEntryManager;
+ @Mock
+ private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
private Bundle mOptions;
@@ -212,8 +215,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
when(resources.getConfiguration()).thenReturn(configuration);
when(resources.getDisplayMetrics()).thenReturn(displayMetrics);
when(mMockContext.getContentResolver()).thenReturn(mMockContentResolver);
- when(mMockContentResolver.query(any(Uri.class), any(), anyString(), any(),
- isNull())).thenReturn(mMockCursor);
+ when(mMockContentResolver.query(any(Uri.class), any(), any(), any(),
+ any())).thenReturn(mMockCursor);
when(mMockContext.getString(R.string.birthday_status)).thenReturn(
mContext.getString(R.string.birthday_status));
when(mMockContext.getString(R.string.basic_status)).thenReturn(
@@ -236,7 +239,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
.build();
PeopleTileKey key = new PeopleTileKey(tile);
PeopleSpaceTile actual = PeopleSpaceUtils
- .augmentTileFromNotification(mContext, tile, key, mNotificationEntry1, 0);
+ .augmentTileFromNotification(mContext, tile, key, mNotificationEntry1, 0,
+ Optional.empty());
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
assertThat(actual.getNotificationSender()).isEqualTo(null);
@@ -275,7 +279,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
.build();
PeopleTileKey key = new PeopleTileKey(tile);
PeopleSpaceTile actual = PeopleSpaceUtils
- .augmentTileFromNotification(mContext, tile, key, notificationEntry, 0);
+ .augmentTileFromNotification(mContext, tile, key, notificationEntry, 0,
+ Optional.empty());
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_TEXT_2);
assertThat(actual.getNotificationSender().toString()).isEqualTo("name");
@@ -291,7 +296,8 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
.build();
PeopleTileKey key = new PeopleTileKey(tile);
PeopleSpaceTile actual = PeopleSpaceUtils
- .augmentTileFromNotification(mContext, tile, key, mNotificationEntry3, 0);
+ .augmentTileFromNotification(mContext, tile, key, mNotificationEntry3, 0,
+ Optional.empty());
assertThat(actual.getNotificationContent()).isEqualTo(null);
}
@@ -308,10 +314,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
Map<Integer, PeopleSpaceTile> widgetIdToTile = Map.of(WIDGET_ID_WITH_SHORTCUT,
new PeopleSpaceTile.Builder(mShortcutInfoWithoutPerson,
mContext.getSystemService(LauncherApps.class)).build());
- PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
+ PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
widgetIdToTile, widgetIdsArray);
- verify(mAppWidgetManager, never()).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ verify(mPeopleSpaceWidgetManager, never()).updateAppWidgetOptionsAndView(
+ eq(WIDGET_ID_WITH_SHORTCUT),
any());
}
@@ -328,10 +335,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
new PeopleSpaceTile.Builder(mShortcutInfoWithoutPerson,
mContext.getSystemService(LauncherApps.class)).setBirthdayText(
mContext.getString(R.string.birthday_status)).build());
- PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
+ PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
widgetIdToTile, widgetIdsArray);
- verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ verify(mPeopleSpaceWidgetManager, times(1)).updateAppWidgetOptionsAndView(
+ eq(WIDGET_ID_WITH_SHORTCUT),
any());
}
@@ -363,10 +371,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
new PeopleSpaceTile.Builder(mShortcutInfo,
mContext.getSystemService(LauncherApps.class)).setBirthdayText(
mContext.getString(R.string.birthday_status)).build());
- PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
+ PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
widgetIdToTile, widgetIdsArray);
- verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ verify(mPeopleSpaceWidgetManager, times(1)).updateAppWidgetOptionsAndView(
+ eq(WIDGET_ID_WITH_SHORTCUT),
any());
}
@@ -375,6 +384,9 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT};
when(mMockCursor.moveToNext()).thenReturn(true, false, true, false);
when(mMockCursor.getString(eq(TEST_COLUMN_INDEX))).thenReturn(TEST_LOOKUP_KEY);
+ when(mMockCursor.getInt(eq(TEST_COLUMN_INDEX + 1))).thenReturn(1);
+ when(mMockCursor.getColumnIndex(eq(ContactsContract.Contacts.STARRED))).thenReturn(
+ TEST_COLUMN_INDEX + 1);
when(mMockCursor.getColumnIndex(eq(ContactsContract.CommonDataKinds.Event.LOOKUP_KEY)
)).thenReturn(TEST_COLUMN_INDEX);
@@ -383,10 +395,11 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
new PeopleSpaceTile.Builder(mShortcutInfo,
mContext.getSystemService(LauncherApps.class)).setBirthdayText(
mContext.getString(R.string.birthday_status)).build());
- PeopleSpaceUtils.getBirthdays(mMockContext, mAppWidgetManager,
+ PeopleSpaceUtils.getDataFromContacts(mMockContext, mPeopleSpaceWidgetManager,
widgetIdToTile, widgetIdsArray);
- verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ verify(mPeopleSpaceWidgetManager, times(1)).updateAppWidgetOptionsAndView(
+ eq(WIDGET_ID_WITH_SHORTCUT),
any());
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
index 764cdee7e36d..228e5e8d481d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/PeopleTileViewHelperTest.java
@@ -21,13 +21,20 @@ import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
import static android.app.people.ConversationStatus.ACTIVITY_NEW_STORY;
import static android.app.people.ConversationStatus.AVAILABILITY_AVAILABLE;
+import static android.app.people.PeopleSpaceTile.BLOCK_CONVERSATIONS;
+import static android.app.people.PeopleSpaceTile.SHOW_CONTACTS;
+import static android.app.people.PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
+import static android.app.people.PeopleSpaceTile.SHOW_STARRED_CONTACTS;
import static android.appwidget.AppWidgetManager.OPTION_APPWIDGET_MIN_WIDTH;
+import static com.android.systemui.people.PeopleSpaceUtils.STARRED_CONTACT;
+import static com.android.systemui.people.PeopleSpaceUtils.VALID_CONTACT;
import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_PEOPLE_TILE;
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -53,6 +60,7 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.people.widget.PeopleTileKey;
import org.junit.Before;
import org.junit.Test;
@@ -148,14 +156,14 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
TextView textView = mock(TextView.class);
when(textView.getLineHeight()).thenReturn(16);
when(mPackageManager.getApplicationIcon(anyString())).thenReturn(null);
- mPeopleTileViewHelper = new PeopleTileViewHelper(mContext,
- PERSON_TILE, 0, mOptions);
+ mPeopleTileViewHelper = getPeopleTileViewHelper(
+ PERSON_TILE, mOptions);
}
@Test
public void testCreateRemoteViewsWithLastInteractionTimeUnderOneDayHidden() {
- RemoteViews views = new PeopleTileViewHelper(mContext,
- PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ PERSON_TILE_WITHOUT_NOTIFICATION, mOptions).getViews();
View result = views.apply(mContext, null);
// Not showing last interaction.
@@ -165,8 +173,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- PERSON_TILE_WITHOUT_NOTIFICATION, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ PERSON_TILE_WITHOUT_NOTIFICATION, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
// Not showing last interaction.
@@ -178,8 +186,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
PeopleSpaceTile tileWithLastInteraction =
PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setLastInteractionTimestamp(
123445L).build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithLastInteraction, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithLastInteraction, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -197,8 +205,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithLastInteraction, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithLastInteraction, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show name over predefined icon.
@@ -214,8 +222,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithLastInteraction, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithLastInteraction, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -240,8 +248,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
new ConversationStatus.Builder(
PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
ACTIVITY_GAME).build())).build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithAvailabilityAndNewStory, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -257,8 +265,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithAvailabilityAndNewStory, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show name rather than game type.
@@ -274,8 +282,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithAvailabilityAndNewStory, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithAvailabilityAndNewStory, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -298,8 +306,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
NEW_STORY_WITH_AVAILABILITY, new ConversationStatus.Builder(
PERSON_TILE_WITHOUT_NOTIFICATION.getId(),
ACTIVITY_BIRTHDAY).build())).build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithStatusTemplate, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithStatusTemplate, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -318,8 +326,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithStatusTemplate, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithStatusTemplate, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show icon instead of name.
@@ -336,8 +344,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithStatusTemplate, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithStatusTemplate, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -362,8 +370,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
PERSON_TILE_WITHOUT_NOTIFICATION.toBuilder().setStatuses(
Arrays.asList(GAME_STATUS,
NEW_STORY_WITH_AVAILABILITY)).build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithStatusTemplate, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithStatusTemplate, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -381,8 +389,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithStatusTemplate, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithStatusTemplate, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show icon instead of name.
@@ -399,8 +407,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithStatusTemplate, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithStatusTemplate, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -420,14 +428,128 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
}
@Test
+ public void testCreateRemoteViewsWithPackageSuspended() {
+ PeopleSpaceTile tile = PERSON_TILE.toBuilder()
+ .setIsPackageSuspended(true)
+ .build();
+ RemoteViews views = getPeopleTileViewHelper(
+ tile, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithUserQuieted() {
+ PeopleSpaceTile tile = PERSON_TILE.toBuilder()
+ .setIsUserQuieted(true)
+ .build();
+ RemoteViews views = getPeopleTileViewHelper(
+ tile, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+ }
+
+ @Test
+ public void testCreateRemoteViewsWithDndBlocking() {
+ PeopleSpaceTile tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(BLOCK_CONVERSATIONS)
+ .build();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ View result = views.apply(mContext, null);
+
+ assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(BLOCK_CONVERSATIONS)
+ .setCanBypassDnd(true)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(SHOW_IMPORTANT_CONVERSATIONS)
+ .setIsImportantConversation(true)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(SHOW_STARRED_CONTACTS)
+ .setContactAffinity(VALID_CONTACT)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(SHOW_STARRED_CONTACTS)
+ .setContactAffinity(STARRED_CONTACT)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(SHOW_CONTACTS)
+ .setContactAffinity(STARRED_CONTACT)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(SHOW_CONTACTS)
+ .setContactAffinity(VALID_CONTACT)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertNotEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+
+ tileWithDndBlocking = PERSON_TILE.toBuilder()
+ .setNotificationPolicyState(SHOW_CONTACTS)
+ .build();
+ views = getPeopleTileViewHelper(
+ tileWithDndBlocking, mOptions).getViews();
+ result = views.apply(mContext, null);
+
+ assertEquals(result.getSourceLayoutResId(), R.layout.people_tile_empty_layout);
+ }
+
+ @Test
public void testCreateRemoteViewsWithMissedCallNotification() {
PeopleSpaceTile tileWithMissedCallNotification = PERSON_TILE.toBuilder()
.setNotificationDataUri(null)
.setNotificationCategory(CATEGORY_MISSED_CALL)
.setNotificationContent(MISSED_CALL)
.build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithMissedCallNotification, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithMissedCallNotification, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -446,8 +568,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithMissedCallNotification, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithMissedCallNotification, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show icon instead of name.
@@ -463,8 +585,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithMissedCallNotification, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithMissedCallNotification, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -489,8 +611,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
.setNotificationDataUri(null)
.setStatuses(Arrays.asList(GAME_STATUS,
NEW_STORY_WITH_AVAILABILITY)).build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -512,8 +634,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show icon instead of name.
@@ -531,8 +653,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -561,8 +683,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
.setNotificationDataUri(null)
.setStatuses(Arrays.asList(GAME_STATUS,
NEW_STORY_WITH_AVAILABILITY)).build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -588,8 +710,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show icon instead of name.
@@ -607,8 +729,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -642,8 +764,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
.setStatuses(Arrays.asList(GAME_STATUS,
NEW_STORY_WITH_AVAILABILITY))
.setMessagesCount(2).build();
- RemoteViews views = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews views = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View result = views.apply(mContext, null);
TextView name = (TextView) result.findViewById(R.id.name);
@@ -665,8 +787,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_width_for_medium) - 1);
- RemoteViews smallView = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews smallView = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View smallResult = smallView.apply(mContext, null);
// Show icon instead of name.
@@ -684,8 +806,8 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
getSizeInDp(R.dimen.required_width_for_large));
mOptions.putInt(OPTION_APPWIDGET_MIN_WIDTH,
getSizeInDp(R.dimen.required_height_for_large));
- RemoteViews largeView = new PeopleTileViewHelper(mContext,
- tileWithStatusAndNotification, 0, mOptions).getViews();
+ RemoteViews largeView = getPeopleTileViewHelper(
+ tileWithStatusAndNotification, mOptions).getViews();
View largeResult = largeView.apply(mContext, null);
name = (TextView) largeResult.findViewById(R.id.name);
@@ -858,4 +980,9 @@ public class PeopleTileViewHelperTest extends SysuiTestCase {
return (int) (mContext.getResources().getDimension(dimenResourceId)
/ mContext.getResources().getDisplayMetrics().density);
}
+
+ private PeopleTileViewHelper getPeopleTileViewHelper(PeopleSpaceTile tile, Bundle options) {
+ return new PeopleTileViewHelper(mContext, tile, 0, options,
+ new PeopleTileKey(tile.getId(), 0, tile.getPackageName()));
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 411fb02ba87a..f31f326c0c45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -20,11 +20,32 @@ import static android.app.Notification.CATEGORY_MISSED_CALL;
import static android.app.Notification.EXTRA_PEOPLE_LIST;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL;
+import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_IMPORTANT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_AMBIENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_BADGE;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCREEN_INTENT;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_NOTIFICATION_LIST;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_ON;
+import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_STATUS_BAR;
import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static android.app.people.PeopleSpaceTile.BLOCK_CONVERSATIONS;
+import static android.app.people.PeopleSpaceTile.SHOW_CONTACTS;
+import static android.app.people.PeopleSpaceTile.SHOW_CONVERSATIONS;
+import static android.app.people.PeopleSpaceTile.SHOW_IMPORTANT_CONVERSATIONS;
+import static android.app.people.PeopleSpaceTile.SHOW_STARRED_CONTACTS;
+import static android.content.Intent.ACTION_BOOT_COMPLETED;
+import static android.content.Intent.ACTION_PACKAGES_SUSPENDED;
import static android.content.PermissionChecker.PERMISSION_GRANTED;
import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
+import static android.service.notification.ZenPolicy.CONVERSATION_SENDERS_ANYONE;
import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
@@ -73,6 +94,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
+import android.service.notification.ZenModeConfig;
import android.testing.AndroidTestingRunner;
import androidx.preference.PreferenceManager;
@@ -89,6 +111,7 @@ import com.android.systemui.statusbar.notification.collection.NoManSimulator;
import com.android.systemui.statusbar.notification.collection.NoManSimulator.NotifEvent;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
+import com.android.systemui.util.concurrency.FakeExecutor;
import com.android.systemui.util.time.FakeSystemClock;
import org.junit.Before;
@@ -99,12 +122,14 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -158,6 +183,16 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
// Same contact uri.
.setContactUri(URI)
.build();
+ private static final int ALL_SUPPRESSED_VISUAL_EFFECTS = SUPPRESSED_EFFECT_SCREEN_OFF
+ | SUPPRESSED_EFFECT_SCREEN_ON
+ | SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+ | SUPPRESSED_EFFECT_AMBIENT
+ | SUPPRESSED_EFFECT_STATUS_BAR
+ | SUPPRESSED_EFFECT_BADGE
+ | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_PEEK
+ | SUPPRESSED_EFFECT_NOTIFICATION_LIST;
+
private ShortcutInfo mShortcutInfo;
private NotificationEntry mNotificationEntry;
@@ -182,9 +217,13 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
@Mock
private PackageManager mPackageManager;
@Mock
- private INotificationManager mNotificationManager;
+ private INotificationManager mINotificationManager;
@Mock
private UserManager mUserManager;
+ @Mock
+ private NotificationManager mNotificationManager;
+ @Mock
+ private NotificationManager.Policy mNotificationPolicy;
@Captor
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
@@ -194,19 +233,16 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
private final NoManSimulator mNoMan = new NoManSimulator();
private final FakeSystemClock mClock = new FakeSystemClock();
- private PeopleSpaceWidgetProvider mProvider;
+ private final FakeExecutor mFakeExecutor = new FakeExecutor(mClock);
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
mLauncherApps = mock(LauncherApps.class);
mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
- mManager = new PeopleSpaceWidgetManager(mContext);
- mProvider = new PeopleSpaceWidgetProvider();
- mProvider.setPeopleSpaceWidgetManager(mManager);
- mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
- mLauncherApps, mNotificationEntryManager, mPackageManager, true, mProvider,
- mUserManager, mNotificationManager);
+ mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager,
+ mPeopleManager, mLauncherApps, mNotificationEntryManager, mPackageManager,
+ mUserManager, mINotificationManager, mNotificationManager, mFakeExecutor);
mManager.attach(mListenerService);
verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
@@ -218,7 +254,19 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
addTileForWidget(PERSON_TILE_WITH_SAME_URI, WIDGET_ID_WITH_SAME_URI);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
.thenReturn(new Bundle());
+
when(mUserManager.isQuietModeEnabled(any())).thenReturn(false);
+ when(mPackageManager.isPackageSuspended(any())).thenReturn(false);
+ setFinalField("suppressedVisualEffects", ALL_SUPPRESSED_VISUAL_EFFECTS);
+ when(mNotificationPolicy.allowConversationsFrom()).thenReturn(CONVERSATION_SENDERS_ANYONE);
+ when(mNotificationPolicy.allowConversations()).thenReturn(false);
+ when(mNotificationPolicy.allowMessagesFrom()).thenReturn(ZenModeConfig.SOURCE_ANYONE);
+ when(mNotificationPolicy.allowMessages()).thenReturn(false);
+ when(mNotificationManager.getNotificationPolicy()).thenReturn(mNotificationPolicy);
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_ALL);
+ int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
when(mMockContext.getPackageName()).thenReturn(TEST_PACKAGE_A);
when(mMockContext.getUserId()).thenReturn(0);
@@ -242,7 +290,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
SHORTCUT_ID + 2,
true, 1);
- when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
+ when(mINotificationManager.getConversations(anyBoolean())).thenReturn(
new ParceledListSlice(Arrays.asList(
newerNonImportantConversation, newerImportantConversation,
olderImportantConversation)));
@@ -280,7 +328,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
SHORTCUT_ID + 2,
true, 1);
- when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
+ when(mINotificationManager.getConversations(anyBoolean())).thenReturn(
new ParceledListSlice(Arrays.asList(
newerNonImportantConversation, newerImportantConversation,
olderImportantConversation)));
@@ -306,7 +354,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
SHORTCUT_ID + 2,
true, 1);
- when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
+ when(mINotificationManager.getConversations(anyBoolean())).thenReturn(
new ParceledListSlice(Arrays.asList(
newerNonImportantConversation, newerImportantConversation,
olderImportantConversation)));
@@ -1027,8 +1075,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners()
throws Exception {
addSecondWidgetForPersonTile();
- mProvider.onUpdate(mContext, mAppWidgetManager,
- new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
+ mManager.updateWidgets(new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
// Delete only one widget for the conversation.
mManager.deleteWidgets(new int[]{WIDGET_ID_WITH_SHORTCUT});
@@ -1050,7 +1097,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
// Delete all widgets for the conversation.
- mProvider.onDeleted(mContext, new int[]{SECOND_WIDGET_ID_WITH_SHORTCUT});
+ mManager.deleteWidgets(new int[]{SECOND_WIDGET_ID_WITH_SHORTCUT});
// Check deleted storage.
SharedPreferences secondWidgetSp = mContext.getSharedPreferences(
@@ -1154,7 +1201,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A));
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(channel);
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
- PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key);
+ PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
assertThat(tile.getId()).isEqualTo(key.getShortcutId());
}
@@ -1162,7 +1209,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
public void testGetPeopleTileFromPersistentStorageNoConversation() throws RemoteException {
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(null);
PeopleTileKey key = new PeopleTileKey(SHORTCUT_ID, 0, TEST_PACKAGE_A);
- PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key);
+ PeopleSpaceTile tile = mManager.getTileFromPersistentStorage(key, WIDGET_ID_WITH_SHORTCUT);
assertThat(tile).isNull();
}
@@ -1195,18 +1242,25 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
@Test
public void testAugmentTileFromNotifications() {
+ clearStorage();
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
+ assertThat(sp.getString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), null)).isEqualTo(null);
PeopleSpaceTile tile =
new PeopleSpaceTile
.Builder(SHORTCUT_ID, "userName", ICON, new Intent())
.setPackageName(TEST_PACKAGE_A)
.setUserHandle(new UserHandle(0))
.build();
+
PeopleTileKey key = new PeopleTileKey(tile);
PeopleSpaceTile actual = mManager.augmentTileFromNotifications(tile, key, EMPTY_STRING,
- Map.of(new PeopleTileKey(mNotificationEntry),
- new HashSet<>(Collections.singleton(mNotificationEntry))));
+ Map.of(new PeopleTileKey(mNotificationEntry),
+ new HashSet<>(Collections.singleton(mNotificationEntry))),
+ Optional.of(WIDGET_ID_WITH_SHORTCUT));
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_CONTENT_1);
+ assertThat(sp.getString(String.valueOf(WIDGET_ID_WITH_SHORTCUT), null)).isEqualTo(
+ URI.toString());
}
@Test
@@ -1221,7 +1275,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
PeopleSpaceTile actual = mManager
.augmentTileFromNotifications(tile, key, EMPTY_STRING,
Map.of(new PeopleTileKey(mNotificationEntry),
- new HashSet<>(Collections.singleton(mNotificationEntry))));
+ new HashSet<>(Collections.singleton(mNotificationEntry))),
+ Optional.empty());
assertThat(actual.getNotificationContent()).isEqualTo(null);
}
@@ -1238,7 +1293,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
.thenReturn(List.of(mNotificationEntry));
PeopleSpaceTile actual =
- mManager.augmentTileFromNotificationEntryManager(tile);
+ mManager.augmentTileFromNotificationEntryManager(tile,
+ Optional.of(WIDGET_ID_WITH_SHORTCUT));
assertThat(actual.getNotificationContent().toString()).isEqualTo(NOTIFICATION_CONTENT_1);
@@ -1246,6 +1302,202 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
.getVisibleNotifications();
}
+ @Test
+ public void testUpdateWidgetsOnStateChange() {
+ mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.isPackageSuspended()).isFalse();
+ assertThat(tile.isUserQuieted()).isFalse();
+ assertThat(tile.canBypassDnd()).isFalse();
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeWithUserQuieted() {
+ when(mUserManager.isQuietModeEnabled(any())).thenReturn(true);
+
+ mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.isPackageSuspended()).isFalse();
+ assertThat(tile.isUserQuieted()).isTrue();
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeWithPackageSuspended() throws Exception {
+ when(mPackageManager.isPackageSuspended(any())).thenReturn(true);
+
+ mManager.updateWidgetsOnStateChange(ACTION_PACKAGES_SUSPENDED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.isPackageSuspended()).isTrue();
+ assertThat(tile.isUserQuieted()).isFalse();
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(SHOW_CONVERSATIONS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeNotInDnd() {
+ int expected = 0;
+ mManager.updateWidgetsOnStateChange(NotificationManager
+ .ACTION_INTERRUPTION_FILTER_CHANGED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONVERSATIONS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeAllConversations() {
+ int expected = 0;
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_PRIORITY);
+ when(mNotificationPolicy.allowConversations()).thenReturn(true);
+ setFinalField("priorityConversationSenders", CONVERSATION_SENDERS_ANYONE);
+
+ mManager.updateWidgetsOnStateChange(NotificationManager
+ .ACTION_INTERRUPTION_FILTER_CHANGED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONVERSATIONS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeAllowOnlyImportantConversations() {
+ int expected = 0;
+ // Only allow important conversations.
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_PRIORITY);
+ when(mNotificationPolicy.allowConversations()).thenReturn(true);
+ setFinalField("priorityConversationSenders", CONVERSATION_SENDERS_IMPORTANT);
+
+ mManager.updateWidgetsOnStateChange(NotificationManager
+ .ACTION_INTERRUPTION_FILTER_CHANGED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(
+ expected | SHOW_IMPORTANT_CONVERSATIONS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeAllowNoConversations() {
+ int expected = 0;
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_PRIORITY);
+ when(mNotificationPolicy.allowConversations()).thenReturn(false);
+
+ mManager.updateWidgetsOnStateChange(NotificationManager
+ .ACTION_INTERRUPTION_FILTER_CHANGED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | BLOCK_CONVERSATIONS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeAllowNoConversationsAllowContactMessages() {
+ int expected = 0;
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_PRIORITY);
+ when(mNotificationPolicy.allowConversations()).thenReturn(false);
+ when(mNotificationPolicy.allowMessagesFrom()).thenReturn(ZenModeConfig.SOURCE_CONTACT);
+ when(mNotificationPolicy.allowMessages()).thenReturn(true);
+
+ mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONTACTS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeAllowNoConversationsAllowStarredContactMessages() {
+ int expected = 0;
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_PRIORITY);
+ when(mNotificationPolicy.allowConversations()).thenReturn(false);
+ when(mNotificationPolicy.allowMessagesFrom()).thenReturn(ZenModeConfig.SOURCE_STAR);
+ when(mNotificationPolicy.allowMessages()).thenReturn(true);
+
+ mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_STARRED_CONTACTS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeAllowAlarmsOnly() {
+ int expected = 0;
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_ALARMS);
+
+ mManager.updateWidgetsOnStateChange(NotificationManager
+ .ACTION_INTERRUPTION_FILTER_CHANGED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | BLOCK_CONVERSATIONS);
+ }
+
+ @Test
+ public void testUpdateWidgetsOnStateChangeAllowVisualEffectsAndAllowAlarmsOnly() {
+ int expected = 0;
+ // If we show visuals, but just only make sounds for alarms, still show content in tiles.
+ when(mNotificationManager.getCurrentInterruptionFilter()).thenReturn(
+ INTERRUPTION_FILTER_ALARMS);
+ setFinalField("suppressedVisualEffects", SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
+ | SUPPRESSED_EFFECT_AMBIENT);
+
+ mManager.updateWidgetsOnStateChange(ACTION_BOOT_COMPLETED);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ PeopleSpaceTile tile = mBundleArgumentCaptor.getValue().getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tile.getNotificationPolicyState()).isEqualTo(expected | SHOW_CONVERSATIONS);
+ }
+
+ private void setFinalField(String fieldName, int value) {
+ try {
+ Field field = NotificationManager.Policy.class.getDeclaredField(fieldName);
+ field.setAccessible(true);
+ field.set(mNotificationPolicy, value);
+ } catch (Exception e) {
+ }
+ }
+
/**
* Adds another widget for {@code PERSON_TILE} with widget ID: {@code
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
index 5d29f520e8a9..e85e19fbd9b8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationConversationInfoTest.java
@@ -21,6 +21,8 @@ import static android.app.NotificationManager.BUBBLE_PREFERENCE_SELECTED;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.NotificationManager.IMPORTANCE_LOW;
+import static android.app.NotificationManager.Policy.CONVERSATION_SENDERS_ANYONE;
+import static android.app.NotificationManager.Policy.PRIORITY_CATEGORY_CONVERSATIONS;
import static android.print.PrintManager.PRINT_SPOOLER_PACKAGE_NAME;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
@@ -150,9 +152,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
private ShadeController mShadeController;
@Mock
private ConversationIconFactory mIconFactory;
- @Mock(answer = Answers.RETURNS_SELF)
- private PriorityOnboardingDialogController.Builder mBuilder;
- private Provider<PriorityOnboardingDialogController.Builder> mBuilderProvider = () -> mBuilder;
@Mock
private Notification.BubbleMetadata mBubbleMetadata;
private Handler mTestHandler;
@@ -236,8 +235,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
when(mMockINotificationManager.getConsolidatedNotificationPolicy())
.thenReturn(mock(NotificationManager.Policy.class));
- when(mBuilder.build()).thenReturn(mock(PriorityOnboardingDialogController.class));
-
when(mPeopleSpaceWidgetManager.requestPinAppWidget(any(), any())).thenReturn(true);
}
@@ -258,7 +255,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -285,7 +281,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -340,7 +335,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -368,7 +362,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -395,7 +388,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -433,7 +425,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -464,7 +455,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -493,7 +483,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -523,7 +512,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
false,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -551,7 +539,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -582,7 +569,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -616,7 +602,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -626,6 +611,110 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
assertThat(((TextView) view.findViewById(R.id.default_summary)).getText()).isEqualTo(
mContext.getString(R.string.notification_channel_summary_default_with_bubbles,
"App Name"));
+ assertThat(((TextView) mNotificationInfo.findViewById(R.id.priority_summary)).getText())
+ .isEqualTo(mContext.getString(
+ R.string.notification_channel_summary_priority_bubble));
+ }
+
+ @Test
+ public void testBindNotification_priorityDnd() throws Exception {
+ NotificationManager.Policy policy = new NotificationManager.Policy(
+ PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_ANYONE);
+ when(mMockINotificationManager.getConsolidatedNotificationPolicy())
+ .thenReturn(policy);
+ when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
+ mConversationChannel.setImportance(IMPORTANCE_HIGH);
+ mConversationChannel.setImportantConversation(false);
+ mConversationChannel.setAllowBubbles(false);
+ mNotificationInfo.bindNotification(
+ -1,
+ mShortcutManager,
+ mMockPackageManager,
+ mPeopleSpaceWidgetManager,
+ mMockINotificationManager,
+ mOnUserInteractionCallback,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mEntry,
+ null,
+ null,
+ null,
+ mIconFactory,
+ mContext,
+ true,
+ mTestHandler,
+ mTestHandler, null, Optional.of(mBubblesManager),
+ mShadeController);
+ assertThat(((TextView) mNotificationInfo.findViewById(R.id.priority_summary)).getText())
+ .isEqualTo(mContext.getString(
+ R.string.notification_channel_summary_priority_dnd));
+ }
+
+ @Test
+ public void testBindNotification_priorityBaseline() throws Exception {
+ when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
+ mConversationChannel.setImportance(IMPORTANCE_HIGH);
+ mConversationChannel.setImportantConversation(false);
+ mConversationChannel.setAllowBubbles(false);
+ mNotificationInfo.bindNotification(
+ -1,
+ mShortcutManager,
+ mMockPackageManager,
+ mPeopleSpaceWidgetManager,
+ mMockINotificationManager,
+ mOnUserInteractionCallback,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mEntry,
+ null,
+ null,
+ null,
+ mIconFactory,
+ mContext,
+ true,
+ mTestHandler,
+ mTestHandler, null, Optional.of(mBubblesManager),
+ mShadeController);
+ assertThat(((TextView) mNotificationInfo.findViewById(R.id.priority_summary)).getText())
+ .isEqualTo(mContext.getString(
+ R.string.notification_channel_summary_priority_baseline));
+ }
+
+ @Test
+ public void testBindNotification_priorityDndAndBubble() throws Exception {
+ NotificationManager.Policy policy = new NotificationManager.Policy(
+ PRIORITY_CATEGORY_CONVERSATIONS, 0, 0, 0, CONVERSATION_SENDERS_ANYONE);
+ when(mMockINotificationManager.getConsolidatedNotificationPolicy())
+ .thenReturn(policy);
+
+ when(mMockINotificationManager.getBubblePreferenceForPackage(anyString(), anyInt()))
+ .thenReturn(BUBBLE_PREFERENCE_ALL);
+ when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
+ mConversationChannel.setImportance(IMPORTANCE_HIGH);
+ mConversationChannel.setImportantConversation(false);
+ mConversationChannel.setAllowBubbles(true);
+ mNotificationInfo.bindNotification(
+ -1,
+ mShortcutManager,
+ mMockPackageManager,
+ mPeopleSpaceWidgetManager,
+ mMockINotificationManager,
+ mOnUserInteractionCallback,
+ TEST_PACKAGE_NAME,
+ mNotificationChannel,
+ mEntry,
+ mBubbleMetadata,
+ null,
+ null,
+ mIconFactory,
+ mContext,
+ true,
+ mTestHandler,
+ mTestHandler, null, Optional.of(mBubblesManager),
+ mShadeController);
+ assertThat(((TextView) mNotificationInfo.findViewById(R.id.priority_summary)).getText())
+ .isEqualTo(mContext.getString(
+ R.string.notification_channel_summary_priority_all));
}
@Test
@@ -649,7 +738,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -696,7 +784,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -742,7 +829,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -789,7 +875,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -829,7 +914,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -868,7 +952,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -911,7 +994,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -944,7 +1026,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -976,7 +1057,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1015,7 +1095,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1054,7 +1133,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1092,7 +1170,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1129,7 +1206,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1157,7 +1233,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1168,97 +1243,8 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
}
@Test
- public void testSelectPriorityPresentsOnboarding_firstTime() {
- // GIVEN pref is false
- Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, false);
-
- // GIVEN the priority onboarding screen is present
- PriorityOnboardingDialogController.Builder b =
- mock(PriorityOnboardingDialogController.Builder.class, Answers.RETURNS_SELF);
- PriorityOnboardingDialogController controller =
- mock(PriorityOnboardingDialogController.class);
- when(b.build()).thenReturn(controller);
-
- // GIVEN the user is changing conversation settings
- mNotificationInfo.bindNotification(
- -1,
- mShortcutManager,
- mMockPackageManager,
- mPeopleSpaceWidgetManager,
- mMockINotificationManager,
- mOnUserInteractionCallback,
- TEST_PACKAGE_NAME,
- mNotificationChannel,
- mEntry,
- mBubbleMetadata,
- null,
- null,
- mIconFactory,
- mContext,
- () -> b,
- true,
- mTestHandler,
- mTestHandler, null, Optional.of(mBubblesManager),
- mShadeController);
-
- // WHEN user clicks "priority"
- mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
- verify(controller, never()).show();
-
- // and then done
- mNotificationInfo.findViewById(R.id.done).performClick();
-
- // THEN the user is presented with the priority onboarding screen
- verify(controller, atLeastOnce()).show();
- }
-
- @Test
- public void testSelectPriorityDoesNotShowOnboarding_secondTime() {
- //WHEN pref is true
- Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, true);
-
- PriorityOnboardingDialogController.Builder b =
- mock(PriorityOnboardingDialogController.Builder.class, Answers.RETURNS_SELF);
- PriorityOnboardingDialogController controller =
- mock(PriorityOnboardingDialogController.class);
- when(b.build()).thenReturn(controller);
-
- mNotificationInfo.bindNotification(
- -1,
- mShortcutManager,
- mMockPackageManager,
- mPeopleSpaceWidgetManager,
- mMockINotificationManager,
- mOnUserInteractionCallback,
- TEST_PACKAGE_NAME,
- mNotificationChannel,
- mEntry,
- mBubbleMetadata,
- null,
- null,
- mIconFactory,
- mContext,
- () -> b,
- true,
- mTestHandler,
- mTestHandler, null, Optional.of(mBubblesManager),
- mShadeController);
-
- // WHEN user clicks "priority"
- mNotificationInfo.setSelectedAction(NotificationConversationInfo.ACTION_FAVORITE);
- verify(controller, never()).show();
-
- // and then done
- mNotificationInfo.findViewById(R.id.done).performClick();
-
- // THEN the user is presented with the priority onboarding screen
- verify(controller, never()).show();
- }
-
- @Test
public void testSelectPriorityRequestsPinPeopleTile() {
- //WHEN pref is true and channel is default importance
- Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, true);
+ //WHEN channel is default importance
mNotificationChannel.setImportantConversation(false);
mNotificationInfo.bindNotification(
-1,
@@ -1275,7 +1261,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1293,9 +1278,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
@Test
public void testSelectDefaultDoesNotRequestPinPeopleTile() {
- //WHEN pref is true
- Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, true);
-
mNotificationInfo.bindNotification(
-1,
mShortcutManager,
@@ -1311,7 +1293,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
@@ -1329,8 +1310,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
@Test
public void testSelectPriority_AlreadyPriority_DoesNotRequestPinPeopleTile() {
- //WHEN pref is true and channel is priority
- Prefs.putBoolean(mContext, Prefs.Key.HAS_SEEN_PRIORITY_ONBOARDING_IN_S, true);
mConversationChannel.setOriginalImportance(IMPORTANCE_HIGH);
mConversationChannel.setImportance(IMPORTANCE_HIGH);
mConversationChannel.setImportantConversation(true);
@@ -1350,7 +1329,6 @@ public class NotificationConversationInfoTest extends SysuiTestCase {
null,
mIconFactory,
mContext,
- mBuilderProvider,
true,
mTestHandler,
mTestHandler, null, Optional.of(mBubblesManager),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
index bfce2a568c78..9f537f5b6afc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsManagerTest.java
@@ -139,9 +139,6 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
@Mock private BubblesManager mBubblesManager;
@Mock private ShadeController mShadeController;
@Mock private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
- @Mock(answer = Answers.RETURNS_SELF)
- private PriorityOnboardingDialogController.Builder mBuilder;
- private Provider<PriorityOnboardingDialogController.Builder> mProvider = () -> mBuilder;
@Mock private AssistantFeedbackController mAssistantFeedbackController;
@Before
@@ -163,7 +160,7 @@ public class NotificationGutsManagerTest extends SysuiTestCase {
() -> mStatusBar, mHandler, mHandler, mAccessibilityManager, mHighPriorityProvider,
mINotificationManager, mNotificationEntryManager, mPeopleSpaceWidgetManager,
mLauncherApps, mShortcutManager, mChannelEditorDialogController, mContextTracker,
- mProvider, mAssistantFeedbackController, Optional.of(mBubblesManager),
+ mAssistantFeedbackController, Optional.of(mBubblesManager),
new UiEventLoggerFake(), mOnUserInteractionCallback, mShadeController);
mGutsManager.setUpWithPresenter(mPresenter, mNotificationListContainer,
mCheckSaveListener, mOnSettingsClickListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
index a01e0b1c3e3a..f485b465e486 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/CollapsedStatusBarFragmentTest.java
@@ -38,7 +38,6 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.R;
import com.android.systemui.SysuiBaseFragmentTest;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.phone.ongoingcall.OngoingCallController;
@@ -57,7 +56,7 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
private StatusBarStateController mStatusBarStateController;
private OngoingCallController mOngoingCallController;
private SystemStatusAnimationScheduler mAnimationScheduler;
- private PrivacyDotViewController mDotViewController;
+ private StatusBarLocationPublisher mLocationPublisher;
public CollapsedStatusBarFragmentTest() {
super(CollapsedStatusBarFragment.class);
@@ -224,12 +223,12 @@ public class CollapsedStatusBarFragmentTest extends SysuiBaseFragmentTest {
protected Fragment instantiate(Context context, String className, Bundle arguments) {
mOngoingCallController = mock(OngoingCallController.class);
mAnimationScheduler = mock(SystemStatusAnimationScheduler.class);
- mDotViewController = mock(PrivacyDotViewController.class);
+ mLocationPublisher = mock(StatusBarLocationPublisher.class);
setUpNotificationIconAreaController();
return new CollapsedStatusBarFragment(
mOngoingCallController,
mAnimationScheduler,
- mDotViewController,
+ mLocationPublisher,
mMockNotificationAreaController);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index b6eb4923ee4a..f98f00cd9187 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -20,6 +20,7 @@ import static com.android.systemui.statusbar.phone.ScrimController.OPAQUE;
import static com.android.systemui.statusbar.phone.ScrimController.SEMI_TRANSPARENT;
import static com.android.systemui.statusbar.phone.ScrimController.TRANSPARENT;
+import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -165,7 +166,7 @@ public class ScrimControllerTest extends SysuiTestCase {
endAnimation(mScrimInFront);
endAnimation(mScrimForBubble);
- Assert.assertEquals("Animators did not finish",
+ assertEquals("Animators did not finish",
mAnimatorListener.getNumStarts(), mAnimatorListener.getNumEnds());
}
@@ -422,7 +423,7 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.AOD);
finishAnimationsImmediately();
mScrimController.setAodFrontScrimAlpha(0.3f);
- Assert.assertEquals(ScrimState.AOD.getFrontAlpha(), mScrimInFront.getViewAlpha(), 0.001f);
+ assertEquals(ScrimState.AOD.getFrontAlpha(), mScrimInFront.getViewAlpha(), 0.001f);
Assert.assertNotEquals(0.3f, mScrimInFront.getViewAlpha(), 0.001f);
}
@@ -601,13 +602,13 @@ public class ScrimControllerTest extends SysuiTestCase {
));
// Front scrim should be transparent
- Assert.assertEquals(ScrimController.TRANSPARENT,
+ assertEquals(ScrimController.TRANSPARENT,
mScrimInFront.getViewAlpha(), 0.0f);
// Back scrim should be visible
- Assert.assertEquals(ScrimController.BUSY_SCRIM_ALPHA,
+ assertEquals(ScrimController.BUSY_SCRIM_ALPHA,
mScrimBehind.getViewAlpha(), 0.0f);
// Bubble scrim should be visible
- Assert.assertEquals(ScrimController.BUBBLE_SCRIM_ALPHA,
+ assertEquals(ScrimController.BUBBLE_SCRIM_ALPHA,
mScrimForBubble.getViewAlpha(), 0.0f);
}
@@ -615,15 +616,15 @@ public class ScrimControllerTest extends SysuiTestCase {
public void scrimStateCallback() {
mScrimController.transitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
- Assert.assertEquals(mScrimState, ScrimState.UNLOCKED);
+ assertEquals(mScrimState, ScrimState.UNLOCKED);
mScrimController.transitionTo(ScrimState.BOUNCER);
finishAnimationsImmediately();
- Assert.assertEquals(mScrimState, ScrimState.BOUNCER);
+ assertEquals(mScrimState, ScrimState.BOUNCER);
mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
finishAnimationsImmediately();
- Assert.assertEquals(mScrimState, ScrimState.BOUNCER_SCRIMMED);
+ assertEquals(mScrimState, ScrimState.BOUNCER_SCRIMMED);
}
@Test
@@ -638,13 +639,13 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setPanelExpansion(1.0f);
finishAnimationsImmediately();
- Assert.assertEquals("Scrim alpha should change after setPanelExpansion",
+ assertEquals("Scrim alpha should change after setPanelExpansion",
mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f);
mScrimController.setPanelExpansion(0f);
finishAnimationsImmediately();
- Assert.assertEquals("Scrim alpha should change after setPanelExpansion",
+ assertEquals("Scrim alpha should change after setPanelExpansion",
mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f);
}
@@ -698,7 +699,7 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setExpansionAffectsAlpha(false);
mScrimController.setPanelExpansion(0.8f);
verifyZeroInteractions(mScrimBehind);
- Assert.assertEquals("Scrim opacity shouldn't change when setExpansionAffectsAlpha "
+ assertEquals("Scrim opacity shouldn't change when setExpansionAffectsAlpha "
+ "is false", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
mScrimController.setExpansionAffectsAlpha(true);
@@ -801,9 +802,9 @@ public class ScrimControllerTest extends SysuiTestCase {
}
});
finishAnimationsImmediately();
- Assert.assertEquals("onStart called in wrong order", 1, callOrder[0]);
- Assert.assertEquals("onDisplayBlanked called in wrong order", 2, callOrder[1]);
- Assert.assertEquals("onFinished called in wrong order", 3, callOrder[2]);
+ assertEquals("onStart called in wrong order", 1, callOrder[0]);
+ assertEquals("onDisplayBlanked called in wrong order", 2, callOrder[1]);
+ assertEquals("onFinished called in wrong order", 3, callOrder[2]);
}
@Test
@@ -911,7 +912,7 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.UNLOCKED);
finishAnimationsImmediately();
- Assert.assertEquals("Scrim expansion opacity wasn't conserved when transitioning back",
+ assertEquals("Scrim expansion opacity wasn't conserved when transitioning back",
expandedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
}
@@ -981,7 +982,7 @@ public class ScrimControllerTest extends SysuiTestCase {
}
mScrimController.transitionTo(state);
finishAnimationsImmediately();
- Assert.assertEquals("Should be clickable unless AOD or PULSING, was: " + state,
+ assertEquals("Should be clickable unless AOD or PULSING, was: " + state,
mScrimBehind.getViewAlpha() != 0 && !eatsTouches.contains(state),
mScrimBehind.isClickable());
}
@@ -1035,9 +1036,9 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.setQsPosition(0, 300);
finishAnimationsImmediately();
- Assert.assertEquals("Behind scrim should be opaque",
+ assertEquals("Behind scrim should be opaque",
mScrimBehind.getViewAlpha(), 1, 0.0);
- Assert.assertEquals("Notifications scrim should be opaque",
+ assertEquals("Notifications scrim should be opaque",
mNotificationsScrim.getViewAlpha(), 1, 0.0);
}
@@ -1093,6 +1094,40 @@ public class ScrimControllerTest extends SysuiTestCase {
mNotificationsScrim, TRANSPARENT));
}
+ @Test
+ public void testNotificationScrimVisible_afterOpeningShadeFromLockscreen() {
+ mScrimController.setPanelExpansion(1);
+ mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+ finishAnimationsImmediately();
+
+ assertScrimAlpha(Map.of(
+ mScrimBehind, OPAQUE,
+ mNotificationsScrim, OPAQUE));
+ }
+
+ @Test
+ public void testNotificationTransparency_followsPanelExpansionInShadeLockedState() {
+ mScrimController.transitionTo(ScrimState.SHADE_LOCKED);
+
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.8f, /* expansion */ 0.8f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.2f, /* expansion */ 0.2f);
+ }
+
+ @Test
+ public void testNotificationTransparency_inKeyguardState() {
+ mScrimController.transitionTo(ScrimState.KEYGUARD);
+
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.2f, /* expansion */ 0.8f);
+ assertAlphaAfterExpansion(mNotificationsScrim, /* alpha */ 0.8f, /* expansion */ 0.2f);
+ }
+
+ private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
+ mScrimController.setPanelExpansion(expansion);
+ finishAnimationsImmediately();
+ // alpha is not changing linearly thus 0.2 of leeway when asserting
+ assertEquals(expectedAlpha, mNotificationsScrim.getViewAlpha(), 0.2);
+ }
+
private void assertScrimTinted(Map<ScrimView, Boolean> scrimToTint) {
scrimToTint.forEach((scrim, hasTint) -> assertScrimTint(scrim, hasTint));
}
@@ -1101,7 +1136,7 @@ public class ScrimControllerTest extends SysuiTestCase {
String message = "Tint test failed at state " + mScrimController.getState()
+ " with scrim: " + getScrimName(scrim) + " and tint: "
+ Integer.toHexString(scrim.getTint());
- Assert.assertEquals(message, hasTint, scrim.getTint() != Color.TRANSPARENT);
+ assertEquals(message, hasTint, scrim.getTint() != Color.TRANSPARENT);
}
private String getScrimName(ScrimView scrim) {
@@ -1146,13 +1181,13 @@ public class ScrimControllerTest extends SysuiTestCase {
} else {
visibility = TRANSPARENT;
}
- Assert.assertEquals("Invalid visibility.",
+ assertEquals("Invalid visibility.",
visibility /* expected */,
mScrimVisibility);
}
private void assertScrimAlpha(ScrimView scrim, int expectedAlpha) {
- Assert.assertEquals("Unexpected " + getScrimName(scrim) + " scrim alpha: "
+ assertEquals("Unexpected " + getScrimName(scrim) + " scrim alpha: "
+ scrim.getViewAlpha(),
expectedAlpha != TRANSPARENT /* expected */,
scrim.getViewAlpha() > TRANSPARENT /* actual */);
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 545e2e08ec07..b2487e8e2444 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
@@ -115,7 +115,6 @@ import com.android.systemui.statusbar.StatusBarStateControllerImpl;
import com.android.systemui.statusbar.SuperStatusBarViewFactory;
import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.charging.WiredChargingRippleController;
-import com.android.systemui.statusbar.events.PrivacyDotViewController;
import com.android.systemui.statusbar.events.SystemStatusAnimationScheduler;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
@@ -267,7 +266,7 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private WiredChargingRippleController mWiredChargingRippleController;
@Mock private OngoingCallController mOngoingCallController;
@Mock private SystemStatusAnimationScheduler mAnimationScheduler;
- @Mock private PrivacyDotViewController mDotViewController;
+ @Mock private StatusBarLocationPublisher mLocationPublisher;
@Mock private FeatureFlags mFeatureFlags;
@Mock private IWallpaperManager mWallpaperManager;
@Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
@@ -437,7 +436,7 @@ public class StatusBarTest extends SysuiTestCase {
mWiredChargingRippleController,
mOngoingCallController,
mAnimationScheduler,
- mDotViewController,
+ mLocationPublisher,
mFeatureFlags,
mKeyguardUnlockAnimationController);
when(mKeyguardViewMediator.registerStatusBar(any(StatusBar.class), any(ViewGroup.class),
diff --git a/services/Android.bp b/services/Android.bp
index 2281a159f6f7..1dd219264575 100644
--- a/services/Android.bp
+++ b/services/Android.bp
@@ -190,13 +190,13 @@ droidstubs {
defaults: ["services-stubs-default"],
check_api: {
current: {
- api_file: "api/non-updatable-current.txt",
- removed_api_file: "api/non-updatable-removed.txt",
+ api_file: "api/current.txt",
+ removed_api_file: "api/removed.txt",
},
api_lint: {
enabled: true,
new_since: ":android-non-updatable.api.system-server.latest",
- baseline_file: "api/non-updatable-lint-baseline.txt",
+ baseline_file: "api/lint-baseline.txt",
},
},
dists: [
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 61de53a2a483..7403af7605bc 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -16,6 +16,9 @@
package com.android.server.accessibility;
+import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
+import static android.view.WindowManager.LayoutParams.TYPE_MAGNIFICATION_OVERLAY;
+
import android.annotation.MainThread;
import android.content.Context;
import android.graphics.Region;
@@ -557,12 +560,16 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
MagnificationGestureHandler magnificationGestureHandler;
if (mAms.getMagnificationMode(displayId)
== Settings.Secure.ACCESSIBILITY_MAGNIFICATION_MODE_WINDOW) {
- magnificationGestureHandler = new WindowMagnificationGestureHandler(displayContext,
+ final Context uiContext = displayContext.createWindowContext(
+ TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY, null /* options */);
+ magnificationGestureHandler = new WindowMagnificationGestureHandler(uiContext,
mAms.getWindowMagnificationMgr(), mAms.getMagnificationController(),
detectControlGestures, triggerable,
displayId);
} else {
- magnificationGestureHandler = new FullScreenMagnificationGestureHandler(displayContext,
+ final Context uiContext = displayContext.createWindowContext(
+ TYPE_MAGNIFICATION_OVERLAY, null /* options */);
+ magnificationGestureHandler = new FullScreenMagnificationGestureHandler(uiContext,
mAms.getFullScreenMagnificationController(), mAms.getMagnificationController(),
detectControlGestures, triggerable,
new WindowMagnificationPromptController(displayContext, mUserId), displayId);
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
index 2434e2ca0b54..f7d1b9a311ba 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/FullScreenMagnificationGestureHandler.java
@@ -34,6 +34,7 @@ import static java.util.Arrays.copyOfRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UiContext;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -139,7 +140,7 @@ public class FullScreenMagnificationGestureHandler extends MagnificationGestureH
private PointerCoords[] mTempPointerCoords;
private PointerProperties[] mTempPointerProperties;
- public FullScreenMagnificationGestureHandler(Context context,
+ public FullScreenMagnificationGestureHandler(@UiContext Context context,
FullScreenMagnificationController fullScreenMagnificationController,
Callback callback,
boolean detectTripleTap,
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
index 07f22dcb2c95..c5495d98226e 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/PanningScalingHandler.java
@@ -19,6 +19,7 @@ package com.android.server.accessibility.magnification;
import static java.lang.Math.abs;
import android.annotation.NonNull;
+import android.annotation.UiContext;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
@@ -63,8 +64,8 @@ class PanningScalingHandler extends
private boolean mScaling;
private boolean mEnable;
- PanningScalingHandler(Context context, float maxScale, float minScale, boolean blockScroll,
- @NonNull MagnificationDelegate magnificationDelegate) {
+ PanningScalingHandler(@UiContext Context context, float maxScale, float minScale,
+ boolean blockScroll, @NonNull MagnificationDelegate magnificationDelegate) {
mDisplayId = context.getDisplayId();
mMaxScale = maxScale;
mMinScale = minScale;
diff --git a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
index fa3406217fa8..4fb9a03b8ac1 100644
--- a/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
+++ b/services/accessibility/java/com/android/server/accessibility/magnification/WindowMagnificationGestureHandler.java
@@ -24,6 +24,7 @@ import static java.util.Arrays.asList;
import static java.util.Arrays.copyOfRange;
import android.annotation.Nullable;
+import android.annotation.UiContext;
import android.content.Context;
import android.graphics.Point;
import android.provider.Settings;
@@ -86,7 +87,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
private final Context mContext;
private final Point mTempPoint = new Point();
- public WindowMagnificationGestureHandler(Context context,
+ public WindowMagnificationGestureHandler(@UiContext Context context,
WindowMagnificationManager windowMagnificationMgr,
Callback callback,
boolean detectTripleTap, boolean detectShortcutTrigger, int displayId) {
@@ -342,7 +343,7 @@ public class WindowMagnificationGestureHandler extends MagnificationGestureHandl
*/
private final boolean mDetectTripleTap;
- DetectingState(Context context, boolean detectTripleTap) {
+ DetectingState(@UiContext Context context, boolean detectTripleTap) {
mDetectTripleTap = detectTripleTap;
final MultiTap multiTap = new MultiTap(context, mDetectTripleTap ? 3 : 1,
mDetectTripleTap
diff --git a/services/api/Android.bp b/services/api/Android.bp
index bbc8c72b2eef..ee7d49fc99c8 100644
--- a/services/api/Android.bp
+++ b/services/api/Android.bp
@@ -24,12 +24,12 @@ package {
filegroup {
name: "non-updatable-system-server-current.txt",
- srcs: ["non-updatable-current.txt"],
+ srcs: ["current.txt"],
visibility: ["//frameworks/base/api"],
}
filegroup {
name: "non-updatable-system-server-removed.txt",
- srcs: ["non-updatable-removed.txt"],
+ srcs: ["removed.txt"],
visibility: ["//frameworks/base/api"],
}
diff --git a/services/api/current.txt b/services/api/current.txt
index a0b1e3349e77..475dcf5eb20e 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -1,57 +1,4 @@
// Signature format: 2.0
-package com.android.permission.persistence {
-
- public interface RuntimePermissionsPersistence {
- method @NonNull public static com.android.permission.persistence.RuntimePermissionsPersistence createInstance();
- method public void deleteForUser(@NonNull android.os.UserHandle);
- method @Nullable public com.android.permission.persistence.RuntimePermissionsState readForUser(@NonNull android.os.UserHandle);
- method public void writeForUser(@NonNull com.android.permission.persistence.RuntimePermissionsState, @NonNull android.os.UserHandle);
- }
-
- public final class RuntimePermissionsState {
- ctor public RuntimePermissionsState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>, @NonNull java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>>);
- method @Nullable public String getFingerprint();
- method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getPackagePermissions();
- method @NonNull public java.util.Map<java.lang.String,java.util.List<com.android.permission.persistence.RuntimePermissionsState.PermissionState>> getSharedUserPermissions();
- method public int getVersion();
- field public static final int NO_VERSION = -1; // 0xffffffff
- }
-
- public static final class RuntimePermissionsState.PermissionState {
- ctor public RuntimePermissionsState.PermissionState(@NonNull String, boolean, int);
- method public int getFlags();
- method @NonNull public String getName();
- method public boolean isGranted();
- }
-
-}
-
-package com.android.role {
-
- public interface RoleManagerLocal {
- method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getRolesAndHolders(int);
- }
-
-}
-
-package com.android.role.persistence {
-
- public interface RolesPersistence {
- method @NonNull public static com.android.role.persistence.RolesPersistence createInstance();
- method public void deleteForUser(@NonNull android.os.UserHandle);
- method @Nullable public com.android.role.persistence.RolesState readForUser(@NonNull android.os.UserHandle);
- method public void writeForUser(@NonNull com.android.role.persistence.RolesState, @NonNull android.os.UserHandle);
- }
-
- public final class RolesState {
- ctor public RolesState(int, @Nullable String, @NonNull java.util.Map<java.lang.String,java.util.Set<java.lang.String>>);
- method @Nullable public String getPackagesHash();
- method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getRoles();
- method public int getVersion();
- }
-
-}
-
package com.android.server {
public final class LocalManagerRegistry {
diff --git a/services/api/lint-baseline.txt b/services/api/lint-baseline.txt
index e985ddb5352b..b46d21edd44c 100644
--- a/services/api/lint-baseline.txt
+++ b/services/api/lint-baseline.txt
@@ -1,4 +1,8 @@
// Baseline format: 1.0
+NotCloseable: com.android.server.wifi.SupplicantManager:
+ Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager
+
+
ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder):
Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)}
ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean):
diff --git a/services/api/non-updatable-current.txt b/services/api/non-updatable-current.txt
deleted file mode 100644
index 475dcf5eb20e..000000000000
--- a/services/api/non-updatable-current.txt
+++ /dev/null
@@ -1,71 +0,0 @@
-// Signature format: 2.0
-package com.android.server {
-
- public final class LocalManagerRegistry {
- method public static <T> void addManager(@NonNull Class<T>, @NonNull T);
- method @Nullable public static <T> T getManager(@NonNull Class<T>);
- }
-
- public abstract class SystemService {
- ctor public SystemService(@NonNull android.content.Context);
- method @NonNull public final android.content.Context getContext();
- method public boolean isUserSupported(@NonNull com.android.server.SystemService.TargetUser);
- method public void onBootPhase(int);
- method public abstract void onStart();
- method public void onUserStarting(@NonNull com.android.server.SystemService.TargetUser);
- method public void onUserStopped(@NonNull com.android.server.SystemService.TargetUser);
- method public void onUserStopping(@NonNull com.android.server.SystemService.TargetUser);
- method public void onUserSwitching(@Nullable com.android.server.SystemService.TargetUser, @NonNull com.android.server.SystemService.TargetUser);
- method public void onUserUnlocked(@NonNull com.android.server.SystemService.TargetUser);
- method public void onUserUnlocking(@NonNull com.android.server.SystemService.TargetUser);
- method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder);
- method protected final void publishBinderService(@NonNull String, @NonNull android.os.IBinder, boolean);
- field public static final int PHASE_ACTIVITY_MANAGER_READY = 550; // 0x226
- field public static final int PHASE_BOOT_COMPLETED = 1000; // 0x3e8
- field public static final int PHASE_DEVICE_SPECIFIC_SERVICES_READY = 520; // 0x208
- field public static final int PHASE_LOCK_SETTINGS_READY = 480; // 0x1e0
- field public static final int PHASE_SYSTEM_SERVICES_READY = 500; // 0x1f4
- field public static final int PHASE_THIRD_PARTY_APPS_CAN_START = 600; // 0x258
- field public static final int PHASE_WAIT_FOR_DEFAULT_DISPLAY = 100; // 0x64
- }
-
- public static final class SystemService.TargetUser {
- method @NonNull public android.os.UserHandle getUserHandle();
- }
-
-}
-
-package com.android.server.am {
-
- public interface ActivityManagerLocal {
- method public boolean canStartForegroundService(int, int, @NonNull String);
- }
-
-}
-
-package com.android.server.role {
-
- public interface RoleServicePlatformHelper {
- method @NonNull public String computePackageStateHash(int);
- method @NonNull public java.util.Map<java.lang.String,java.util.Set<java.lang.String>> getLegacyRoleState(int);
- }
-
-}
-
-package com.android.server.stats {
-
- public final class StatsHelper {
- method public static void sendStatsdReadyBroadcast(@NonNull android.content.Context);
- }
-
-}
-
-package com.android.server.wifi {
-
- public class SupplicantManager {
- method public static void start();
- method public static void stop();
- }
-
-}
-
diff --git a/services/api/non-updatable-lint-baseline.txt b/services/api/non-updatable-lint-baseline.txt
deleted file mode 100644
index b46d21edd44c..000000000000
--- a/services/api/non-updatable-lint-baseline.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-// Baseline format: 1.0
-NotCloseable: com.android.server.wifi.SupplicantManager:
- Classes that release resources (stop()) should implement AutoClosable and CloseGuard: class com.android.server.wifi.SupplicantManager
-
-
-ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder):
- Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder)}
-ProtectedMember: com.android.server.SystemService#publishBinderService(String, android.os.IBinder, boolean):
- Protected methods not allowed; must be public: method com.android.server.SystemService.publishBinderService(String,android.os.IBinder,boolean)}
diff --git a/services/api/non-updatable-removed.txt b/services/api/non-updatable-removed.txt
deleted file mode 100644
index d802177e249b..000000000000
--- a/services/api/non-updatable-removed.txt
+++ /dev/null
@@ -1 +0,0 @@
-// Signature format: 2.0
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index 816c50dde2a8..76a6c0eecd3e 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -1133,7 +1133,7 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP
* @param handler to use for postponed calculations.
*/
public abstract void requestChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Type int optional, @Checksum.Type int required,
+ @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
@Nullable List trustedInstallers,
@NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
@NonNull Executor executor, @NonNull Handler handler);
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 906702866889..047aae772f44 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -839,33 +839,45 @@ public abstract class IntentResolver<F, R extends Object> {
}
};
+ // Method to take the snapshot of an F.
+ protected F snapshot(F f) {
+ return f;
+ }
+
// Helper method to copy some of the maps.
- private static <E> void copyInto(ArrayMap<String, E[]> l, ArrayMap<String, E[]> r) {
+ protected void copyInto(ArrayMap<String, F[]> l, ArrayMap<String, F[]> r) {
final int end = r.size();
+ l.clear();
l.ensureCapacity(end);
for (int i = 0; i < end; i++) {
- final E[] val = r.valueAt(i);
+ final F[] val = r.valueAt(i);
final String key = r.keyAt(i);
- l.put(key, Arrays.copyOf(val, val.length));
+ final F[] newval = Arrays.copyOf(val, val.length);
+ for (int j = 0; j < newval.length; j++) {
+ newval[j] = snapshot(newval[j]);
+ }
+ l.put(key, newval);
+ }
+ }
+
+ protected void copyInto(ArraySet<F> l, ArraySet<F> r) {
+ l.clear();
+ final int end = r.size();
+ l.ensureCapacity(end);
+ for (int i = 0; i < end; i++) {
+ l.append(snapshot(r.valueAt(i)));
}
}
// Make <this> a copy of <orig>. The presumption is that <this> is empty but all
// arrays are cleared out explicitly, just to be sure.
protected void copyFrom(IntentResolver orig) {
- mFilters.clear();
- mFilters.addAll(orig.mFilters);
- mTypeToFilter.clear();
+ copyInto(mFilters, orig.mFilters);
copyInto(mTypeToFilter, orig.mTypeToFilter);
- mBaseTypeToFilter.clear();
copyInto(mBaseTypeToFilter, orig.mBaseTypeToFilter);
- mWildTypeToFilter.clear();
copyInto(mWildTypeToFilter, orig.mWildTypeToFilter);
- mSchemeToFilter.clear();
copyInto(mSchemeToFilter, orig.mSchemeToFilter);
- mActionToFilter.clear();
copyInto(mActionToFilter, orig.mActionToFilter);
- mTypedActionToFilter.clear();
copyInto(mTypedActionToFilter, orig.mTypedActionToFilter);
}
diff --git a/services/core/java/com/android/server/WatchedIntentResolver.java b/services/core/java/com/android/server/WatchedIntentResolver.java
index e514f3c6fd59..0831c36d2bf6 100644
--- a/services/core/java/com/android/server/WatchedIntentResolver.java
+++ b/services/core/java/com/android/server/WatchedIntentResolver.java
@@ -19,10 +19,13 @@ package com.android.server;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import com.android.server.pm.WatchedIntentFilter;
+import com.android.server.utils.Snappable;
import com.android.server.utils.Watchable;
import com.android.server.utils.WatchableImpl;
import com.android.server.utils.Watcher;
+import java.util.ArrayList;
import java.util.List;
/**
@@ -31,9 +34,9 @@ import java.util.List;
* @param <R> The resolver type.
* {@hide}
*/
-public abstract class WatchedIntentResolver<F, R extends Object>
+public abstract class WatchedIntentResolver<F extends Watchable, R extends Object>
extends IntentResolver<F, R>
- implements Watchable {
+ implements Watchable, Snappable {
/**
* Watchable machinery
@@ -78,6 +81,13 @@ public abstract class WatchedIntentResolver<F, R extends Object>
mWatchable.dispatchChange(what);
}
+ private final Watcher mWatcher = new Watcher() {
+ @Override
+ public void onChange(@Nullable Watchable what) {
+ dispatchChange(what);
+ }
+ };
+
/**
* Notify listeners that this object has changed.
*/
@@ -88,17 +98,20 @@ public abstract class WatchedIntentResolver<F, R extends Object>
@Override
public void addFilter(F f) {
super.addFilter(f);
+ f.registerObserver(mWatcher);
onChanged();
}
@Override
public void removeFilter(F f) {
+ f.unregisterObserver(mWatcher);
super.removeFilter(f);
onChanged();
}
@Override
protected void removeFilterInternal(F f) {
+ f.unregisterObserver(mWatcher);
super.removeFilterInternal(f);
onChanged();
}
@@ -109,4 +122,17 @@ public abstract class WatchedIntentResolver<F, R extends Object>
super.sortResults(results);
onChanged();
}
+
+ /**
+ * @see IntentResolver#findFilters(IntentFilter)
+ */
+ public ArrayList<F> findFilters(WatchedIntentFilter matching) {
+ return super.findFilters(matching.getIntentFilter());
+ }
+
+ // Make <this> a copy of <orig>. The presumption is that <this> is empty but all
+ // arrays are cleared out explicitly, just to be sure.
+ protected void copyFrom(WatchedIntentResolver orig) {
+ super.copyFrom(orig);
+ }
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9aedf1504df5..d526ebc8e581 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -14831,7 +14831,7 @@ public class ActivityManagerService extends IActivityManager.Stub
throw new IllegalArgumentException("null fd");
}
- synchronized (mProcLock) {
+ synchronized (this) {
ProcessRecord proc = findProcessLOSP(process, userId, "dumpHeap");
IApplicationThread thread;
if (proc == null || (thread = proc.getThread()) == null) {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 6765ad02efa9..cc98abfc17f2 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -135,6 +135,7 @@ import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.wm.ActivityServiceConnectionsHolder;
import com.android.server.wm.WindowManagerService;
+import com.android.server.wm.WindowProcessController;
import dalvik.system.VMRuntime;
@@ -4626,6 +4627,7 @@ public final class ProcessList {
@GuardedBy(anyOf = {"mService", "mProcLock"})
void updateApplicationInfoLOSP(List<String> packagesToUpdate, int userId,
boolean updateFrameworkRes) {
+ final ArrayList<WindowProcessController> targetProcesses = new ArrayList<>();
for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
final ProcessRecord app = mLruProcesses.get(i);
if (app.getThread() == null) {
@@ -4646,6 +4648,7 @@ public final class ProcessList {
if (ai.packageName.equals(app.info.packageName)) {
app.info = ai;
}
+ targetProcesses.add(app.getWindowProcessController());
}
} catch (RemoteException e) {
Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s",
@@ -4654,6 +4657,9 @@ public final class ProcessList {
}
});
}
+
+ mService.mActivityTaskManager.updateAssetConfiguration(
+ updateFrameworkRes ? null : targetProcesses);
}
@GuardedBy("mService")
diff --git a/services/core/java/com/android/server/app/GameManagerService.java b/services/core/java/com/android/server/app/GameManagerService.java
index b7ef10a5d45d..d2c6c6c620dd 100644
--- a/services/core/java/com/android/server/app/GameManagerService.java
+++ b/services/core/java/com/android/server/app/GameManagerService.java
@@ -56,6 +56,7 @@ import android.os.ShellCallback;
import android.provider.DeviceConfig;
import android.provider.DeviceConfig.Properties;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Slog;
@@ -180,9 +181,14 @@ public final class GameManagerService extends IGameManagerService.Stub {
break;
}
case POPULATE_GAME_MODE_SETTINGS: {
+ // Scan all game packages and re-enforce the configured compat mode overrides
+ // as the DeviceConfig may have be wiped/since last reboot and we can't risk
+ // having overrides configured for packages that no longer have any DeviceConfig
+ // and thus any way to escape compat mode.
removeMessages(POPULATE_GAME_MODE_SETTINGS, msg.obj);
- loadDeviceConfigLocked();
- break;
+ final int userId = (int) msg.obj;
+ final String[] packageNames = getInstalledGamePackageNames(userId);
+ updateConfigsForUser(userId, packageNames);
}
}
}
@@ -198,28 +204,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
@Override
public void onPropertiesChanged(Properties properties) {
- synchronized (mDeviceConfigLock) {
- for (final String packageName : properties.getKeyset()) {
- try {
- // Check if the package is installed before caching it.
- mPackageManager.getPackageInfo(packageName, 0);
- final GamePackageConfiguration config =
- GamePackageConfiguration.fromProperties(packageName, properties);
- if (config.isValid()) {
- putConfig(config);
- } else {
- // This means that we received a bad config, or the config was deleted.
- Slog.i(TAG, "Removing config for: " + packageName);
- mConfigs.remove(packageName);
- disableCompatScale(packageName);
- }
- } catch (PackageManager.NameNotFoundException e) {
- if (DEBUG) {
- Slog.v(TAG, "Package name not found", e);
- }
- }
- }
- }
+ final String[] packageNames = properties.getKeyset().toArray(new String[0]);
+ updateConfigsForUser(mContext.getUserId(), packageNames);
}
@Override
@@ -228,80 +214,166 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
}
- private static class GameModeConfiguration {
- public static final String TAG = "GameManagerService_GameModeConfiguration";
- public static final String MODE_KEY = "mode";
- public static final String SCALING_KEY = "downscaleFactor";
+ /**
+ * GamePackageConfiguration manages all game mode config details for its associated package.
+ */
+ @VisibleForTesting
+ public class GamePackageConfiguration {
+ public static final String TAG = "GameManagerService_GamePackageConfiguration";
- private final @GameMode int mGameMode;
- private final String mScaling;
+ /**
+ * Metadata that can be included in the app manifest to allow/disallow any window manager
+ * downscaling interventions. Default value is TRUE.
+ */
+ public static final String METADATA_WM_ALLOW_DOWNSCALE =
+ "com.android.graphics.intervention.wm.allowDownscale";
- private GameModeConfiguration(@NonNull int gameMode,
- @NonNull String scaling) {
- mGameMode = gameMode;
- mScaling = scaling;
- }
+ /**
+ * Metadata that needs to be included in the app manifest to OPT-IN to PERFORMANCE mode.
+ * This means the app will assume full responsibility for the experience provided by this
+ * mode and the system will enable no window manager downscaling.
+ * Default value is FALSE
+ */
+ public static final String METADATA_PERFORMANCE_MODE_ENABLE =
+ "com.android.app.gamemode.performance.enabled";
- public static GameModeConfiguration fromKeyValueListParser(KeyValueListParser parser) {
- return new GameModeConfiguration(
- parser.getInt(MODE_KEY, GameManager.GAME_MODE_UNSUPPORTED),
- parser.getString(SCALING_KEY, "1.0")
- );
- }
+ /**
+ * Metadata that needs to be included in the app manifest to OPT-IN to BATTERY mode.
+ * This means the app will assume full responsibility for the experience provided by this
+ * mode and the system will enable no window manager downscaling.
+ * Default value is FALSE
+ */
+ public static final String METADATA_BATTERY_MODE_ENABLE =
+ "com.android.app.gamemode.battery.enabled";
- public int getGameMode() {
- return mGameMode;
- }
+ private final String mPackageName;
+ private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
+ private boolean mPerfModeOptedIn;
+ private boolean mBatteryModeOptedIn;
+ private boolean mAllowDownscale;
- public String getScaling() {
- return mScaling;
+ GamePackageConfiguration(String packageName, int userId) {
+ mPackageName = packageName;
+ mModeConfigs = new ArrayMap<>();
+ try {
+ final ApplicationInfo ai = mPackageManager.getApplicationInfoAsUser(packageName,
+ PackageManager.GET_META_DATA, userId);
+ if (ai.metaData != null) {
+ mPerfModeOptedIn = ai.metaData.getBoolean(METADATA_PERFORMANCE_MODE_ENABLE);
+ mBatteryModeOptedIn = ai.metaData.getBoolean(METADATA_BATTERY_MODE_ENABLE);
+ mAllowDownscale = ai.metaData.getBoolean(METADATA_WM_ALLOW_DOWNSCALE, true);
+ } else {
+ mPerfModeOptedIn = false;
+ mBatteryModeOptedIn = false;
+ mAllowDownscale = true;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.e(TAG, "Failed to get package metadata", e);
+ }
+ final String configString = DeviceConfig.getProperty(
+ DeviceConfig.NAMESPACE_GAME_OVERLAY, packageName);
+ if (configString != null) {
+ final String[] gameModeConfigStrings = configString.split(":");
+ for (String gameModeConfigString : gameModeConfigStrings) {
+ try {
+ final KeyValueListParser parser = new KeyValueListParser(',');
+ parser.setString(gameModeConfigString);
+ addModeConfig(new GameModeConfiguration(parser));
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Invalid config string");
+ }
+ }
+ }
}
- public boolean isValid() {
- return (mGameMode == GameManager.GAME_MODE_PERFORMANCE
- || mGameMode == GameManager.GAME_MODE_BATTERY) && getCompatChangeId() != 0;
- }
+ /**
+ * GameModeConfiguration contains all the values for all the interventions associated with
+ * a game mode.
+ */
+ @VisibleForTesting
+ public class GameModeConfiguration {
+ public static final String TAG = "GameManagerService_GameModeConfiguration";
+ public static final String MODE_KEY = "mode";
+ public static final String SCALING_KEY = "downscaleFactor";
+ public static final String DEFAULT_SCALING = "1.0";
+
+ private final @GameMode int mGameMode;
+ private final String mScaling;
+
+ GameModeConfiguration(KeyValueListParser parser) {
+ mGameMode = parser.getInt(MODE_KEY, GameManager.GAME_MODE_UNSUPPORTED);
+ mScaling = !mAllowDownscale || isGameModeOptedIn(mGameMode)
+ ? DEFAULT_SCALING : parser.getString(SCALING_KEY, DEFAULT_SCALING);
+ }
- public String toString() {
- return "[Game Mode:" + mGameMode + ",Scaling:" + mScaling + "]";
- }
+ public int getGameMode() {
+ return mGameMode;
+ }
- public long getCompatChangeId() {
- switch (mScaling) {
- case "0.5":
- return DOWNSCALE_50;
- case "0.6":
- return DOWNSCALE_60;
- case "0.7":
- return DOWNSCALE_70;
- case "0.8":
- return DOWNSCALE_80;
- case "0.9":
- return DOWNSCALE_90;
+ public String getScaling() {
+ return mScaling;
}
- return 0;
- }
- }
- private static class GamePackageConfiguration {
- public static final String TAG = "GameManagerService_GamePackageConfiguration";
+ public boolean isValid() {
+ return (mGameMode == GameManager.GAME_MODE_PERFORMANCE
+ || mGameMode == GameManager.GAME_MODE_BATTERY)
+ && (!mAllowDownscale || getCompatChangeId() != 0);
+ }
- private final String mPackageName;
- private final ArrayMap<Integer, GameModeConfiguration> mModeConfigs;
+ /**
+ * @hide
+ */
+ public String toString() {
+ return "[Game Mode:" + mGameMode + ",Scaling:" + mScaling + "]";
+ }
- private GamePackageConfiguration(String packageName) {
- mPackageName = packageName;
- mModeConfigs = new ArrayMap<>();
+ /**
+ * Get the corresponding compat change id for the current scaling string.
+ */
+ public long getCompatChangeId() {
+ switch (mScaling) {
+ case "0.5":
+ return DOWNSCALE_50;
+ case "0.6":
+ return DOWNSCALE_60;
+ case "0.7":
+ return DOWNSCALE_70;
+ case "0.8":
+ return DOWNSCALE_80;
+ case "0.9":
+ return DOWNSCALE_90;
+ }
+ return 0;
+ }
}
public String getPackageName() {
return mPackageName;
}
+ /**
+ * Gets whether a package has opted into a game mode via its manifest.
+ *
+ * @return True if the app package has specified in its metadata either:
+ * "com.android.app.gamemode.performance.enabled" or
+ * "com.android.app.gamemode.battery.enabled" with a value of "true"
+ */
+ public boolean isGameModeOptedIn(@GameMode int gameMode) {
+ return (mBatteryModeOptedIn && gameMode == GameManager.GAME_MODE_BATTERY)
+ || (mPerfModeOptedIn && gameMode == GameManager.GAME_MODE_PERFORMANCE);
+ }
+
public @GameMode int[] getAvailableGameModes() {
- if (mModeConfigs.keySet().size() > 0) {
- return mModeConfigs.keySet().stream()
- .mapToInt(Integer::intValue).toArray();
+ ArraySet<Integer> modeSet = new ArraySet<>(mModeConfigs.keySet());
+ if (mBatteryModeOptedIn) {
+ modeSet.add(GameManager.GAME_MODE_BATTERY);
+ }
+ if (mPerfModeOptedIn) {
+ modeSet.add(GameManager.GAME_MODE_PERFORMANCE);
+ }
+ if (modeSet.size() > 0) {
+ modeSet.add(GameManager.GAME_MODE_STANDARD);
+ return modeSet.stream().mapToInt(Integer::intValue).toArray();
}
return new int[]{GameManager.GAME_MODE_UNSUPPORTED};
}
@@ -327,30 +399,8 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
}
- /**
- * Create a new instance from a package name and DeviceConfig.Properties instance
- */
- public static GamePackageConfiguration fromProperties(String key,
- Properties properties) {
- final GamePackageConfiguration packageConfig = new GamePackageConfiguration(key);
- final String configString = properties.getString(key, "");
- final String[] gameModeConfigStrings = configString.split(":");
- for (String gameModeConfigString : gameModeConfigStrings) {
- try {
- final KeyValueListParser parser = new KeyValueListParser(',');
- parser.setString(gameModeConfigString);
- final GameModeConfiguration config =
- GameModeConfiguration.fromKeyValueListParser(parser);
- packageConfig.addModeConfig(config);
- } catch (IllegalArgumentException e) {
- Slog.e(TAG, "Invalid config string");
- }
- }
- return packageConfig;
- }
-
public boolean isValid() {
- return mModeConfigs.size() > 0;
+ return mModeConfigs.size() > 0 || mBatteryModeOptedIn || mPerfModeOptedIn;
}
public String toString() {
@@ -534,8 +584,6 @@ public final class GameManagerService extends IGameManagerService.Stub {
@VisibleForTesting
void onBootCompleted() {
Slog.d(TAG, "onBootCompleted");
- final Message msg = mHandler.obtainMessage(POPULATE_GAME_MODE_SETTINGS);
- mHandler.sendMessage(msg);
}
void onUserStarting(int userId) {
@@ -549,6 +597,9 @@ public final class GameManagerService extends IGameManagerService.Stub {
mSettings.put(userId, userSettings);
userSettings.readPersistentDataLocked();
}
+ final Message msg = mHandler.obtainMessage(POPULATE_GAME_MODE_SETTINGS);
+ msg.obj = userId;
+ mHandler.sendMessage(msg);
}
void onUserStopping(int userId) {
@@ -562,24 +613,14 @@ public final class GameManagerService extends IGameManagerService.Stub {
}
}
- void loadDeviceConfigLocked() {
- final List<PackageInfo> packages = mPackageManager.getInstalledPackages(0);
- final String[] packageNames = packages.stream().map(e -> e.packageName)
- .toArray(String[]::new);
- synchronized (mDeviceConfigLock) {
- final Properties properties = DeviceConfig.getProperties(
- DeviceConfig.NAMESPACE_GAME_OVERLAY, packageNames);
- for (String key : properties.getKeyset()) {
- final GamePackageConfiguration config =
- GamePackageConfiguration.fromProperties(key, properties);
- putConfig(config);
- }
- }
- }
-
- private void disableCompatScale(String packageName) {
+ /**
+ * @hide
+ */
+ @VisibleForTesting
+ public void disableCompatScale(String packageName) {
final long uid = Binder.clearCallingIdentity();
try {
+ Slog.i(TAG, "Disabling downscale for " + packageName);
final ArrayMap<Long, PackageOverride> overrides = new ArrayMap<>();
overrides.put(DOWNSCALED, COMPAT_DISABLED);
final CompatibilityOverrideConfig changeConfig = new CompatibilityOverrideConfig(
@@ -597,6 +638,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
private void enableCompatScale(String packageName, long scaleId) {
final long uid = Binder.clearCallingIdentity();
try {
+ Slog.i(TAG, "Enabling downscale: " + scaleId + " for " + packageName);
final ArrayMap<Long, PackageOverride> overrides = new ArrayMap<>();
overrides.put(DOWNSCALED, COMPAT_ENABLED);
overrides.put(DOWNSCALE_50, COMPAT_DISABLED);
@@ -622,21 +664,25 @@ public final class GameManagerService extends IGameManagerService.Stub {
if (gameMode == GameManager.GAME_MODE_STANDARD
|| gameMode == GameManager.GAME_MODE_UNSUPPORTED) {
disableCompatScale(packageName);
- Slog.v(TAG, "Disabling downscale");
+ return;
+ }
+ final GamePackageConfiguration packageConfig = mConfigs.get(packageName);
+ if (packageConfig == null) {
+ disableCompatScale(packageName);
+ Slog.v(TAG, "Package configuration not found for " + packageName);
return;
}
if (DEBUG) {
Slog.v(TAG, dumpDeviceConfigs());
}
- final GamePackageConfiguration packageConfig = mConfigs.get(packageName);
- if (packageConfig == null) {
- Slog.w(TAG, "Package configuration not found for " + packageName);
+ if (packageConfig.isGameModeOptedIn(gameMode)) {
+ disableCompatScale(packageName);
return;
}
- final GameModeConfiguration modeConfig = packageConfig.getGameModeConfiguration(
- gameMode);
+ final GamePackageConfiguration.GameModeConfiguration modeConfig =
+ packageConfig.getGameModeConfiguration(gameMode);
if (modeConfig == null) {
- Slog.w(TAG, "Game mode " + gameMode + " not found for " + packageName);
+ Slog.i(TAG, "Game mode " + gameMode + " not found for " + packageName);
return;
}
long scaleId = modeConfig.getCompatChangeId();
@@ -645,23 +691,64 @@ public final class GameManagerService extends IGameManagerService.Stub {
+ packageName);
return;
}
- Slog.i(TAG, "Enabling downscale: " + scaleId + " for " + packageName);
+
enableCompatScale(packageName, scaleId);
}
}
- private void putConfig(GamePackageConfiguration config) {
- if (config.isValid()) {
- if (DEBUG) {
- Slog.i(TAG, "Adding config: " + config.toString());
+ /**
+ * @hide
+ */
+ @VisibleForTesting
+ public void updateConfigsForUser(int userId, String ...packageNames) {
+ try {
+ synchronized (mDeviceConfigLock) {
+ for (String packageName : packageNames) {
+ GamePackageConfiguration config =
+ new GamePackageConfiguration(packageName, userId);
+ if (config.isValid()) {
+ if (DEBUG) {
+ Slog.i(TAG, "Adding config: " + config.toString());
+ }
+ mConfigs.put(packageName, config);
+ } else {
+ Slog.w(TAG, "Invalid package config for "
+ + config.getPackageName() + ":" + config.toString());
+ mConfigs.remove(packageName);
+ }
+ }
}
- mConfigs.put(config.getPackageName(), config);
- } else {
- Slog.w(TAG, "Invalid package config for "
- + config.getPackageName() + ":" + config.toString());
+ for (String packageName : packageNames) {
+ synchronized (mLock) {
+ if (mSettings.containsKey(userId)) {
+ GameManagerSettings userSettings = mSettings.get(userId);
+ updateCompatModeDownscale(packageName,
+ userSettings.getGameModeLocked(packageName));
+ }
+ }
+ }
+ } catch (Exception e) {
+ Slog.e(TAG, "Failed to update compat modes for user: " + userId);
}
}
+ private String[] getInstalledGamePackageNames(int userId) {
+ final List<PackageInfo> packages =
+ mPackageManager.getInstalledPackagesAsUser(0, userId);
+ return packages.stream().filter(e -> e.applicationInfo != null && e.applicationInfo.category
+ == ApplicationInfo.CATEGORY_GAME)
+ .map(e -> e.packageName)
+ .toArray(String[]::new);
+ }
+
+ /**
+ * @hide
+ */
+ @VisibleForTesting
+ public GamePackageConfiguration getConfig(String packageName) {
+ return mConfigs.get(packageName);
+ }
+
private void registerPackageReceiver() {
final IntentFilter packageFilter = new IntentFilter();
packageFilter.addAction(ACTION_PACKAGE_ADDED);
@@ -677,16 +764,7 @@ public final class GameManagerService extends IGameManagerService.Stub {
switch (intent.getAction()) {
case ACTION_PACKAGE_ADDED:
case ACTION_PACKAGE_CHANGED:
- synchronized (mDeviceConfigLock) {
- Properties properties = DeviceConfig.getProperties(
- DeviceConfig.NAMESPACE_GAME_OVERLAY, packageName);
- for (String key : properties.getKeyset()) {
- GamePackageConfiguration config =
- GamePackageConfiguration.fromProperties(key,
- properties);
- putConfig(config);
- }
- }
+ updateConfigsForUser(mContext.getUserId(), packageName);
break;
case ACTION_PACKAGE_REMOVED:
disableCompatScale(packageName);
diff --git a/services/core/java/com/android/server/appop/DiscreteRegistry.java b/services/core/java/com/android/server/appop/DiscreteRegistry.java
index 63b41b789280..e9b61b3ab7fb 100644
--- a/services/core/java/com/android/server/appop/DiscreteRegistry.java
+++ b/services/core/java/com/android/server/appop/DiscreteRegistry.java
@@ -69,18 +69,47 @@ import java.util.Date;
import java.util.List;
/**
- * This class manages information about recent accesses to ops for
- * permission usage timeline.
+ * This class manages information about recent accesses to ops for permission usage timeline.
*
- * The timeline history is kept for limited time (initial default is 24 hours) and
- * discarded after that.
+ * The discrete history is kept for limited time (initial default is 24 hours, set in
+ * {@link DiscreteRegistry#sDiscreteHistoryCutoff) and discarded after that.
+ *
+ * Discrete history is quantized to reduce resources footprint. By default quantization is set to
+ * one minute in {@link DiscreteRegistry#sDiscreteHistoryQuantization}. All access times are aligned
+ * to the closest quantized time. All durations (except -1, meaning no duration) are rounded up to
+ * the closest quantized interval.
+ *
+ * When data is queried through API, events are deduplicated and for every time quant there can
+ * be only one {@link AppOpsManager.AttributedOpEntry}. Each entry contains information about
+ * different accesses which happened in specified time quant - across dimensions of
+ * {@link AppOpsManager.UidState} and {@link AppOpsManager.OpFlags}. For each dimension
+ * it is only possible to know if at least one access happened in the time quant.
*
* Every time state is saved (default is 30 minutes), memory state is dumped to a
* new file and memory state is cleared. Files older than time limit are deleted
* during the process.
*
* When request comes in, files are read and requested information is collected
- * and delivered.
+ * and delivered. Information is cached in memory until the next state save (up to 30 minutes), to
+ * avoid reading disk if more API calls come in a quick succession.
+ *
+ * THREADING AND LOCKING:
+ * For in-memory transactions this class relies on {@link DiscreteRegistry#mInMemoryLock}. It is
+ * assumed that the same lock is used for in-memory transactions in {@link AppOpsService},
+ * {@link HistoricalRegistry}, and {@link DiscreteRegistry}.
+ * {@link DiscreteRegistry#recordDiscreteAccess(int, String, int, String, int, int, long, long)}
+ * must only be called while holding this lock.
+ * {@link DiscreteRegistry#mOnDiskLock} is used when disk transactions are performed.
+ * It is very important to release {@link DiscreteRegistry#mInMemoryLock} as soon as possible, as
+ * no AppOps related transactions across the system can be performed while it is held.
+ *
+ * INITIALIZATION: We can initialize persistence only after the system is ready
+ * as we need to check the optional configuration override from the settings
+ * database which is not initialized at the time the app ops service is created. This class
+ * relies on {@link HistoricalRegistry} for controlling that no calls are allowed until then. All
+ * outside calls are going through {@link HistoricalRegistry}, where
+ * {@link HistoricalRegistry#isPersistenceInitializedMLocked()} check is done.
+ *
*/
final class DiscreteRegistry {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 08a7d9e38d96..0840e75823b5 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -123,7 +123,7 @@ import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL;
import android.Manifest;
import android.Manifest.permission;
-import android.annotation.CallbackExecutor;
+import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -492,7 +492,7 @@ public class NotificationManagerService extends SystemService {
private DeviceIdleManager mDeviceIdleManager;
private IUriGrantsManager mUgm;
private UriGrantsManagerInternal mUgmInternal;
- private RoleObserver mRoleObserver;
+ private volatile RoleObserver mRoleObserver;
private UserManager mUm;
private IPlatformCompat mPlatformCompat;
private ShortcutHelper mShortcutHelper;
@@ -629,6 +629,8 @@ public class NotificationManagerService extends SystemService {
static class Archive {
final SparseArray<Boolean> mEnabled;
final int mBufferSize;
+ final Object mBufferLock = new Object();
+ @GuardedBy("mBufferLock")
final LinkedList<Pair<StatusBarNotification, Integer>> mBuffer;
public Archive(int size) {
@@ -651,14 +653,16 @@ public class NotificationManagerService extends SystemService {
if (!mEnabled.get(sbn.getNormalizedUserId(), false)) {
return;
}
- if (mBuffer.size() == mBufferSize) {
- mBuffer.removeFirst();
- }
+ synchronized (mBufferLock) {
+ if (mBuffer.size() == mBufferSize) {
+ mBuffer.removeFirst();
+ }
- // We don't want to store the heavy bits of the notification in the archive,
- // but other clients in the system process might be using the object, so we
- // store a (lightened) copy.
- mBuffer.addLast(new Pair<>(sbn.cloneLight(), reason));
+ // We don't want to store the heavy bits of the notification in the archive,
+ // but other clients in the system process might be using the object, so we
+ // store a (lightened) copy.
+ mBuffer.addLast(new Pair<>(sbn.cloneLight(), reason));
+ }
}
public Iterator<Pair<StatusBarNotification, Integer>> descendingIterator() {
@@ -666,27 +670,31 @@ public class NotificationManagerService extends SystemService {
}
public StatusBarNotification[] getArray(int count, boolean includeSnoozed) {
- if (count == 0) count = mBufferSize;
- List<StatusBarNotification> a = new ArrayList();
- Iterator<Pair<StatusBarNotification, Integer>> iter = descendingIterator();
- int i=0;
- while (iter.hasNext() && i < count) {
- Pair<StatusBarNotification, Integer> pair = iter.next();
- if (pair.second != REASON_SNOOZED || includeSnoozed) {
- i++;
- a.add(pair.first);
+ synchronized (mBufferLock) {
+ if (count == 0) count = mBufferSize;
+ List<StatusBarNotification> a = new ArrayList();
+ Iterator<Pair<StatusBarNotification, Integer>> iter = descendingIterator();
+ int i = 0;
+ while (iter.hasNext() && i < count) {
+ Pair<StatusBarNotification, Integer> pair = iter.next();
+ if (pair.second != REASON_SNOOZED || includeSnoozed) {
+ i++;
+ a.add(pair.first);
+ }
}
+ return a.toArray(new StatusBarNotification[a.size()]);
}
- return a.toArray(new StatusBarNotification[a.size()]);
}
public void updateHistoryEnabled(@UserIdInt int userId, boolean enabled) {
mEnabled.put(userId, enabled);
if (!enabled) {
- for (int i = mBuffer.size() - 1; i >= 0; i--) {
- if (userId == mBuffer.get(i).first.getNormalizedUserId()) {
- mBuffer.remove(i);
+ synchronized (mBufferLock) {
+ for (int i = mBuffer.size() - 1; i >= 0; i--) {
+ if (userId == mBuffer.get(i).first.getNormalizedUserId()) {
+ mBuffer.remove(i);
+ }
}
}
}
@@ -695,15 +703,18 @@ public class NotificationManagerService extends SystemService {
// Remove notifications with the specified user & channel ID.
public void removeChannelNotifications(String pkg, @UserIdInt int userId,
String channelId) {
- Iterator<Pair<StatusBarNotification, Integer>> bufferIter = mBuffer.iterator();
- while (bufferIter.hasNext()) {
- final Pair<StatusBarNotification, Integer> pair = bufferIter.next();
- if (pair.first != null
- && userId == pair.first.getNormalizedUserId()
- && pkg != null && pkg.equals(pair.first.getPackageName())
- && pair.first.getNotification() != null
- && Objects.equals(channelId, pair.first.getNotification().getChannelId())) {
- bufferIter.remove();
+ synchronized (mBufferLock) {
+ Iterator<Pair<StatusBarNotification, Integer>> bufferIter = descendingIterator();
+ while (bufferIter.hasNext()) {
+ final Pair<StatusBarNotification, Integer> pair = bufferIter.next();
+ if (pair.first != null
+ && userId == pair.first.getNormalizedUserId()
+ && pkg != null && pkg.equals(pair.first.getPackageName())
+ && pair.first.getNotification() != null
+ && Objects.equals(channelId,
+ pair.first.getNotification().getChannelId())) {
+ bufferIter.remove();
+ }
}
}
}
@@ -2640,6 +2651,11 @@ public class NotificationManagerService extends SystemService {
@Override
public void onBootPhase(int phase) {
+ onBootPhase(phase, Looper.getMainLooper());
+ }
+
+ @VisibleForTesting
+ void onBootPhase(int phase, Looper mainLooper) {
if (phase == SystemService.PHASE_SYSTEM_SERVICES_READY) {
// no beeping until we're basically done booting
mSystemReady = true;
@@ -2649,9 +2665,11 @@ public class NotificationManagerService extends SystemService {
mAudioManagerInternal = getLocalService(AudioManagerInternal.class);
mWindowManagerInternal = LocalServices.getService(WindowManagerInternal.class);
mZenModeHelper.onSystemReady();
- mRoleObserver = new RoleObserver(getContext().getSystemService(RoleManager.class),
- mPackageManager, getContext().getMainExecutor());
- mRoleObserver.init();
+ RoleObserver roleObserver = new RoleObserver(getContext(),
+ getContext().getSystemService(RoleManager.class),
+ mPackageManager, mainLooper);
+ roleObserver.init();
+ mRoleObserver = roleObserver;
LauncherApps launcherApps =
(LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE);
mShortcutHelper = new ShortcutHelper(launcherApps, mShortcutListener, getLocalService(
@@ -10677,26 +10695,40 @@ public class NotificationManagerService extends SystemService {
// Role name : user id : list of approved packages
private ArrayMap<String, ArrayMap<Integer, ArraySet<String>>> mNonBlockableDefaultApps;
+ /**
+ * Writes should be pretty rare (only when default browser changes) and reads are done
+ * during activity start code-path, so we're optimizing for reads. This means this set is
+ * immutable once written and we'll recreate the set every time there is a role change and
+ * then assign that new set to the volatile below, so reads can be done without needing to
+ * hold a lock. Every write is done on the main-thread, so write atomicity is guaranteed.
+ *
+ * Didn't use unmodifiable set to enforce immutability to avoid iterating via iterators.
+ */
+ private volatile ArraySet<Integer> mTrampolineExemptUids = new ArraySet<>();
+
private final RoleManager mRm;
private final IPackageManager mPm;
private final Executor mExecutor;
+ private final Looper mMainLooper;
- RoleObserver(@NonNull RoleManager roleManager,
- @NonNull IPackageManager pkgMgr,
- @NonNull @CallbackExecutor Executor executor) {
+ RoleObserver(Context context, @NonNull RoleManager roleManager,
+ @NonNull IPackageManager pkgMgr, @NonNull Looper mainLooper) {
mRm = roleManager;
mPm = pkgMgr;
- mExecutor = executor;
+ mExecutor = context.getMainExecutor();
+ mMainLooper = mainLooper;
}
+ /** Should be called from the main-thread. */
+ @MainThread
public void init() {
- List<UserInfo> users = mUm.getUsers();
+ List<UserHandle> users = mUm.getUserHandles(/* excludeDying */ true);
mNonBlockableDefaultApps = new ArrayMap<>();
for (int i = 0; i < NON_BLOCKABLE_DEFAULT_ROLES.length; i++) {
final ArrayMap<Integer, ArraySet<String>> userToApprovedList = new ArrayMap<>();
mNonBlockableDefaultApps.put(NON_BLOCKABLE_DEFAULT_ROLES[i], userToApprovedList);
for (int j = 0; j < users.size(); j++) {
- Integer userId = users.get(j).getUserHandle().getIdentifier();
+ Integer userId = users.get(j).getIdentifier();
ArraySet<String> approvedForUserId = new ArraySet<>(mRm.getRoleHoldersAsUser(
NON_BLOCKABLE_DEFAULT_ROLES[i], UserHandle.of(userId)));
ArraySet<Pair<String, Integer>> approvedAppUids = new ArraySet<>();
@@ -10707,7 +10739,7 @@ public class NotificationManagerService extends SystemService {
mPreferencesHelper.updateDefaultApps(userId, null, approvedAppUids);
}
}
-
+ updateTrampolineExemptUidsForUsers(users.toArray(new UserHandle[0]));
mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
}
@@ -10716,6 +10748,11 @@ public class NotificationManagerService extends SystemService {
return mNonBlockableDefaultApps.get(role).get(userId).contains(pkg);
}
+ @VisibleForTesting
+ public boolean isUidExemptFromTrampolineRestrictions(int uid) {
+ return mTrampolineExemptUids.contains(uid);
+ }
+
/**
* Convert the assistant-role holder into settings. The rest of the system uses the
* settings.
@@ -10725,6 +10762,12 @@ public class NotificationManagerService extends SystemService {
*/
@Override
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
+ onRoleHoldersChangedForNonBlockableDefaultApps(roleName, user);
+ onRoleHoldersChangedForTrampolines(roleName, user);
+ }
+
+ private void onRoleHoldersChangedForNonBlockableDefaultApps(@NonNull String roleName,
+ @NonNull UserHandle user) {
// we only care about a couple of the roles they'll tell us about
boolean relevantChange = false;
for (int i = 0; i < NON_BLOCKABLE_DEFAULT_ROLES.length; i++) {
@@ -10772,6 +10815,41 @@ public class NotificationManagerService extends SystemService {
// write of the notification policy xml for this change
}
+ private void onRoleHoldersChangedForTrampolines(@NonNull String roleName,
+ @NonNull UserHandle user) {
+ if (!RoleManager.ROLE_BROWSER.equals(roleName)) {
+ return;
+ }
+ updateTrampolineExemptUidsForUsers(user);
+ }
+
+ private void updateTrampolineExemptUidsForUsers(UserHandle... users) {
+ Preconditions.checkState(mMainLooper.isCurrentThread());
+ ArraySet<Integer> oldUids = mTrampolineExemptUids;
+ ArraySet<Integer> newUids = new ArraySet<>();
+ // Add the uids from previous set for the users that we won't update.
+ for (int i = 0, n = oldUids.size(); i < n; i++) {
+ int uid = oldUids.valueAt(i);
+ UserHandle user = UserHandle.of(UserHandle.getUserId(uid));
+ if (!ArrayUtils.contains(users, user)) {
+ newUids.add(uid);
+ }
+ }
+ // Now lookup the new uids for the users that we want to update.
+ for (int i = 0, n = users.length; i < n; i++) {
+ UserHandle user = users[i];
+ for (String pkg : mRm.getRoleHoldersAsUser(RoleManager.ROLE_BROWSER, user)) {
+ int uid = getUidForPackage(pkg, user.getIdentifier());
+ if (uid != -1) {
+ newUids.add(uid);
+ } else {
+ Slog.e(TAG, "Bad uid (-1) for browser package " + pkg);
+ }
+ }
+ }
+ mTrampolineExemptUids = newUids;
+ }
+
private int getUidForPackage(String pkg, int userId) {
try {
return mPm.getPackageUid(pkg, MATCH_ALL, userId);
@@ -10936,7 +11014,7 @@ public class NotificationManagerService extends SystemService {
}
String logcatMessage =
"Indirect notification activity start (trampoline) from " + packageName;
- if (CompatChanges.isChangeEnabled(NOTIFICATION_TRAMPOLINE_BLOCK, uid)) {
+ if (blockTrampoline(uid)) {
// Post toast() call to mHandler to offload PM lookup from the activity start path
mHandler.post(() -> toast(packageName, uid));
Slog.e(TAG, logcatMessage + " blocked");
@@ -10947,6 +11025,13 @@ public class NotificationManagerService extends SystemService {
}
}
+ private boolean blockTrampoline(int uid) {
+ if (mRoleObserver != null && mRoleObserver.isUidExemptFromTrampolineRestrictions(uid)) {
+ return false;
+ }
+ return CompatChanges.isChangeEnabled(NOTIFICATION_TRAMPOLINE_BLOCK, uid);
+ }
+
@Override
public boolean canCloseSystemDialogs(Collection<IBinder> tokens, int uid) {
// If the start is allowed via notification, we allow the app to close system dialogs
diff --git a/services/core/java/com/android/server/pm/ApkChecksums.java b/services/core/java/com/android/server/pm/ApkChecksums.java
index afce23fe7647..28511070fc8e 100644
--- a/services/core/java/com/android/server/pm/ApkChecksums.java
+++ b/services/core/java/com/android/server/pm/ApkChecksums.java
@@ -303,8 +303,8 @@ public class ApkChecksums {
* @param onChecksumsReadyListener to receive the resulting checksums
*/
public static void getChecksums(List<Pair<String, File>> filesToChecksum,
- @Checksum.Type int optional,
- @Checksum.Type int required,
+ @Checksum.TypeMask int optional,
+ @Checksum.TypeMask int required,
@Nullable String installerPackageName,
@Nullable Certificate[] trustedInstallers,
@NonNull IOnChecksumsReadyListener onChecksumsReadyListener,
@@ -331,7 +331,7 @@ public class ApkChecksums {
private static void processRequiredChecksums(List<Pair<String, File>> filesToChecksum,
List<Map<Integer, ApkChecksum>> result,
- @Checksum.Type int required,
+ @Checksum.TypeMask int required,
@NonNull IOnChecksumsReadyListener onChecksumsReadyListener,
@NonNull Injector injector,
long startTime) {
@@ -382,7 +382,7 @@ public class ApkChecksums {
* @param checksums resulting checksums
*/
private static void getAvailableApkChecksums(String split, File file,
- @Checksum.Type int types,
+ @Checksum.TypeMask int types,
@Nullable String installerPackageName,
@Nullable Certificate[] trustedInstallers,
Map<Integer, ApkChecksum> checksums,
@@ -415,7 +415,7 @@ public class ApkChecksums {
}
private static void getInstallerChecksums(String split, File file,
- @Checksum.Type int types,
+ @Checksum.TypeMask int types,
@Nullable String installerPackageName,
@Nullable Certificate[] trustedInstallers,
Map<Integer, ApkChecksum> checksums,
@@ -523,7 +523,7 @@ public class ApkChecksums {
* Whether the file is available for checksumming or we need to wait.
*/
private static boolean needToWait(File file,
- @Checksum.Type int types,
+ @Checksum.TypeMask int types,
Map<Integer, ApkChecksum> checksums,
@NonNull Injector injector) throws IOException {
if (!isRequired(TYPE_WHOLE_MERKLE_ROOT_4K_SHA256, types, checksums)
@@ -564,7 +564,7 @@ public class ApkChecksums {
* @param checksums resulting checksums
*/
private static void getRequiredApkChecksums(String split, File file,
- @Checksum.Type int types,
+ @Checksum.TypeMask int types,
Map<Integer, ApkChecksum> checksums) {
final String filePath = file.getAbsolutePath();
@@ -596,7 +596,7 @@ public class ApkChecksums {
}
private static boolean isRequired(@Checksum.Type int type,
- @Checksum.Type int types, Map<Integer, ApkChecksum> checksums) {
+ @Checksum.TypeMask int types, Map<Integer, ApkChecksum> checksums) {
if ((types & type) == 0) {
return false;
}
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index 1d556fec31ea..dde9f822ac76 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -59,6 +59,9 @@ import com.android.server.IntentResolver;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageInfoUtils.CachedApplicationInfoGenerator;
import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.utils.Snappable;
+import com.android.server.utils.SnapshotCache;
+import com.android.server.utils.WatchableImpl;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -72,12 +75,19 @@ import java.util.Set;
import java.util.function.Function;
/** Resolves all Android component types [activities, services, providers and receivers]. */
-public class ComponentResolver {
+public class ComponentResolver
+ extends WatchableImpl
+ implements Snappable {
private static final boolean DEBUG = false;
private static final String TAG = "PackageManager";
private static final boolean DEBUG_FILTERS = false;
private static final boolean DEBUG_SHOW_INFO = false;
+ // Convenience function to report that this object has changed.
+ private void onChanged() {
+ dispatchChange(this);
+ }
+
/**
* The set of all protected actions [i.e. those actions for which a high priority
* intent filter is disallowed].
@@ -158,27 +168,27 @@ public class ComponentResolver {
* would be able to hold its lock while checking the package setting state.</li>
* </ol>
*/
- private final Object mLock;
+ private final PackageManagerTracedLock mLock;
/** All available activities, for your resolving pleasure. */
@GuardedBy("mLock")
- private final ActivityIntentResolver mActivities = new ActivityIntentResolver();
+ private final ActivityIntentResolver mActivities;
/** All available providers, for your resolving pleasure. */
@GuardedBy("mLock")
- private final ProviderIntentResolver mProviders = new ProviderIntentResolver();
+ private final ProviderIntentResolver mProviders;
/** All available receivers, for your resolving pleasure. */
@GuardedBy("mLock")
- private final ActivityIntentResolver mReceivers = new ReceiverIntentResolver();
+ private final ReceiverIntentResolver mReceivers;
/** All available services, for your resolving pleasure. */
@GuardedBy("mLock")
- private final ServiceIntentResolver mServices = new ServiceIntentResolver();
+ private final ServiceIntentResolver mServices;
/** Mapping from provider authority [first directory in content URI codePath) to provider. */
@GuardedBy("mLock")
- private final ArrayMap<String, ParsedProvider> mProvidersByAuthority = new ArrayMap<>();
+ private final ArrayMap<String, ParsedProvider> mProvidersByAuthority;
/** Whether or not processing protected filters should be deferred. */
private boolean mDeferProtectedFilters = true;
@@ -200,12 +210,57 @@ public class ComponentResolver {
ComponentResolver(UserManagerService userManager,
PackageManagerInternal packageManagerInternal,
- Object lock) {
+ PackageManagerTracedLock lock) {
sPackageManagerInternal = packageManagerInternal;
sUserManager = userManager;
mLock = lock;
+
+ mActivities = new ActivityIntentResolver();
+ mProviders = new ProviderIntentResolver();
+ mReceivers = new ReceiverIntentResolver();
+ mServices = new ServiceIntentResolver();
+ mProvidersByAuthority = new ArrayMap<>();
+ mDeferProtectedFilters = true;
+
+ mSnapshot = new SnapshotCache<ComponentResolver>(this, this) {
+ @Override
+ public ComponentResolver createSnapshot() {
+ return new ComponentResolver(mSource);
+ }};
+ }
+
+ // Copy constructor used in creating snapshots.
+ private ComponentResolver(ComponentResolver orig) {
+ // Do not set the static variables that are set in the default constructor. Do
+ // create a new object for the lock. The snapshot is read-only, so a lock is not
+ // strictly required. However, the current code is simpler if the lock exists,
+ // but does not contend with any outside class.
+ // TODO: make the snapshot lock-free
+ mLock = new PackageManagerTracedLock();
+
+ mActivities = new ActivityIntentResolver(orig.mActivities);
+ mProviders = new ProviderIntentResolver(orig.mProviders);
+ mReceivers = new ReceiverIntentResolver(orig.mReceivers);
+ mServices = new ServiceIntentResolver(orig.mServices);
+ mProvidersByAuthority = new ArrayMap<>(orig.mProvidersByAuthority);
+ mDeferProtectedFilters = orig.mDeferProtectedFilters;
+ mProtectedFilters = (mProtectedFilters == null)
+ ? null
+ : new ArrayList<>(orig.mProtectedFilters);
+
+ mSnapshot = null;
}
+ final SnapshotCache<ComponentResolver> mSnapshot;
+
+ /**
+ * Create a snapshot.
+ */
+ public ComponentResolver snapshot() {
+ return mSnapshot.snapshot();
+ }
+
+
/** Returns the given activity */
@Nullable
@VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
@@ -474,6 +529,7 @@ public class ComponentResolver {
addReceiversLocked(pkg, chatty);
addProvidersLocked(pkg, chatty);
addServicesLocked(pkg, chatty);
+ onChanged();
}
// expect single setupwizard package
final String setupWizardPackage = ArrayUtils.firstOrNull(
@@ -489,6 +545,7 @@ public class ComponentResolver {
final List<ParsedActivity> systemActivities =
disabledPkg != null ? disabledPkg.getActivities() : null;
adjustPriority(systemActivities, pair.first, pair.second, setupWizardPackage);
+ onChanged();
}
}
@@ -496,6 +553,7 @@ public class ComponentResolver {
void removeAllComponents(AndroidPackage pkg, boolean chatty) {
synchronized (mLock) {
removeAllComponentsLocked(pkg, chatty);
+ onChanged();
}
}
@@ -504,51 +562,54 @@ public class ComponentResolver {
* all of the filters defined on the /system partition and know the special components.
*/
void fixProtectedFilterPriorities() {
- if (!mDeferProtectedFilters) {
- return;
- }
- mDeferProtectedFilters = false;
+ synchronized (mLock) {
+ if (!mDeferProtectedFilters) {
+ return;
+ }
+ mDeferProtectedFilters = false;
- if (mProtectedFilters == null || mProtectedFilters.size() == 0) {
- return;
- }
- final List<Pair<ParsedMainComponent, ParsedIntentInfo>> protectedFilters =
- mProtectedFilters;
- mProtectedFilters = null;
+ if (mProtectedFilters == null || mProtectedFilters.size() == 0) {
+ return;
+ }
+ final List<Pair<ParsedMainComponent, ParsedIntentInfo>> protectedFilters =
+ mProtectedFilters;
+ mProtectedFilters = null;
- // expect single setupwizard package
- final String setupWizardPackage = ArrayUtils.firstOrNull(
+ // expect single setupwizard package
+ final String setupWizardPackage = ArrayUtils.firstOrNull(
sPackageManagerInternal.getKnownPackageNames(
- PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM));
-
- if (DEBUG_FILTERS && setupWizardPackage == null) {
- Slog.i(TAG, "No setup wizard;"
- + " All protected intents capped to priority 0");
- }
- for (int i = protectedFilters.size() - 1; i >= 0; --i) {
- final Pair<ParsedMainComponent, ParsedIntentInfo> pair = protectedFilters.get(i);
- ParsedMainComponent component = pair.first;
- ParsedIntentInfo filter = pair.second;
- String packageName = component.getPackageName();
- String className = component.getClassName();
- if (packageName.equals(setupWizardPackage)) {
+ PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM));
+
+ if (DEBUG_FILTERS && setupWizardPackage == null) {
+ Slog.i(TAG, "No setup wizard;"
+ + " All protected intents capped to priority 0");
+ }
+ for (int i = protectedFilters.size() - 1; i >= 0; --i) {
+ final Pair<ParsedMainComponent, ParsedIntentInfo> pair = protectedFilters.get(i);
+ ParsedMainComponent component = pair.first;
+ ParsedIntentInfo filter = pair.second;
+ String packageName = component.getPackageName();
+ String className = component.getClassName();
+ if (packageName.equals(setupWizardPackage)) {
+ if (DEBUG_FILTERS) {
+ Slog.i(TAG, "Found setup wizard;"
+ + " allow priority " + filter.getPriority() + ";"
+ + " package: " + packageName
+ + " activity: " + className
+ + " priority: " + filter.getPriority());
+ }
+ // skip setup wizard; allow it to keep the high priority filter
+ continue;
+ }
if (DEBUG_FILTERS) {
- Slog.i(TAG, "Found setup wizard;"
- + " allow priority " + filter.getPriority() + ";"
+ Slog.i(TAG, "Protected action; cap priority to 0;"
+ " package: " + packageName
+ " activity: " + className
- + " priority: " + filter.getPriority());
+ + " origPrio: " + filter.getPriority());
}
- // skip setup wizard; allow it to keep the high priority filter
- continue;
- }
- if (DEBUG_FILTERS) {
- Slog.i(TAG, "Protected action; cap priority to 0;"
- + " package: " + packageName
- + " activity: " + className
- + " origPrio: " + filter.getPriority());
+ filter.setPriority(0);
}
- filter.setPriority(0);
+ onChanged();
}
}
@@ -1181,9 +1242,20 @@ public class ComponentResolver {
private abstract static class MimeGroupsAwareIntentResolver<F extends Pair<?
extends ParsedComponent, ParsedIntentInfo>, R>
extends IntentResolver<F, R> {
- private ArrayMap<String, F[]> mMimeGroupToFilter = new ArrayMap<>();
+ private final ArrayMap<String, F[]> mMimeGroupToFilter = new ArrayMap<>();
private boolean mIsUpdatingMimeGroup = false;
+ // Default constructor
+ MimeGroupsAwareIntentResolver() {
+ }
+
+ // Copy constructor used in creating snapshots
+ MimeGroupsAwareIntentResolver(MimeGroupsAwareIntentResolver<F, R> orig) {
+ copyFrom(orig);
+ copyInto(mMimeGroupToFilter, orig.mMimeGroupToFilter);
+ mIsUpdatingMimeGroup = orig.mIsUpdatingMimeGroup;
+ }
+
@Override
public void addFilter(F f) {
IntentFilter intentFilter = getIntentFilter(f);
@@ -1282,6 +1354,17 @@ public class ComponentResolver {
private static class ActivityIntentResolver
extends MimeGroupsAwareIntentResolver<Pair<ParsedActivity, ParsedIntentInfo>, ResolveInfo> {
+ // Default constructor
+ ActivityIntentResolver() {
+ }
+
+ // Copy constructor used in creating snapshots
+ ActivityIntentResolver(ActivityIntentResolver orig) {
+ super(orig);
+ mActivities.putAll(orig.mActivities);
+ mFlags = orig.mFlags;
+ }
+
@Override
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
boolean defaultOnly, int userId) {
@@ -1330,7 +1413,7 @@ public class ComponentResolver {
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
- private void addActivity(ParsedActivity a, String type,
+ protected void addActivity(ParsedActivity a, String type,
List<Pair<ParsedActivity, ParsedIntentInfo>> newIntents) {
mActivities.put(a.getComponentName(), a);
if (DEBUG_SHOW_INFO) {
@@ -1354,7 +1437,7 @@ public class ComponentResolver {
}
}
- private void removeActivity(ParsedActivity a, String type) {
+ protected void removeActivity(ParsedActivity a, String type) {
mActivities.remove(a.getComponentName());
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " " + type + ":");
@@ -1567,8 +1650,11 @@ public class ComponentResolver {
return pkg.getActivities();
}
- // Keys are String (activity class name), values are Activity.
- private final ArrayMap<ComponentName, ParsedActivity> mActivities =
+ // Keys are String (activity class name), values are Activity. This attribute is
+ // protected because it is accessed directly from ComponentResolver. That works
+ // even if the attribute is private, but fails for subclasses of
+ // ActivityIntentResolver.
+ protected final ArrayMap<ComponentName, ParsedActivity> mActivities =
new ArrayMap<>();
private int mFlags;
}
@@ -1576,6 +1662,15 @@ public class ComponentResolver {
// Both receivers and activities share a class, but point to different get methods
private static final class ReceiverIntentResolver extends ActivityIntentResolver {
+ // Default constructor
+ ReceiverIntentResolver() {
+ }
+
+ // Copy constructor used in creating snapshots
+ ReceiverIntentResolver(ReceiverIntentResolver orig) {
+ super(orig);
+ }
+
@Override
protected List<ParsedActivity> getResolveList(AndroidPackage pkg) {
return pkg.getReceivers();
@@ -1584,6 +1679,17 @@ public class ComponentResolver {
private static final class ProviderIntentResolver
extends MimeGroupsAwareIntentResolver<Pair<ParsedProvider, ParsedIntentInfo>, ResolveInfo> {
+ // Default constructor
+ ProviderIntentResolver() {
+ }
+
+ // Copy constructor used in creating snapshots
+ ProviderIntentResolver(ProviderIntentResolver orig) {
+ super(orig);
+ mProviders.putAll(orig.mProviders);
+ mFlags = orig.mFlags;
+ }
+
@Override
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
boolean defaultOnly, int userId) {
@@ -1829,6 +1935,17 @@ public class ComponentResolver {
private static final class ServiceIntentResolver
extends MimeGroupsAwareIntentResolver<Pair<ParsedService, ParsedIntentInfo>, ResolveInfo> {
+ // Default constructor
+ ServiceIntentResolver() {
+ }
+
+ // Copy constructor used in creating snapshots
+ ServiceIntentResolver(ServiceIntentResolver orig) {
+ copyFrom(orig);
+ mServices.putAll(orig.mServices);
+ mFlags = orig.mFlags;
+ }
+
@Override
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
boolean defaultOnly, int userId) {
@@ -2213,11 +2330,16 @@ public class ComponentResolver {
* @return true if any intent filters were changed due to this update
*/
boolean updateMimeGroup(String packageName, String group) {
- boolean hasChanges = mActivities.updateMimeGroup(packageName, group);
- hasChanges |= mProviders.updateMimeGroup(packageName, group);
- hasChanges |= mReceivers.updateMimeGroup(packageName, group);
- hasChanges |= mServices.updateMimeGroup(packageName, group);
-
+ boolean hasChanges = false;
+ synchronized (mLock) {
+ hasChanges |= mActivities.updateMimeGroup(packageName, group);
+ hasChanges |= mProviders.updateMimeGroup(packageName, group);
+ hasChanges |= mReceivers.updateMimeGroup(packageName, group);
+ hasChanges |= mServices.updateMimeGroup(packageName, group);
+ if (hasChanges) {
+ onChanged();
+ }
+ }
return hasChanges;
}
}
diff --git a/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java b/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
index 7c19d90e4ede..f5910fa3143c 100644
--- a/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
+++ b/services/core/java/com/android/server/pm/CrossProfileIntentFilter.java
@@ -24,6 +24,7 @@ import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import com.android.internal.util.XmlUtils;
+import com.android.server.utils.SnapshotCache;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -35,7 +36,7 @@ import java.io.IOException;
* If an {@link Intent} matches the {@link CrossProfileIntentFilter}, then activities in the user
* {@link #mTargetUserId} can access it.
*/
-class CrossProfileIntentFilter extends IntentFilter {
+class CrossProfileIntentFilter extends WatchedIntentFilter {
private static final String ATTR_TARGET_USER_ID = "targetUserId";
private static final String ATTR_FLAGS = "flags";
private static final String ATTR_OWNER_PACKAGE = "ownerPackage";
@@ -48,12 +49,41 @@ class CrossProfileIntentFilter extends IntentFilter {
final String mOwnerPackage; // packageName of the app.
final int mFlags;
+ // The cache for snapshots, so they are not rebuilt if the base object has not
+ // changed.
+ final SnapshotCache<CrossProfileIntentFilter> mSnapshot;
+
+ private SnapshotCache makeCache() {
+ return new SnapshotCache<CrossProfileIntentFilter>(this, this) {
+ @Override
+ public CrossProfileIntentFilter createSnapshot() {
+ CrossProfileIntentFilter s = new CrossProfileIntentFilter(mSource);
+ s.seal();
+ return s;
+ }};
+ }
+
CrossProfileIntentFilter(IntentFilter filter, String ownerPackage, int targetUserId,
int flags) {
super(filter);
mTargetUserId = targetUserId;
mOwnerPackage = ownerPackage;
mFlags = flags;
+ mSnapshot = makeCache();
+ }
+
+ CrossProfileIntentFilter(WatchedIntentFilter filter, String ownerPackage, int targetUserId,
+ int flags) {
+ this(filter.mFilter, ownerPackage, targetUserId, flags);
+ }
+
+ // Copy constructor used only to create a snapshot.
+ private CrossProfileIntentFilter(CrossProfileIntentFilter f) {
+ super(f);
+ mTargetUserId = f.mTargetUserId;
+ mOwnerPackage = f.mOwnerPackage;
+ mFlags = f.mFlags;
+ mSnapshot = new SnapshotCache.Sealed();
}
public int getTargetUserId() {
@@ -72,6 +102,7 @@ class CrossProfileIntentFilter extends IntentFilter {
mTargetUserId = parser.getAttributeInt(null, ATTR_TARGET_USER_ID, UserHandle.USER_NULL);
mOwnerPackage = getStringFromXml(parser, ATTR_OWNER_PACKAGE, "");
mFlags = parser.getAttributeInt(null, ATTR_FLAGS, 0);
+ mSnapshot = makeCache();
int outerDepth = parser.getDepth();
String tagName = parser.getName();
@@ -94,7 +125,7 @@ class CrossProfileIntentFilter extends IntentFilter {
}
}
if (tagName.equals(ATTR_FILTER)) {
- readFromXml(parser);
+ mFilter.readFromXml(parser);
} else {
String msg = "Missing element under " + TAG + ": " + ATTR_FILTER +
" at " + parser.getPositionDescription();
@@ -103,7 +134,8 @@ class CrossProfileIntentFilter extends IntentFilter {
}
}
- String getStringFromXml(TypedXmlPullParser parser, String attribute, String defaultValue) {
+ private String getStringFromXml(TypedXmlPullParser parser, String attribute,
+ String defaultValue) {
String value = parser.getAttributeValue(null, attribute);
if (value == null) {
String msg = "Missing element under " + TAG +": " + attribute + " at " +
@@ -120,7 +152,7 @@ class CrossProfileIntentFilter extends IntentFilter {
serializer.attributeInt(null, ATTR_FLAGS, mFlags);
serializer.attribute(null, ATTR_OWNER_PACKAGE, mOwnerPackage);
serializer.startTag(null, ATTR_FILTER);
- super.writeToXml(serializer);
+ mFilter.writeToXml(serializer);
serializer.endTag(null, ATTR_FILTER);
}
@@ -135,4 +167,8 @@ class CrossProfileIntentFilter extends IntentFilter {
&& mOwnerPackage.equals(other.mOwnerPackage)
&& mFlags == other.mFlags;
}
+
+ public CrossProfileIntentFilter snapshot() {
+ return mSnapshot.snapshot();
+ }
}
diff --git a/services/core/java/com/android/server/pm/CrossProfileIntentResolver.java b/services/core/java/com/android/server/pm/CrossProfileIntentResolver.java
index 791a1057d112..792753860358 100644
--- a/services/core/java/com/android/server/pm/CrossProfileIntentResolver.java
+++ b/services/core/java/com/android/server/pm/CrossProfileIntentResolver.java
@@ -21,6 +21,7 @@ import android.content.IntentFilter;
import com.android.server.WatchedIntentResolver;
import com.android.server.utils.Snappable;
+import com.android.server.utils.SnapshotCache;
import java.util.List;
@@ -47,7 +48,34 @@ class CrossProfileIntentResolver
@Override
protected IntentFilter getIntentFilter(@NonNull CrossProfileIntentFilter input) {
- return input;
+ return input.getIntentFilter();
+ }
+
+ CrossProfileIntentResolver() {
+ mSnapshot = makeCache();
+ }
+
+ // Take the snapshot of F
+ protected CrossProfileIntentFilter snapshot(CrossProfileIntentFilter f) {
+ return (f == null) ? null : f.snapshot();
+ }
+
+ // Copy constructor used only to create a snapshot.
+ private CrossProfileIntentResolver(CrossProfileIntentResolver f) {
+ copyFrom(f);
+ mSnapshot = new SnapshotCache.Sealed();
+ }
+
+ // The cache for snapshots, so they are not rebuilt if the base object has not
+ // changed.
+ final SnapshotCache<CrossProfileIntentResolver> mSnapshot;
+
+ private SnapshotCache makeCache() {
+ return new SnapshotCache<CrossProfileIntentResolver>(this, this) {
+ @Override
+ public CrossProfileIntentResolver createSnapshot() {
+ return new CrossProfileIntentResolver(mSource);
+ }};
}
/**
@@ -56,8 +84,6 @@ class CrossProfileIntentResolver
* @return A snapshot of the current object.
*/
public CrossProfileIntentResolver snapshot() {
- CrossProfileIntentResolver result = new CrossProfileIntentResolver();
- result.copyFrom(this);
- return result;
+ return mSnapshot.snapshot();
}
}
diff --git a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java
index a32e107d9e73..c58128a3c9b1 100644
--- a/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java
+++ b/services/core/java/com/android/server/pm/DefaultCrossProfileIntentFilter.java
@@ -43,7 +43,7 @@ final class DefaultCrossProfileIntentFilter {
}
/** The intent filter that's used */
- public final IntentFilter filter;
+ public final WatchedIntentFilter filter;
/**
* The flags related to the forwarding, e.g.
@@ -66,7 +66,7 @@ final class DefaultCrossProfileIntentFilter {
*/
public final boolean letsPersonalDataIntoProfile;
- private DefaultCrossProfileIntentFilter(IntentFilter filter, int flags,
+ private DefaultCrossProfileIntentFilter(WatchedIntentFilter filter, int flags,
@Direction int direction, boolean letsPersonalDataIntoProfile) {
this.filter = requireNonNull(filter);
this.flags = flags;
@@ -75,7 +75,7 @@ final class DefaultCrossProfileIntentFilter {
}
static final class Builder {
- private IntentFilter mFilter = new IntentFilter();
+ private WatchedIntentFilter mFilter = new WatchedIntentFilter();
private int mFlags;
private @Direction int mDirection;
private boolean mLetsPersonalDataIntoProfile;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index dad37f40babb..db2b166aac63 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -134,6 +134,7 @@ import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTi
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.makeDirRecursive;
import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
+import static com.android.server.pm.parsing.PackageInfoUtils.checkUseInstalledOrHidden;
import android.Manifest;
import android.annotation.AppIdInt;
@@ -1481,7 +1482,9 @@ public class PackageManagerService extends IPackageManager.Stub
// Internal interface for permission manager
private final PermissionManagerServiceInternal mPermissionManager;
+ @Watched
private final ComponentResolver mComponentResolver;
+
// List of packages names to keep cached, even if they are uninstalled for all users
private List<String> mKeepUninstalledPackages;
@@ -1825,6 +1828,7 @@ public class PackageManagerService extends IPackageManager.Stub
public final ApplicationInfo androidApplication;
public final String appPredictionServicePackage;
public final AppsFilter appsFilter;
+ public final ComponentResolver componentResolver;
public final PackageManagerService service;
Snapshot(int type) {
@@ -1850,6 +1854,7 @@ public class PackageManagerService extends IPackageManager.Stub
: new ApplicationInfo(mAndroidApplication);
appPredictionServicePackage = mAppPredictionServicePackage;
appsFilter = mAppsFilter.snapshot();
+ componentResolver = mComponentResolver.snapshot();
} else if (type == Snapshot.LIVE) {
settings = mSettings;
isolatedOwners = mIsolatedOwners;
@@ -1866,6 +1871,7 @@ public class PackageManagerService extends IPackageManager.Stub
androidApplication = mAndroidApplication;
appPredictionServicePackage = mAppPredictionServicePackage;
appsFilter = mAppsFilter;
+ componentResolver = mComponentResolver;
} else {
throw new IllegalArgumentException();
}
@@ -1955,8 +1961,8 @@ public class PackageManagerService extends IPackageManager.Stub
int callingUid);
ResolveInfo createForwardingResolveInfo(CrossProfileIntentFilter filter, Intent intent,
String resolvedType, int flags, int sourceUserId);
- ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter, int sourceUserId,
- int targetUserId);
+ ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
+ int sourceUserId, int targetUserId);
ResolveInfo queryCrossProfileIntents(List<CrossProfileIntentFilter> matchingFilters,
Intent intent, String resolvedType, int flags, int sourceUserId,
boolean matchInCurrentProfile);
@@ -2113,6 +2119,7 @@ public class PackageManagerService extends IPackageManager.Stub
mInstantAppRegistry = args.instantAppRegistry;
mLocalAndroidApplication = args.androidApplication;
mAppsFilter = args.appsFilter;
+ mComponentResolver = args.componentResolver;
mAppPredictionServicePackage = args.appPredictionServicePackage;
@@ -2123,7 +2130,6 @@ public class PackageManagerService extends IPackageManager.Stub
mContext = args.service.mContext;
mInjector = args.service.mInjector;
mApexManager = args.service.mApexManager;
- mComponentResolver = args.service.mComponentResolver;
mInstantAppResolverConnection = args.service.mInstantAppResolverConnection;
mDefaultAppProvider = args.service.mDefaultAppProvider;
mDomainVerificationManager = args.service.mDomainVerificationManager;
@@ -2510,8 +2516,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName());
+ PackageSetting ps = a == null ? null : mSettings.getPackageLPr(a.getPackageName());
if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
- PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
if (ps == null) return null;
if (shouldFilterApplicationLocked(
ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
@@ -2521,8 +2527,8 @@ public class PackageManagerService extends IPackageManager.Stub
a, flags, ps.readUserState(userId), userId, ps);
}
if (resolveComponentName().equals(component)) {
- return PackageParser.generateActivityInfo(
- mResolveActivity, flags, new PackageUserState(), userId);
+ return generateDelegateActivityInfo(pkg, ps, new PackageUserState(),
+ mResolveActivity, flags, userId);
}
return null;
}
@@ -2859,8 +2865,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (result == null) {
result = new CrossProfileDomainInfo();
- result.resolveInfo = createForwardingResolveInfoUnchecked(new IntentFilter(),
- sourceUserId, parentUserId);
+ result.resolveInfo = createForwardingResolveInfoUnchecked(
+ new WatchedIntentFilter(), sourceUserId, parentUserId);
}
result.highestApprovalLevel = Math.max(mDomainVerificationManager
@@ -3168,8 +3174,8 @@ public class PackageManagerService extends IPackageManager.Stub
return result;
}
final ResolveInfo ephemeralInstaller = new ResolveInfo(mInstantAppInstallerInfo);
- ephemeralInstaller.activityInfo = PackageParser.generateActivityInfo(
- instantAppInstallerActivity(), 0, ps.readUserState(userId), userId);
+ ephemeralInstaller.activityInfo = generateDelegateActivityInfo(ps.getPkg(), ps,
+ ps.readUserState(userId), instantAppInstallerActivity(), 0 /*flags*/, userId);
ephemeralInstaller.match = IntentFilter.MATCH_CATEGORY_SCHEME_SPECIFIC_PART
| IntentFilter.MATCH_ADJUSTMENT_NORMAL;
// add a non-generic filter
@@ -3253,7 +3259,7 @@ public class PackageManagerService extends IPackageManager.Stub
ai.flags = ps.pkgFlags;
ai.privateFlags = ps.pkgPrivateFlags;
pi.applicationInfo =
- PackageParser.generateApplicationInfo(ai, flags, state, userId);
+ PackageInfoUtils.generateApplicationInfo(p, flags, state, userId, ps);
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "ps.pkg is n/a for ["
+ ps.name + "]. Provides a minimum info.");
@@ -3369,6 +3375,19 @@ public class PackageManagerService extends IPackageManager.Stub
return getInstalledPackagesBody(flags, userId, callingUid);
}
+ private static ActivityInfo generateDelegateActivityInfo(@Nullable AndroidPackage pkg,
+ @Nullable PackageSetting ps, @NonNull PackageUserState state,
+ @Nullable ActivityInfo activity, int flags, int userId) {
+ if (activity == null || pkg == null
+ || !checkUseInstalledOrHidden(pkg, ps, state, flags)) {
+ return null;
+ }
+ final ActivityInfo info = new ActivityInfo(activity);
+ info.applicationInfo =
+ PackageInfoUtils.generateApplicationInfo(pkg, flags, state, userId, ps);
+ return info;
+ }
+
public ParceledListSlice<PackageInfo> getInstalledPackagesBody(int flags, int userId,
int callingUid) {
// writer
@@ -3455,15 +3474,15 @@ public class PackageManagerService extends IPackageManager.Stub
for (int i = resultTargetUser.size() - 1; i >= 0; i--) {
if ((resultTargetUser.get(i).activityInfo.applicationInfo.flags
& ApplicationInfo.FLAG_SUSPENDED) == 0) {
- return createForwardingResolveInfoUnchecked(filter, sourceUserId,
- targetUserId);
+ return createForwardingResolveInfoUnchecked(filter,
+ sourceUserId, targetUserId);
}
}
}
return null;
}
- public ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
+ public ResolveInfo createForwardingResolveInfoUnchecked(WatchedIntentFilter filter,
int sourceUserId, int targetUserId) {
ResolveInfo forwardingResolveInfo = new ResolveInfo();
final long ident = Binder.clearCallingIdentity();
@@ -3493,7 +3512,7 @@ public class PackageManagerService extends IPackageManager.Stub
forwardingResolveInfo.preferredOrder = 0;
forwardingResolveInfo.match = 0;
forwardingResolveInfo.isDefault = true;
- forwardingResolveInfo.filter = filter;
+ forwardingResolveInfo.filter = new IntentFilter(filter.getIntentFilter());
forwardingResolveInfo.targetUserId = targetUserId;
return forwardingResolveInfo;
}
@@ -5693,8 +5712,8 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void requestChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Type int optional,
- @Checksum.Type int required, @Nullable List trustedInstallers,
+ @Checksum.TypeMask int optional,
+ @Checksum.TypeMask int required, @Nullable List trustedInstallers,
@NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId) {
requestChecksumsInternal(packageName, includeSplits, optional, required, trustedInstallers,
onChecksumsReadyListener, userId, mInjector.getBackgroundExecutor(),
@@ -5702,7 +5721,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
private void requestChecksumsInternal(@NonNull String packageName, boolean includeSplits,
- @Checksum.Type int optional, @Checksum.Type int required,
+ @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
@Nullable List trustedInstallers,
@NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
@NonNull Executor executor, @NonNull Handler handler) {
@@ -6130,6 +6149,7 @@ public class PackageManagerService extends IPackageManager.Stub
mInstantAppRegistry.registerObserver(mWatcher);
mSettings.registerObserver(mWatcher);
mIsolatedOwners.registerObserver(mWatcher);
+ mComponentResolver.registerObserver(mWatcher);
// If neither "build" attribute is true then this may be a mockito test, and verification
// can fail as a false positive.
Watchable.verifyWatchedAttributes(this, mWatcher, !(mIsEngBuild || mIsUserDebugBuild));
@@ -9443,6 +9463,15 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
IntentFilter filter, int match, ComponentName activity) {
+ setLastChosenActivity(intent, resolvedType, flags,
+ new WatchedIntentFilter(filter), match, activity);
+ }
+
+ /**
+ * Variant that takes a {@link WatchedIntentFilter}
+ */
+ public void setLastChosenActivity(Intent intent, String resolvedType, int flags,
+ WatchedIntentFilter filter, int match, ComponentName activity) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return;
}
@@ -9463,7 +9492,7 @@ public class PackageManagerService extends IPackageManager.Stub
findPreferredActivityNotLocked(
intent, resolvedType, flags, query, 0, false, true, false, userId);
// Add the new activity as the last chosen for this filter
- addPreferredActivityInternal(filter, match, null, activity, false, userId,
+ addPreferredActivity(filter, match, null, activity, false, userId,
"Setting last chosen", false);
}
@@ -10181,12 +10210,6 @@ public class PackageManagerService extends IPackageManager.Stub
resolvedType, flags, sourceUserId);
}
- private ResolveInfo createForwardingResolveInfoUnchecked(IntentFilter filter,
- int sourceUserId, int targetUserId) {
- return liveComputer().createForwardingResolveInfoUnchecked(filter,
- sourceUserId, targetUserId);
- }
-
@Override
public @NonNull ParceledListSlice<ResolveInfo> queryIntentActivityOptions(ComponentName caller,
Intent[] specifics, String[] specificTypes, Intent intent,
@@ -16463,7 +16486,7 @@ public class PackageManagerService extends IPackageManager.Stub
return new ParceledListSlice<IntentFilter>(result) {
@Override
protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
- // IntentFilter has final Parcelable methods, so redirect to the subclass
+ // WatchedIntentFilter has final Parcelable methods, so redirect to the subclass
((ParsedIntentInfo) parcelable).writeIntentInfoToParcel(dest,
callFlags);
}
@@ -21950,11 +21973,14 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void addPreferredActivity(IntentFilter filter, int match,
ComponentName[] set, ComponentName activity, int userId, boolean removeExisting) {
- addPreferredActivityInternal(filter, match, set, activity, true, userId,
+ addPreferredActivity(new WatchedIntentFilter(filter), match, set, activity, true, userId,
"Adding preferred", removeExisting);
}
- private void addPreferredActivityInternal(IntentFilter filter, int match,
+ /**
+ * Variant that takes a {@link WatchedIntentFilter}
+ */
+ public void addPreferredActivity(WatchedIntentFilter filter, int match,
ComponentName[] set, ComponentName activity, boolean always, int userId,
String opname, boolean removeExisting) {
// writer
@@ -22020,6 +22046,15 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void replacePreferredActivity(IntentFilter filter, int match,
ComponentName[] set, ComponentName activity, int userId) {
+ replacePreferredActivity(new WatchedIntentFilter(filter), match,
+ set, activity, userId);
+ }
+
+ /**
+ * Variant that takes a {@link WatchedIntentFilter}
+ */
+ public void replacePreferredActivity(WatchedIntentFilter filter, int match,
+ ComponentName[] set, ComponentName activity, int userId) {
if (filter.countActions() != 1) {
throw new IllegalArgumentException(
"replacePreferredActivity expects filter to have only 1 action.");
@@ -22092,7 +22127,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
}
- addPreferredActivityInternal(filter, match, set, activity, true, userId,
+ addPreferredActivity(filter, match, set, activity, true, userId,
"Replacing preferred", false);
}
@@ -22199,6 +22234,22 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public int getPreferredActivities(List<IntentFilter> outFilters,
List<ComponentName> outActivities, String packageName) {
+ List<WatchedIntentFilter> temp =
+ WatchedIntentFilter.toWatchedIntentFilterList(outFilters);
+ final int result = getPreferredActivitiesInternal(
+ temp, outActivities, packageName);
+ outFilters.clear();
+ for (int i = 0; i < temp.size(); i++) {
+ outFilters.add(temp.get(i).getIntentFilter());
+ }
+ return result;
+ }
+
+ /**
+ * Variant that takes a {@link WatchedIntentFilter}
+ */
+ public int getPreferredActivitiesInternal(List<WatchedIntentFilter> outFilters,
+ List<ComponentName> outActivities, String packageName) {
if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
return 0;
}
@@ -22215,7 +22266,7 @@ public class PackageManagerService extends IPackageManager.Stub
|| (pa.mPref.mComponent.getPackageName().equals(packageName)
&& pa.mPref.mAlways)) {
if (outFilters != null) {
- outFilters.add(new IntentFilter(pa));
+ outFilters.add(new WatchedIntentFilter(pa.getIntentFilter()));
}
if (outActivities != null) {
outActivities.add(pa.mPref.mComponent);
@@ -22231,6 +22282,14 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void addPersistentPreferredActivity(IntentFilter filter, ComponentName activity,
int userId) {
+ addPersistentPreferredActivity(new WatchedIntentFilter(filter), activity, userId);
+ }
+
+ /**
+ * Variant that takes a {@link WatchedIntentFilter}
+ */
+ public void addPersistentPreferredActivity(WatchedIntentFilter filter, ComponentName activity,
+ int userId) {
int callingUid = Binder.getCallingUid();
if (callingUid != Process.SYSTEM_UID) {
throw new SecurityException(
@@ -22474,6 +22533,15 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void addCrossProfileIntentFilter(IntentFilter intentFilter, String ownerPackage,
int sourceUserId, int targetUserId, int flags) {
+ addCrossProfileIntentFilter(new WatchedIntentFilter(intentFilter), ownerPackage,
+ sourceUserId, targetUserId, flags);
+ }
+
+ /**
+ * Variant that takes a {@link WatchedIntentFilter}
+ */
+ public void addCrossProfileIntentFilter(WatchedIntentFilter intentFilter, String ownerPackage,
+ int sourceUserId, int targetUserId, int flags) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
int callingUid = Binder.getCallingUid();
@@ -22603,8 +22671,8 @@ public class PackageManagerService extends IPackageManager.Stub
return liveComputer().getHomeIntent();
}
- private IntentFilter getHomeFilter() {
- IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
+ private WatchedIntentFilter getHomeFilter() {
+ WatchedIntentFilter filter = new WatchedIntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);
return filter;
@@ -23604,7 +23672,7 @@ public class PackageManagerService extends IPackageManager.Stub
boolean compatibilityModeEnabled = android.provider.Settings.Global.getInt(
mContext.getContentResolver(),
android.provider.Settings.Global.COMPATIBILITY_MODE, 1) == 1;
- PackageParser.setCompatibilityModeEnabled(compatibilityModeEnabled);
+ ParsingPackageUtils.setCompatibilityModeEnabled(compatibilityModeEnabled);
if (DEBUG_SETTINGS) {
Log.d(TAG, "compatibility mode:" + compatibilityModeEnabled);
@@ -26019,18 +26087,29 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public String[] getNamesForUids(int[] uids) throws RemoteException {
- if (uids == null || uids.length == 0) {
- return null;
- }
- final String[] names = PackageManagerService.this.getNamesForUids(uids);
- final String[] results = (names != null) ? names : new String[uids.length];
- // massage results so they can be parsed by the native binder
- for (int i = results.length - 1; i >= 0; --i) {
- if (results[i] == null) {
- results[i] = "";
+ String[] names = null;
+ String[] results = null;
+ try {
+ if (uids == null || uids.length == 0) {
+ return null;
}
+ names = PackageManagerService.this.getNamesForUids(uids);
+ results = (names != null) ? names : new String[uids.length];
+ // massage results so they can be parsed by the native binder
+ for (int i = results.length - 1; i >= 0; --i) {
+ if (results[i] == null) {
+ results[i] = "";
+ }
+ }
+ return results;
+ } catch (Throwable t) {
+ // STOPSHIP(186558987): revert addition of try/catch/log
+ Slog.e(TAG, "uids: " + Arrays.toString(uids));
+ Slog.e(TAG, "names: " + Arrays.toString(names));
+ Slog.e(TAG, "results: " + Arrays.toString(results));
+ Slog.e(TAG, "throwing exception", t);
+ throw t;
}
- return results;
}
// NB: this differentiates between preloads and sideloads
@@ -27225,7 +27304,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void requestChecksums(@NonNull String packageName, boolean includeSplits,
- @Checksum.Type int optional, @Checksum.Type int required,
+ @Checksum.TypeMask int optional, @Checksum.TypeMask int required,
@Nullable List trustedInstallers,
@NonNull IOnChecksumsReadyListener onChecksumsReadyListener, int userId,
@NonNull Executor executor, @NonNull Handler handler) {
diff --git a/services/core/java/com/android/server/pm/PersistentPreferredActivity.java b/services/core/java/com/android/server/pm/PersistentPreferredActivity.java
index a015456f1485..ad3950c906ef 100644
--- a/services/core/java/com/android/server/pm/PersistentPreferredActivity.java
+++ b/services/core/java/com/android/server/pm/PersistentPreferredActivity.java
@@ -23,13 +23,14 @@ import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import com.android.internal.util.XmlUtils;
+import com.android.server.utils.SnapshotCache;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
-class PersistentPreferredActivity extends IntentFilter {
+class PersistentPreferredActivity extends WatchedIntentFilter {
private static final String ATTR_NAME = "name"; // component name
private static final String ATTR_FILTER = "filter"; // filter
private static final String ATTR_SET_BY_DPM = "set-by-dpm"; // set by DPM
@@ -41,10 +42,38 @@ class PersistentPreferredActivity extends IntentFilter {
final ComponentName mComponent;
final boolean mIsSetByDpm;
+ // The cache for snapshots, so they are not rebuilt if the base object has not
+ // changed.
+ final SnapshotCache<PersistentPreferredActivity> mSnapshot;
+
+ private SnapshotCache makeCache() {
+ return new SnapshotCache<PersistentPreferredActivity>(this, this) {
+ @Override
+ public PersistentPreferredActivity createSnapshot() {
+ PersistentPreferredActivity s = new PersistentPreferredActivity(mSource);
+ s.seal();
+ return s;
+ }};
+ }
+
PersistentPreferredActivity(IntentFilter filter, ComponentName activity, boolean isSetByDpm) {
super(filter);
mComponent = activity;
mIsSetByDpm = isSetByDpm;
+ mSnapshot = makeCache();
+ }
+
+ PersistentPreferredActivity(WatchedIntentFilter filter, ComponentName activity,
+ boolean isSetByDpm) {
+ this(filter.mFilter, activity, isSetByDpm);
+ }
+
+ // Copy constructor used only to create a snapshot
+ private PersistentPreferredActivity(PersistentPreferredActivity f) {
+ super(f);
+ mComponent = f.mComponent;
+ mIsSetByDpm = f.mIsSetByDpm;
+ mSnapshot = new SnapshotCache.Sealed();
}
PersistentPreferredActivity(TypedXmlPullParser parser)
@@ -79,27 +108,36 @@ class PersistentPreferredActivity extends IntentFilter {
}
}
if (tagName.equals(ATTR_FILTER)) {
- readFromXml(parser);
+ mFilter.readFromXml(parser);
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Missing element filter at " +
parser.getPositionDescription());
XmlUtils.skipCurrentTag(parser);
}
+ mSnapshot = makeCache();
}
public void writeToXml(TypedXmlSerializer serializer) throws IOException {
serializer.attribute(null, ATTR_NAME, mComponent.flattenToShortString());
serializer.attributeBoolean(null, ATTR_SET_BY_DPM, mIsSetByDpm);
serializer.startTag(null, ATTR_FILTER);
- super.writeToXml(serializer);
+ mFilter.writeToXml(serializer);
serializer.endTag(null, ATTR_FILTER);
}
+ public IntentFilter getIntentFilter() {
+ return mFilter;
+ }
+
@Override
public String toString() {
return "PersistentPreferredActivity{0x" + Integer.toHexString(System.identityHashCode(this))
+ " " + mComponent.flattenToShortString()
+ ", mIsSetByDpm=" + mIsSetByDpm + "}";
}
+
+ public PersistentPreferredActivity snapshot() {
+ return mSnapshot.snapshot();
+ }
}
diff --git a/services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java b/services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java
index 2b11a4297835..bfddaea0dd75 100644
--- a/services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java
+++ b/services/core/java/com/android/server/pm/PersistentPreferredIntentResolver.java
@@ -21,6 +21,7 @@ import android.content.IntentFilter;
import com.android.server.WatchedIntentResolver;
import com.android.server.utils.Snappable;
+import com.android.server.utils.SnapshotCache;
public class PersistentPreferredIntentResolver
extends WatchedIntentResolver<PersistentPreferredActivity, PersistentPreferredActivity>
@@ -32,7 +33,7 @@ public class PersistentPreferredIntentResolver
@Override
protected IntentFilter getIntentFilter(@NonNull PersistentPreferredActivity input) {
- return input;
+ return input.getIntentFilter();
}
@Override
@@ -40,14 +41,40 @@ public class PersistentPreferredIntentResolver
return packageName.equals(filter.mComponent.getPackageName());
}
+ public PersistentPreferredIntentResolver() {
+ super();
+ mSnapshot = makeCache();
+ }
+
+ // Take the snapshot of F
+ protected PersistentPreferredActivity snapshot(PersistentPreferredActivity f) {
+ return (f == null) ? null : f.snapshot();
+ }
+
+ // Copy constructor used only to create a snapshot.
+ private PersistentPreferredIntentResolver(PersistentPreferredIntentResolver f) {
+ copyFrom(f);
+ mSnapshot = new SnapshotCache.Sealed();
+ }
+
+ // The cache for snapshots, so they are not rebuilt if the base object has not
+ // changed.
+ final SnapshotCache<PersistentPreferredIntentResolver> mSnapshot;
+
+ private SnapshotCache makeCache() {
+ return new SnapshotCache<PersistentPreferredIntentResolver>(this, this) {
+ @Override
+ public PersistentPreferredIntentResolver createSnapshot() {
+ return new PersistentPreferredIntentResolver(mSource);
+ }};
+ }
+
/**
* Return a snapshot of the current object. The snapshot is a read-only copy suitable
* for read-only methods.
* @return A snapshot of the current object.
*/
public PersistentPreferredIntentResolver snapshot() {
- PersistentPreferredIntentResolver result = new PersistentPreferredIntentResolver();
- result.copyFrom(this);
- return result;
+ return mSnapshot.snapshot();
}
}
diff --git a/services/core/java/com/android/server/pm/PreferredActivity.java b/services/core/java/com/android/server/pm/PreferredActivity.java
index 4e1dcb27111d..5bc915f2c1c4 100644
--- a/services/core/java/com/android/server/pm/PreferredActivity.java
+++ b/services/core/java/com/android/server/pm/PreferredActivity.java
@@ -23,32 +23,62 @@ import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import com.android.internal.util.XmlUtils;
+import com.android.server.utils.SnapshotCache;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.io.PrintWriter;
-class PreferredActivity extends IntentFilter implements PreferredComponent.Callbacks {
+class PreferredActivity extends WatchedIntentFilter implements PreferredComponent.Callbacks {
private static final String TAG = "PreferredActivity";
private static final boolean DEBUG_FILTERS = false;
final PreferredComponent mPref;
+ // The cache for snapshots, so they are not rebuilt if the base object has not
+ // changed.
+ final SnapshotCache<PreferredActivity> mSnapshot;
+
+ private SnapshotCache makeCache() {
+ return new SnapshotCache<PreferredActivity>(this, this) {
+ @Override
+ public PreferredActivity createSnapshot() {
+ PreferredActivity s = new PreferredActivity(mSource);
+ s.seal();
+ return s;
+ }};
+ }
+
PreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity,
boolean always) {
super(filter);
mPref = new PreferredComponent(this, match, set, activity, always);
+ mSnapshot = makeCache();
+ }
+
+ PreferredActivity(WatchedIntentFilter filter, int match, ComponentName[] set,
+ ComponentName activity, boolean always) {
+ this(filter.mFilter, match, set, activity, always);
+ }
+
+ // Copy constructor used only to create a snapshot
+ private PreferredActivity(PreferredActivity f) {
+ super(f);
+ mPref = f.mPref;
+ mSnapshot = new SnapshotCache.Sealed();
}
PreferredActivity(TypedXmlPullParser parser) throws XmlPullParserException, IOException {
mPref = new PreferredComponent(this, parser);
+ mSnapshot = makeCache();
}
public void writeToXml(TypedXmlSerializer serializer, boolean full) throws IOException {
mPref.writeToXml(serializer, full);
serializer.startTag(null, "filter");
- super.writeToXml(serializer);
+ mFilter.writeToXml(serializer);
serializer.endTag(null, "filter");
}
@@ -58,7 +88,7 @@ class PreferredActivity extends IntentFilter implements PreferredComponent.Callb
if (DEBUG_FILTERS) {
Log.i(TAG, "Starting to parse filter...");
}
- readFromXml(parser);
+ mFilter.readFromXml(parser);
if (DEBUG_FILTERS) {
Log.i(TAG, "Finished filter: depth=" + parser.getDepth() + " tag="
+ parser.getName());
@@ -71,9 +101,17 @@ class PreferredActivity extends IntentFilter implements PreferredComponent.Callb
return true;
}
+ public void dumpPref(PrintWriter out, String prefix, PreferredActivity filter) {
+ mPref.dump(out, prefix, filter);
+ }
+
@Override
public String toString() {
return "PreferredActivity{0x" + Integer.toHexString(System.identityHashCode(this))
+ " " + mPref.mComponent.flattenToShortString() + "}";
}
+
+ public PreferredActivity snapshot() {
+ return mSnapshot.snapshot();
+ }
}
diff --git a/services/core/java/com/android/server/pm/PreferredIntentResolver.java b/services/core/java/com/android/server/pm/PreferredIntentResolver.java
index 10a6b3f69fde..0aca6eec25fc 100644
--- a/services/core/java/com/android/server/pm/PreferredIntentResolver.java
+++ b/services/core/java/com/android/server/pm/PreferredIntentResolver.java
@@ -21,6 +21,7 @@ import android.content.IntentFilter;
import com.android.server.WatchedIntentResolver;
import com.android.server.utils.Snappable;
+import com.android.server.utils.SnapshotCache;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -46,7 +47,7 @@ public class PreferredIntentResolver
@Override
protected IntentFilter getIntentFilter(@NonNull PreferredActivity input) {
- return input;
+ return input.getIntentFilter();
}
public boolean shouldAddPreferredActivity(PreferredActivity pa) {
@@ -69,14 +70,40 @@ public class PreferredIntentResolver
return true;
}
+ public PreferredIntentResolver() {
+ super();
+ mSnapshot = makeCache();
+ }
+
+ // Take the snapshot of F
+ protected PreferredActivity snapshot(PreferredActivity f) {
+ return (f == null) ? null : f.snapshot();
+ }
+
+ // Copy constructor used only to create a snapshot.
+ private PreferredIntentResolver(PreferredIntentResolver f) {
+ copyFrom(f);
+ mSnapshot = new SnapshotCache.Sealed();
+ }
+
+ // The cache for snapshots, so they are not rebuilt if the base object has not
+ // changed.
+ final SnapshotCache<PreferredIntentResolver> mSnapshot;
+
+ private SnapshotCache makeCache() {
+ return new SnapshotCache<PreferredIntentResolver>(this, this) {
+ @Override
+ public PreferredIntentResolver createSnapshot() {
+ return new PreferredIntentResolver(mSource);
+ }};
+ }
+
/**
* Return a snapshot of the current object. The snapshot is a read-only copy suitable
* for read-only methods.
* @return A snapshot of the current object.
*/
public PreferredIntentResolver snapshot() {
- PreferredIntentResolver result = new PreferredIntentResolver();
- result.copyFrom(this);
- return result;
+ return mSnapshot.snapshot();
}
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index b985229d3116..1b8eee3925a5 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3026,8 +3026,9 @@ public final class Settings implements Watchable, Snappable {
= ps.pkg.getPreferredActivityFilters();
for (int i=0; i<intents.size(); i++) {
Pair<String, ParsedIntentInfo> pair = intents.get(i);
- applyDefaultPreferredActivityLPw(pmInternal, pair.second, new ComponentName(
- ps.name, pair.first), userId);
+ applyDefaultPreferredActivityLPw(pmInternal,
+ new WatchedIntentFilter(pair.second),
+ new ComponentName(ps.name, pair.first), userId);
}
}
}
@@ -3097,7 +3098,7 @@ public final class Settings implements Watchable, Snappable {
}
static void removeFilters(@NonNull PreferredIntentResolver pir,
- @NonNull IntentFilter filter, @NonNull List<PreferredActivity> existing) {
+ @NonNull WatchedIntentFilter filter, @NonNull List<PreferredActivity> existing) {
if (PackageManagerService.DEBUG_PREFERRED) {
Slog.i(TAG, existing.size() + " preferred matches for:");
filter.dump(new LogPrinter(Log.INFO, TAG), " ");
@@ -3112,8 +3113,8 @@ public final class Settings implements Watchable, Snappable {
}
}
- private void applyDefaultPreferredActivityLPw(
- PackageManagerInternal pmInternal, IntentFilter tmpPa, ComponentName cn, int userId) {
+ private void applyDefaultPreferredActivityLPw(PackageManagerInternal pmInternal,
+ WatchedIntentFilter tmpPa, ComponentName cn, int userId) {
// The initial preferences only specify the target activity
// component and intent-filter, not the set of matches. So we
// now need to query for the matches to build the correct
@@ -3284,7 +3285,7 @@ public final class Settings implements Watchable, Snappable {
haveNonSys = null;
}
if (haveAct && haveNonSys == null) {
- IntentFilter filter = new IntentFilter();
+ WatchedIntentFilter filter = new WatchedIntentFilter();
if (intent.getAction() != null) {
filter.addAction(intent.getAction());
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 3dfb835eeb45..1bd9e5eedb84 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -319,7 +319,7 @@ class ShortcutPackage extends ShortcutPackageItem {
}
final Icon icon = si.getIcon();
if (icon != null && icon.getType() != Icon.TYPE_BITMAP
- && icon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
+ && icon.getType() != Icon.TYPE_ADAPTIVE_BITMAP) {
continue;
}
if (icon == null && !si.hasIconFile()) {
diff --git a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
index 61f51e36202c..b89dbdc863e0 100644
--- a/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
+++ b/services/core/java/com/android/server/pm/parsing/PackageInfoUtils.java
@@ -417,7 +417,7 @@ public class PackageInfoUtils {
* Returns true if the package is installed and not hidden, or if the caller
* explicitly wanted all uninstalled and hidden packages as well.
*/
- private static boolean checkUseInstalledOrHidden(AndroidPackage pkg,
+ public static boolean checkUseInstalledOrHidden(AndroidPackage pkg,
PackageSetting pkgSetting, PackageUserState state,
@PackageManager.PackageInfoFlags int flags) {
// Returns false if the package is hidden system app until installed.
diff --git a/services/core/java/com/android/server/telecom/TelecomLoaderService.java b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
index f0c96e18930a..32ad702ceff5 100644
--- a/services/core/java/com/android/server/telecom/TelecomLoaderService.java
+++ b/services/core/java/com/android/server/telecom/TelecomLoaderService.java
@@ -31,6 +31,7 @@ import android.telecom.DefaultDialerManager;
import android.telecom.PhoneAccountHandle;
import android.telecom.TelecomManager;
import android.telephony.CarrierConfigManager;
+import android.telephony.SubscriptionManager;
import android.util.IntArray;
import android.util.Slog;
@@ -44,6 +45,9 @@ import com.android.server.SystemService;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.permission.LegacyPermissionManagerInternal;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* Starts the telecom component by binding to its ITelecomService implementation. Telecom is setup
* to run in the system-server process so once it is loaded into memory it will stay running.
@@ -208,13 +212,23 @@ public class TelecomLoaderService extends SystemService {
return null;
}
}
+ SubscriptionManager subscriptionManager =
+ mContext.getSystemService(SubscriptionManager.class);
+ if (subscriptionManager == null) {
+ return null;
+ }
TelecomManager telecomManager =
(TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
- PhoneAccountHandle phoneAccount = telecomManager.getSimCallManager(userId);
- if (phoneAccount != null) {
- return new String[]{phoneAccount.getComponentName().getPackageName()};
+ List<String> packages = new ArrayList<>();
+ int[] subIds = subscriptionManager.getActiveSubscriptionIdList();
+ for (int subId : subIds) {
+ PhoneAccountHandle phoneAccount =
+ telecomManager.getSimCallManagerForSubscription(subId);
+ if (phoneAccount != null) {
+ packages.add(phoneAccount.getComponentName().getPackageName());
+ }
}
- return null;
+ return packages.toArray(new String[] {});
});
}
diff --git a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java
index c8c828f10ad3..27b50d892144 100644
--- a/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java
+++ b/services/core/java/com/android/server/timezonedetector/MetricsTimeZoneDetectorState.java
@@ -89,8 +89,6 @@ public final class MetricsTimeZoneDetectorState {
@Nullable TelephonyTimeZoneSuggestion latestTelephonySuggestion,
@Nullable GeolocationTimeZoneSuggestion latestGeolocationSuggestion) {
- // TODO(b/172934905) Add logic to canonicalize the time zone IDs to Android's preferred IDs
- // so that the ordinals will match even when the ID is not identical, just equivalent.
int deviceTimeZoneIdOrdinal =
tzIdOrdinalGenerator.ordinal(Objects.requireNonNull(deviceTimeZoneId));
MetricsTimeZoneSuggestion latestObfuscatedManualSuggestion =
diff --git a/services/core/java/com/android/server/timezonedetector/OrdinalGenerator.java b/services/core/java/com/android/server/timezonedetector/OrdinalGenerator.java
index a448773c40d5..50875308db7d 100644
--- a/services/core/java/com/android/server/timezonedetector/OrdinalGenerator.java
+++ b/services/core/java/com/android/server/timezonedetector/OrdinalGenerator.java
@@ -15,9 +15,12 @@
*/
package com.android.server.timezonedetector;
+import android.annotation.NonNull;
import android.util.ArraySet;
import java.util.List;
+import java.util.Objects;
+import java.util.function.Function;
/**
* A helper class that turns a set of objects into ordinal values, i.e. each object is offered
@@ -30,11 +33,19 @@ import java.util.List;
class OrdinalGenerator<T> {
private final ArraySet<T> mKnownIds = new ArraySet<>();
+ private final @NonNull Function<T, T> mCanonicalizationFunction;
+
+ OrdinalGenerator(@NonNull Function<T, T> canonicalizationFunction) {
+ mCanonicalizationFunction = Objects.requireNonNull(canonicalizationFunction);
+ }
+
int ordinal(T object) {
- int ordinal = mKnownIds.indexOf(object);
+ T canonical = mCanonicalizationFunction.apply(object);
+
+ int ordinal = mKnownIds.indexOf(canonical);
if (ordinal < 0) {
ordinal = mKnownIds.size();
- mKnownIds.add(object);
+ mKnownIds.add(canonical);
}
return ordinal;
}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneCanonicalizer.java b/services/core/java/com/android/server/timezonedetector/TimeZoneCanonicalizer.java
new file mode 100644
index 000000000000..bdbf60712008
--- /dev/null
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneCanonicalizer.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2021 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.timezonedetector;
+
+import com.android.i18n.timezone.TimeZoneFinder;
+
+import java.util.function.Function;
+
+/**
+ * Returns preferred time zone ID if {@code timeZoneId} was deprecated. For example, returns
+ * America/Nuuk for America/Godthab.
+ */
+final class TimeZoneCanonicalizer implements Function<String, String> {
+ @Override
+ public String apply(String timeZoneId) {
+ String canonicialZoneId = TimeZoneFinder.getInstance().getCountryZonesFinder()
+ .findCanonicalTimeZoneId(timeZoneId);
+
+ return canonicialZoneId == null ? timeZoneId : canonicialZoneId;
+ }
+}
diff --git a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
index c34a7d37ba24..ab2a88b44a87 100644
--- a/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
+++ b/services/core/java/com/android/server/timezonedetector/TimeZoneDetectorStrategyImpl.java
@@ -383,7 +383,8 @@ public final class TimeZoneDetectorStrategyImpl implements TimeZoneDetectorStrat
bestQualifiedTelephonySuggestion == null
? null : bestQualifiedTelephonySuggestion.suggestion;
// A new generator is created each time: we don't want / require consistency.
- OrdinalGenerator<String> tzIdOrdinalGenerator = new OrdinalGenerator<>();
+ OrdinalGenerator<String> tzIdOrdinalGenerator =
+ new OrdinalGenerator<>(new TimeZoneCanonicalizer());
return MetricsTimeZoneDetectorState.create(
tzIdOrdinalGenerator,
getConfigurationInternal(currentUserId),
diff --git a/services/core/java/com/android/server/utils/SnapshotCache.java b/services/core/java/com/android/server/utils/SnapshotCache.java
index f0fb8b25b402..b4b8835ac026 100644
--- a/services/core/java/com/android/server/utils/SnapshotCache.java
+++ b/services/core/java/com/android/server/utils/SnapshotCache.java
@@ -57,6 +57,15 @@ public abstract class SnapshotCache<T> extends Watcher{
}
/**
+ * A private constructor that sets fields to null and mSealed to true. This supports
+ * the Sealed subclass.
+ */
+ public SnapshotCache() {
+ mSource = null;
+ mSealed = true;
+ }
+
+ /**
* Notify the object that the source object has changed. If the local object is sealed then
* IllegalStateException is thrown. Otherwise, the cache is cleared.
*/
@@ -93,4 +102,25 @@ public abstract class SnapshotCache<T> extends Watcher{
* @return A snapshot
*/
public abstract T createSnapshot();
+
+ /**
+ * A snapshot cache suitable for sealed snapshots. Attempting to retrieve the
+ * snapshot will throw an UnsupportedOperationException.
+ * @param <T> the type of object being cached. This is needed for compilation only. It
+ * has no effect on execution.
+ */
+ public static class Sealed<T> extends SnapshotCache<T> {
+ /**
+ * Create a sealed SnapshotCache that cannot be used to create new snapshots.
+ */
+ public Sealed() {
+ }
+ /**
+ * Provide a concrete implementation of createSnapshot() that throws
+ * UnsupportedOperationException.
+ */
+ public T createSnapshot() {
+ throw new UnsupportedOperationException("cannot snapshot a sealed snaphot");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 6a1b1069f57c..8f3702ac1a5e 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -91,6 +91,7 @@ import static android.content.pm.ActivityInfo.SIZE_CHANGES_UNSUPPORTED_OVERRIDE;
import static android.content.pm.ActivityInfo.isFixedOrientationLandscape;
import static android.content.pm.ActivityInfo.isFixedOrientationPortrait;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
import static android.content.res.Configuration.EMPTY;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
@@ -6618,9 +6619,15 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Override
void onCancelFixedRotationTransform(int originalDisplayRotation) {
- if (this != mDisplayContent.getLastOrientationSource()
- || getRequestedConfigurationOrientation() != ORIENTATION_UNDEFINED) {
- // Only need to handle the activity that should be rotated with display.
+ if (this != mDisplayContent.getLastOrientationSource()) {
+ // This activity doesn't affect display rotation.
+ return;
+ }
+ final int requestedOrientation = getRequestedConfigurationOrientation();
+ if (requestedOrientation != ORIENTATION_UNDEFINED
+ && requestedOrientation != mDisplayContent.getConfiguration().orientation) {
+ // Only need to handle the activity that can be rotated with display or the activity
+ // has requested the same orientation.
return;
}
@@ -6858,6 +6865,11 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A
@Override
void resolveOverrideConfiguration(Configuration newParentConfiguration) {
+ final Configuration requestedOverrideConfig = getRequestedOverrideConfiguration();
+ if (requestedOverrideConfig.assetsSeq != ASSETS_SEQ_UNDEFINED
+ && newParentConfiguration.assetsSeq > requestedOverrideConfig.assetsSeq) {
+ requestedOverrideConfig.assetsSeq = ASSETS_SEQ_UNDEFINED;
+ }
super.resolveOverrideConfiguration(newParentConfiguration);
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
if (isFixedRotationTransforming()) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index e249e674a174..c6a66c573ada 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -472,6 +472,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
/** Current sequencing integer of the configuration, for skipping old configurations. */
private int mConfigurationSeq;
+
+ /** Current sequencing integer of the asset changes, for skipping old resources overlays. */
+ private int mGlobalAssetsSeq;
+
// To cache the list of supported system locales
private String[] mSupportedSystemLocales = null;
@@ -4129,6 +4133,35 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return changes;
}
+ private int increaseAssetConfigurationSeq() {
+ mGlobalAssetsSeq = Math.max(++mGlobalAssetsSeq, 1);
+ return mGlobalAssetsSeq;
+ }
+
+ /**
+ * Update the asset configuration and increase the assets sequence number.
+ * @param processes the processes that needs to update the asset configuration, if none
+ * updates the global configuration for all processes.
+ */
+ public void updateAssetConfiguration(List<WindowProcessController> processes) {
+ synchronized (mGlobalLock) {
+ final int assetSeq = increaseAssetConfigurationSeq();
+
+ // Update the global configuration if the no target processes
+ if (processes == null) {
+ Configuration newConfig = new Configuration();
+ newConfig.assetsSeq = assetSeq;
+ updateConfiguration(newConfig);
+ return;
+ }
+
+ for (int i = processes.size() - 1; i >= 0; i--) {
+ final WindowProcessController wpc = processes.get(i);
+ wpc.updateAssetConfiguration(assetSeq);
+ }
+ }
+ }
+
void startLaunchPowerMode(@PowerModeReason int reason) {
if (mPowerManagerInternal == null) return;
mPowerManagerInternal.setPowerMode(Mode.LAUNCH, true);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 9aabdac58f69..2c592d00f90c 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -2258,7 +2258,6 @@ class Task extends WindowContainer<WindowContainer> {
mTmpPrevBounds.set(getBounds());
final boolean wasInMultiWindowMode = inMultiWindowMode();
final boolean wasInPictureInPicture = inPinnedWindowingMode();
- final int oldOrientation = getOrientation();
super.onConfigurationChanged(newParentConfig);
// Only need to update surface size here since the super method will handle updating
// surface position.
@@ -2301,11 +2300,6 @@ class Task extends WindowContainer<WindowContainer> {
mForceNotOrganized = false;
}
- // Report orientation change such as changing from freeform to fullscreen.
- if (oldOrientation != getOrientation()) {
- onDescendantOrientationChanged(this);
- }
-
saveLaunchingStateIfNeeded();
final boolean taskOrgChanged = updateTaskOrganizerState(false /* forceUpdate */);
if (taskOrgChanged) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
index 4dc60070d6ec..d59654949a27 100644
--- a/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
+++ b/services/core/java/com/android/server/wm/WindowManagerShellCommand.java
@@ -130,6 +130,12 @@ public class WindowManagerShellCommand extends ShellCommand {
return runResetLetterboxStyle(pw);
case "set-sandbox-display-apis":
return runSandboxDisplayApis(pw);
+ case "set-multi-window-config":
+ return runSetMultiWindowConfig();
+ case "get-multi-window-config":
+ return runGetMultiWindowConfig(pw);
+ case "reset-multi-window-config":
+ return runResetMultiWindowConfig();
case "reset":
return runReset(pw);
case "disable-blur":
@@ -815,6 +821,80 @@ public class WindowManagerShellCommand extends ShellCommand {
return 0;
}
+ private int runSetMultiWindowConfig() {
+ if (peekNextArg() == null) {
+ getErrPrintWriter().println("Error: No arguments provided.");
+ }
+ int result = 0;
+ while (peekNextArg() != null) {
+ String arg = getNextArg();
+ switch (arg) {
+ case "--supportsNonResizable":
+ result += runSetSupportsNonResizableMultiWindow();
+ break;
+ case "--respectsActivityMinWidthHeight":
+ result += runSetRespectsActivityMinWidthHeightMultiWindow();
+ break;
+ default:
+ getErrPrintWriter().println(
+ "Error: Unrecognized multi window option: " + arg);
+ return -1;
+ }
+ }
+ return result == 0 ? 0 : -1;
+ }
+
+ private int runSetSupportsNonResizableMultiWindow() {
+ final String arg = getNextArg();
+ if (!arg.equals("-1") && !arg.equals("0") && !arg.equals("1")) {
+ getErrPrintWriter().println("Error: a config value of [-1, 0, 1] must be provided as"
+ + " an argument for supportsNonResizableMultiWindow");
+ return -1;
+ }
+ final int configValue = Integer.parseInt(arg);
+ synchronized (mInternal.mAtmService.mGlobalLock) {
+ mInternal.mAtmService.mSupportsNonResizableMultiWindow = configValue;
+ }
+ return 0;
+ }
+
+ private int runSetRespectsActivityMinWidthHeightMultiWindow() {
+ final String arg = getNextArg();
+ if (!arg.equals("-1") && !arg.equals("0") && !arg.equals("1")) {
+ getErrPrintWriter().println("Error: a config value of [-1, 0, 1] must be provided as"
+ + " an argument for respectsActivityMinWidthHeightMultiWindow");
+ return -1;
+ }
+ final int configValue = Integer.parseInt(arg);
+ synchronized (mInternal.mAtmService.mGlobalLock) {
+ mInternal.mAtmService.mRespectsActivityMinWidthHeightMultiWindow = configValue;
+ }
+ return 0;
+ }
+
+ private int runGetMultiWindowConfig(PrintWriter pw) {
+ synchronized (mInternal.mAtmService.mGlobalLock) {
+ pw.println("Supports non-resizable in multi window: "
+ + mInternal.mAtmService.mSupportsNonResizableMultiWindow);
+ pw.println("Respects activity min width/height in multi window: "
+ + mInternal.mAtmService.mRespectsActivityMinWidthHeightMultiWindow);
+ }
+ return 0;
+ }
+
+ private int runResetMultiWindowConfig() {
+ final int supportsNonResizable = mInternal.mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_supportsNonResizableMultiWindow);
+ final int respectsActivityMinWidthHeight = mInternal.mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_respectsActivityMinWidthHeightMultiWindow);
+ synchronized (mInternal.mAtmService.mGlobalLock) {
+ mInternal.mAtmService.mSupportsNonResizableMultiWindow = supportsNonResizable;
+ mInternal.mAtmService.mRespectsActivityMinWidthHeightMultiWindow =
+ respectsActivityMinWidthHeight;
+ }
+ return 0;
+ }
+
private void resetLetterboxStyle() {
synchronized (mInternal.mGlobalLock) {
mLetterboxConfiguration.resetFixedOrientationLetterboxAspectRatio();
@@ -879,6 +959,9 @@ public class WindowManagerShellCommand extends ShellCommand {
// set-sandbox-display-apis
mInternal.setSandboxDisplayApis(displayId, /* sandboxDisplayApis= */ true);
+ // set-multi-window-config
+ runResetMultiWindowConfig();
+
pw.println("Reset all settings for displayId=" + displayId);
return 0;
}
@@ -916,6 +999,7 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" Size Compat Mode.");
printLetterboxHelp(pw);
+ printMultiWindowConfigHelp(pw);
pw.println(" reset [-d DISPLAY_ID]");
pw.println(" Reset all override settings.");
@@ -969,4 +1053,31 @@ public class WindowManagerShellCommand extends ShellCommand {
pw.println(" get-letterbox-style");
pw.println(" Prints letterbox style configuration.");
}
+
+ private void printMultiWindowConfigHelp(PrintWriter pw) {
+ pw.println(" set-multi-window-config");
+ pw.println(" Sets options to determine if activity should be shown in multi window:");
+ pw.println(" --supportsNonResizable [configValue]");
+ pw.println(" Whether the device supports non-resizable activity in multi window.");
+ pw.println(" -1: The device doesn't support non-resizable in multi window.");
+ pw.println(" 0: The device supports non-resizable in multi window only if");
+ pw.println(" this is a large screen device.");
+ pw.println(" 1: The device always supports non-resizable in multi window.");
+ pw.println(" --respectsActivityMinWidthHeight [configValue]");
+ pw.println(" Whether the device checks the activity min width/height to determine ");
+ pw.println(" if it can be shown in multi window.");
+ pw.println(" -1: The device ignores the activity min width/height when determining");
+ pw.println(" if it can be shown in multi window.");
+ pw.println(" 0: If this is a small screen, the device compares the activity min");
+ pw.println(" width/height with the min multi window modes dimensions");
+ pw.println(" the device supports to determine if the activity can be shown in");
+ pw.println(" multi window.");
+ pw.println(" 1: The device always compare the activity min width/height with the");
+ pw.println(" min multi window dimensions the device supports to determine if");
+ pw.println(" the activity can be shown in multi window.");
+ pw.println(" get-multi-window-config");
+ pw.println(" Prints values of the multi window config options.");
+ pw.println(" reset-multi-window-config");
+ pw.println(" Resets overrides to default values of the multi window config options.");
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index bac1ab1264ab..26cfbdf80681 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -18,6 +18,7 @@ package com.android.server.wm;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.content.res.Configuration.ASSETS_SEQ_UNDEFINED;
import static android.os.Build.VERSION_CODES.Q;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
@@ -1318,6 +1319,11 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
@Override
void resolveOverrideConfiguration(Configuration newParentConfig) {
+ final Configuration requestedOverrideConfig = getRequestedOverrideConfiguration();
+ if (requestedOverrideConfig.assetsSeq != ASSETS_SEQ_UNDEFINED
+ && newParentConfig.assetsSeq > requestedOverrideConfig.assetsSeq) {
+ requestedOverrideConfig.assetsSeq = ASSETS_SEQ_UNDEFINED;
+ }
super.resolveOverrideConfiguration(newParentConfig);
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
// Make sure that we don't accidentally override the activity type.
@@ -1396,6 +1402,28 @@ public class WindowProcessController extends ConfigurationContainer<Configuratio
return mHasPendingConfigurationChange;
}
+ void updateAssetConfiguration(int assetSeq) {
+ // Update the process override configuration directly if the process configuration will
+ // not be override from its activities.
+ if (!mHasActivities || !mIsActivityConfigOverrideAllowed) {
+ Configuration overrideConfig = new Configuration(getRequestedOverrideConfiguration());
+ overrideConfig.assetsSeq = assetSeq;
+ onRequestedOverrideConfigurationChanged(overrideConfig);
+ return;
+ }
+
+ // Otherwise, we can just update the activity override configuration.
+ for (int i = mActivities.size() - 1; i >= 0; i--) {
+ ActivityRecord r = mActivities.get(i);
+ Configuration overrideConfig = new Configuration(r.getRequestedOverrideConfiguration());
+ overrideConfig.assetsSeq = assetSeq;
+ r.onRequestedOverrideConfigurationChanged(overrideConfig);
+ if (r.mVisibleRequested) {
+ r.ensureActivityConfiguration(0, true);
+ }
+ }
+ }
+
/**
* This is called for sending {@link android.app.servertransaction.LaunchActivityItem}.
* The caller must call {@link #setLastReportedConfiguration} if the delivered configuration
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 074eeb942377..9de50585bf67 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7244,6 +7244,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
Objects.requireNonNull(who, "ComponentName is null");
final CallerIdentity caller = getCallerIdentity(who);
Preconditions.checkCallAuthorization(isDeviceOwner(caller));
+ checkAllUsersAreAffiliatedWithDevice();
mInjector.binderWithCleanCallingIdentity(
() -> mInjector.getConnectivityManager().setGlobalProxy(proxyInfo));
}
@@ -15736,6 +15737,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
Objects.requireNonNull(who, "ComponentName is null");
final CallerIdentity caller = getCallerIdentity(who);
Preconditions.checkCallAuthorization(isDeviceOwner(caller));
+ checkAllUsersAreAffiliatedWithDevice();
checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_SET_GLOBAL_PRIVATE_DNS);
switch (mode) {
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index 5299547fef67..36c0a677f43a 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -398,6 +398,15 @@ static long elapsedMcs(Duration start, Duration end) {
return std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
}
+static uint64_t elapsedUsSinceMonoTs(uint64_t monoTsUs) {
+ timespec now;
+ if (clock_gettime(CLOCK_MONOTONIC, &now) != 0) {
+ return 0;
+ }
+ uint64_t nowUs = now.tv_sec * 1000000LL + now.tv_nsec / 1000;
+ return nowUs - monoTsUs;
+}
+
void IncrementalService::onDump(int fd) {
dprintf(fd, "Incremental is %s\n", incfs::enabled() ? "ENABLED" : "DISABLED");
dprintf(fd, "IncFs features: 0x%x\n", int(mIncFs->features()));
@@ -415,6 +424,8 @@ void IncrementalService::onDump(int fd) {
} else {
dprintf(fd, " mountId: %d\n", mnt.mountId);
dprintf(fd, " root: %s\n", mnt.root.c_str());
+ const auto metricsInstanceName = path::basename(ifs->root);
+ dprintf(fd, " metrics instance name: %s\n", path::c_str(metricsInstanceName).get());
dprintf(fd, " nextStorageDirNo: %d\n", mnt.nextStorageDirNo.load());
dprintf(fd, " flags: %d\n", int(mnt.flags));
if (mnt.startLoadingTs.time_since_epoch() == Clock::duration::zero()) {
@@ -444,6 +455,45 @@ void IncrementalService::onDump(int fd) {
dprintf(fd, " kind: %s\n", toString(bind.kind));
}
dprintf(fd, " }\n");
+
+ dprintf(fd, " incfsMetrics: {\n");
+ const auto incfsMetrics = mIncFs->getMetrics(metricsInstanceName);
+ if (incfsMetrics) {
+ dprintf(fd, " readsDelayedMin: %d\n", incfsMetrics.value().readsDelayedMin);
+ dprintf(fd, " readsDelayedMinUs: %lld\n",
+ (long long)incfsMetrics.value().readsDelayedMinUs);
+ dprintf(fd, " readsDelayedPending: %d\n",
+ incfsMetrics.value().readsDelayedPending);
+ dprintf(fd, " readsDelayedPendingUs: %lld\n",
+ (long long)incfsMetrics.value().readsDelayedPendingUs);
+ dprintf(fd, " readsFailedHashVerification: %d\n",
+ incfsMetrics.value().readsFailedHashVerification);
+ dprintf(fd, " readsFailedOther: %d\n", incfsMetrics.value().readsFailedOther);
+ dprintf(fd, " readsFailedTimedOut: %d\n",
+ incfsMetrics.value().readsFailedTimedOut);
+ } else {
+ dprintf(fd, " Metrics not available. Errno: %d\n", errno);
+ }
+ dprintf(fd, " }\n");
+
+ const auto lastReadError = mIncFs->getLastReadError(ifs->control);
+ const auto errorNo = errno;
+ dprintf(fd, " lastReadError: {\n");
+ if (lastReadError) {
+ if (lastReadError->timestampUs == 0) {
+ dprintf(fd, " No read errors.\n");
+ } else {
+ dprintf(fd, " fileId: %s\n",
+ IncFsWrapper::toString(lastReadError->id).c_str());
+ dprintf(fd, " time: %llu microseconds ago\n",
+ (unsigned long long)elapsedUsSinceMonoTs(lastReadError->timestampUs));
+ dprintf(fd, " blockIndex: %d\n", lastReadError->block);
+ dprintf(fd, " errno: %d\n", lastReadError->errorNo);
+ }
+ } else {
+ dprintf(fd, " Info not available. Errno: %d\n", errorNo);
+ }
+ dprintf(fd, " }\n");
}
dprintf(fd, " }\n");
}
@@ -582,7 +632,7 @@ StorageId IncrementalService::createStorage(std::string_view mountPoint,
if (!mkdirOrLog(path::join(backing, ".incomplete"), 0777)) {
return kInvalidStorageId;
}
- auto status = mVold->mountIncFs(backing, mountTarget, 0, &controlParcel);
+ auto status = mVold->mountIncFs(backing, mountTarget, 0, mountKey, &controlParcel);
if (!status.isOk()) {
LOG(ERROR) << "Vold::mountIncFs() failed: " << status.toString8();
return kInvalidStorageId;
@@ -1590,9 +1640,10 @@ void IncrementalService::mountExistingImages(
bool IncrementalService::mountExistingImage(std::string_view root) {
auto mountTarget = path::join(root, constants().mount);
const auto backing = path::join(root, constants().backing);
+ std::string mountKey(path::basename(path::dirname(mountTarget)));
IncrementalFileSystemControlParcel controlParcel;
- auto status = mVold->mountIncFs(backing, mountTarget, 0, &controlParcel);
+ auto status = mVold->mountIncFs(backing, mountTarget, 0, mountKey, &controlParcel);
if (!status.isOk()) {
LOG(ERROR) << "Vold::mountIncFs() failed: " << status.toString8();
return false;
diff --git a/services/incremental/ServiceWrappers.cpp b/services/incremental/ServiceWrappers.cpp
index 0755a22ab2ea..68a28b25b2a4 100644
--- a/services/incremental/ServiceWrappers.cpp
+++ b/services/incremental/ServiceWrappers.cpp
@@ -43,8 +43,9 @@ public:
~RealVoldService() = default;
binder::Status mountIncFs(
const std::string& backingPath, const std::string& targetDir, int32_t flags,
+ const std::string& sysfsName,
os::incremental::IncrementalFileSystemControlParcel* _aidl_return) const final {
- return mInterface->mountIncFs(backingPath, targetDir, flags, _aidl_return);
+ return mInterface->mountIncFs(backingPath, targetDir, flags, sysfsName, _aidl_return);
}
binder::Status unmountIncFs(const std::string& dir) const final {
return mInterface->unmountIncFs(dir);
@@ -261,6 +262,12 @@ public:
return cb(control, id);
});
}
+ std::optional<Metrics> getMetrics(std::string_view sysfsName) const final {
+ return incfs::getMetrics(sysfsName);
+ }
+ std::optional<LastReadError> getLastReadError(const Control& control) const final {
+ return incfs::getLastReadError(control);
+ }
};
static JNIEnv* getOrAttachJniEnv(JavaVM* jvm);
diff --git a/services/incremental/ServiceWrappers.h b/services/incremental/ServiceWrappers.h
index 78e9589e63ff..c0ef7ba5c85b 100644
--- a/services/incremental/ServiceWrappers.h
+++ b/services/incremental/ServiceWrappers.h
@@ -51,6 +51,7 @@ public:
virtual ~VoldServiceWrapper() = default;
virtual binder::Status mountIncFs(
const std::string& backingPath, const std::string& targetDir, int32_t flags,
+ const std::string& sysfsName,
os::incremental::IncrementalFileSystemControlParcel* result) const = 0;
virtual binder::Status unmountIncFs(const std::string& dir) const = 0;
virtual binder::Status bindMount(const std::string& sourceDir,
@@ -79,6 +80,8 @@ public:
using UniqueFd = incfs::UniqueFd;
using WaitResult = incfs::WaitResult;
using Features = incfs::Features;
+ using Metrics = incfs::Metrics;
+ using LastReadError = incfs::LastReadError;
using ExistingMountCallback = android::base::function_ref<
void(std::string_view root, std::string_view backingDir,
@@ -124,6 +127,8 @@ public:
const = 0;
virtual ErrorCode forEachFile(const Control& control, FileCallback cb) const = 0;
virtual ErrorCode forEachIncompleteFile(const Control& control, FileCallback cb) const = 0;
+ virtual std::optional<Metrics> getMetrics(std::string_view sysfsName) const = 0;
+ virtual std::optional<LastReadError> getLastReadError(const Control& control) const = 0;
};
class AppOpsManagerWrapper {
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index 68586a89ff07..da7f0db5efc1 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -49,9 +49,9 @@ namespace android::os::incremental {
class MockVoldService : public VoldServiceWrapper {
public:
- MOCK_CONST_METHOD4(mountIncFs,
+ MOCK_CONST_METHOD5(mountIncFs,
binder::Status(const std::string& backingPath, const std::string& targetDir,
- int32_t flags,
+ int32_t flags, const std::string& sysfsName,
IncrementalFileSystemControlParcel* _aidl_return));
MOCK_CONST_METHOD1(unmountIncFs, binder::Status(const std::string& dir));
MOCK_CONST_METHOD2(bindMount,
@@ -62,16 +62,16 @@ public:
bool, bool));
void mountIncFsFails() {
- ON_CALL(*this, mountIncFs(_, _, _, _))
+ ON_CALL(*this, mountIncFs(_, _, _, _, _))
.WillByDefault(
Return(binder::Status::fromExceptionCode(1, String8("failed to mount"))));
}
void mountIncFsInvalidControlParcel() {
- ON_CALL(*this, mountIncFs(_, _, _, _))
+ ON_CALL(*this, mountIncFs(_, _, _, _, _))
.WillByDefault(Invoke(this, &MockVoldService::getInvalidControlParcel));
}
void mountIncFsSuccess() {
- ON_CALL(*this, mountIncFs(_, _, _, _))
+ ON_CALL(*this, mountIncFs(_, _, _, _, _))
.WillByDefault(Invoke(this, &MockVoldService::incFsSuccess));
}
void bindMountFails() {
@@ -93,12 +93,14 @@ public:
}
binder::Status getInvalidControlParcel(const std::string& imagePath,
const std::string& targetDir, int32_t flags,
+ const std::string& sysfsName,
IncrementalFileSystemControlParcel* _aidl_return) {
_aidl_return = {};
return binder::Status::ok();
}
binder::Status incFsSuccess(const std::string& imagePath, const std::string& targetDir,
- int32_t flags, IncrementalFileSystemControlParcel* _aidl_return) {
+ int32_t flags, const std::string& sysfsName,
+ IncrementalFileSystemControlParcel* _aidl_return) {
_aidl_return->pendingReads.reset(base::unique_fd(dup(STDIN_FILENO)));
_aidl_return->cmd.reset(base::unique_fd(dup(STDIN_FILENO)));
_aidl_return->log.reset(base::unique_fd(dup(STDIN_FILENO)));
@@ -414,6 +416,8 @@ public:
const std::vector<PerUidReadTimeouts>& perUidReadTimeouts));
MOCK_CONST_METHOD2(forEachFile, ErrorCode(const Control& control, FileCallback cb));
MOCK_CONST_METHOD2(forEachIncompleteFile, ErrorCode(const Control& control, FileCallback cb));
+ MOCK_CONST_METHOD1(getMetrics, std::optional<Metrics>(std::string_view path));
+ MOCK_CONST_METHOD1(getLastReadError, std::optional<LastReadError>(const Control& control));
MockIncFs() {
ON_CALL(*this, listExistingMounts(_)).WillByDefault(Return());
diff --git a/services/net/Android.bp b/services/net/Android.bp
index 800f7addbd65..f92db86bb880 100644
--- a/services/net/Android.bp
+++ b/services/net/Android.bp
@@ -52,7 +52,8 @@ java_library {
libs: [
"unsupportedappusage",
"framework-wifi-util-lib",
- "framework-connectivity"
+ "framework-connectivity",
+ "modules-utils-build_system",
],
static_libs: [
// All the classes in netd_aidl_interface must be jarjar so they do not conflict with the
@@ -60,6 +61,7 @@ java_library {
"netd_aidl_interface-V3-java",
"netlink-client",
"networkstack-client",
+ "modules-utils-build_system",
],
apex_available: [
"com.android.wifi",
@@ -80,7 +82,7 @@ filegroup {
],
visibility: [
"//frameworks/base/packages/Tethering",
- "//packages/modules/Connectivity/Tethering"
+ "//packages/modules/Connectivity/Tethering",
],
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
index a8d8a90e8935..96495701811e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/app/GameManagerServiceTests.java
@@ -19,6 +19,7 @@ package com.android.server.app;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -32,8 +33,10 @@ import android.content.ContextWrapper;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
+import android.os.Bundle;
import android.platform.test.annotations.Presubmit;
import android.provider.DeviceConfig;
+import android.util.ArraySet;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
@@ -140,15 +143,19 @@ public class GameManagerServiceTests {
applicationInfo.category = ApplicationInfo.CATEGORY_GAME;
final PackageInfo pi = new PackageInfo();
pi.packageName = mPackageName;
+ pi.applicationInfo = applicationInfo;
final List<PackageInfo> packages = new ArrayList<>();
packages.add(pi);
- when(mMockPackageManager.getInstalledPackages(anyInt())).thenReturn(packages);
+ when(mMockPackageManager.getInstalledPackagesAsUser(anyInt(), anyInt()))
+ .thenReturn(packages);
when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
.thenReturn(applicationInfo);
}
@After
public void tearDown() throws Exception {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.disableCompatScale(mPackageName);
if (mMockingSession != null) {
mMockingSession.finishMocking();
}
@@ -165,57 +172,95 @@ public class GameManagerServiceTests {
}
private void mockDeviceConfigDefault() {
- DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, "").build();
- when(DeviceConfig.getProperties(anyString(), anyString()))
- .thenReturn(properties);
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn("");
}
private void mockDeviceConfigNone() {
- DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_GAME_OVERLAY).build();
- when(DeviceConfig.getProperties(anyString(), anyString()))
- .thenReturn(properties);
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(null);
}
private void mockDeviceConfigPerformance() {
String configString = "mode=2,downscaleFactor=0.5";
- DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
- when(DeviceConfig.getProperties(anyString(), anyString()))
- .thenReturn(properties);
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configString);
}
private void mockDeviceConfigBattery() {
String configString = "mode=3,downscaleFactor=0.7";
- DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
- when(DeviceConfig.getProperties(anyString(), anyString()))
- .thenReturn(properties);
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configString);
}
private void mockDeviceConfigAll() {
String configString = "mode=3,downscaleFactor=0.7:mode=2,downscaleFactor=0.5";
- DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
- when(DeviceConfig.getProperties(anyString(), anyString()))
- .thenReturn(properties);
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configString);
}
private void mockDeviceConfigInvalid() {
String configString = "mode=2,downscaleFactor=0.55";
- DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
- when(DeviceConfig.getProperties(anyString(), anyString()))
- .thenReturn(properties);
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configString);
}
private void mockDeviceConfigMalformed() {
String configString = "adsljckv=nin3rn9hn1231245:8795tq=21ewuydg";
- DeviceConfig.Properties properties = new DeviceConfig.Properties.Builder(
- DeviceConfig.NAMESPACE_GAME_OVERLAY).setString(mPackageName, configString).build();
- when(DeviceConfig.getProperties(anyString(), anyString()))
- .thenReturn(properties);
+ when(DeviceConfig.getProperty(anyString(), anyString()))
+ .thenReturn(configString);
+ }
+
+ private void mockGameModeOptInAll() throws Exception {
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ Bundle metaDataBundle = new Bundle();
+ metaDataBundle.putBoolean(
+ GameManagerService.GamePackageConfiguration.METADATA_PERFORMANCE_MODE_ENABLE, true);
+ metaDataBundle.putBoolean(
+ GameManagerService.GamePackageConfiguration.METADATA_BATTERY_MODE_ENABLE, true);
+ applicationInfo.metaData = metaDataBundle;
+ when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+ .thenReturn(applicationInfo);
+ }
+
+ private void mockGameModeOptInPerformance() throws Exception {
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ Bundle metaDataBundle = new Bundle();
+ metaDataBundle.putBoolean(
+ GameManagerService.GamePackageConfiguration.METADATA_PERFORMANCE_MODE_ENABLE, true);
+ applicationInfo.metaData = metaDataBundle;
+ when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+ .thenReturn(applicationInfo);
+ }
+
+ private void mockGameModeOptInBattery() throws Exception {
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ Bundle metaDataBundle = new Bundle();
+ metaDataBundle.putBoolean(
+ GameManagerService.GamePackageConfiguration.METADATA_BATTERY_MODE_ENABLE, true);
+ applicationInfo.metaData = metaDataBundle;
+ when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+ .thenReturn(applicationInfo);
+ }
+
+ private void mockInterventionAllowDownscaleTrue() throws Exception {
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ Bundle metaDataBundle = new Bundle();
+ metaDataBundle.putBoolean(
+ GameManagerService.GamePackageConfiguration.METADATA_WM_ALLOW_DOWNSCALE, true);
+ applicationInfo.metaData = metaDataBundle;
+ when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+ .thenReturn(applicationInfo);
+ }
+
+ private void mockInterventionAllowDownscaleFalse() throws Exception {
+ final ApplicationInfo applicationInfo = new ApplicationInfo();
+ Bundle metaDataBundle = new Bundle();
+ metaDataBundle.putBoolean(
+ GameManagerService.GamePackageConfiguration.METADATA_WM_ALLOW_DOWNSCALE, false);
+ applicationInfo.metaData = metaDataBundle;
+ when(mMockPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), anyInt()))
+ .thenReturn(applicationInfo);
}
/**
@@ -353,136 +398,209 @@ public class GameManagerServiceTests {
gameManagerService.getGameMode(mPackageName, USER_ID_2));
}
+ private void checkReportedModes(int ...requiredModes) {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ ArraySet<Integer> reportedModes = new ArraySet<>();
+ int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
+ for (int mode : modes) {
+ reportedModes.add(mode);
+ }
+ assertEquals(requiredModes.length, reportedModes.size());
+ for (int requiredMode : reportedModes) {
+ assertTrue("Required game mode not supported: " + requiredMode,
+ reportedModes.contains(requiredMode));
+ }
+ }
+
+ private void checkDownscaling(int gameMode, String scaling) {
+ GameManagerService gameManagerService = new GameManagerService(mMockContext);
+ gameManagerService.onUserStarting(USER_ID_1);
+ gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ GameManagerService.GamePackageConfiguration config =
+ gameManagerService.getConfig(mPackageName);
+ assertEquals(config.getGameModeConfiguration(gameMode).getScaling(), scaling);
+ }
+
/**
- * Phonesky device config exists, but is only propagating the default value.
+ * Phenotype device config exists, but is only propagating the default value.
*/
@Test
public void testDeviceConfigDefault() {
mockDeviceConfigDefault();
mockModifyGameModeGranted();
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.loadDeviceConfigLocked();
-
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- assertEquals(modes.length, 1);
- assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ checkReportedModes(GameManager.GAME_MODE_UNSUPPORTED);
}
/**
- * Phonesky device config does not exists.
+ * Phenotype device config does not exists.
*/
@Test
public void testDeviceConfigNone() {
mockDeviceConfigNone();
mockModifyGameModeGranted();
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.loadDeviceConfigLocked();
-
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- assertEquals(modes.length, 1);
- assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ checkReportedModes(GameManager.GAME_MODE_UNSUPPORTED);
}
/**
- * Phonesky device config for performance mode exists and is valid.
+ * Phenotype device config for performance mode exists and is valid.
*/
@Test
public void testDeviceConfigPerformance() {
mockDeviceConfigPerformance();
mockModifyGameModeGranted();
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.loadDeviceConfigLocked();
-
- boolean perfModeExists = false;
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- for (int mode : modes) {
- if (mode == GameManager.GAME_MODE_PERFORMANCE) {
- perfModeExists = true;
- }
- }
- assertEquals(modes.length, 1);
- assertTrue(perfModeExists);
+ checkReportedModes(GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD);
}
/**
- * Phonesky device config for battery mode exists and is valid.
+ * Phenotype device config for battery mode exists and is valid.
*/
@Test
public void testDeviceConfigBattery() {
mockDeviceConfigBattery();
mockModifyGameModeGranted();
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.loadDeviceConfigLocked();
-
- boolean batteryModeExists = false;
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- for (int mode : modes) {
- if (mode == GameManager.GAME_MODE_BATTERY) {
- batteryModeExists = true;
- }
- }
- assertEquals(modes.length, 1);
- assertTrue(batteryModeExists);
+ checkReportedModes(GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD);
}
/**
- * Phonesky device configs for both battery and performance modes exists and are valid.
+ * Phenotype device configs for both battery and performance modes exists and are valid.
*/
@Test
public void testDeviceConfigAll() {
mockDeviceConfigAll();
mockModifyGameModeGranted();
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.loadDeviceConfigLocked();
-
- boolean batteryModeExists = false;
- boolean perfModeExists = false;
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- for (int mode : modes) {
- if (mode == GameManager.GAME_MODE_BATTERY) {
- batteryModeExists = true;
- } else if (mode == GameManager.GAME_MODE_PERFORMANCE) {
- perfModeExists = true;
- }
- }
- assertTrue(batteryModeExists);
- assertTrue(perfModeExists);
+ checkReportedModes(GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD);
}
/**
- * Phonesky device config contains values that parse correctly but are not valid in game mode.
+ * Phenotype device config contains values that parse correctly but are not valid in game mode.
*/
@Test
public void testDeviceConfigInvalid() {
mockDeviceConfigInvalid();
mockModifyGameModeGranted();
- GameManagerService gameManagerService = new GameManagerService(mMockContext);
- gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.loadDeviceConfigLocked();
-
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- assertEquals(modes.length, 1);
- assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ checkReportedModes(GameManager.GAME_MODE_UNSUPPORTED);
}
/**
- * Phonesky device config is garbage.
+ * Phenotype device config is garbage.
*/
@Test
public void testDeviceConfigMalformed() {
mockDeviceConfigMalformed();
mockModifyGameModeGranted();
+ checkReportedModes(GameManager.GAME_MODE_UNSUPPORTED);
+ }
+
+ /**
+ * Game modes are made available only through app manifest opt-in.
+ */
+ @Test
+ public void testGameModeOptInAll() throws Exception {
+ mockGameModeOptInAll();
+ mockDeviceConfigNone();
+ mockModifyGameModeGranted();
+ checkReportedModes(GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD);
+ }
+
+ /**
+ * BATTERY game mode is available through the app manifest opt-in.
+ */
+ @Test
+ public void testGameModeOptInBattery() throws Exception {
+ mockGameModeOptInBattery();
+ mockDeviceConfigNone();
+ mockModifyGameModeGranted();
+ checkReportedModes(GameManager.GAME_MODE_BATTERY, GameManager.GAME_MODE_STANDARD);
+ }
+
+ /**
+ * PERFORMANCE game mode is available through the app manifest opt-in.
+ */
+ @Test
+ public void testGameModeOptInPerformance() throws Exception {
+ mockGameModeOptInPerformance();
+ mockDeviceConfigNone();
+ mockModifyGameModeGranted();
+ checkReportedModes(GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_STANDARD);
+ }
+
+ /**
+ * BATTERY game mode is available through the app manifest opt-in and PERFORMANCE game mode is
+ * available through Phenotype.
+ */
+ @Test
+ public void testGameModeOptInBatteryMixed() throws Exception {
+ mockGameModeOptInBattery();
+ mockDeviceConfigPerformance();
+ mockModifyGameModeGranted();
+ checkReportedModes(GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD);
+ }
+
+ /**
+ * PERFORMANCE game mode is available through the app manifest opt-in and BATTERY game mode is
+ * available through Phenotype.
+ */
+ @Test
+ public void testGameModeOptInPerformanceMixed() throws Exception {
+ mockGameModeOptInPerformance();
+ mockDeviceConfigBattery();
+ mockModifyGameModeGranted();
+ checkReportedModes(GameManager.GAME_MODE_PERFORMANCE, GameManager.GAME_MODE_BATTERY,
+ GameManager.GAME_MODE_STANDARD);
+ }
+
+ /**
+ * PERFORMANCE game mode is configured through Phenotype. The app hasn't specified any metadata.
+ */
+ @Test
+ public void testInterventionAllowScalingDefault() throws Exception {
+ mockDeviceConfigPerformance();
+ mockModifyGameModeGranted();
+ checkDownscaling(GameManager.GAME_MODE_PERFORMANCE, "0.5");
+ }
+
+ /**
+ * PERFORMANCE game mode is configured through Phenotype. The app has opted-out of scaling.
+ */
+ @Test
+ public void testInterventionAllowDownscaleFalse() throws Exception {
+ mockDeviceConfigPerformance();
+ mockInterventionAllowDownscaleFalse();
+ mockModifyGameModeGranted();
+ checkDownscaling(GameManager.GAME_MODE_PERFORMANCE, "1.0");
+ }
+
+ /**
+ * PERFORMANCE game mode is configured through Phenotype. The app has redundantly specified
+ * the downscaling metadata default value of "true".
+ */
+ @Test
+ public void testInterventionAllowDownscaleTrue() throws Exception {
+ mockDeviceConfigPerformance();
+ mockInterventionAllowDownscaleTrue();
+ mockModifyGameModeGranted();
+ checkDownscaling(GameManager.GAME_MODE_PERFORMANCE, "0.5");
+ }
+
+ /**
+ * PERFORMANCE game mode is configured through Phenotype, but the app has also opted into the
+ * same mode. No interventions for this game mode should be available in this case.
+ */
+ @Test
+ public void testDeviceConfigOptInOverlap() throws Exception {
+ mockDeviceConfigPerformance();
+ mockGameModeOptInPerformance();
+ mockModifyGameModeGranted();
GameManagerService gameManagerService = new GameManagerService(mMockContext);
gameManagerService.onUserStarting(USER_ID_1);
- gameManagerService.loadDeviceConfigLocked();
-
- int[] modes = gameManagerService.getAvailableGameModes(mPackageName);
- assertEquals(modes.length, 1);
- assertEquals(modes[0], GameManager.GAME_MODE_UNSUPPORTED);
+ gameManagerService.updateConfigsForUser(USER_ID_1, mPackageName);
+ GameManagerService.GamePackageConfiguration config =
+ gameManagerService.getConfig(mPackageName);
+ assertNull(config.getGameModeConfiguration(GameManager.GAME_MODE_PERFORMANCE));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index 1b42dfa0712e..c54dffc3c431 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -30,6 +30,7 @@ import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_HIGH;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_LOW;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_MEDIUM;
import static android.app.admin.DevicePolicyManager.PASSWORD_COMPLEXITY_NONE;
+import static android.app.admin.DevicePolicyManager.PRIVATE_DNS_SET_NO_ERROR;
import static android.app.admin.DevicePolicyManager.WIPE_EUICC;
import static android.app.admin.PasswordMetrics.computeForPasswordOrPin;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
@@ -7333,6 +7334,48 @@ public class DevicePolicyManagerTest extends DpmTestBase {
assertThat(dpm.getPolicyExemptApps()).containsExactly("4", "8", "15", "16", "23", "42");
}
+ @Test
+ public void testSetGlobalPrivateDnsModeOpportunistic_asDeviceOwner() throws Exception {
+ setDeviceOwner();
+ // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
+ // feature is disabled because there are non-affiliated secondary users.
+ getServices().removeUser(CALLER_USER_HANDLE);
+ clearInvocations(getServices().settings);
+
+ int result = dpm.setGlobalPrivateDnsModeOpportunistic(admin1);
+
+ assertThat(result).isEqualTo(PRIVATE_DNS_SET_NO_ERROR);
+ }
+
+ @Test
+ public void testSetGlobalPrivateDnsModeOpportunistic_hasUnaffiliatedUsers() throws Exception {
+ setDeviceOwner();
+ setAsProfileOwner(admin2);
+
+ assertThrows(SecurityException.class,
+ () -> dpm.setGlobalPrivateDnsModeOpportunistic(admin1));
+ }
+
+ @Test
+ public void testSetRecommendedGlobalProxy_asDeviceOwner() throws Exception {
+ setDeviceOwner();
+ // setUp() adds a secondary user for CALLER_USER_HANDLE. Remove it as otherwise the
+ // feature is disabled because there are non-affiliated secondary users.
+ getServices().removeUser(CALLER_USER_HANDLE);
+
+ dpm.setRecommendedGlobalProxy(admin1, null);
+
+ verify(getServices().connectivityManager).setGlobalProxy(null);
+ }
+
+ @Test
+ public void testSetRecommendedGlobalProxy_hasUnaffiliatedUsers() throws Exception {
+ setDeviceOwner();
+ setAsProfileOwner(admin2);
+
+ assertThrows(SecurityException.class, () -> dpm.setRecommendedGlobalProxy(admin1, null));
+ }
+
private void setUserUnlocked(int userHandle, boolean unlocked) {
when(getServices().userManager.isUserUnlocked(eq(userHandle))).thenReturn(unlocked);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java b/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
index 153938cbbbf1..b2c300255aef 100644
--- a/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/WatchedIntentHandlingTest.java
@@ -18,6 +18,7 @@ package com.android.server.pm;
import static org.junit.Assert.assertTrue;
+import android.content.ComponentName;
import android.content.IntentFilter;
import androidx.test.filters.SmallTest;
@@ -83,4 +84,80 @@ public class WatchedIntentHandlingTest {
watcher.verifyNoChangeReported("pulled snapshot");
}
+ @Test
+ public void testPreferredActivity() {
+ // Create a bunch of nondescript component names
+ ComponentName component = new ComponentName("Package_A", "Class_A");
+ ComponentName[] components = new ComponentName[10];
+ for (int i = 0; i < components.length; i++) {
+ components[i] = new ComponentName("Package_" + i, "Class_" + i);
+ }
+ IntentFilter i = new IntentFilter("TEST_ACTION");
+ PreferredActivity a = new PreferredActivity(i, 1, components, component, true);
+ final WatchableTester watcher = new WatchableTester(a, "PreferredIntentResolver");
+ watcher.register();
+
+ // Verify that the initial IntentFilter and the PreferredActivity are truly
+ // independent. This is in addition to verifying that the PreferredActivity
+ // properly reports its changes.
+ i.setPriority(i.getPriority() + 1);
+ watcher.verifyNoChangeReported("indepenent intent");
+ a.setPriority(a.getPriority() + 2);
+ watcher.verifyChangeReported("dependent intent");
+ // Verify independence of i and a
+ assertTrue(i.getPriority() != a.getPriority());
+
+ // Verify that snapshots created from the PreferredActivity are stable when the
+ // source PreferredActivity changes.
+ a.setPriority(3);
+ watcher.verifyChangeReported("initialize intent priority");
+ PreferredActivity s1 = a.snapshot();
+ watcher.verifyNoChangeReported("pulled snapshot");
+ // Verify snapshot cache. In the absence of changes to the PreferredActivity, the
+ // snapshot will not be rebuilt and will be the exact same object as before.
+ assertTrue(s1 == a.snapshot());
+ // Force a change by incrementing the priority. The next snapshot must be
+ // different from the first snapshot.
+ a.setPriority(a.getPriority() + 1);
+ watcher.verifyChangeReported("increment priority");
+ PreferredActivity s2 = a.snapshot();
+ watcher.verifyNoChangeReported("pulled second snapshot");
+ assertTrue(s1 != s2);
+ // Assert the two snapshots are different. s1 should have priority 3 and s2
+ // should have priority 4. s2 should match the current value in a.
+ assertTrue(a.getPriority() == s2.getPriority());
+ assertTrue(s1.getPriority() != s2.getPriority());
+ }
+
+ @Test
+ public void testPreferredIntentResolver() {
+ PreferredIntentResolver r = new PreferredIntentResolver();
+ final WatchableTester watcher = new WatchableTester(r, "PreferredIntentResolver");
+ watcher.register();
+ // Create a bunch of nondescript component names
+ ComponentName component = new ComponentName("Package_A", "Class_A");
+ ComponentName[] components = new ComponentName[10];
+ for (int i = 0; i < components.length; i++) {
+ components[i] = new ComponentName("Package_" + i, "Class_" + i);
+ }
+ IntentFilter i = new IntentFilter("TEST_ACTION");
+ PreferredActivity a1 = new PreferredActivity(i, 1, components, component, true);
+
+ r.addFilter(a1);
+ watcher.verifyChangeReported("addFilter");
+ i.setPriority(i.getPriority() + 1);
+ watcher.verifyNoChangeReported("indepenent intent");
+ a1.setPriority(a1.getPriority() + 1);
+ watcher.verifyChangeReported("dependent intent");
+
+ PreferredActivity s1 = a1.snapshot();
+ watcher.verifyNoChangeReported("pulled snapshot");
+ // Verify snapshot cache.
+ assertTrue(s1 == a1.snapshot());
+ a1.setPriority(a1.getPriority() + 1);
+ watcher.verifyChangeReported("increment priority");
+ PreferredActivity s2 = a1.snapshot();
+ watcher.verifyNoChangeReported("pulled second snapshot");
+ assertTrue(s1.getPriority() != s2.getPriority());
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/OrdinalGeneratorTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/OrdinalGeneratorTest.java
index af954d599334..3fdac66225a8 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/OrdinalGeneratorTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/OrdinalGeneratorTest.java
@@ -25,13 +25,14 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import java.util.Arrays;
+import java.util.function.Function;
@RunWith(AndroidJUnit4.class)
public class OrdinalGeneratorTest {
@Test
- public void testOrdinal() {
- OrdinalGenerator<String> ordinalGenerator = new OrdinalGenerator<>();
+ public void testOrdinal_withIdentityFunction() {
+ OrdinalGenerator<String> ordinalGenerator = new OrdinalGenerator<>(Function.identity());
int oneOrd = ordinalGenerator.ordinal("One");
int twoOrd = ordinalGenerator.ordinal("Two");
assertNotEquals(oneOrd, twoOrd);
@@ -45,8 +46,8 @@ public class OrdinalGeneratorTest {
}
@Test
- public void testOrdinals() {
- OrdinalGenerator<String> ordinalGenerator = new OrdinalGenerator<>();
+ public void testOrdinals_withIdentityFunction() {
+ OrdinalGenerator<String> ordinalGenerator = new OrdinalGenerator<>(Function.identity());
int[] oneTwoOrds = ordinalGenerator.ordinals(Arrays.asList("One", "Two"));
int[] twoThreeOrds = ordinalGenerator.ordinals(Arrays.asList("Two", "Three"));
assertEquals(oneTwoOrds[0], ordinalGenerator.ordinal("One"));
@@ -54,4 +55,33 @@ public class OrdinalGeneratorTest {
assertEquals(twoThreeOrds[0], ordinalGenerator.ordinal("Two"));
assertEquals(twoThreeOrds[1], ordinalGenerator.ordinal("Three"));
}
+
+ @Test
+ public void testOrdinal_withCanonicalizationFunction() {
+ OrdinalGenerator<String> ordinalGenerator = new OrdinalGenerator<>(String::toLowerCase);
+
+ int oneOrd = ordinalGenerator.ordinal("One");
+ int twoOrd = ordinalGenerator.ordinal("Two");
+ assertNotEquals(oneOrd, twoOrd);
+
+ assertEquals(oneOrd, ordinalGenerator.ordinal("ONE"));
+ assertEquals(twoOrd, ordinalGenerator.ordinal("two"));
+
+ int threeOrd = ordinalGenerator.ordinal("Three");
+ assertNotEquals(oneOrd, threeOrd);
+ assertNotEquals(twoOrd, threeOrd);
+ }
+
+ @Test
+ public void testOrdinals_withCanonicalizationFunction() {
+ OrdinalGenerator<String> ordinalGenerator = new OrdinalGenerator<>(String::toLowerCase);
+
+ int[] oneTwoOrds = ordinalGenerator.ordinals(Arrays.asList("One", "Two"));
+ int[] twoThreeOrds = ordinalGenerator.ordinals(Arrays.asList("Two", "Three"));
+
+ assertEquals(oneTwoOrds[0], ordinalGenerator.ordinal("ONE"));
+ assertEquals(oneTwoOrds[1], ordinalGenerator.ordinal("two"));
+ assertEquals(twoThreeOrds[0], ordinalGenerator.ordinal("TWO"));
+ assertEquals(twoThreeOrds[1], ordinalGenerator.ordinal("threE"));
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneCanonicalizerTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneCanonicalizerTest.java
new file mode 100644
index 000000000000..0c78f5b85fac
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneCanonicalizerTest.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2021 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.timezonedetector;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class TimeZoneCanonicalizerTest {
+
+ TimeZoneCanonicalizer mFunction = new TimeZoneCanonicalizer();
+
+ @Test
+ public void deprecatedTimeZonesAreEqualToCanonical() {
+ assertThat(mFunction.apply("America/Godthab")).isEqualTo("America/Nuuk");
+ assertThat(mFunction.apply("Australia/Currie")).isEqualTo("Australia/Hobart");
+ }
+
+ @Test
+ public void wellKnownCanonicalIDs() {
+ assertThat(mFunction.apply("America/Detroit")).isEqualTo("America/Detroit");
+ assertThat(mFunction.apply("Europe/London")).isEqualTo("Europe/London");
+ assertThat(mFunction.apply("America/New_York")).isEqualTo("America/New_York");
+ assertThat(mFunction.apply("Europe/Volgograd")).isEqualTo("Europe/Volgograd");
+ }
+
+ @Test
+ public void timeZonesAsGmtOffsetsTreatedAsCanonical() {
+ assertThat(mFunction.apply("Etc/GMT-11")).isEqualTo("Etc/GMT-11");
+ }
+
+ @Test
+ public void nonExistingOneMappedToThemselves() {
+ assertThat(mFunction.apply("Mars/Base")).isEqualTo("Mars/Base");
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
index 47475a66c0d5..331f76cf7dc2 100644
--- a/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/timezonedetector/TimeZoneDetectorStrategyImplTest.java
@@ -56,6 +56,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Function;
/**
* White-box unit tests for {@link TimeZoneDetectorStrategyImpl}.
@@ -1008,7 +1009,7 @@ public class TimeZoneDetectorStrategyImplTest {
// Check the various feature state values are what we expect.
assertFeatureStateMatchesConfig(expectedInternalConfig, actualState, expectedDetectionMode);
- OrdinalGenerator<String> tzIdOrdinalGenerator = new OrdinalGenerator<>();
+ OrdinalGenerator<String> tzIdOrdinalGenerator = new OrdinalGenerator<>(Function.identity());
MetricsTimeZoneDetectorState expectedState =
MetricsTimeZoneDetectorState.create(
tzIdOrdinalGenerator, expectedInternalConfig, expectedDeviceTimeZoneId,
diff --git a/services/tests/servicestests/src/com/android/server/utils/OWNERS b/services/tests/servicestests/src/com/android/server/utils/OWNERS
new file mode 100644
index 000000000000..1853220b9433
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/utils/OWNERS
@@ -0,0 +1,4 @@
+per-file WatchableTester.java = file:/services/core/java/com/android/server/pm/OWNERS
+per-file WatchableTester.java = shombert@google.com
+per-file WatcherTest.java = file:/services/core/java/com/android/server/pm/OWNERS
+per-file WatcherTest.java = shombert@google.com
diff --git a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
index f255c67cf47d..9679e58c4e7d 100644
--- a/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
+++ b/services/tests/servicestests/src/com/android/server/utils/WatcherTest.java
@@ -916,5 +916,14 @@ public class WatcherTest {
assertTrue(s1 != s2);
assertTrue(leafA.get() == s1.get() + 1);
assertTrue(leafA.get() == s2.get());
+
+ // Test sealed snapshots
+ SnapshotCache<Leaf> sealed = new SnapshotCache.Sealed();
+ try {
+ Leaf x1 = sealed.snapshot();
+ fail(name + " sealed snapshot did not throw");
+ } catch (UnsupportedOperationException e) {
+ // This is the passing scenario - the exception is expected.
+ }
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
index a05fea2c8f70..1126e1ece452 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ArchiveTest.java
@@ -21,6 +21,8 @@ import static android.service.notification.NotificationListenerService.REASON_CA
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.fail;
+
import android.app.Notification;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
@@ -37,7 +39,11 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.ConcurrentModificationException;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -165,4 +171,54 @@ public class ArchiveTest extends UiServiceTestCase {
assertThat(expected).contains(sbn.getKey());
}
}
+
+ @Test
+ public void testRemoveChannelNotifications_concurrently() throws InterruptedException {
+ List<String> expected = new ArrayList<>();
+ // Add one extra notification to the beginning to test when 2 adjacent notifications will be
+ // removed in the same pass.
+ StatusBarNotification sbn0 = getNotification("pkg", 0, UserHandle.of(USER_CURRENT));
+ mArchive.record(sbn0, REASON_CANCEL);
+ for (int i = 0; i < SIZE; i++) {
+ StatusBarNotification sbn = getNotification("pkg", i, UserHandle.of(USER_CURRENT));
+ mArchive.record(sbn, REASON_CANCEL);
+ if (i >= SIZE - 2) {
+ // Remove everything < SIZE - 2
+ expected.add(sbn.getKey());
+ }
+ }
+
+ // Remove these in multiple threads to try to get them to happen at the same time
+ int numThreads = SIZE - 2;
+ AtomicBoolean error = new AtomicBoolean(false);
+ CountDownLatch startThreadsLatch = new CountDownLatch(1);
+ CountDownLatch threadsDone = new CountDownLatch(numThreads);
+ for (int i = 0; i < numThreads; i++) {
+ final int idx = i;
+ new Thread(() -> {
+ try {
+ startThreadsLatch.await(10, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ throw new RuntimeException(e);
+ }
+ try {
+ mArchive.removeChannelNotifications("pkg", USER_CURRENT, "test" + idx);
+ } catch (ConcurrentModificationException e) {
+ error.compareAndSet(false, true);
+ }
+ }).start();
+ }
+
+ startThreadsLatch.countDown();
+ threadsDone.await(10, TimeUnit.SECONDS);
+ if (error.get()) {
+ fail("Concurrent modification exception");
+ }
+
+ List<StatusBarNotification> actual = Arrays.asList(mArchive.getArray(SIZE, true));
+ assertThat(actual).hasSize(expected.size());
+ for (StatusBarNotification sbn : actual) {
+ assertThat(expected).contains(sbn.getKey());
+ }
+ }
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 537bc2c7d52c..c33287c57377 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -141,6 +141,7 @@ import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Parcel;
import android.os.Process;
import android.os.RemoteException;
@@ -267,6 +268,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
RankingHandler mRankingHandler;
@Mock
ActivityManagerInternal mAmi;
+ @Mock
+ private Looper mMainLooper;
@Mock
IIntentSender pi1;
@@ -514,7 +517,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mAppUsageStats, mock(DevicePolicyManagerInternal.class), mUgm, mUgmInternal,
mAppOpsManager, mUm, mHistoryManager, mStatsManager, mock(TelephonyManager.class),
mAmi, mToastRateLimiter);
- mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
+ // Return first true for RoleObserver main-thread check
+ when(mMainLooper.isCurrentThread()).thenReturn(true).thenReturn(false);
+ mService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY, mMainLooper);
mService.setAudioManager(mAudioManager);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
index 4ce237e3aadc..27ae46c87b28 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/RoleObserverTest.java
@@ -16,6 +16,7 @@
package com.android.server.notification;
+import static android.app.role.RoleManager.ROLE_BROWSER;
import static android.app.role.RoleManager.ROLE_DIALER;
import static android.app.role.RoleManager.ROLE_EMERGENCY;
import static android.content.pm.PackageManager.MATCH_ALL;
@@ -23,6 +24,7 @@ import static android.content.pm.PackageManager.MATCH_ALL;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
+import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
@@ -31,6 +33,8 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static java.util.Arrays.asList;
+
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppOpsManager;
@@ -44,7 +48,6 @@ import android.companion.ICompanionDeviceManager;
import android.content.Context;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.os.Looper;
import android.os.UserHandle;
import android.os.UserManager;
@@ -80,7 +83,6 @@ import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
import java.util.List;
-import java.util.concurrent.Executor;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -98,13 +100,13 @@ public class RoleObserverTest extends UiServiceTestCase {
@Mock
private UserManager mUm;
@Mock
- private Executor mExecutor;
- @Mock
private RoleManager mRoleManager;
+ @Mock
+ private Looper mMainLooper;
NotificationRecordLoggerFake mNotificationRecordLogger = new NotificationRecordLoggerFake();
private InstanceIdSequence mNotificationInstanceIdSequence = new InstanceIdSequenceFake(
1 << 30);
- private List<UserInfo> mUsers;
+ private List<UserHandle> mUsers;
private static class TestableNotificationManagerService extends NotificationManagerService {
TestableNotificationManagerService(Context context,
@@ -133,13 +135,15 @@ public class RoleObserverTest extends UiServiceTestCase {
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
mUsers = new ArrayList<>();
- mUsers.add(new UserInfo(0, "system", 0));
- mUsers.add(new UserInfo(10, "second", 0));
- when(mUm.getUsers()).thenReturn(mUsers);
+ mUsers.add(new UserHandle(0));
+ mUsers.add(new UserHandle(10));
+ when(mUm.getUserHandles(anyBoolean())).thenReturn(mUsers);
+
+ when(mMainLooper.isCurrentThread()).thenReturn(true);
mService = new TestableNotificationManagerService(mContext, mNotificationRecordLogger,
mNotificationInstanceIdSequence);
- mRoleObserver = mService.new RoleObserver(mRoleManager, mPm, mExecutor);
+ mRoleObserver = mService.new RoleObserver(mContext, mRoleManager, mPm, mMainLooper);
try {
mService.init(mService.new WorkerHandler(mock(Looper.class)),
@@ -174,7 +178,7 @@ public class RoleObserverTest extends UiServiceTestCase {
}
@Test
- public void testInit() throws Exception {
+ public void testInit_forNonBlockableDefaultApps() throws Exception {
List<String> dialer0 = new ArrayList<>();
dialer0.add("dialer");
List<String> emer0 = new ArrayList<>();
@@ -191,29 +195,29 @@ public class RoleObserverTest extends UiServiceTestCase {
when(mRoleManager.getRoleHoldersAsUser(
ROLE_DIALER,
- mUsers.get(0).getUserHandle())).
- thenReturn(dialer0);
+ mUsers.get(0)))
+ .thenReturn(dialer0);
when(mRoleManager.getRoleHoldersAsUser(
ROLE_EMERGENCY,
- mUsers.get(0).getUserHandle())).
- thenReturn(emer0);
+ mUsers.get(0)))
+ .thenReturn(emer0);
mRoleObserver.init();
// verify internal records of current state of the world
assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(
- ROLE_DIALER, dialer0.get(0), mUsers.get(0).id));
+ ROLE_DIALER, dialer0.get(0), mUsers.get(0).getIdentifier()));
assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
- ROLE_DIALER, dialer0.get(0), mUsers.get(1).id));
+ ROLE_DIALER, dialer0.get(0), mUsers.get(1).getIdentifier()));
assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(
- ROLE_EMERGENCY, emer0.get(0), mUsers.get(0).id));
+ ROLE_EMERGENCY, emer0.get(0), mUsers.get(0).getIdentifier()));
assertFalse(mRoleObserver.isApprovedPackageForRoleForUser(
- ROLE_EMERGENCY, emer0.get(0), mUsers.get(1).id));
+ ROLE_EMERGENCY, emer0.get(0), mUsers.get(1).getIdentifier()));
// make sure we're listening to updates
verify(mRoleManager, times(1)).addOnRoleHoldersChangedListenerAsUser(
- eq(mExecutor), any(), eq(UserHandle.ALL));
+ any(), any(), eq(UserHandle.ALL));
// make sure we told pref helper about the state of the world
verify(mPreferencesHelper, times(1)).updateDefaultApps(0, null, dialer0Pair);
@@ -221,14 +225,31 @@ public class RoleObserverTest extends UiServiceTestCase {
}
@Test
- public void testSwapDefault() throws Exception {
+ public void testInit_forTrampolines() throws Exception {
+ when(mPm.getPackageUid("com.browser", MATCH_ALL, 0)).thenReturn(30);
+ when(mRoleManager.getRoleHoldersAsUser(
+ ROLE_BROWSER,
+ mUsers.get(0)))
+ .thenReturn(asList("com.browser"));
+
+ mRoleObserver.init();
+
+ assertTrue(mRoleObserver.isUidExemptFromTrampolineRestrictions(30));
+
+ // make sure we're listening to updates
+ verify(mRoleManager, times(1)).addOnRoleHoldersChangedListenerAsUser(any(), any(),
+ eq(UserHandle.ALL));
+ }
+
+ @Test
+ public void testSwapDefault_forNonBlockableDefaultApps() throws Exception {
List<String> dialer0 = new ArrayList<>();
dialer0.add("dialer");
when(mRoleManager.getRoleHoldersAsUser(
ROLE_DIALER,
- mUsers.get(0).getUserHandle())).
- thenReturn(dialer0);
+ mUsers.get(0)))
+ .thenReturn(dialer0);
mRoleObserver.init();
@@ -241,8 +262,8 @@ public class RoleObserverTest extends UiServiceTestCase {
when(mRoleManager.getRoleHoldersAsUser(
ROLE_DIALER,
- mUsers.get(0).getUserHandle())).
- thenReturn(newDefault);
+ mUsers.get(0)))
+ .thenReturn(newDefault);
mRoleObserver.onRoleHoldersChanged(ROLE_DIALER, UserHandle.of(0));
@@ -251,15 +272,39 @@ public class RoleObserverTest extends UiServiceTestCase {
}
@Test
- public void testSwapDefault_multipleOverlappingApps() throws Exception {
+ public void testSwapDefault_forTrampolines() throws Exception {
+ List<String> dialer0 = new ArrayList<>();
+ when(mPm.getPackageUid("com.browser", MATCH_ALL, 0)).thenReturn(30);
+ when(mPm.getPackageUid("com.browser2", MATCH_ALL, 0)).thenReturn(31);
+ when(mRoleManager.getRoleHoldersAsUser(
+ ROLE_BROWSER,
+ mUsers.get(0)))
+ .thenReturn(asList("com.browser"));
+ mRoleObserver.init();
+ assertTrue(mRoleObserver.isUidExemptFromTrampolineRestrictions(30));
+ assertFalse(mRoleObserver.isUidExemptFromTrampolineRestrictions(31));
+ // Default changed
+ when(mRoleManager.getRoleHoldersAsUser(
+ ROLE_BROWSER,
+ mUsers.get(0)))
+ .thenReturn(asList("com.browser2"));
+ mRoleObserver.onRoleHoldersChanged(ROLE_BROWSER, UserHandle.of(0));
+
+ assertFalse(mRoleObserver.isUidExemptFromTrampolineRestrictions(30));
+ assertTrue(mRoleObserver.isUidExemptFromTrampolineRestrictions(31));
+ }
+
+ @Test
+ public void testSwapDefault_multipleOverlappingApps_forNonBlockableDefaultApps()
+ throws Exception {
List<String> dialer0 = new ArrayList<>();
dialer0.add("dialer");
dialer0.add("phone");
when(mRoleManager.getRoleHoldersAsUser(
ROLE_DIALER,
- mUsers.get(0).getUserHandle())).
- thenReturn(dialer0);
+ mUsers.get(0)))
+ .thenReturn(dialer0);
mRoleObserver.init();
@@ -273,8 +318,8 @@ public class RoleObserverTest extends UiServiceTestCase {
when(mRoleManager.getRoleHoldersAsUser(
ROLE_DIALER,
- mUsers.get(0).getUserHandle())).
- thenReturn(newDefault);
+ mUsers.get(0)))
+ .thenReturn(newDefault);
ArraySet<String> expectedRemove = new ArraySet<>();
expectedRemove.add("dialer");
@@ -294,14 +339,14 @@ public class RoleObserverTest extends UiServiceTestCase {
}
@Test
- public void testSwapDefault_newUser() throws Exception {
+ public void testSwapDefault_newUser_forNonBlockableDefaultApps() throws Exception {
List<String> dialer0 = new ArrayList<>();
dialer0.add("dialer");
when(mRoleManager.getRoleHoldersAsUser(
ROLE_DIALER,
- mUsers.get(0).getUserHandle())).
- thenReturn(dialer0);
+ mUsers.get(0)))
+ .thenReturn(dialer0);
mRoleObserver.init();
@@ -310,8 +355,8 @@ public class RoleObserverTest extends UiServiceTestCase {
when(mRoleManager.getRoleHoldersAsUser(
ROLE_DIALER,
- mUsers.get(1).getUserHandle())).
- thenReturn(dialer10);
+ mUsers.get(1)))
+ .thenReturn(dialer10);
ArraySet<Pair<String, Integer>> expectedAddPair = new ArraySet<>();
expectedAddPair.add(new Pair("phone", 30));
@@ -329,4 +374,27 @@ public class RoleObserverTest extends UiServiceTestCase {
assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "phone", 10));
assertTrue(mRoleObserver.isApprovedPackageForRoleForUser(ROLE_DIALER, "dialer", 0));
}
+
+ @Test
+ public void testSwapDefault_newUser_forTrampolines() throws Exception {
+ List<String> dialer0 = new ArrayList<>();
+ when(mPm.getPackageUid("com.browser", MATCH_ALL, 0)).thenReturn(30);
+ when(mPm.getPackageUid("com.browser2", MATCH_ALL, 10)).thenReturn(1031);
+ when(mRoleManager.getRoleHoldersAsUser(
+ ROLE_BROWSER,
+ mUsers.get(0)))
+ .thenReturn(asList("com.browser"));
+ mRoleObserver.init();
+ assertTrue(mRoleObserver.isUidExemptFromTrampolineRestrictions(30));
+ assertFalse(mRoleObserver.isUidExemptFromTrampolineRestrictions(1031));
+ // New user
+ when(mRoleManager.getRoleHoldersAsUser(
+ ROLE_BROWSER,
+ mUsers.get(1)))
+ .thenReturn(asList("com.browser2"));
+ mRoleObserver.onRoleHoldersChanged(ROLE_BROWSER, UserHandle.of(10));
+
+ assertTrue(mRoleObserver.isUidExemptFromTrampolineRestrictions(30));
+ assertTrue(mRoleObserver.isUidExemptFromTrampolineRestrictions(1031));
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index fdeb7a6eb71a..4bbea94060c4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1723,6 +1723,15 @@ public class ActivityRecordTests extends WindowTestsBase {
assertFalse(display.hasTopFixedRotationLaunchingApp());
assertFalse(activity.hasFixedRotationTransform());
+
+ // Simulate that the activity requests the same orientation as display.
+ activity.setOrientation(display.getConfiguration().orientation);
+ // Skip the real freezing.
+ activity.mVisibleRequested = false;
+ clearInvocations(activity);
+ activity.onCancelFixedRotationTransform(originalRotation);
+ // The implementation of cancellation must be executed.
+ verify(activity).startFreezingScreen(originalRotation);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 13ef9982494e..9226c0b6f32b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -62,7 +62,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.reset;
import android.app.ActivityManager;
import android.app.TaskInfo;
@@ -1323,20 +1322,22 @@ public class TaskTests extends WindowTestsBase {
}
@Test
- public void testNotifyOrientationChangeCausedByConfigurationChange() {
+ public void testTaskOrientationOnDisplayWindowingModeChange() {
+ // Skip unnecessary operations to speed up the test.
+ mAtm.deferWindowLayout();
final Task task = getTestTask();
final ActivityRecord activity = task.getTopMostActivity();
final DisplayContent display = task.getDisplayContent();
- display.setWindowingMode(WINDOWING_MODE_FREEFORM);
+ mWm.setWindowingMode(display.mDisplayId, WINDOWING_MODE_FREEFORM);
activity.setRequestedOrientation(SCREEN_ORIENTATION_LANDSCAPE);
assertEquals(SCREEN_ORIENTATION_UNSET, task.getOrientation());
- verify(display).onDescendantOrientationChanged(same(task));
- reset(display);
+ assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, display.getLastOrientation());
- display.setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ mWm.setWindowingMode(display.mDisplayId, WINDOWING_MODE_FULLSCREEN);
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, task.getOrientation());
- verify(display).onDescendantOrientationChanged(same(task));
+ assertEquals(SCREEN_ORIENTATION_LANDSCAPE, display.getLastOrientation());
+ assertEquals(Configuration.ORIENTATION_LANDSCAPE, display.getConfiguration().orientation);
}
@Test
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index d9001bd488f4..78da86c57ef1 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -15016,6 +15016,15 @@ public class TelephonyManager {
"CAPABILITY_SLICING_CONFIG_SUPPORTED";
/**
+ * Indicates whether PHYSICAL_CHANNEL_CONFIG HAL1.6 is supported. See comments on
+ * respective methods for more information.
+ *
+ * @hide
+ */
+ public static final String CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED =
+ "CAPABILITY_PHYSICAL_CHANNEL_CONFIG_1_6_SUPPORTED";
+
+ /**
* A list of the radio interface capability values with public valid constants.
*
* Here is a related list for the systemapi-only valid constants:
diff --git a/test-mock/Android.bp b/test-mock/Android.bp
index a2447d71c3bd..b83bce654a85 100644
--- a/test-mock/Android.bp
+++ b/test-mock/Android.bp
@@ -38,6 +38,7 @@ java_sdk_library {
],
libs: [
"framework",
+ "framework-annotations-lib",
"app-compat-annotations",
"unsupportedappusage",
],
diff --git a/tests/HwAccelerationTest/res/layout/stretch_layout.xml b/tests/HwAccelerationTest/res/layout/stretch_layout.xml
index df5f297da729..81e0c019490f 100644
--- a/tests/HwAccelerationTest/res/layout/stretch_layout.xml
+++ b/tests/HwAccelerationTest/res/layout/stretch_layout.xml
@@ -16,7 +16,6 @@
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scroll_view"
- android:edgeEffectType="stretch"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
@@ -26,7 +25,6 @@
<HorizontalScrollView
android:id="@+id/horizontal_scroll_view"
- android:edgeEffectType="stretch"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
diff --git a/tests/Input/src/com/android/test/input/ViewFrameInfoTest.kt b/tests/Input/src/com/android/test/input/ViewFrameInfoTest.kt
index c01d32bf4cd2..6ef1ecdae59b 100644
--- a/tests/Input/src/com/android/test/input/ViewFrameInfoTest.kt
+++ b/tests/Input/src/com/android/test/input/ViewFrameInfoTest.kt
@@ -35,7 +35,7 @@ class ViewFrameInfoTest {
fun setUp() {
mViewFrameInfo.reset()
mViewFrameInfo.setInputEvent(139)
- mViewFrameInfo.flags = mViewFrameInfo.flags or FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED
+ mViewFrameInfo.flags = mViewFrameInfo.flags or FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED
mTimeStarted = SystemClock.uptimeNanos()
mViewFrameInfo.markDrawStart()
}
@@ -43,7 +43,7 @@ class ViewFrameInfoTest {
@Test
fun testPopulateFields() {
assertThat(mViewFrameInfo.drawStart).isGreaterThan(mTimeStarted)
- assertThat(mViewFrameInfo.flags).isEqualTo(FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED)
+ assertThat(mViewFrameInfo.flags).isEqualTo(FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED)
}
@Test
@@ -66,7 +66,7 @@ class ViewFrameInfoTest {
mViewFrameInfo.populateFrameInfo(frameInfo)
assertThat(frameInfo.frameInfo[FrameInfo.INPUT_EVENT_ID]).isEqualTo(139)
assertThat(frameInfo.frameInfo[FrameInfo.FLAGS]).isEqualTo(
- FrameInfo.FLAG_WINDOW_LAYOUT_CHANGED)
+ FrameInfo.FLAG_WINDOW_VISIBILITY_CHANGED)
assertThat(frameInfo.frameInfo[FrameInfo.DRAW_START]).isGreaterThan(mTimeStarted)
}
} \ No newline at end of file
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index 8b0ae5c37bae..ea5a43104bba 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -21,16 +21,15 @@ package {
default_applicable_licenses: ["frameworks_base_license"],
}
-java_test_host {
+android_test {
name: "UpdatableSystemFontTest",
srcs: ["src/**/*.java"],
- libs: [
- "tradefed",
- "compatibility-tradefed",
- "compatibility-host-util",
- ],
+ libs: ["android.test.runner"],
static_libs: [
- "frameworks-base-hostutils",
+ "androidx.test.ext.junit",
+ "compatibility-device-util-axt",
+ "platform-test-annotations",
+ "truth-prebuilt",
],
test_suites: [
"general-tests",
@@ -47,4 +46,5 @@ java_test_host {
":UpdatableSystemFontTestNotoColorEmojiVPlus2Ttf",
":UpdatableSystemFontTestNotoColorEmojiVPlus2TtfFsvSig",
],
+ sdk_version: "test_current",
}
diff --git a/tests/UpdatableSystemFontTest/AndroidManifest.xml b/tests/UpdatableSystemFontTest/AndroidManifest.xml
new file mode 100644
index 000000000000..531ee981a92c
--- /dev/null
+++ b/tests/UpdatableSystemFontTest/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2021 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.updatablesystemfont">
+
+ <application android:label="UpdatableSystemFontTest">
+ <uses-library android:name="android.test.runner"/>
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:label="UpdatableSystemFontTest"
+ android:targetPackage="com.android.updatablesystemfont">
+ </instrumentation>
+
+</manifest>
diff --git a/tests/UpdatableSystemFontTest/AndroidTest.xml b/tests/UpdatableSystemFontTest/AndroidTest.xml
index 4f116698ba72..4f6487e7e953 100644
--- a/tests/UpdatableSystemFontTest/AndroidTest.xml
+++ b/tests/UpdatableSystemFontTest/AndroidTest.xml
@@ -21,6 +21,7 @@
<target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
<option name="cleanup-apks" value="true" />
+ <option name="test-file-name" value="UpdatableSystemFontTest.apk" />
<option name="test-file-name" value="EmojiRenderingTestApp.apk" />
</target_preparer>
@@ -37,7 +38,7 @@
<option name="push" value="UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmojiVPlus2.ttf.fsv_sig" />
</target_preparer>
- <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
- <option name="jar" value="UpdatableSystemFontTest.jar" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest">
+ <option name="package" value="com.android.updatablesystemfont" />
</test>
</configuration>
diff --git a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
index 74f6bca4d7a0..9793c3447ff2 100644
--- a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
+++ b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
@@ -16,44 +16,59 @@
package com.android.updatablesystemfont;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+
import static com.google.common.truth.Truth.assertThat;
-import static com.google.common.truth.Truth.assertWithMessage;
+
+import static org.junit.Assume.assumeTrue;
import static java.util.concurrent.TimeUnit.SECONDS;
+import android.app.UiAutomation;
+import android.content.Context;
+import android.graphics.fonts.FontFamilyUpdateRequest;
+import android.graphics.fonts.FontFileUpdateRequest;
+import android.graphics.fonts.FontManager;
+import android.os.ParcelFileDescriptor;
import android.platform.test.annotations.RootPermissionTest;
+import android.security.FileIntegrityManager;
+import android.text.FontConfig;
+import android.util.Log;
+import android.util.Pair;
-import com.android.fsverity.AddFsVerityCertRule;
-import com.android.tradefed.device.DeviceNotAvailableException;
-import com.android.tradefed.log.LogUtil.CLog;
-import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
-import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test;
-import com.android.tradefed.util.CommandResult;
-import com.android.tradefed.util.CommandStatus;
+import androidx.annotation.Nullable;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.compatibility.common.util.StreamUtil;
+import com.android.compatibility.common.util.SystemUtil;
import org.junit.After;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.nio.file.Paths;
/**
- * Tests if fonts can be updated by 'cmd font'.
+ * Tests if fonts can be updated by {@link FontManager} API.
*/
@RootPermissionTest
-@RunWith(DeviceJUnit4ClassRunner.class)
-public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
+@RunWith(AndroidJUnit4.class)
+public class UpdatableSystemFontTest {
+ private static final String TAG = "UpdatableSystemFontTest";
private static final String SYSTEM_FONTS_DIR = "/system/fonts/";
private static final String DATA_FONTS_DIR = "/data/fonts/files/";
-
private static final String CERT_PATH = "/data/local/tmp/UpdatableSystemFontTestCert.der";
-
- private static final Pattern PATTERN_FONT = Pattern.compile("path = ([^, \n]*)");
- private static final String NOTO_COLOR_EMOJI_TTF = "NotoColorEmoji.ttf";
+ private static final String NOTO_COLOR_EMOJI_POSTSCRIPT_NAME = "NotoColorEmoji";
private static final String ORIGINAL_NOTO_COLOR_EMOJI_TTF =
"/data/local/tmp/NotoColorEmoji.ttf";
@@ -80,64 +95,75 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
EMOJI_RENDERING_TEST_APP_ID + "/.EmojiRenderingTestActivity";
private static final long ACTIVITY_TIMEOUT_MILLIS = SECONDS.toMillis(10);
- private interface ThrowingSupplier<T> {
- T get() throws Exception;
- }
-
- @Rule
- public final AddFsVerityCertRule mAddFsverityCertRule =
- new AddFsVerityCertRule(this, CERT_PATH);
+ private String mKeyId;
+ private FontManager mFontManager;
@Before
public void setUp() throws Exception {
- expectRemoteCommandToSucceed("cmd font clear");
+ Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
+ // Run tests only if updatable system font is enabled.
+ FileIntegrityManager fim = context.getSystemService(FileIntegrityManager.class);
+ assumeTrue(fim != null);
+ assumeTrue(fim.isApkVeritySupported());
+ mKeyId = insertCert(CERT_PATH);
+ mFontManager = context.getSystemService(FontManager.class);
+ expectCommandToSucceed("cmd font clear");
}
@After
public void tearDown() throws Exception {
- expectRemoteCommandToSucceed("cmd font clear");
+ expectCommandToSucceed("cmd font clear");
+ if (mKeyId != null) {
+ expectCommandToSucceed("mini-keyctl unlink " + mKeyId + " .fs-verity");
+ }
}
@Test
public void updateFont() throws Exception {
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
- String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ String fontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(fontPath).startsWith(DATA_FONTS_DIR);
// The updated font should be readable and unmodifiable.
- expectRemoteCommandToSucceed("cat " + fontPath + " > /dev/null");
- expectRemoteCommandToFail("echo -n '' >> " + fontPath);
+ expectCommandToSucceed("dd status=none if=" + fontPath + " of=/dev/null");
+ expectCommandToFail("dd status=none if=" + CERT_PATH + " of=" + fontPath);
}
@Test
public void updateFont_twice() throws Exception {
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
- String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG));
- String fontPath2 = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ String fontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ String fontPath2 = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(fontPath2).startsWith(DATA_FONTS_DIR);
assertThat(fontPath2).isNotEqualTo(fontPath);
// The new file should be readable.
- expectRemoteCommandToSucceed("cat " + fontPath2 + " > /dev/null");
+ expectCommandToSucceed("dd status=none if=" + fontPath2 + " of=/dev/null");
// The old file should be still readable.
- expectRemoteCommandToSucceed("cat " + fontPath + " > /dev/null");
+ expectCommandToSucceed("dd status=none if=" + fontPath + " of=/dev/null");
}
@Test
public void updateFont_allowSameVersion() throws Exception {
// Update original font to the same version
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- ORIGINAL_NOTO_COLOR_EMOJI_TTF, ORIGINAL_NOTO_COLOR_EMOJI_TTF_FSV_SIG));
- String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
- String fontPath2 = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(updateFontFile(
+ ORIGINAL_NOTO_COLOR_EMOJI_TTF, ORIGINAL_NOTO_COLOR_EMOJI_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ String fontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ String fontPath2 = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
// Update updated font to the same version
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
- String fontPath3 = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ String fontPath3 = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(fontPath).startsWith(DATA_FONTS_DIR);
assertThat(fontPath2).isNotEqualTo(fontPath);
assertThat(fontPath2).startsWith(DATA_FONTS_DIR);
@@ -147,134 +173,171 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
@Test
public void updateFont_invalidCert() throws Exception {
- expectRemoteCommandToFail(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG));
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_ERROR_VERIFICATION_FAILURE);
}
@Test
public void updateFont_downgradeFromSystem() throws Exception {
- expectRemoteCommandToFail(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_V0_TTF, TEST_NOTO_COLOR_EMOJI_V0_TTF_FSV_SIG));
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_V0_TTF, TEST_NOTO_COLOR_EMOJI_V0_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_ERROR_DOWNGRADING);
}
@Test
public void updateFont_downgradeFromData() throws Exception {
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG));
- expectRemoteCommandToFail(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS2_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_ERROR_DOWNGRADING);
}
@Test
public void launchApp() throws Exception {
- String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ String fontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(fontPath).startsWith(SYSTEM_FONTS_DIR);
startActivity(EMOJI_RENDERING_TEST_APP_ID, EMOJI_RENDERING_TEST_ACTIVITY);
- waitUntil(ACTIVITY_TIMEOUT_MILLIS, () ->
- isFileOpenedBy(fontPath, EMOJI_RENDERING_TEST_APP_ID));
+ SystemUtil.eventually(
+ () -> assertThat(isFileOpenedBy(fontPath, EMOJI_RENDERING_TEST_APP_ID)).isTrue(),
+ ACTIVITY_TIMEOUT_MILLIS);
}
@Test
public void launchApp_afterUpdateFont() throws Exception {
- String originalFontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ String originalFontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(originalFontPath).startsWith(SYSTEM_FONTS_DIR);
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
- String updatedFontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ assertThat(updateFontFile(
+ TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG))
+ .isEqualTo(FontManager.RESULT_SUCCESS);
+ String updatedFontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(updatedFontPath).startsWith(DATA_FONTS_DIR);
startActivity(EMOJI_RENDERING_TEST_APP_ID, EMOJI_RENDERING_TEST_ACTIVITY);
// The original font should NOT be opened by the app.
- waitUntil(ACTIVITY_TIMEOUT_MILLIS, () ->
- isFileOpenedBy(updatedFontPath, EMOJI_RENDERING_TEST_APP_ID)
- && !isFileOpenedBy(originalFontPath, EMOJI_RENDERING_TEST_APP_ID));
+ SystemUtil.eventually(() -> {
+ assertThat(isFileOpenedBy(updatedFontPath, EMOJI_RENDERING_TEST_APP_ID)).isTrue();
+ assertThat(isFileOpenedBy(originalFontPath, EMOJI_RENDERING_TEST_APP_ID)).isFalse();
+ }, ACTIVITY_TIMEOUT_MILLIS);
}
@Test
public void reboot() throws Exception {
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
+ expectCommandToSucceed(String.format("cmd font update %s %s",
TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF, TEST_NOTO_COLOR_EMOJI_VPLUS1_TTF_FSV_SIG));
- String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ String fontPath = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(fontPath).startsWith(DATA_FONTS_DIR);
// Emulate reboot by 'cmd font restart'.
- expectRemoteCommandToSucceed("cmd font restart");
- String fontPathAfterReboot = getFontPath(NOTO_COLOR_EMOJI_TTF);
+ expectCommandToSucceed("cmd font restart");
+ String fontPathAfterReboot = getFontPath(NOTO_COLOR_EMOJI_POSTSCRIPT_NAME);
assertThat(fontPathAfterReboot).isEqualTo(fontPath);
}
- private String getFontPath(String fontFileName) throws Exception {
- // TODO: add a dedicated command for testing.
- String lines = expectRemoteCommandToSucceed("cmd font dump");
- for (String line : lines.split("\n")) {
- Matcher m = PATTERN_FONT.matcher(line);
- if (m.find() && m.group(1).endsWith(fontFileName)) {
- return m.group(1);
- }
+ private static String insertCert(String certPath) throws Exception {
+ Pair<String, String> result;
+ try (InputStream is = new FileInputStream(certPath)) {
+ result = runShellCommand("mini-keyctl padd asymmetric fsv_test .fs-verity", is);
+ }
+ // Assert that there are no errors.
+ assertThat(result.second).isEmpty();
+ String keyId = result.first.trim();
+ assertThat(keyId).matches("^\\d+$");
+ return keyId;
+ }
+
+ private int updateFontFile(String fontPath, String signaturePath) throws IOException {
+ byte[] signature = Files.readAllBytes(Paths.get(signaturePath));
+ try (ParcelFileDescriptor fd =
+ ParcelFileDescriptor.open(new File(fontPath), MODE_READ_ONLY)) {
+ return SystemUtil.runWithShellPermissionIdentity(() -> {
+ FontConfig fontConfig = mFontManager.getFontConfig();
+ return mFontManager.updateFontFamily(
+ new FontFamilyUpdateRequest.Builder()
+ .addFontFileUpdateRequest(new FontFileUpdateRequest(fd, signature))
+ .build(),
+ fontConfig.getConfigVersion());
+ });
}
- CLog.e("Font not found: " + fontFileName);
- return null;
}
- private void startActivity(String appId, String activityId) throws Exception {
- // Make sure that the app is installed and enabled.
- waitUntil(ACTIVITY_TIMEOUT_MILLIS, () -> {
- String packageInfo = expectRemoteCommandToSucceed(
- "pm list packages -e " + EMOJI_RENDERING_TEST_APP_ID);
- return !packageInfo.isEmpty();
+ private String getFontPath(String psName) {
+ return SystemUtil.runWithShellPermissionIdentity(() -> {
+ FontConfig fontConfig = mFontManager.getFontConfig();
+ for (FontConfig.FontFamily family : fontConfig.getFontFamilies()) {
+ for (FontConfig.Font font : family.getFontList()) {
+ if (psName.equals(font.getPostScriptName())) {
+ return font.getFile().getAbsolutePath();
+ }
+ }
+ }
+ throw new AssertionError("Font not found: " + psName);
});
- expectRemoteCommandToSucceed("am force-stop " + EMOJI_RENDERING_TEST_APP_ID);
- expectRemoteCommandToSucceed("am start-activity -n " + EMOJI_RENDERING_TEST_ACTIVITY);
}
- private String expectRemoteCommandToSucceed(String cmd) throws Exception {
- CommandResult result = getDevice().executeShellV2Command(cmd);
- assertWithMessage("`" + cmd + "` failed: " + result.getStderr())
- .that(result.getStatus())
- .isEqualTo(CommandStatus.SUCCESS);
- return result.getStdout();
+ private static void startActivity(String appId, String activityId) throws Exception {
+ expectCommandToSucceed("am force-stop " + appId);
+ expectCommandToSucceed("am start-activity -n " + activityId);
+ }
+
+ private static String expectCommandToSucceed(String cmd) throws IOException {
+ Pair<String, String> result = runShellCommand(cmd, null);
+ // UiAutomation.runShellCommand() does not return exit code.
+ // Assume that the command fails if stderr is not empty.
+ assertThat(result.second.trim()).isEmpty();
+ return result.first;
}
- private void expectRemoteCommandToFail(String cmd) throws Exception {
- CommandResult result = getDevice().executeShellV2Command(cmd);
- assertWithMessage("Unexpected success from `" + cmd + "`: " + result.getStderr())
- .that(result.getStatus())
- .isNotEqualTo(CommandStatus.SUCCESS);
+ private static void expectCommandToFail(String cmd) throws IOException {
+ Pair<String, String> result = runShellCommand(cmd, null);
+ // UiAutomation.runShellCommand() does not return exit code.
+ // Assume that the command fails if stderr is not empty.
+ assertThat(result.second.trim()).isNotEmpty();
}
- private void waitUntil(long timeoutMillis, ThrowingSupplier<Boolean> func) {
- long untilMillis = System.currentTimeMillis() + timeoutMillis;
- do {
- try {
- if (func.get()) return;
- Thread.sleep(100);
- } catch (InterruptedException e) {
- throw new AssertionError("Interrupted", e);
- } catch (Exception e) {
- throw new AssertionError("Unexpected exception", e);
+ /** Runs a command and returns (stdout, stderr). */
+ private static Pair<String, String> runShellCommand(String cmd, @Nullable InputStream input)
+ throws IOException {
+ Log.i(TAG, "runShellCommand: " + cmd);
+ UiAutomation automation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
+ ParcelFileDescriptor[] rwe = automation.executeShellCommandRwe(cmd);
+ // executeShellCommandRwe returns [stdout, stdin, stderr].
+ try (ParcelFileDescriptor outFd = rwe[0];
+ ParcelFileDescriptor inFd = rwe[1];
+ ParcelFileDescriptor errFd = rwe[2]) {
+ if (input != null) {
+ try (OutputStream os = new FileOutputStream(inFd.getFileDescriptor())) {
+ StreamUtil.copyStreams(input, os);
+ }
}
- } while (System.currentTimeMillis() < untilMillis);
- throw new AssertionError("Timed out");
+ // We have to close stdin before reading stdout and stderr.
+ // It's safe to close ParcelFileDescriptor multiple times.
+ inFd.close();
+ String stdout;
+ try (InputStream is = new FileInputStream(outFd.getFileDescriptor())) {
+ stdout = StreamUtil.readInputStream(is);
+ }
+ Log.i(TAG, "stdout = " + stdout);
+ String stderr;
+ try (InputStream is = new FileInputStream(errFd.getFileDescriptor())) {
+ stderr = StreamUtil.readInputStream(is);
+ }
+ Log.i(TAG, "stderr = " + stderr);
+ return new Pair<>(stdout, stderr);
+ }
}
- private boolean isFileOpenedBy(String path, String appId) throws DeviceNotAvailableException {
+ private static boolean isFileOpenedBy(String path, String appId) throws Exception {
String pid = pidOf(appId);
if (pid.isEmpty()) {
return false;
}
- CommandResult result = getDevice().executeShellV2Command(
- String.format("lsof -t -p %s '%s'", pid, path));
- if (result.getStatus() != CommandStatus.SUCCESS) {
- return false;
- }
- // The file is open if the output of lsof is non-empty.
- return !result.getStdout().trim().isEmpty();
+ String cmd = String.format("lsof -t -p %s %s", pid, path);
+ return !expectCommandToSucceed(cmd).trim().isEmpty();
}
- private String pidOf(String appId) throws DeviceNotAvailableException {
- CommandResult result = getDevice().executeShellV2Command("pidof " + appId);
- if (result.getStatus() != CommandStatus.SUCCESS) {
- return "";
- }
- return result.getStdout().trim();
+ private static String pidOf(String appId) throws Exception {
+ return expectCommandToSucceed("pidof " + appId).trim();
}
}
diff --git a/tools/aapt/Android.bp b/tools/aapt/Android.bp
index c75ba71c4432..a19d183d617b 100644
--- a/tools/aapt/Android.bp
+++ b/tools/aapt/Android.bp
@@ -124,6 +124,9 @@ cc_binary_host {
srcs: ["Main.cpp"],
use_version_lib: true,
static_libs: ["libaapt"],
+ dist: {
+ targets: ["aapt2_artifacts"],
+ },
}
// ==========================================================
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 21386b88ce2c..f2c3b86e409e 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -969,6 +969,8 @@ int doDump(Bundle* bundle)
densities.add(dens);
}
+ std::vector<ResXMLParser::ResXMLPosition> tagsToSkip;
+
size_t len;
ResXMLTree::event_code_t code;
int depth = 0;
@@ -1091,6 +1093,42 @@ int doDump(Bundle* bundle)
Vector<FeatureGroup> featureGroups;
KeyedVector<String8, ImpliedFeature> impliedFeatures;
+ {
+ int curDepth = 0;
+ ResXMLParser::ResXMLPosition initialPos;
+ tree.getPosition(&initialPos);
+
+ // Find all of the "uses-sdk" tags within the "manifest" tag.
+ std::vector<ResXMLParser::ResXMLPosition> usesSdkTagPositions;
+ ResXMLParser::ResXMLPosition curPos;
+ while ((code = tree.next()) != ResXMLTree::END_DOCUMENT &&
+ code != ResXMLTree::BAD_DOCUMENT) {
+ if (code == ResXMLTree::END_TAG) {
+ curDepth--;
+ continue;
+ }
+ if (code == ResXMLTree::START_TAG) {
+ curDepth++;
+ }
+ const char16_t* ctag16 = tree.getElementName(&len);
+ if (ctag16 == NULL || String8(ctag16) != "uses-sdk" || curDepth != 2) {
+ continue;
+ }
+
+ tree.getPosition(&curPos);
+ usesSdkTagPositions.emplace_back(curPos);
+ }
+
+ // Skip all "uses-sdk" tags besides the very last tag. The android runtime only uses
+ // the attribute values from the last defined tag.
+ for (size_t i = 0; i < usesSdkTagPositions.size() - 1; i++) {
+ tagsToSkip.emplace_back(usesSdkTagPositions[i]);
+ }
+
+ // Reset the position before parsing.
+ tree.setPosition(initialPos);
+ }
+
while ((code=tree.next()) != ResXMLTree::END_DOCUMENT &&
code != ResXMLTree::BAD_DOCUMENT) {
if (code == ResXMLTree::END_TAG) {
@@ -1202,8 +1240,25 @@ int doDump(Bundle* bundle)
if (code != ResXMLTree::START_TAG) {
continue;
}
+
depth++;
+ // If this tag should be skipped, skip to the end of this tag.
+ ResXMLParser::ResXMLPosition curPos;
+ tree.getPosition(&curPos);
+ if (std::find(tagsToSkip.begin(), tagsToSkip.end(), curPos) != tagsToSkip.end()) {
+ const int breakDepth = depth - 1;
+ while ((code = tree.next()) != ResXMLTree::END_DOCUMENT &&
+ code != ResXMLTree::BAD_DOCUMENT) {
+ if (code == ResXMLTree::END_TAG && --depth == breakDepth) {
+ break;
+ } else if (code == ResXMLTree::START_TAG) {
+ depth++;
+ }
+ }
+ continue;
+ }
+
const char16_t* ctag16 = tree.getElementName(&len);
if (ctag16 == NULL) {
SourcePos(manifestFile, tree.getLineNumber()).error(
diff --git a/tools/aapt2/dump/DumpManifest.cpp b/tools/aapt2/dump/DumpManifest.cpp
index f29c9185cafa..61ba09b6a3c9 100644
--- a/tools/aapt2/dump/DumpManifest.cpp
+++ b/tools/aapt2/dump/DumpManifest.cpp
@@ -132,6 +132,12 @@ class ManifestExtractor {
/** Adds an element to the list of children of the element. */
void AddChild(std::unique_ptr<Element>& child) { children_.push_back(std::move(child)); }
+ template <typename Predicate>
+ void Filter(Predicate&& func) {
+ children_.erase(std::remove_if(children_.begin(), children_.end(),
+ [&](const auto& e) { return func(e.get()); }));
+ }
+
/** Retrieves the list of children of the element. */
const std::vector<std::unique_ptr<Element>>& children() const {
return children_;
@@ -1963,6 +1969,21 @@ bool ManifestExtractor::Dump(text::Printer* printer, IDiagnostics* diag) {
// Extract badging information
auto root = Visit(element);
+ // Filter out all "uses-sdk" tags besides the very last tag. The android runtime only uses the
+ // attribute values from the last defined tag.
+ std::vector<UsesSdkBadging*> filtered_uses_sdk_tags;
+ for (const auto& child : root->children()) {
+ if (auto uses_sdk = ElementCast<UsesSdkBadging>(child.get())) {
+ filtered_uses_sdk_tags.emplace_back(uses_sdk);
+ }
+ }
+ filtered_uses_sdk_tags.pop_back();
+
+ root->Filter([&](const ManifestExtractor::Element* e) {
+ return std::find(filtered_uses_sdk_tags.begin(), filtered_uses_sdk_tags.end(), e) !=
+ filtered_uses_sdk_tags.end();
+ });
+
// Print the elements in order seen
Print(root.get(), printer);