summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp56
-rw-r--r--cmds/idmap2/Android.bp4
-rw-r--r--cmds/idmap2/tests/ResultTests.cpp5
-rw-r--r--cmds/svc/src/com/android/commands/svc/UsbCommand.java63
-rw-r--r--cmds/telecom/src/com/android/commands/telecom/Telecom.java12
-rw-r--r--core/api/current.txt31
-rw-r--r--core/api/system-current.txt38
-rw-r--r--core/api/system-lint-baseline.txt9
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/Android.bp8
-rw-r--r--core/java/android/app/Dialog.java3
-rw-r--r--core/java/android/app/IWallpaperManager.aidl2
-rw-r--r--core/java/android/app/UiAutomationConnection.java3
-rw-r--r--core/java/android/app/WallpaperManager.java2
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java4
-rw-r--r--core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS1
-rw-r--r--core/java/android/app/admin/WorkDeviceExperience_OWNERS1
-rw-r--r--core/java/android/app/backup/BackupManager.java5
-rw-r--r--core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java10
-rw-r--r--core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java32
-rw-r--r--core/java/android/companion/SystemDataTransferRequest.java76
-rw-r--r--core/java/android/content/pm/PackageManager.java22
-rw-r--r--core/java/android/content/pm/ShortcutInfo.java18
-rw-r--r--core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java4
-rw-r--r--core/java/android/permission/PermissionUsageHelper.java15
-rw-r--r--core/java/android/permission/Permissions.md49
-rw-r--r--core/java/android/provider/Settings.java13
-rw-r--r--core/java/android/service/autofill/FillContext.java4
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletService.java49
-rw-r--r--core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java6
-rw-r--r--core/java/android/service/voice/AbstractHotwordDetector.java7
-rw-r--r--core/java/android/service/voice/AlwaysOnHotwordDetector.java23
-rw-r--r--core/java/android/service/voice/HotwordDetectionService.java21
-rw-r--r--core/java/android/service/voice/SoftwareHotwordDetector.java15
-rw-r--r--core/java/android/service/voice/VoiceInteractionService.java11
-rw-r--r--core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java3
-rw-r--r--core/java/android/text/TextUtils.java5
-rw-r--r--core/java/android/view/View.java4
-rw-r--r--core/java/android/view/accessibility/AccessibilityNodeInfo.java6
-rw-r--r--core/java/android/widget/AbsListView.java27
-rw-r--r--core/java/android/widget/HorizontalScrollView.java24
-rw-r--r--core/java/android/widget/RemoteViewsAdapter.java20
-rw-r--r--core/java/android/widget/ScrollView.java23
-rw-r--r--core/java/com/android/internal/content/FileSystemProvider.java10
-rw-r--r--core/java/com/android/internal/logging/InstanceId.java98
-rw-r--r--core/java/com/android/internal/logging/InstanceIdSequence.java62
-rw-r--r--core/java/com/android/internal/logging/UiEvent.java30
-rw-r--r--core/java/com/android/internal/logging/UiEventLogger.java111
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java25
-rw-r--r--core/java/com/android/internal/os/MobileRadioPowerCalculator.java11
-rw-r--r--core/java/com/android/internal/view/menu/CascadingMenuPopup.java17
-rw-r--r--core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java3
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java2
-rw-r--r--core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java10
-rw-r--r--core/java/com/android/server/SystemConfig.java37
-rw-r--r--core/proto/OWNERS1
-rw-r--r--core/res/AndroidManifest.xml10
-rw-r--r--core/res/res/values/colors_car.xml4
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java9
-rw-r--r--core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java4
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java112
-rw-r--r--core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java3
-rw-r--r--errorprone/Android.bp3
-rw-r--r--errorprone/java/com/google/errorprone/bugpatterns/android/HideInCommentsChecker.java158
-rw-r--r--errorprone/tests/java/com/google/errorprone/bugpatterns/android/HideInCommentsCheckerTest.java235
-rw-r--r--identity/java/android/security/identity/CredstoreIdentityCredential.java7
-rw-r--r--identity/java/android/security/identity/CredstoreWritableIdentityCredential.java5
-rw-r--r--identity/java/android/security/identity/PersonalizationData.java5
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java1
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl12
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java93
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java3
-rw-r--r--libs/androidfw/Android.bp1
-rw-r--r--libs/androidfw/include/androidfw/StringPiece.h4
-rw-r--r--libs/hwui/HardwareBitmapUploader.cpp3
-rw-r--r--libs/hwui/HardwareBitmapUploader.h3
-rw-r--r--libs/hwui/Readback.cpp12
-rw-r--r--libs/hwui/Readback.h6
-rw-r--r--libs/hwui/RecordingCanvas.cpp4
-rw-r--r--libs/hwui/RecordingCanvas.h2
-rw-r--r--libs/hwui/SkiaCanvas.cpp6
-rw-r--r--libs/hwui/SkiaCanvas.h2
-rw-r--r--libs/hwui/VectorDrawable.cpp5
-rw-r--r--libs/hwui/VectorDrawable.h1
-rw-r--r--libs/hwui/apex/android_bitmap.cpp5
-rw-r--r--libs/hwui/canvas/CanvasOps.h12
-rw-r--r--libs/hwui/hwui/Bitmap.cpp8
-rw-r--r--libs/hwui/hwui/Bitmap.h2
-rw-r--r--libs/hwui/hwui/Canvas.cpp1
-rw-r--r--libs/hwui/hwui/Canvas.h1
-rw-r--r--libs/hwui/hwui/MinikinSkia.cpp5
-rw-r--r--libs/hwui/jni/AnimatedImageDrawable.cpp3
-rwxr-xr-xlibs/hwui/jni/Bitmap.cpp12
-rw-r--r--libs/hwui/jni/Bitmap.h1
-rw-r--r--libs/hwui/jni/BitmapFactory.cpp10
-rw-r--r--libs/hwui/jni/ByteBufferStreamAdaptor.cpp1
-rw-r--r--libs/hwui/jni/FontFamily.cpp1
-rw-r--r--libs/hwui/jni/GIFMovie.cpp2
-rw-r--r--libs/hwui/jni/Graphics.cpp8
-rw-r--r--libs/hwui/jni/ImageDecoder.cpp6
-rw-r--r--libs/hwui/jni/Movie.h1
-rw-r--r--libs/hwui/jni/MovieImpl.cpp9
-rw-r--r--libs/hwui/jni/NinePatch.cpp2
-rw-r--r--libs/hwui/jni/NinePatchPeeker.cpp2
-rw-r--r--libs/hwui/jni/Shader.cpp14
-rw-r--r--libs/hwui/jni/Utils.h3
-rw-r--r--libs/hwui/jni/YuvToJpegEncoder.cpp2
-rw-r--r--libs/hwui/jni/YuvToJpegEncoder.h4
-rw-r--r--libs/hwui/jni/android_graphics_Canvas.cpp14
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp10
-rw-r--r--libs/hwui/jni/fonts/Font.cpp3
-rw-r--r--libs/hwui/pipeline/skia/DumpOpsCanvas.h2
-rw-r--r--libs/hwui/pipeline/skia/HolePunch.h1
-rw-r--r--libs/hwui/pipeline/skia/RenderNodeDrawable.cpp4
-rw-r--r--libs/hwui/pipeline/skia/ShaderCache.cpp1
-rw-r--r--libs/hwui/pipeline/skia/ShaderCache.h5
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.cpp10
-rw-r--r--libs/hwui/pipeline/skia/SkiaPipeline.h1
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp13
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.h5
-rw-r--r--libs/hwui/pipeline/skia/SkiaVulkanPipeline.h5
-rw-r--r--libs/hwui/pipeline/skia/TransformCanvas.cpp4
-rw-r--r--libs/hwui/pipeline/skia/TransformCanvas.h7
-rw-r--r--libs/hwui/renderthread/RenderProxy.cpp4
-rw-r--r--libs/hwui/renderthread/RenderProxy.h6
-rw-r--r--libs/hwui/tests/common/TestUtils.cpp6
-rw-r--r--libs/hwui/tests/common/TestUtils.h10
-rw-r--r--libs/hwui/tests/common/scenes/BitmapShaders.cpp12
-rw-r--r--libs/hwui/tests/common/scenes/HwBitmap565.cpp6
-rw-r--r--libs/hwui/tests/common/scenes/ListViewAnimation.cpp11
-rw-r--r--libs/hwui/tests/common/scenes/MagnifierAnimation.cpp4
-rw-r--r--libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp6
-rw-r--r--libs/hwui/tests/common/scenes/RecentsAnimation.cpp5
-rw-r--r--libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp8
-rw-r--r--libs/hwui/tests/common/scenes/TvApp.cpp5
-rw-r--r--libs/hwui/tests/unit/CanvasOpTests.cpp10
-rw-r--r--libs/hwui/tests/unit/FatalTestCanvas.h2
-rw-r--r--libs/hwui/tests/unit/ShaderCacheTests.cpp2
-rw-r--r--libs/hwui/tests/unit/SkiaBehaviorTests.cpp7
-rw-r--r--libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp1
-rw-r--r--libs/hwui/tests/unit/TypefaceTests.cpp3
-rw-r--r--libs/hwui/tests/unit/VectorDrawableTests.cpp6
-rw-r--r--libs/input/MouseCursorController.cpp6
-rw-r--r--libs/input/TouchSpotController.cpp6
-rw-r--r--media/aidl/android/media/audio/common/AudioPort.aidl5
-rw-r--r--media/aidl/android/media/audio/common/AudioPortExt.aidl5
-rw-r--r--media/java/android/media/tv/TvInputManager.java3
-rwxr-xr-xmedia/java/android/media/tv/interactive/TvInteractiveAppManager.java4
-rw-r--r--native/graphics/jni/imagedecoder.cpp6
-rw-r--r--packages/CompanionDeviceManager/AndroidManifest.xml8
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java6
-rw-r--r--packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java12
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java2
-rw-r--r--packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java3
-rw-r--r--packages/Shell/AndroidManifest.xml2
-rw-r--r--packages/Shell/src/com/android/shell/BugreportProgressService.java71
-rw-r--r--packages/SystemUI/res/drawable/ic_circular_unchecked.xml2
-rw-r--r--packages/SystemUI/res/drawable/media_output_status_check.xml2
-rw-r--r--packages/SystemUI/res/drawable/media_output_status_failed.xml2
-rw-r--r--packages/SystemUI/res/layout/media_output_dialog.xml2
-rw-r--r--packages/SystemUI/res/layout/media_output_list_item.xml4
-rw-r--r--packages/SystemUI/res/values-af/strings.xml2
-rw-r--r--packages/SystemUI/res/values-am/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ar/strings.xml2
-rw-r--r--packages/SystemUI/res/values-as/strings.xml2
-rw-r--r--packages/SystemUI/res/values-az/strings.xml2
-rw-r--r--packages/SystemUI/res/values-b+sr+Latn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-be/strings.xml2
-rw-r--r--packages/SystemUI/res/values-bg/strings.xml2
-rw-r--r--packages/SystemUI/res/values-bn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-bs/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml2
-rw-r--r--packages/SystemUI/res/values-cs/strings.xml2
-rw-r--r--packages/SystemUI/res/values-da/strings.xml2
-rw-r--r--packages/SystemUI/res/values-de/strings.xml2
-rw-r--r--packages/SystemUI/res/values-el/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rAU/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rCA/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rGB/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rIN/strings.xml2
-rw-r--r--packages/SystemUI/res/values-en-rXC/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es-rUS/strings.xml2
-rw-r--r--packages/SystemUI/res/values-es/strings.xml2
-rw-r--r--packages/SystemUI/res/values-et/strings.xml2
-rw-r--r--packages/SystemUI/res/values-eu/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fa/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fr-rCA/strings.xml2
-rw-r--r--packages/SystemUI/res/values-fr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-gl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-gu/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hu/strings.xml2
-rw-r--r--packages/SystemUI/res/values-hy/strings.xml2
-rw-r--r--packages/SystemUI/res/values-in/strings.xml2
-rw-r--r--packages/SystemUI/res/values-is/strings.xml2
-rw-r--r--packages/SystemUI/res/values-it/strings.xml2
-rw-r--r--packages/SystemUI/res/values-iw/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ja/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ka/strings.xml2
-rw-r--r--packages/SystemUI/res/values-kk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-km/strings.xml2
-rw-r--r--packages/SystemUI/res/values-kn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ko/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ky/strings.xml2
-rw-r--r--packages/SystemUI/res/values-lo/strings.xml2
-rw-r--r--packages/SystemUI/res/values-lt/strings.xml2
-rw-r--r--packages/SystemUI/res/values-lv/strings.xml2
-rw-r--r--packages/SystemUI/res/values-mk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ml/strings.xml2
-rw-r--r--packages/SystemUI/res/values-mn/strings.xml2
-rw-r--r--packages/SystemUI/res/values-mr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ms/strings.xml2
-rw-r--r--packages/SystemUI/res/values-my/strings.xml2
-rw-r--r--packages/SystemUI/res/values-nb/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ne/strings.xml2
-rw-r--r--packages/SystemUI/res/values-night/colors.xml10
-rw-r--r--packages/SystemUI/res/values-nl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-or/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pa/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pt-rBR/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pt-rPT/strings.xml2
-rw-r--r--packages/SystemUI/res/values-pt/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ru/strings.xml2
-rw-r--r--packages/SystemUI/res/values-si/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sq/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sv/strings.xml2
-rw-r--r--packages/SystemUI/res/values-sw/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ta/strings.xml2
-rw-r--r--packages/SystemUI/res/values-te/strings.xml2
-rw-r--r--packages/SystemUI/res/values-th/strings.xml2
-rw-r--r--packages/SystemUI/res/values-tl/strings.xml2
-rw-r--r--packages/SystemUI/res/values-tr/strings.xml2
-rw-r--r--packages/SystemUI/res/values-uk/strings.xml2
-rw-r--r--packages/SystemUI/res/values-ur/strings.xml2
-rw-r--r--packages/SystemUI/res/values-uz/strings.xml2
-rw-r--r--packages/SystemUI/res/values-vi/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rCN/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rHK/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zh-rTW/strings.xml2
-rw-r--r--packages/SystemUI/res/values-zu/strings.xml2
-rw-r--r--packages/SystemUI/res/values/colors.xml8
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/res/values/styles.xml2
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java58
-rw-r--r--packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt31
-rw-r--r--packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt)6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt (renamed from packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt)4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt92
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java12
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java8
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt14
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java15
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java10
-rw-r--r--services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java68
-rw-r--r--services/backup/java/com/android/server/backup/UserBackupManagerService.java19
-rw-r--r--services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java67
-rw-r--r--services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java18
-rw-r--r--services/companion/java/com/android/server/companion/DataStoreUtils.java19
-rw-r--r--services/companion/java/com/android/server/companion/PackageUtils.java19
-rw-r--r--services/companion/java/com/android/server/companion/PersistentDataStore.java2
-rw-r--r--services/companion/java/com/android/server/companion/Utils.java47
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java165
-rw-r--r--services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferRequestStore.java (renamed from services/companion/java/com/android/server/companion/SystemDataTransferRequestDataStore.java)137
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java4
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java83
-rw-r--r--services/core/java/com/android/server/attention/AttentionManagerService.java29
-rw-r--r--services/core/java/com/android/server/display/DisplayPowerController.java51
-rw-r--r--services/core/java/com/android/server/notification/NotificationHistoryDatabase.java11
-rw-r--r--services/core/java/com/android/server/pm/ApexManager.java9
-rw-r--r--services/core/java/com/android/server/pm/InitAppsHelper.java13
-rw-r--r--services/core/java/com/android/server/pm/InstallPackageHelper.java7
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java1
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java5
-rw-r--r--services/core/java/com/android/server/pm/ShortcutPackage.java106
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java2
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java13
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageState.java5
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageStateImpl.java8
-rw-r--r--services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java30
-rw-r--r--services/core/java/com/android/server/power/PowerManagerService.java20
-rw-r--r--services/core/java/com/android/server/slice/SliceManagerService.java4
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java8
-rw-r--r--services/core/java/com/android/server/wm/Transition.java15
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java2
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java150
-rw-r--r--services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java134
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java28
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DimmerTests.java15
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java15
-rw-r--r--services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java54
-rw-r--r--services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java8
-rw-r--r--telecomm/java/android/telecom/Connection.java9
-rw-r--r--telecomm/java/android/telecom/Logging/EventManager.java6
-rw-r--r--telecomm/java/android/telecom/ParcelableCallAnalytics.java2
-rw-r--r--telecomm/java/android/telecom/TelecomManager.java24
-rw-r--r--telecomm/java/com/android/internal/telecom/ITelecomService.aidl24
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java2
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java114
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java12
-rw-r--r--telephony/java/android/telephony/ims/ImsRcsManager.java53
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java34
-rw-r--r--telephony/java/android/telephony/ims/RcsUceAdapter.java10
-rw-r--r--telephony/java/android/telephony/ims/feature/MmTelFeature.java6
-rw-r--r--telephony/java/android/telephony/ims/feature/RcsFeature.java70
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java2
-rw-r--r--tools/aapt2/Android.bp1
-rw-r--r--tools/aapt2/Debug.cpp6
-rw-r--r--tools/aapt2/Resource.cpp6
-rw-r--r--tools/aapt2/ResourceParser.cpp8
-rw-r--r--tools/aapt2/ResourceTable.cpp43
-rw-r--r--tools/aapt2/ResourceTable.h13
-rw-r--r--tools/aapt2/ResourceUtils.cpp46
-rw-r--r--tools/aapt2/Resource_test.cpp10
-rw-r--r--tools/aapt2/cmd/Compile.cpp4
-rw-r--r--tools/aapt2/cmd/Diff.cpp24
-rw-r--r--tools/aapt2/cmd/Link.cpp92
-rw-r--r--tools/aapt2/cmd/Link_test.cpp48
-rw-r--r--tools/aapt2/cmd/Optimize.cpp2
-rw-r--r--tools/aapt2/compile/IdAssigner.cpp4
-rw-r--r--tools/aapt2/compile/IdAssigner_test.cpp4
-rw-r--r--tools/aapt2/format/binary/BinaryResourceParser.cpp14
-rw-r--r--tools/aapt2/format/binary/TableFlattener.cpp11
-rw-r--r--tools/aapt2/format/binary/TableFlattener_test.cpp41
-rw-r--r--tools/aapt2/format/proto/ProtoDeserialize.cpp6
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize.cpp4
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize_test.cpp72
-rw-r--r--tools/aapt2/java/JavaClassGenerator.cpp21
-rw-r--r--tools/aapt2/java/ProguardRules.cpp2
-rw-r--r--tools/aapt2/link/AutoVersioner.cpp2
-rw-r--r--tools/aapt2/link/NoDefaultResourceRemover.cpp2
-rw-r--r--tools/aapt2/link/PrivateAttributeMover.cpp5
-rw-r--r--tools/aapt2/link/PrivateAttributeMover_test.cpp12
-rw-r--r--tools/aapt2/link/ProductFilter.cpp2
-rw-r--r--tools/aapt2/link/ReferenceLinker.cpp2
-rw-r--r--tools/aapt2/link/TableMerger.cpp6
-rw-r--r--tools/aapt2/optimize/ResourceFilter.cpp2
-rw-r--r--tools/aapt2/split/TableSplitter.cpp4
-rw-r--r--tools/lint/README.md1
-rw-r--r--tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt4
-rw-r--r--tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt209
-rw-r--r--tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt38
-rw-r--r--tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt107
-rw-r--r--tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt428
-rw-r--r--tools/preload-check/device/src/com/android/preload/check/Util.java4
384 files changed, 4472 insertions, 1548 deletions
diff --git a/Android.bp b/Android.bp
index edaa11e3dc73..aee252c382f5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -266,6 +266,61 @@ java_defaults {
],
aidl: {
generate_get_transaction_name: true,
+ enforce_permissions: true,
+ enforce_permissions_exceptions: [
+ // Do not add entries to this list.
+ ":framework-annotations",
+ ":framework-blobstore-sources",
+ ":framework-connectivity-tiramisu-sources",
+ ":framework-core-sources",
+ ":framework-drm-sources",
+ ":framework-graphics-nonupdatable-sources",
+ ":framework-jobscheduler-sources",
+ ":framework-keystore-sources",
+ ":framework-identity-sources",
+ ":framework-location-sources",
+ ":framework-lowpan-sources",
+ ":framework-mca-effect-sources",
+ ":framework-mca-filterfw-sources",
+ ":framework-mca-filterpacks-sources",
+ ":framework-media-non-updatable-sources",
+ ":framework-mms-sources",
+ ":framework-omapi-sources",
+ ":framework-opengl-sources",
+ ":framework-rs-sources",
+ ":framework-sax-sources",
+ ":framework-telecomm-sources",
+ ":framework-telephony-common-sources",
+ ":framework-telephony-sources",
+ ":framework-vcn-util-sources",
+ ":framework-wifi-annotations",
+ ":framework-wifi-non-updatable-sources",
+ ":PacProcessor-aidl-sources",
+ ":ProxyHandler-aidl-sources",
+ ":net-utils-framework-common-srcs",
+ ":platform-compat-native-aidl",
+ ":credstore_aidl",
+ ":dumpstate_aidl",
+ ":framework_native_aidl",
+ ":gatekeeper_aidl",
+ ":gsiservice_aidl",
+ ":idmap2_aidl",
+ ":idmap2_core_aidl",
+ ":incidentcompanion_aidl",
+ ":inputconstants_aidl",
+ ":installd_aidl",
+ ":libaudioclient_aidl",
+ ":libbinder_aidl",
+ ":libbluetooth-binder-aidl",
+ ":libcamera_client_aidl",
+ ":libcamera_client_framework_aidl",
+ ":libupdate_engine_aidl",
+ ":logd_aidl",
+ ":resourcemanager_aidl",
+ ":storaged_aidl",
+ ":vold_aidl",
+ ":deviceproductinfoconstants_aidl",
+ ],
local_include_dirs: [
"media/aidl",
],
@@ -329,6 +384,7 @@ java_defaults {
"modules-utils-preconditions",
"modules-utils-synchronous-result-receiver",
"modules-utils-os",
+ "modules-utils-uieventlogger-interface",
"framework-permission-aidl-java",
"spatializer-aidl-java",
"audiopolicy-types-aidl-java",
diff --git a/cmds/idmap2/Android.bp b/cmds/idmap2/Android.bp
index 6ef6845c75f2..18ec5a407b24 100644
--- a/cmds/idmap2/Android.bp
+++ b/cmds/idmap2/Android.bp
@@ -23,6 +23,7 @@ package {
cc_defaults {
name: "idmap2_defaults",
+ cpp_std: "gnu++2b",
tidy: true,
tidy_checks: [
"modernize-*",
@@ -31,6 +32,7 @@ cc_defaults {
"android-*",
"misc-*",
"readability-*",
+ "-readability-identifier-length",
],
tidy_checks_as_errors: [
"modernize-*",
@@ -54,7 +56,6 @@ cc_defaults {
"-readability-convert-member-functions-to-static",
"-readability-duplicate-include",
"-readability-else-after-return",
- "-readability-identifier-length",
"-readability-named-parameter",
"-readability-redundant-access-specifiers",
"-readability-uppercase-literal-suffix",
@@ -115,6 +116,7 @@ cc_library {
"libidmap2/proto/*.proto",
],
host_supported: true,
+ tidy: false,
proto: {
type: "lite",
export_proto_headers: true,
diff --git a/cmds/idmap2/tests/ResultTests.cpp b/cmds/idmap2/tests/ResultTests.cpp
index f2f8854cec3a..f9c4fa3c798b 100644
--- a/cmds/idmap2/tests/ResultTests.cpp
+++ b/cmds/idmap2/tests/ResultTests.cpp
@@ -259,7 +259,8 @@ TEST(ResultTests, CascadeError) {
}
struct NoCopyContainer {
- uint32_t value; // NOLINT(misc-non-private-member-variables-in-classes)
+ uint32_t value = 0; // NOLINT(misc-non-private-member-variables-in-classes)
+ NoCopyContainer() = default;
NoCopyContainer(const NoCopyContainer&) = delete;
NoCopyContainer& operator=(const NoCopyContainer&) = delete;
};
@@ -268,7 +269,7 @@ Result<std::unique_ptr<NoCopyContainer>> CreateNoCopyContainer(bool succeed) {
if (!succeed) {
return Error("foo");
}
- std::unique_ptr<NoCopyContainer> p(new NoCopyContainer{0U});
+ std::unique_ptr<NoCopyContainer> p(new NoCopyContainer{});
p->value = 42U;
return std::move(p);
}
diff --git a/cmds/svc/src/com/android/commands/svc/UsbCommand.java b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
index 115c1f23c521..66e982a9ec1c 100644
--- a/cmds/svc/src/com/android/commands/svc/UsbCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/UsbCommand.java
@@ -16,12 +16,18 @@
package com.android.commands.svc;
+import android.app.ActivityThread;
import android.content.Context;
import android.hardware.usb.IUsbManager;
import android.hardware.usb.UsbManager;
+import android.hardware.usb.UsbPort;
+import android.hardware.usb.UsbPortStatus;
+import android.os.Looper;
import android.os.RemoteException;
import android.os.ServiceManager;
+import java.util.List;
+
public class UsbCommand extends Svc.Command {
public UsbCommand() {
super("usb");
@@ -39,8 +45,9 @@ public class UsbCommand extends Svc.Command {
+ "usage: svc usb setFunctions [function]\n"
+ " Set the current usb function. If function is blank, sets to charging.\n"
+ " svc usb setScreenUnlockedFunctions [function]\n"
- + " Sets the functions which, if the device was charging, become current on"
- + "screen unlock. If function is blank, turn off this feature.\n"
+ + " Sets the functions which, if the device was charging,\n"
+ + " become current on screen unlock.\n"
+ + " If function is blank, turn off this feature.\n"
+ " svc usb getFunctions\n"
+ " Gets the list of currently enabled functions\n"
+ " possible values of [function] are any of 'mtp', 'ptp', 'rndis',\n"
@@ -59,14 +66,21 @@ public class UsbCommand extends Svc.Command {
+ " svc usb getUsbHalVersion\n"
+ " Gets current USB Hal Version\n"
+ " possible values of Hal version are any of 'unknown', 'V1_0', 'V1_1',\n"
- + " 'V1_2', 'V1_3'\n";
+ + " 'V1_2', 'V1_3'\n"
+ + " svc usb resetUsbPort [port number]\n"
+ + " Reset the specified connected usb port\n"
+ + " default: the first connected usb port\n";
}
@Override
public void run(String[] args) {
if (args.length >= 2) {
+ Looper.prepareMainLooper();
+ Context context = ActivityThread.systemMain().getSystemContext();
+ UsbManager usbManager = context.getSystemService(UsbManager.class);
IUsbManager usbMgr = IUsbManager.Stub.asInterface(ServiceManager.getService(
Context.USB_SERVICE));
+
if ("setFunctions".equals(args[1])) {
try {
usbMgr.setCurrentFunctions(UsbManager.usbFunctionsFromString(
@@ -134,6 +148,49 @@ public class UsbCommand extends Svc.Command {
System.err.println("Error communicating with UsbManager: " + e);
}
return;
+ } else if ("resetUsbPort".equals(args[1])) {
+ try {
+ int portNum = args.length >= 3 ? Integer.parseInt(args[2]) : -1;
+ UsbPort port = null;
+ UsbPortStatus portStatus = null;
+ List<UsbPort> ports = usbManager.getPorts();
+ final int numPorts = ports.size();
+
+ if (numPorts > 0) {
+ if (portNum != -1 && portNum < numPorts) {
+ portStatus = ports.get(portNum).getStatus();
+ if (portStatus.isConnected()) {
+ port = ports.get(portNum);
+ System.err.println(
+ "Get the USB port: port" + portNum);
+ }
+ } else {
+ for (portNum = 0; portNum < numPorts; portNum++) {
+ UsbPortStatus status = ports.get(portNum).getStatus();
+ if (status.isConnected()) {
+ port = ports.get(portNum);
+ portStatus = status;
+ System.err.println(
+ "Use the default USB port: port" + portNum);
+ break;
+ }
+ }
+ }
+ if (port != null && portStatus.isConnected()) {
+ System.err.println(
+ "Reset the USB port: port" + portNum);
+ port.resetUsbPort();
+ } else {
+ System.err.println(
+ "There is no available reset USB port");
+ }
+ } else {
+ System.err.println("No USB ports");
+ }
+ } catch (Exception e) {
+ System.err.println("Error communicating with UsbManager: " + e);
+ }
+ return;
}
}
System.err.println(longHelp());
diff --git a/cmds/telecom/src/com/android/commands/telecom/Telecom.java b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
index 52f883b5fbb7..50c2e75c3a01 100644
--- a/cmds/telecom/src/com/android/commands/telecom/Telecom.java
+++ b/cmds/telecom/src/com/android/commands/telecom/Telecom.java
@@ -52,7 +52,7 @@ public final class Telecom extends BaseCommand {
(new Telecom()).run(args);
}
-
+ private static final String CALLING_PACKAGE = Telecom.class.getPackageName();
private static final String COMMAND_SET_PHONE_ACCOUNT_ENABLED = "set-phone-account-enabled";
private static final String COMMAND_SET_PHONE_ACCOUNT_DISABLED = "set-phone-account-disabled";
private static final String COMMAND_REGISTER_PHONE_ACCOUNT = "register-phone-account";
@@ -286,7 +286,7 @@ public final class Telecom extends BaseCommand {
final String label = nextArgRequired();
PhoneAccount account = PhoneAccount.builder(handle, label)
.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER).build();
- mTelecomService.registerPhoneAccount(account);
+ mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
System.out.println("Success - " + handle + " registered.");
}
@@ -316,7 +316,7 @@ public final class Telecom extends BaseCommand {
.addSupportedUriScheme(PhoneAccount.SCHEME_TEL)
.addSupportedUriScheme(PhoneAccount.SCHEME_VOICEMAIL)
.build();
- mTelecomService.registerPhoneAccount(account);
+ mTelecomService.registerPhoneAccount(account, CALLING_PACKAGE);
System.out.println("Success - " + handle + " registered.");
}
@@ -358,7 +358,7 @@ public final class Telecom extends BaseCommand {
private void runUnregisterPhoneAccount() throws RemoteException {
final PhoneAccountHandle handle = getPhoneAccountHandleFromArgs();
- mTelecomService.unregisterPhoneAccount(handle);
+ mTelecomService.unregisterPhoneAccount(handle, CALLING_PACKAGE);
System.out.println("Success - " + handle + " unregistered.");
}
@@ -395,11 +395,11 @@ public final class Telecom extends BaseCommand {
}
private void runGetDefaultDialer() throws RemoteException {
- System.out.println(mTelecomService.getDefaultDialerPackage());
+ System.out.println(mTelecomService.getDefaultDialerPackage(CALLING_PACKAGE));
}
private void runGetSystemDialer() throws RemoteException {
- System.out.println(mTelecomService.getSystemDialerPackage());
+ System.out.println(mTelecomService.getSystemDialerPackage(CALLING_PACKAGE));
}
private void runWaitOnHandler() throws RemoteException {
diff --git a/core/api/current.txt b/core/api/current.txt
index 3f12b6ca7d64..175a8e301e57 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -12310,6 +12310,7 @@ package android.content.pm {
method @Nullable public java.util.Set<java.lang.String> getCategories();
method @Nullable public CharSequence getDisabledMessage();
method public int getDisabledReason();
+ method public int getExcludedFromSurfaces();
method @Nullable public android.os.PersistableBundle getExtras();
method @NonNull public String getId();
method @Nullable public android.content.Intent getIntent();
@@ -12327,8 +12328,8 @@ package android.content.pm {
method public boolean isDeclaredInManifest();
method public boolean isDynamic();
method public boolean isEnabled();
+ method public boolean isExcludedFromSurfaces(int);
method public boolean isImmutable();
- method public boolean isIncludedIn(int);
method public boolean isPinned();
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.ShortcutInfo> CREATOR;
@@ -39190,6 +39191,7 @@ package android.service.quickaccesswallet {
public abstract class QuickAccessWalletService extends android.app.Service {
ctor public QuickAccessWalletService();
method @Nullable public android.app.PendingIntent getTargetActivityPendingIntent();
+ method public final boolean getUseTargetActivityForQuickAccess();
method @Nullable public android.os.IBinder onBind(@NonNull android.content.Intent);
method public abstract void onWalletCardSelected(@NonNull android.service.quickaccesswallet.SelectWalletCardRequest);
method public abstract void onWalletCardsRequested(@NonNull android.service.quickaccesswallet.GetWalletCardsRequest, @NonNull android.service.quickaccesswallet.GetWalletCardsCallback);
@@ -43403,7 +43405,7 @@ package android.telephony {
method public int getPhoneType();
method @RequiresPermission(anyOf={"android.permission.READ_PRIVILEGED_PHONE_STATE", android.Manifest.permission.READ_PHONE_STATE}) public int getPreferredOpportunisticDataSubscription();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState();
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState(boolean, boolean);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.READ_PHONE_STATE, android.Manifest.permission.ACCESS_COARSE_LOCATION}) public android.telephony.ServiceState getServiceState(int);
method @Nullable public android.telephony.SignalStrength getSignalStrength();
method public int getSimCarrierId();
method @Nullable public CharSequence getSimCarrierIdName();
@@ -43458,10 +43460,10 @@ package android.telephony {
method @Deprecated public void listen(android.telephony.PhoneStateListener, int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void rebootModem();
method public void registerTelephonyCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
- method public void registerTelephonyCallback(boolean, boolean, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
+ method public void registerTelephonyCallback(int, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyCallback);
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void requestCellInfoUpdate(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyManager.CellInfoCallback);
method @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(android.telephony.NetworkScanRequest, java.util.concurrent.Executor, android.telephony.TelephonyScanManager.NetworkScanCallback);
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(boolean, @NonNull android.telephony.NetworkScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyScanManager.NetworkScanCallback);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.MODIFY_PHONE_STATE, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.telephony.NetworkScan requestNetworkScan(int, @NonNull android.telephony.NetworkScanRequest, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.TelephonyScanManager.NetworkScanCallback);
method public void sendDialerSpecialCode(String);
method public String sendEnvelopeWithStatus(String);
method @RequiresPermission(android.Manifest.permission.CALL_PHONE) public void sendUssdRequest(String, android.telephony.TelephonyManager.UssdResponseCallback, android.os.Handler);
@@ -43571,6 +43573,9 @@ package android.telephony {
field public static final String EXTRA_STATE_RINGING;
field public static final String EXTRA_SUBSCRIPTION_ID = "android.telephony.extra.SUBSCRIPTION_ID";
field public static final String EXTRA_VOICEMAIL_NUMBER = "android.telephony.extra.VOICEMAIL_NUMBER";
+ field public static final int INCLUDE_LOCATION_DATA_COARSE = 1; // 0x1
+ field public static final int INCLUDE_LOCATION_DATA_FINE = 2; // 0x2
+ field public static final int INCLUDE_LOCATION_DATA_NONE = 0; // 0x0
field public static final String METADATA_HIDE_VOICEMAIL_SETTINGS_MENU = "android.telephony.HIDE_VOICEMAIL_SETTINGS_MENU";
field public static final int MULTISIM_ALLOWED = 0; // 0x0
field public static final int MULTISIM_NOT_SUPPORTED_BY_CARRIER = 2; // 0x2
@@ -44232,6 +44237,9 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.READ_PRECISE_PHONE_STATE) public void unregisterImsRegistrationCallback(@NonNull android.telephony.ims.RegistrationManager.RegistrationCallback);
method public void unregisterImsStateCallback(@NonNull android.telephony.ims.ImsStateCallback);
field public static final String ACTION_SHOW_CAPABILITY_DISCOVERY_OPT_IN = "android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
+ field public static final int CAPABILITY_TYPE_NONE = 0; // 0x0
+ field public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1; // 0x1
+ field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
}
public final class ImsReasonInfo implements android.os.Parcelable {
@@ -44453,10 +44461,10 @@ package android.telephony.ims {
method public void unregisterFeatureProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.FeatureProvisioningCallback);
}
- public static class ProvisioningManager.FeatureProvisioningCallback {
+ public abstract static class ProvisioningManager.FeatureProvisioningCallback {
ctor public ProvisioningManager.FeatureProvisioningCallback();
- method public void onFeatureProvisioningChanged(int, int, boolean);
- method public void onRcsFeatureProvisioningChanged(int, int, boolean);
+ method public abstract void onFeatureProvisioningChanged(int, int, boolean);
+ method public abstract void onRcsFeatureProvisioningChanged(int, int, boolean);
}
public class RcsUceAdapter {
@@ -44499,15 +44507,6 @@ package android.telephony.ims.feature {
field public static final int CAPABILITY_TYPE_VOICE = 1; // 0x1
}
- public class RcsFeature {
- }
-
- public static class RcsFeature.RcsImsCapabilities {
- field public static final int CAPABILITY_TYPE_NONE = 0; // 0x0
- field public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1; // 0x1
- field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
- }
-
}
package android.telephony.ims.stub {
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index d094f4bad511..874ade36034a 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -198,6 +198,7 @@ package android {
field public static final String MANAGE_WEAK_ESCROW_TOKEN = "android.permission.MANAGE_WEAK_ESCROW_TOKEN";
field public static final String MANAGE_WIFI_COUNTRY_CODE = "android.permission.MANAGE_WIFI_COUNTRY_CODE";
field public static final String MARK_DEVICE_ORGANIZATION_OWNED = "android.permission.MARK_DEVICE_ORGANIZATION_OWNED";
+ field public static final String MEDIA_RESOURCE_OVERRIDE_PID = "android.permission.MEDIA_RESOURCE_OVERRIDE_PID";
field public static final String MODIFY_APPWIDGET_BIND_PERMISSIONS = "android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS";
field public static final String MODIFY_AUDIO_ROUTING = "android.permission.MODIFY_AUDIO_ROUTING";
field public static final String MODIFY_CELL_BROADCASTS = "android.permission.MODIFY_CELL_BROADCASTS";
@@ -1046,7 +1047,7 @@ package android.app {
public class WallpaperManager {
method @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) public void clearWallpaper(int, int);
- method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public float getWallpaperDimAmount();
+ method @FloatRange(from=0.0f, to=1.0f) @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public float getWallpaperDimAmount();
method public void setDisplayOffset(android.os.IBinder, int, int);
method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_COMPONENT) public boolean setWallpaperComponent(android.content.ComponentName);
method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT) public void setWallpaperDimAmount(@FloatRange(from=0.0f, to=1.0f) float);
@@ -1105,7 +1106,7 @@ package android.app.admin {
method @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, android.Manifest.permission.PROVISION_DEMO_DEVICE}) public void provisionFullyManagedDevice(@NonNull android.app.admin.FullyManagedDeviceProvisioningParams) throws android.app.admin.ProvisioningException;
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void resetDrawables(@NonNull String[]);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_MANAGEMENT_RESOURCES) public void resetStrings(@NonNull String[]);
- method @RequiresPermission(android.Manifest.permission.SEND_LOST_MODE_LOCATION_UPDATES) public void sendLostModeLocationUpdate(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method @RequiresPermission(android.Manifest.permission.TRIGGER_LOST_MODE) public void sendLostModeLocationUpdate(@NonNull java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.lang.Boolean>);
method @Deprecated @RequiresPermission(android.Manifest.permission.MANAGE_DEVICE_ADMINS) public boolean setActiveProfileOwner(@NonNull android.content.ComponentName, String) throws java.lang.IllegalArgumentException;
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setDeviceProvisioningConfigApplied();
method @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public void setDpcDownloaded(boolean);
@@ -2659,18 +2660,18 @@ package android.app.wallpapereffectsgeneration {
method public int describeContents();
method @NonNull public float[] getAnchorPointInOutputUvSpace();
method @NonNull public float[] getAnchorPointInWorldSpace();
- method public float getCameraOrbitPitchDegrees();
- method public float getCameraOrbitYawDegrees();
+ method @FloatRange(from=-90.0F, to=90.0f) public float getCameraOrbitPitchDegrees();
+ method @FloatRange(from=-180.0F, to=180.0f) public float getCameraOrbitYawDegrees();
method public float getDollyDistanceInWorldSpace();
- method public float getFrustumFarInWorldSpace();
- method public float getFrustumNearInWorldSpace();
- method public float getVerticalFovDegrees();
+ method @FloatRange(from=0.0f) public float getFrustumFarInWorldSpace();
+ method @FloatRange(from=0.0f) public float getFrustumNearInWorldSpace();
+ method @FloatRange(from=0.0f, to=180.0f, fromInclusive=false) public float getVerticalFovDegrees();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.CameraAttributes> CREATOR;
}
public static final class CameraAttributes.Builder {
- ctor public CameraAttributes.Builder(@NonNull float[], @NonNull float[]);
+ ctor public CameraAttributes.Builder(@NonNull @Size(3) float[], @NonNull @Size(2) float[]);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes build();
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setCameraOrbitPitchDegrees(@FloatRange(from=-90.0F, to=90.0f) float);
method @NonNull public android.app.wallpapereffectsgeneration.CameraAttributes.Builder setCameraOrbitYawDegrees(@FloatRange(from=-180.0F, to=180.0f) float);
@@ -2698,12 +2699,11 @@ package android.app.wallpapereffectsgeneration {
method @NonNull public String getTaskId();
method @NonNull public java.util.List<android.app.wallpapereffectsgeneration.TexturedMesh> getTexturedMeshes();
method public void writeToParcel(@NonNull android.os.Parcel, int);
- field public static final int CINEMATIC_EFFECT_STATUS_ERROR = 2; // 0x2
- field public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 3; // 0x3
+ field public static final int CINEMATIC_EFFECT_STATUS_ERROR = 0; // 0x0
+ field public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 2; // 0x2
field public static final int CINEMATIC_EFFECT_STATUS_OK = 1; // 0x1
- field public static final int CINEMATIC_EFFECT_STATUS_PENDING = 4; // 0x4
- field public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 5; // 0x5
- field public static final int CINEMATIC_EFFECT_STATUS_UNKNOWN = 0; // 0x0
+ field public static final int CINEMATIC_EFFECT_STATUS_PENDING = 3; // 0x3
+ field public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 4; // 0x4
field @NonNull public static final android.os.Parcelable.Creator<android.app.wallpapereffectsgeneration.CinematicEffectResponse> CREATOR;
field public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2; // 0x2
field public static final int IMAGE_CONTENT_TYPE_OTHER = 3; // 0x3
@@ -3413,6 +3413,8 @@ package android.content.pm {
field public static final String EXTRA_REQUEST_PERMISSIONS_RESULTS = "android.content.pm.extra.REQUEST_PERMISSIONS_RESULTS";
field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
field public static final String FEATURE_CONTEXT_HUB = "android.hardware.context_hub";
+ field public static final String FEATURE_EROFS = "android.software.erofs";
+ field public static final String FEATURE_EROFS_LEGACY = "android.software.erofs_legacy";
field public static final String FEATURE_GAME_SERVICE = "android.software.game_service";
field public static final String FEATURE_INCREMENTAL_DELIVERY = "android.software.incremental_delivery";
field public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow";
@@ -6341,7 +6343,7 @@ package android.media {
}
public final class MediaCodec {
- method @NonNull @RequiresPermission("android.permission.MEDIA_RESOURCE_OVERRIDE_PID") public static android.media.MediaCodec createByCodecNameForClient(@NonNull String, int, int) throws java.io.IOException;
+ method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_RESOURCE_OVERRIDE_PID) public static android.media.MediaCodec createByCodecNameForClient(@NonNull String, int, int) throws java.io.IOException;
}
public class MediaPlayer implements android.media.AudioRouting android.media.VolumeAutomation {
@@ -12042,8 +12044,9 @@ package android.service.wallpapereffectsgeneration {
public abstract class WallpaperEffectsGenerationService extends android.app.Service {
ctor public WallpaperEffectsGenerationService();
method @NonNull public final android.os.IBinder onBind(@NonNull android.content.Intent);
- method public abstract void onGenerateCinematicEffect(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectRequest);
+ method @MainThread public abstract void onGenerateCinematicEffect(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectRequest);
method public final void returnCinematicEffectResponse(@NonNull android.app.wallpapereffectsgeneration.CinematicEffectResponse);
+ field public static final String SERVICE_INTERFACE = "android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService";
}
}
@@ -15023,7 +15026,7 @@ package android.telephony.ims {
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestAvailability(@NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(allOf={android.Manifest.permission.ACCESS_RCS_USER_CAPABILITY_EXCHANGE, android.Manifest.permission.READ_CONTACTS}) public void requestCapabilities(@NonNull java.util.Collection<android.net.Uri>, @NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.RcsUceAdapter.CapabilitiesCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setUceSettingEnabled(boolean) throws android.telephony.ims.ImsException;
- field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
+ field @Deprecated public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
field public static final int CAPABILITY_UPDATE_TRIGGER_ETAG_EXPIRED = 1; // 0x1
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_2G = 7; // 0x7
field public static final int CAPABILITY_UPDATE_TRIGGER_MOVE_TO_3G = 6; // 0x6
@@ -15306,6 +15309,9 @@ package android.telephony.ims.feature {
method public void addCapabilities(int);
method public boolean isCapable(int);
method public void removeCapabilities(int);
+ field public static final int CAPABILITY_TYPE_NONE = 0; // 0x0
+ field public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1; // 0x1
+ field public static final int CAPABILITY_TYPE_PRESENCE_UCE = 2; // 0x2
}
}
diff --git a/core/api/system-lint-baseline.txt b/core/api/system-lint-baseline.txt
index 1b45e88584fe..db375d42f0b1 100644
--- a/core/api/system-lint-baseline.txt
+++ b/core/api/system-lint-baseline.txt
@@ -99,15 +99,6 @@ ProtectedMember: android.service.notification.NotificationAssistantService#attac
-RethrowRemoteException: android.app.WallpaperManager#getWallpaperDimAmount():
- Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#getWallpaperDimmingAmount():
- Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#setWallpaperDimAmount(float):
- Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-RethrowRemoteException: android.app.WallpaperManager#setWallpaperDimmingAmount(float):
- Methods calling system APIs should rethrow `RemoteException` as `RuntimeException` (but do not list it in the throws clause)
-
SamShouldBeLast: android.accounts.AccountManager#addAccount(String, String, String[], android.os.Bundle, android.app.Activity, android.accounts.AccountManagerCallback<android.os.Bundle>, android.os.Handler):
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index d984abe457c9..1fdf288a326e 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2428,7 +2428,7 @@ package android.service.quicksettings {
package android.service.voice {
public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector {
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public void triggerHardwareRecognitionEventForTest(int, int, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[]);
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public void triggerHardwareRecognitionEventForTest(int, int, boolean, int, int, int, boolean, @NonNull android.media.AudioFormat, @Nullable byte[], @NonNull java.util.List<android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra>);
}
public static final class AlwaysOnHotwordDetector.EventPayload.Builder {
diff --git a/core/java/Android.bp b/core/java/Android.bp
index a5526bc66431..f081a439c49c 100644
--- a/core/java/Android.bp
+++ b/core/java/Android.bp
@@ -145,16 +145,16 @@ genrule {
out: ["com/android/internal/util/FrameworkStatsLog.java"],
}
+// Library that provides functionality to log UiEvents in framework space.
+// If this functionality is needed outside the framework, the interfaces library
+// can be re-used and a local implementation is needed.
java_library {
name: "uieventloggerlib",
srcs: [
- "com/android/internal/logging/UiEvent.java",
- "com/android/internal/logging/UiEventLogger.java",
"com/android/internal/logging/UiEventLoggerImpl.java",
- "com/android/internal/logging/InstanceId.java",
- "com/android/internal/logging/InstanceIdSequence.java",
":statslog-framework-java-gen",
],
+ static_libs: ["modules-utils-uieventlogger-interface"],
}
filegroup {
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 82ff42b41799..170853020811 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -465,7 +465,8 @@ public class Dialog implements DialogInterface, Window.Callback,
onBackPressed();
}
};
- getOnBackInvokedDispatcher().registerSystemOnBackInvokedCallback(mDefaultBackCallback);
+ getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
+ mDefaultBackCallback, OnBackInvokedDispatcher.PRIORITY_DEFAULT);
mDefaultBackCallback = null;
}
}
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 28c273ec50a6..167de463ad17 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -211,6 +211,7 @@ interface IWallpaperManager {
*
* @hide
*/
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT)")
oneway void setWallpaperDimAmount(float dimAmount);
/**
@@ -219,6 +220,7 @@ interface IWallpaperManager {
*
* @hide
*/
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT)")
float getWallpaperDimAmount();
/**
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index e016027329ac..fb34af7088fe 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -405,8 +405,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
writeTo.write(buffer, 0, readByteCount);
writeTo.flush();
}
- } catch (IOException ioe) {
- Log.w(TAG, "Error while reading/writing to streams");
+ } catch (IOException ignored) {
} finally {
IoUtils.closeQuietly(readFrom);
IoUtils.closeQuietly(writeTo);
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index 0a18588e0131..ea80369983a5 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -2023,7 +2023,7 @@ public class WallpaperManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.SET_WALLPAPER_DIM_AMOUNT)
- public float getWallpaperDimAmount() {
+ public @FloatRange (from = 0f, to = 1f) float getWallpaperDimAmount() {
if (sGlobals.mService == null) {
Log.w(TAG, "WallpaperService not running");
throw new RuntimeException(new DeadSystemException());
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 7269b0d91d02..8a521ec37ab0 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6127,7 +6127,7 @@ public class DevicePolicyManager {
* organization-owned managed profile.
*
* <p>The caller must hold the
- * {@link android.Manifest.permission#SEND_LOST_MODE_LOCATION_UPDATES} permission.
+ * {@link android.Manifest.permission#TRIGGER_LOST_MODE} permission.
*
* <p> Not for use by third-party applications.
*
@@ -6137,7 +6137,7 @@ public class DevicePolicyManager {
* @hide
*/
@SystemApi
- @RequiresPermission(android.Manifest.permission.SEND_LOST_MODE_LOCATION_UPDATES)
+ @RequiresPermission(android.Manifest.permission.TRIGGER_LOST_MODE)
public void sendLostModeLocationUpdate(@NonNull @CallbackExecutor Executor executor,
@NonNull Consumer<Boolean> callback) {
throwIfParentInstance("sendLostModeLocationUpdate");
diff --git a/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS b/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS
index f5604347065e..0ec825371515 100644
--- a/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS
+++ b/core/java/android/app/admin/EnterprisePlatformSecurity_OWNERS
@@ -1,4 +1,5 @@
rubinxu@google.com
acjohnston@google.com
pgrafov@google.com
+ayushsha@google.com
alexkershaw@google.com #{LAST_RESORT_SUGGESTION} \ No newline at end of file
diff --git a/core/java/android/app/admin/WorkDeviceExperience_OWNERS b/core/java/android/app/admin/WorkDeviceExperience_OWNERS
index dcacaa25a236..7c90feb1871f 100644
--- a/core/java/android/app/admin/WorkDeviceExperience_OWNERS
+++ b/core/java/android/app/admin/WorkDeviceExperience_OWNERS
@@ -2,4 +2,5 @@ work-device-experience+reviews@google.com
scottjonathan@google.com
arangelov@google.com
kholoudm@google.com
+eliselliott@google.com
alexkershaw@google.com #{LAST_RESORT_SUGGESTION} \ No newline at end of file
diff --git a/core/java/android/app/backup/BackupManager.java b/core/java/android/app/backup/BackupManager.java
index 67f631f98f0b..88a7c0f910d3 100644
--- a/core/java/android/app/backup/BackupManager.java
+++ b/core/java/android/app/backup/BackupManager.java
@@ -246,6 +246,9 @@ public class BackupManager {
* new changes to its data. A backup operation using your application's
* {@link android.app.backup.BackupAgent} subclass will be scheduled when you
* call this method.
+ *
+ * <p>
+ * Note: This only works if your application is performing Key/Value backups.
*/
public void dataChanged() {
checkServiceBinder();
@@ -268,6 +271,8 @@ public class BackupManager {
* as the caller.
*
* @param packageName The package name identifying the application to back up.
+ * <p>
+ * Note: Only works for packages performing Key/Value backups.
*/
public static void dataChanged(String packageName) {
checkServiceBinder();
diff --git a/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java b/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java
index dfbc7a4c3276..c91ce24dfd8d 100644
--- a/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java
+++ b/core/java/android/app/wallpapereffectsgeneration/CameraAttributes.java
@@ -18,6 +18,7 @@ package android.app.wallpapereffectsgeneration;
import android.annotation.FloatRange;
import android.annotation.NonNull;
+import android.annotation.Size;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -117,6 +118,7 @@ public final class CameraAttributes implements Parcelable {
/**
* Get the camera yaw orbit rotation.
*/
+ @FloatRange(from = -180.0f, to = 180.0f)
public float getCameraOrbitYawDegrees() {
return mCameraOrbitYawDegrees;
}
@@ -124,6 +126,7 @@ public final class CameraAttributes implements Parcelable {
/**
* Get the camera pitch orbit rotation.
*/
+ @FloatRange(from = -90.0f, to = 90.0f)
public float getCameraOrbitPitchDegrees() {
return mCameraOrbitPitchDegrees;
}
@@ -138,6 +141,7 @@ public final class CameraAttributes implements Parcelable {
/**
* Get the camera vertical fov degrees.
*/
+ @FloatRange(from = 0.0f, to = 180.0f, fromInclusive = false)
public float getVerticalFovDegrees() {
return mVerticalFovDegrees;
}
@@ -145,6 +149,7 @@ public final class CameraAttributes implements Parcelable {
/**
* Get the frustum in near plane.
*/
+ @FloatRange(from = 0.0f)
public float getFrustumNearInWorldSpace() {
return mFrustumNearInWorldSpace;
}
@@ -152,6 +157,7 @@ public final class CameraAttributes implements Parcelable {
/**
* Get the frustum in far plane.
*/
+ @FloatRange(from = 0.0f)
public float getFrustumFarInWorldSpace() {
return mFrustumFarInWorldSpace;
}
@@ -217,8 +223,8 @@ public final class CameraAttributes implements Parcelable {
* @hide
*/
@SystemApi
- public Builder(@NonNull float[] anchorPointInWorldSpace,
- @NonNull float[] anchorPointInOutputUvSpace) {
+ public Builder(@NonNull @Size(3) float[] anchorPointInWorldSpace,
+ @NonNull @Size(2) float[] anchorPointInOutputUvSpace) {
mAnchorPointInWorldSpace = anchorPointInWorldSpace;
mAnchorPointInOutputUvSpace = anchorPointInOutputUvSpace;
}
diff --git a/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java b/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java
index 1254794964dd..b1d2b384a80b 100644
--- a/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java
+++ b/core/java/android/app/wallpapereffectsgeneration/CinematicEffectResponse.java
@@ -39,27 +39,31 @@ import java.util.Objects;
public final class CinematicEffectResponse implements Parcelable {
/** @hide */
@IntDef(prefix = {"CINEMATIC_EFFECT_STATUS_"},
- value = {CINEMATIC_EFFECT_STATUS_UNKNOWN,
+ value = {CINEMATIC_EFFECT_STATUS_ERROR,
CINEMATIC_EFFECT_STATUS_OK,
- CINEMATIC_EFFECT_STATUS_ERROR,
CINEMATIC_EFFECT_STATUS_NOT_READY,
CINEMATIC_EFFECT_STATUS_PENDING,
- CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS})
+ CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS
+ })
@Retention(RetentionPolicy.SOURCE)
public @interface CinematicEffectStatusCode {}
- /** Cinematic effect generation unknown status. */
- public static final int CINEMATIC_EFFECT_STATUS_UNKNOWN = 0;
+ /** Cinematic effect generation failure with internal error. */
+ public static final int CINEMATIC_EFFECT_STATUS_ERROR = 0;
+
/** Cinematic effect generation success. */
public static final int CINEMATIC_EFFECT_STATUS_OK = 1;
- /** Cinematic effect generation failure. */
- public static final int CINEMATIC_EFFECT_STATUS_ERROR = 2;
+
/** Service not ready for cinematic effect generation. */
- public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 3;
- /** Cienmatic effect generation process is pending. */
- public static final int CINEMATIC_EFFECT_STATUS_PENDING = 4;
- /** Too manay requests for server to handle. */
- public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 5;
+ public static final int CINEMATIC_EFFECT_STATUS_NOT_READY = 2;
+ /**
+ * There is already a task being processed for the same task id.
+ * Client should wait for the response and not send the same request
+ * again.
+ */
+ public static final int CINEMATIC_EFFECT_STATUS_PENDING = 3;
+ /** Too many requests for server to handle. */
+ public static final int CINEMATIC_EFFECT_STATUS_TOO_MANY_REQUESTS = 4;
/** @hide */
@IntDef(prefix = {"IMAGE_CONTENT_TYPE_"},
@@ -71,13 +75,13 @@ public final class CinematicEffectResponse implements Parcelable {
@Retention(RetentionPolicy.SOURCE)
public @interface ImageContentType {}
- /** Image content unknown. */
+ /** Unable to determine image type. */
public static final int IMAGE_CONTENT_TYPE_UNKNOWN = 0;
/** Image content is people portrait. */
public static final int IMAGE_CONTENT_TYPE_PEOPLE_PORTRAIT = 1;
/** Image content is landscape. */
public static final int IMAGE_CONTENT_TYPE_LANDSCAPE = 2;
- /** Image content is doesn't belong to other types. */
+ /** Image content is not people portrait or landscape. */
public static final int IMAGE_CONTENT_TYPE_OTHER = 3;
diff --git a/core/java/android/companion/SystemDataTransferRequest.java b/core/java/android/companion/SystemDataTransferRequest.java
index e3b0369e203d..ccc720edbe33 100644
--- a/core/java/android/companion/SystemDataTransferRequest.java
+++ b/core/java/android/companion/SystemDataTransferRequest.java
@@ -17,7 +17,7 @@
package android.companion;
import android.annotation.NonNull;
-import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.OneTimeUseBuilder;
@@ -38,10 +38,25 @@ public final class SystemDataTransferRequest implements Parcelable {
private final List<String> mPermissionSyncPackages;
/**
+ * User Id that the request belongs to.
+ * Populated by the system.
+ *
+ * @hide
+ */
+ @UserIdInt
+ private int mUserId;
+
+ /**
+ * Whether the request is consented by the user.
+ * Populated by the system.
+ *
* @hide
*/
+ private boolean mUserConsented = false;
+
+ /* @hide */
public SystemDataTransferRequest(int associationId, boolean syncAllPackages,
- @Nullable List<String> permissionSyncPackages) {
+ @NonNull List<String> permissionSyncPackages) {
mAssociationId = associationId;
mPermissionSyncAllPackages = syncAllPackages;
mPermissionSyncPackages = permissionSyncPackages;
@@ -51,8 +66,7 @@ public final class SystemDataTransferRequest implements Parcelable {
return mAssociationId;
}
- @NonNull
- public boolean isPermissionSyncAllPackages() {
+ public boolean getPermissionSyncAllPackages() {
return mPermissionSyncAllPackages;
}
@@ -61,6 +75,38 @@ public final class SystemDataTransferRequest implements Parcelable {
return mPermissionSyncPackages;
}
+ /* @hide */
+ public int getUserId() {
+ return mUserId;
+ }
+
+ /* @hide */
+ public boolean isUserConsented() {
+ return mUserConsented;
+ }
+
+ /* @hide */
+ public void setUserId(@UserIdInt int userId) {
+ mUserId = userId;
+ }
+
+ /* @hide */
+ public void setUserConsented(boolean isUserConsented) {
+ mUserConsented = isUserConsented;
+ }
+
+ /* @hide */
+ @Override
+ public String toString() {
+ return "SystemDataTransferRequest("
+ + "associationId=" + mAssociationId
+ + ", isPermissionSyncAllPackages=" + mPermissionSyncAllPackages
+ + ", permissionSyncPackages=[" + String.join(",", mPermissionSyncPackages) + "]"
+ + ", userId=" + mUserId
+ + ", isUserConsented=" + mUserConsented
+ + ")";
+ }
+
/**
* A builder for {@link SystemDataTransferRequest}.
*
@@ -90,9 +136,8 @@ public final class SystemDataTransferRequest implements Parcelable {
* <p>If a system or policy granted or revoked permission is granted or revoked by the user
* later, the permission will be ignored.</p>
*
- * @see #setPermissionSyncPackages(List)
- *
* @return the builder
+ * @see #setPermissionSyncPackages(List)
*/
@NonNull
public Builder setPermissionSyncAllPackages() {
@@ -104,10 +149,9 @@ public final class SystemDataTransferRequest implements Parcelable {
* Set a list of packages to sync permissions. You can optionally call
* {@link #setPermissionSyncAllPackages()} to sync permissions for all the packages.
*
- * @see #setPermissionSyncAllPackages()
- *
* @param permissionSyncPackages packages to sync permissions
* @return builder
+ * @see #setPermissionSyncAllPackages()
*/
@NonNull
public Builder setPermissionSyncPackages(@NonNull List<String> permissionSyncPackages) {
@@ -127,6 +171,8 @@ public final class SystemDataTransferRequest implements Parcelable {
mAssociationId = in.readInt();
mPermissionSyncAllPackages = in.readBoolean();
mPermissionSyncPackages = Arrays.asList(in.createString8Array());
+ mUserId = in.readInt();
+ mUserConsented = in.readBoolean();
}
@Override
@@ -134,6 +180,8 @@ public final class SystemDataTransferRequest implements Parcelable {
dest.writeInt(mAssociationId);
dest.writeBoolean(mPermissionSyncAllPackages);
dest.writeString8Array(mPermissionSyncPackages.toArray(new String[0]));
+ dest.writeInt(mUserId);
+ dest.writeBoolean(mUserConsented);
}
@Override
@@ -141,6 +189,18 @@ public final class SystemDataTransferRequest implements Parcelable {
return 0;
}
+ /**
+ * Check if two requests have the same data type.
+ */
+ public boolean hasSameDataType(@NonNull SystemDataTransferRequest request) {
+ // Check if they are permission sync requests.
+ if (this.getPermissionSyncAllPackages() || !this.getPermissionSyncPackages().isEmpty()) {
+ return request.getPermissionSyncAllPackages() || !request.getPermissionSyncPackages()
+ .isEmpty();
+ }
+ return false;
+ }
+
@NonNull
public static final Creator<SystemDataTransferRequest> CREATOR =
new Creator<SystemDataTransferRequest>() {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 81c941eedef0..c91ee1395687 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -4087,6 +4087,28 @@ public abstract class PackageManager {
"android.software.incremental_delivery";
/**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
+ * has the requisite kernel support for the EROFS filesystem present in 4.19 kernels as a
+ * staging driver, which lacks 0padding and big pcluster support.
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_EROFS_LEGACY = "android.software.erofs_legacy";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device
+ * has the requisite kernel support for the EROFS filesystem present in 5.10 kernels, which
+ * has 0padding, big pcluster, and chunked index support.
+ *
+ * @hide
+ */
+ @SystemApi
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_EROFS = "android.software.erofs";
+
+ /**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
* The device has tuner hardware to support tuner operations.
*
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index 41dd5bb3f21d..dc7cd71101b2 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -2257,10 +2257,20 @@ public final class ShortcutInfo implements Parcelable {
}
/**
- * Return true if the shortcut is included in specified surface.
+ * Return true if the shortcut is excluded from specified surface.
*/
- public boolean isIncludedIn(@Surface int surface) {
- return (mExcludedSurfaces & surface) == 0;
+ public boolean isExcludedFromSurfaces(@Surface int surface) {
+ return (mExcludedSurfaces & surface) != 0;
+ }
+
+ /**
+ * Returns a bitmask of all surfaces this shortcut is excluded from.
+ *
+ * @see ShortcutInfo.Builder#setExcludedFromSurfaces(int)
+ */
+ @Surface
+ public int getExcludedFromSurfaces() {
+ return mExcludedSurfaces;
}
/**
@@ -2522,7 +2532,7 @@ public final class ShortcutInfo implements Parcelable {
if (isLongLived()) {
sb.append("Liv");
}
- if (!isIncludedIn(SURFACE_LAUNCHER)) {
+ if (isExcludedFromSurfaces(SURFACE_LAUNCHER)) {
sb.append("Hid-L");
}
sb.append("]");
diff --git a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
index 3a6d5087c260..694d6d8c23c0 100644
--- a/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
+++ b/core/java/android/hardware/soundtrigger/KeyphraseEnrollmentInfo.java
@@ -40,11 +40,11 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
@@ -151,7 +151,7 @@ public class KeyphraseEnrollmentInfo {
return;
}
- List<String> parseErrors = new LinkedList<>();
+ List<String> parseErrors = new ArrayList<>();
mKeyphrasePackageMap = new HashMap<>();
for (ResolveInfo ri : ris) {
try {
diff --git a/core/java/android/permission/PermissionUsageHelper.java b/core/java/android/permission/PermissionUsageHelper.java
index 0b57842cde11..4ed939c48bd7 100644
--- a/core/java/android/permission/PermissionUsageHelper.java
+++ b/core/java/android/permission/PermissionUsageHelper.java
@@ -47,6 +47,7 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.icu.text.ListFormatter;
+import android.location.LocationManager;
import android.media.AudioManager;
import android.os.Process;
import android.os.UserHandle;
@@ -411,10 +412,13 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
}
/**
- * Returns true if the app supports subattribution.
+ * Returns true if the app satisfies subattribution policies and supports it
*/
private boolean isSubattributionSupported(String packageName, int uid) {
try {
+ if (!isLocationProvider(packageName)) {
+ return false;
+ }
PackageManager userPkgManager =
getUserContext(UserHandle.getUserHandleForUid(uid)).getPackageManager();
ApplicationInfo appInfo = userPkgManager.getApplicationInfoAsUser(packageName,
@@ -430,6 +434,15 @@ public class PermissionUsageHelper implements AppOpsManager.OnOpActiveChangedLis
}
/**
+ * @param packageName
+ * @return If the package is location provider
+ */
+ private boolean isLocationProvider(String packageName) {
+ return Objects.requireNonNull(
+ mContext.getSystemService(LocationManager.class)).isProviderPackage(packageName);
+ }
+
+ /**
* Get the raw usages from the system, and then parse out the ones that are not recent enough,
* determine which permission group each belongs in, and removes duplicates (if the same app
* uses multiple permissions of the same group). Stores the package name, attribution tag, user,
diff --git a/core/java/android/permission/Permissions.md b/core/java/android/permission/Permissions.md
index dfe748b09464..e61ecd8781d0 100644
--- a/core/java/android/permission/Permissions.md
+++ b/core/java/android/permission/Permissions.md
@@ -71,9 +71,9 @@ Any app can request any permission via adding an entry in the manifest file like
A requested permission does not necessarily mean that the permission is granted. When and how a
permission is granted depends on the protection level of the permission. If no protection level is
-set, the permission will always be granted. Such "normal" permissions can still be useful as it
-will be easy to find apps using a certain functionality on app stores and by checking `dumpsys
-package`.
+set, it will default to `normal` and the permission will always be granted if requested. Such
+`normal` permissions can still be useful as it will be easy to find apps using a certain
+functionality on app stores and by checking `dumpsys package`.
#### Checking a permission
@@ -686,17 +686,37 @@ able to call APIs not available to other apps. This is implemented by granting p
these system apps and then enforcing the permissions in the API similar to other [install time
permissions](#checking-a-permission).
-System apps are not different from regular apps, but the protection levels (e.g.
+System apps are not different from regular apps, but the protection flags (e.g.
[privileged](#privileged-permissions), [preinstalled](#preinstalled-permissions)) mentioned in this
section are more commonly used by system apps.
-### Multiple permission levels
+### Permission protection level
-It is possible to assign multiple protection levels to a permission. Very common combinations are
-for example adding `signature` to all permissions to make sure the platform signed apps can be
-granted the permission, e.g. `privileged|signature`.
+Every permission has a protection level (`android:protectionlevel`), which is a combination of one
+required protection (`PermissionInfo.getProtection()`) and multiple optional protection flags
+(`PermissionInfo.getProtectionFlags()`).
-The permission will be granted if the app qualifies for _any_ of the permission levels.
+The protection can be one of the following:
+
+- [`normal`](#requesting-a-permission): The permission will be granted to apps requesting it in
+their manifest.
+- [`dangerous`](#runtime-permissions): The permission will be a runtime permission.
+- [`signature`](#signature-permissions): The permission will be granted to apps being signed with
+the same certificate as the app defining the permission. If the permission is a platform permission,
+it means those apps need to be platform-signed.
+- `internal`: This is a no-op protection so that it won't allow granting the permission by itself.
+However, it will be useful when defining permissions that should only be granted according to its
+protection flags, e.g. `internal|role` for a role-only permission.
+
+There are various optional protection flags that can be added to protection level, in addition to
+the required protection, e.g. [appop](#app_op-permissions),
+[preinstalled](#preinstalled-permissions), [privileged](#privileged-permissions),
+[installer](#limited-permissions), [role](#role-protected-permissions) and
+[development](#development-permissions).
+
+The permission will be granted to an app if it meets _any_ of the protection or protection flags (an
+`OR` relationship). For example, `signature|privileged` allows the permission to be granted to
+platform-signed apps as well as privileged apps.
### App-op permissions
@@ -716,18 +736,15 @@ and special behavior. Hence this section is a guideline, not a rule.
#### Defining an app-op permission
Only the platform can reasonably define an app-op permission. The permission is defined in the
-platforms manifest using the `appop` protection level
+platforms manifest using the `appop` protection flag:
```xml
<manifest package="android">
<permission android:name="android.permission.MY_APPOP_PERMISSION"
- android:protectionLevel="appop|signature" />
+ android:protectionLevel="signature|appop" />
</manifest>
```
-Almost always the protection level is app-op | something else, like
-[signature](#signature-permissions) (in the case above) or [privileged](#privileged-permissions).
-
#### Checking an app-op permission
The `PermissionChecker` utility can check app-op permissions with the [same syntax as runtime
@@ -913,12 +930,12 @@ See
> Not recommended
-By adding the `development` protection level to any permissions the permission can be granted via
+By adding the `development` protection flag to any permissions the permission can be granted via
the `pm grant` shell command. This appears to be useful for development and testing, but it is very
highly discouraged. Any user can grant them permanently via adb, hence adding this tag removes
all guarantees the permission might otherwise provide.
-### Other protection levels
+### Other protection flags
There are other levels (such as `runtime`) but they are for special purposes on should not be
used by platform developers.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a6ad5e5863df..48e6a49ef84e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -4515,13 +4515,6 @@ public final class Settings {
public static final String SCREEN_OFF_TIMEOUT = "screen_off_timeout";
/**
- * The amount of time in milliseconds before the device goes to sleep or begins to dream
- * after a period of inactivity while it is docked.
- * @hide
- */
- public static final String SCREEN_OFF_TIMEOUT_DOCKED = "screen_off_timeout_docked";
-
- /**
* The screen backlight brightness between 0 and 255.
*/
@Readable
@@ -17212,6 +17205,12 @@ public final class Settings {
public static final String AMBIENT_TILT_TO_BRIGHT = "ambient_tilt_to_bright";
/**
+ * Whether touch and hold to edit WF is enabled
+ * @hide
+ */
+ public static final String TOUCH_AND_HOLD_WATCH_FACE = "touch_and_hold_watchface";
+
+ /**
* Whether the current watchface is decomposable.
* @hide
*/
diff --git a/core/java/android/service/autofill/FillContext.java b/core/java/android/service/autofill/FillContext.java
index 8331550a7ef5..cc1b6cda82bb 100644
--- a/core/java/android/service/autofill/FillContext.java
+++ b/core/java/android/service/autofill/FillContext.java
@@ -32,7 +32,7 @@ import android.view.autofill.AutofillId;
import com.android.internal.util.DataClass;
-import java.util.LinkedList;
+import java.util.ArrayDeque;
/**
* This class represents a context for each fill request made via {@link
@@ -95,7 +95,7 @@ public final class FillContext implements Parcelable {
* @hide
*/
@NonNull public ViewNode[] findViewNodesByAutofillIds(@NonNull AutofillId[] ids) {
- final LinkedList<ViewNode> nodesToProcess = new LinkedList<>();
+ final ArrayDeque<ViewNode> nodesToProcess = new ArrayDeque<>();
final ViewNode[] foundNodes = new AssistStructure.ViewNode[ids.length];
// Indexes of foundNodes that are not found yet
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
index 70ccd6fbd590..1d74a6470a84 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletService.java
@@ -16,12 +16,20 @@
package android.service.quickaccesswallet;
+import static android.content.pm.PackageManager.GET_META_DATA;
+import static android.content.pm.PackageManager.MATCH_DEFAULT_ONLY;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
+import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@@ -30,6 +38,8 @@ import android.os.RemoteException;
import android.provider.Settings;
import android.util.Log;
+import java.util.List;
+
/**
* A {@code QuickAccessWalletService} provides a list of {@code WalletCard}s shown in the Quick
* Access Wallet. The Quick Access Wallet allows the user to change their selected payment method
@@ -341,6 +351,45 @@ public abstract class QuickAccessWalletService extends Service {
return null;
}
+ /**
+ * Returns the value specified by the attribute
+ * {@link android.R.styleable#QuickAccessWalletService_useTargetActivityForQuickAccess}
+ * in the QuickAccessWalletService's metadata configuration. If the attribute or metadata is
+ * not supplied, returns false.
+ */
+ public final boolean getUseTargetActivityForQuickAccess() {
+ Intent intent = new Intent(SERVICE_INTERFACE).setPackage(getPackageName());
+ List<ResolveInfo> matchedServices = getPackageManager()
+ .queryIntentServices(intent,
+ PackageManager.ResolveInfoFlags.of(
+ GET_META_DATA | MATCH_DIRECT_BOOT_UNAWARE | MATCH_DIRECT_BOOT_AWARE
+ | MATCH_DEFAULT_ONLY));
+
+ ResolveInfo resolveInfo = null;
+
+ for (ResolveInfo info : matchedServices) {
+ ServiceInfo serviceInfo = info.serviceInfo;
+ if (serviceInfo == null) {
+ continue;
+ }
+ String serviceName = serviceInfo.name;
+ if (serviceName == null) {
+ continue;
+ }
+ if (serviceName.equals(getClass().getCanonicalName())) {
+ resolveInfo = info;
+ }
+ }
+
+ if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+ Log.i(TAG, "Matching QuickAccessWalletService not found.");
+ return false;
+ }
+ QuickAccessWalletServiceInfo.ServiceMetadata serviceMetadata =
+ QuickAccessWalletServiceInfo.parseServiceMetadata(this, resolveInfo.serviceInfo);
+ return serviceMetadata != null && serviceMetadata.mUseTargetActivityForQuickAccess;
+ }
+
private void sendWalletServiceEventInternal(WalletServiceEvent serviceEvent) {
if (mEventListener == null) {
Log.i(TAG, "No dismiss listener registered");
diff --git a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
index cf4be739e05a..cc393a4ce605 100644
--- a/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
+++ b/core/java/android/service/quickaccesswallet/QuickAccessWalletServiceInfo.java
@@ -135,7 +135,7 @@ class QuickAccessWalletServiceInfo {
return null;
}
- private static class ServiceMetadata {
+ static class ServiceMetadata {
@Nullable
private final String mSettingsActivity;
@Nullable
@@ -144,7 +144,7 @@ class QuickAccessWalletServiceInfo {
private final CharSequence mShortcutShortLabel;
@Nullable
private final CharSequence mShortcutLongLabel;
- private final boolean mUseTargetActivityForQuickAccess;
+ final boolean mUseTargetActivityForQuickAccess;
private static ServiceMetadata empty() {
return new ServiceMetadata(null, null, null, null, false);
@@ -164,7 +164,7 @@ class QuickAccessWalletServiceInfo {
}
}
- private static ServiceMetadata parseServiceMetadata(Context context, ServiceInfo serviceInfo) {
+ static ServiceMetadata parseServiceMetadata(Context context, ServiceInfo serviceInfo) {
PackageManager pm = context.getPackageManager();
final XmlResourceParser parser =
serviceInfo.loadXmlMetaData(pm, QuickAccessWalletService.SERVICE_META_DATA);
diff --git a/core/java/android/service/voice/AbstractHotwordDetector.java b/core/java/android/service/voice/AbstractHotwordDetector.java
index 01d5638461af..305995a3d2b7 100644
--- a/core/java/android/service/voice/AbstractHotwordDetector.java
+++ b/core/java/android/service/voice/AbstractHotwordDetector.java
@@ -65,6 +65,13 @@ abstract class AbstractHotwordDetector implements HotwordDetector {
}
/**
+ * Method to be called for the detector to ready/register itself with underlying system
+ * services.
+ */
+ abstract void initialize(@Nullable PersistableBundle options,
+ @Nullable SharedMemory sharedMemory);
+
+ /**
* Detect hotword from an externally supplied stream of data.
*
* @return true if the request to start recognition succeeded
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index bec5d1be57fd..b7c86d7c0cb7 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -279,7 +279,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
private KeyphraseMetadata mKeyphraseMetadata;
private final KeyphraseEnrollmentInfo mKeyphraseEnrollmentInfo;
private final IVoiceInteractionManagerService mModelManagementService;
- private final IVoiceInteractionSoundTriggerSession mSoundTriggerSession;
+ private IVoiceInteractionSoundTriggerSession mSoundTriggerSession;
private final SoundTriggerListener mInternalCallback;
private final Callback mExternalCallback;
private final Handler mHandler;
@@ -788,8 +788,7 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
public AlwaysOnHotwordDetector(String text, Locale locale, Callback callback,
KeyphraseEnrollmentInfo keyphraseEnrollmentInfo,
IVoiceInteractionManagerService modelManagementService, int targetSdkVersion,
- boolean supportHotwordDetectionService, @Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory) {
+ boolean supportHotwordDetectionService) {
super(modelManagementService, callback,
supportHotwordDetectionService ? DETECTOR_TYPE_TRUSTED_HOTWORD_DSP
: DETECTOR_TYPE_NORMAL);
@@ -803,6 +802,12 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
mModelManagementService = modelManagementService;
mTargetSdkVersion = targetSdkVersion;
mSupportHotwordDetectionService = supportHotwordDetectionService;
+ }
+
+ @Override
+ void initialize(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) {
+ // TODO: transition to use an API that is not updateState to provide
+ // onHotwordDetectionServiceInitialized status to external callback
if (mSupportHotwordDetectionService) {
updateStateLocked(options, sharedMemory, mInternalCallback,
DETECTOR_TYPE_TRUSTED_HOTWORD_DSP);
@@ -851,7 +856,8 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
public void triggerHardwareRecognitionEventForTest(int status, int soundModelHandle,
boolean captureAvailable, int captureSession, int captureDelayMs, int capturePreambleMs,
- boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data) {
+ boolean triggerInData, @NonNull AudioFormat captureFormat, @Nullable byte[] data,
+ @NonNull List<KeyphraseRecognitionExtra> keyphraseRecognitionExtras) {
Log.d(TAG, "triggerHardwareRecognitionEventForTest()");
synchronized (mLock) {
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
@@ -862,7 +868,8 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
mModelManagementService.triggerHardwareRecognitionEventForTest(
new KeyphraseRecognitionEvent(status, soundModelHandle, captureAvailable,
captureSession, captureDelayMs, capturePreambleMs, triggerInData,
- captureFormat, data, null /* keyphraseExtras */),
+ captureFormat, data, keyphraseRecognitionExtras.toArray(
+ new KeyphraseRecognitionExtra[0])),
mInternalCallback);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
@@ -1210,7 +1217,11 @@ public class AlwaysOnHotwordDetector extends AbstractHotwordDetector {
public void destroy() {
synchronized (mLock) {
if (mAvailability == STATE_KEYPHRASE_ENROLLED) {
- stopRecognition();
+ try {
+ stopRecognition();
+ } catch (Exception e) {
+ Log.i(TAG, "failed to stopRecognition in destroy", e);
+ }
}
mAvailability = STATE_INVALID;
diff --git a/core/java/android/service/voice/HotwordDetectionService.java b/core/java/android/service/voice/HotwordDetectionService.java
index dfe0f542b3ca..19e248fc5cf5 100644
--- a/core/java/android/service/voice/HotwordDetectionService.java
+++ b/core/java/android/service/voice/HotwordDetectionService.java
@@ -243,13 +243,26 @@ public abstract class HotwordDetectionService extends Service {
/**
* Called when the device hardware (such as a DSP) detected the hotword, to request second stage
* validation before handing over the audio to the {@link AlwaysOnHotwordDetector}.
- * <p>
- * After {@code callback} is invoked or {@code timeoutMillis} has passed, and invokes the
+ *
+ * <p>After {@code callback} is invoked or {@code timeoutMillis} has passed, and invokes the
* appropriate {@link AlwaysOnHotwordDetector.Callback callback}.
*
+ * <p>When responding to a detection event, the
+ * {@link HotwordDetectedResult#getHotwordPhraseId()} must match a keyphrase ID listed
+ * in the eventPayload's
+ * {@link AlwaysOnHotwordDetector.EventPayload#getKeyphraseRecognitionExtras()} list. This is
+ * forcing the intention of the {@link HotwordDetectionService} to validate an event from the
+ * voice engine and not augment its result.
+ *
* @param eventPayload Payload data for the hardware detection event. This may contain the
- * trigger audio, if requested when calling
- * {@link AlwaysOnHotwordDetector#startRecognition(int)}.
+ * trigger audio, if requested when calling
+ * {@link AlwaysOnHotwordDetector#startRecognition(int)}.
+ * Each {@link AlwaysOnHotwordDetector} will be associated with at minimum a unique
+ * keyphrase ID indicated by
+ * {@link AlwaysOnHotwordDetector.EventPayload#getKeyphraseRecognitionExtras()}[0].
+ * Any extra
+ * {@link android.hardware.soundtrigger.SoundTrigger.KeyphraseRecognitionExtra}'s
+ * in the eventPayload represent additional phrases detected by the voice engine.
* @param timeoutMillis Timeout in milliseconds for the operation to invoke the callback. If
* the application fails to abide by the timeout, system will close the
* microphone and cancel the operation.
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index 2d662eaf0a4f..d4c58d281a51 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -30,6 +30,7 @@ import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SharedMemory;
+import android.util.Log;
import android.util.Slog;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
@@ -57,8 +58,6 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
SoftwareHotwordDetector(
IVoiceInteractionManagerService managerService,
AudioFormat audioFormat,
- PersistableBundle options,
- SharedMemory sharedMemory,
HotwordDetector.Callback callback) {
super(managerService, callback, DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE);
@@ -66,6 +65,12 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
mAudioFormat = audioFormat;
mCallback = callback;
mHandler = new Handler(Looper.getMainLooper());
+ }
+
+ @Override
+ void initialize(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory) {
+ // TODO: transition to use an API that is not updateState to provide
+ // onHotwordDetectionServiceInitialized status to external callback
updateStateLocked(options, sharedMemory,
new InitializationStateListener(mHandler, mCallback),
DETECTOR_TYPE_TRUSTED_HOTWORD_SOFTWARE);
@@ -113,7 +118,11 @@ class SoftwareHotwordDetector extends AbstractHotwordDetector {
@Override
public void destroy() {
- stopRecognition();
+ try {
+ stopRecognition();
+ } catch (Exception e) {
+ Log.i(TAG, "failed to stopRecognition in destroy", e);
+ }
maybeCloseExistingSession();
try {
diff --git a/core/java/android/service/voice/VoiceInteractionService.java b/core/java/android/service/voice/VoiceInteractionService.java
index bf0cfbe49f31..88b7a58a5709 100644
--- a/core/java/android/service/voice/VoiceInteractionService.java
+++ b/core/java/android/service/voice/VoiceInteractionService.java
@@ -381,12 +381,15 @@ public class VoiceInteractionService extends Service {
synchronized (mLock) {
// Allow only one concurrent recognition via the APIs.
safelyShutdownAllHotwordDetectors();
- mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale, callback,
+
+ mHotwordDetector = new AlwaysOnHotwordDetector(keyphrase, locale,
+ callback,
mKeyphraseEnrollmentInfo, mSystemService,
getApplicationContext().getApplicationInfo().targetSdkVersion,
- supportHotwordDetectionService, options, sharedMemory);
+ supportHotwordDetectionService);
mHotwordDetector.registerOnDestroyListener((detector) -> onDspHotwordDetectorDestroyed(
(AlwaysOnHotwordDetector) detector));
+ mHotwordDetector.initialize(options, sharedMemory);
}
return mHotwordDetector;
}
@@ -436,12 +439,14 @@ public class VoiceInteractionService extends Service {
synchronized (mLock) {
// Allow only one concurrent recognition via the APIs.
safelyShutdownAllHotwordDetectors();
+
mSoftwareHotwordDetector =
new SoftwareHotwordDetector(
- mSystemService, null, options, sharedMemory, callback);
+ mSystemService, null, callback);
mSoftwareHotwordDetector.registerOnDestroyListener(
(detector) -> onMicrophoneHotwordDetectorDestroyed(
(SoftwareHotwordDetector) detector));
+ mSoftwareHotwordDetector.initialize(options, sharedMemory);
}
return mSoftwareHotwordDetector;
}
diff --git a/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java b/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java
index 18b654ec8f04..2898149036c1 100644
--- a/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java
+++ b/core/java/android/service/wallpapereffectsgeneration/WallpaperEffectsGenerationService.java
@@ -19,6 +19,7 @@ package android.service.wallpapereffectsgeneration;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import android.annotation.CallSuper;
+import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.app.Service;
@@ -69,7 +70,6 @@ public abstract class WallpaperEffectsGenerationService extends Service {
* {@link android.permission#MANAGE_WALLPAPER_EFFECTS_GENERATION}
* permission.
*
- * @hide
*/
public static final String SERVICE_INTERFACE =
"android.service.wallpapereffectsgeneration.WallpaperEffectsGenerationService";
@@ -97,6 +97,7 @@ public abstract class WallpaperEffectsGenerationService extends Service {
*
* @param request the cinematic effect request passed from the client.
*/
+ @MainThread
public abstract void onGenerateCinematicEffect(@NonNull CinematicEffectRequest request);
/**
diff --git a/core/java/android/text/TextUtils.java b/core/java/android/text/TextUtils.java
index 28f5c2114b1d..1c2bf1adfa67 100644
--- a/core/java/android/text/TextUtils.java
+++ b/core/java/android/text/TextUtils.java
@@ -70,7 +70,6 @@ import android.util.Log;
import android.util.Printer;
import android.view.View;
-import com.android.internal.R;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
@@ -1183,8 +1182,8 @@ public class TextUtils {
/**
* Transforms a CharSequences to uppercase, copying the sources spans and keeping them spans as
- * much as possible close to their relative original places. In the case the the uppercase
- * string is identical to the sources, the source itself is returned instead of being copied.
+ * much as possible close to their relative original places. If uppercase string is identical
+ * to the sources, the source itself is returned instead of being copied.
*
* If copySpans is set, source must be an instance of Spanned.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1b8dc706371e..7f0943988bee 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -31344,6 +31344,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* {@link android.view.inputmethod.InputMethodManager#startStylusHandwriting(View)} when there
* is stylus movement detected.
*
+ * Note that this attribute has no effect on the View's children. For example, if a
+ * {@link ViewGroup} disables auto handwriting but its children set auto handwriting to true,
+ * auto handwriting will still work for the children, and vice versa.
+ *
* @see #onCreateInputConnection(EditorInfo)
* @see android.view.inputmethod.InputMethodManager#startStylusHandwriting(View)
* @param enabled whether auto handwriting initiation is enabled for this view.
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index 0008aa64efa4..af8a017eb66e 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -3063,6 +3063,9 @@ public class AccessibilityNodeInfo implements Parcelable {
int spanToReplaceStart = spannable.getSpanStart(span);
int spanToReplaceEnd = spannable.getSpanEnd(span);
int spanToReplaceFlags = spannable.getSpanFlags(span);
+ if (spanToReplaceStart < 0) {
+ continue;
+ }
spannable.removeSpan(span);
ClickableSpan replacementSpan = (span instanceof URLSpan)
? new AccessibilityURLSpan((URLSpan) span)
@@ -3100,6 +3103,9 @@ public class AccessibilityNodeInfo implements Parcelable {
int spanToReplaceStart = spannable.getSpanStart(span);
int spanToReplaceEnd = spannable.getSpanEnd(span);
int spanToReplaceFlags = spannable.getSpanFlags(span);
+ if (spanToReplaceStart < 0) {
+ continue;
+ }
spannable.removeSpan(span);
ReplacementSpan replacementSpan = new AccessibilityReplacementSpan(replacementText);
spannable.setSpan(replacementSpan, spanToReplaceStart, spanToReplaceEnd,
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 231ae084dd6c..184e7bca963b 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -4363,8 +4363,35 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final int delta = Math.round(axisValue * mVerticalScrollFactor);
if (delta != 0) {
+ // If we're moving down, we want the top item. If we're moving up, bottom item.
+ final int motionIndex = delta > 0 ? 0 : getChildCount() - 1;
+
+ int motionViewPrevTop = 0;
+ View motionView = this.getChildAt(motionIndex);
+ if (motionView != null) {
+ motionViewPrevTop = motionView.getTop();
+ }
+
+ final int overscrollMode = getOverScrollMode();
+
if (!trackMotionScroll(delta, delta)) {
return true;
+ } else if (!event.isFromSource(InputDevice.SOURCE_MOUSE) && motionView != null
+ && (overscrollMode == OVER_SCROLL_ALWAYS
+ || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS
+ && !contentFits()))) {
+ int motionViewRealTop = motionView.getTop();
+ float overscroll = (delta - (motionViewRealTop - motionViewPrevTop))
+ / ((float) getHeight());
+ if (delta > 0) {
+ mEdgeGlowTop.onPullDistance(overscroll, 0.5f);
+ mEdgeGlowTop.onRelease();
+ } else {
+ mEdgeGlowBottom.onPullDistance(-overscroll, 0.5f);
+ mEdgeGlowBottom.onRelease();
+ }
+ invalidate();
+ return true;
}
}
break;
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index 018cba7f95e5..2dbfd7e5b2e2 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -872,15 +872,39 @@ public class HorizontalScrollView extends FrameLayout {
final int range = getScrollRange();
int oldScrollX = mScrollX;
int newScrollX = oldScrollX + delta;
+
+ final int overscrollMode = getOverScrollMode();
+ boolean canOverscroll = !event.isFromSource(InputDevice.SOURCE_MOUSE)
+ && (overscrollMode == OVER_SCROLL_ALWAYS
+ || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0));
+ boolean absorbed = false;
+
if (newScrollX < 0) {
+ if (canOverscroll) {
+ mEdgeGlowLeft.onPullDistance(-(float) newScrollX / getWidth(),
+ 0.5f);
+ mEdgeGlowLeft.onRelease();
+ invalidate();
+ absorbed = true;
+ }
newScrollX = 0;
} else if (newScrollX > range) {
+ if (canOverscroll) {
+ mEdgeGlowRight.onPullDistance(
+ (float) (newScrollX - range) / getWidth(), 0.5f);
+ mEdgeGlowRight.onRelease();
+ invalidate();
+ absorbed = true;
+ }
newScrollX = range;
}
if (newScrollX != oldScrollX) {
super.scrollTo(newScrollX, mScrollY);
return true;
}
+ if (absorbed) {
+ return true;
+ }
}
}
}
diff --git a/core/java/android/widget/RemoteViewsAdapter.java b/core/java/android/widget/RemoteViewsAdapter.java
index 8e293f4b356d..61a7599e8f73 100644
--- a/core/java/android/widget/RemoteViewsAdapter.java
+++ b/core/java/android/widget/RemoteViewsAdapter.java
@@ -52,9 +52,9 @@ import android.widget.RemoteViews.InteractionHandler;
import com.android.internal.widget.IRemoteViewsFactory;
import java.lang.ref.WeakReference;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.concurrent.Executor;
/**
@@ -424,17 +424,17 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
* adapter that have not yet had their RemoteViews loaded.
*/
private class RemoteViewsFrameLayoutRefSet
- extends SparseArray<LinkedList<RemoteViewsFrameLayout>> {
+ extends SparseArray<ArrayList<RemoteViewsFrameLayout>> {
/**
* Adds a new reference to a RemoteViewsFrameLayout returned by the adapter.
*/
public void add(int position, RemoteViewsFrameLayout layout) {
- LinkedList<RemoteViewsFrameLayout> refs = get(position);
+ ArrayList<RemoteViewsFrameLayout> refs = get(position);
// Create the list if necessary
if (refs == null) {
- refs = new LinkedList<>();
+ refs = new ArrayList<>();
put(position, refs);
}
@@ -451,7 +451,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
if (view == null) return;
// Remove this set from the original mapping
- final LinkedList<RemoteViewsFrameLayout> refs = removeReturnOld(position);
+ final ArrayList<RemoteViewsFrameLayout> refs = removeReturnOld(position);
if (refs != null) {
// Notify all the references for that position of the newly loaded RemoteViews
for (final RemoteViewsFrameLayout ref : refs) {
@@ -467,7 +467,7 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
if (rvfl.cacheIndex < 0) {
return;
}
- final LinkedList<RemoteViewsFrameLayout> refs = get(rvfl.cacheIndex);
+ final ArrayList<RemoteViewsFrameLayout> refs = get(rvfl.cacheIndex);
if (refs != null) {
refs.remove(rvfl);
}
@@ -933,12 +933,8 @@ public class RemoteViewsAdapter extends BaseAdapter implements Handler.Callback
Runnable r = () -> {
synchronized (sCachedRemoteViewsCaches) {
- if (sCachedRemoteViewsCaches.containsKey(key)) {
- sCachedRemoteViewsCaches.remove(key);
- }
- if (sRemoteViewsCacheRemoveRunnables.containsKey(key)) {
- sRemoteViewsCacheRemoveRunnables.remove(key);
- }
+ sCachedRemoteViewsCaches.remove(key);
+ sRemoteViewsCacheRemoveRunnables.remove(key);
}
};
sRemoteViewsCacheRemoveRunnables.put(key, r);
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 15cd17b20f4f..2acd50c9e169 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -939,15 +939,38 @@ public class ScrollView extends FrameLayout {
final int range = getScrollRange();
int oldScrollY = mScrollY;
int newScrollY = oldScrollY - delta;
+
+ final int overscrollMode = getOverScrollMode();
+ boolean canOverscroll = !event.isFromSource(InputDevice.SOURCE_MOUSE)
+ && (overscrollMode == OVER_SCROLL_ALWAYS
+ || (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0));
+ boolean absorbed = false;
+
if (newScrollY < 0) {
+ if (canOverscroll) {
+ mEdgeGlowTop.onPullDistance(-(float) newScrollY / getHeight(), 0.5f);
+ mEdgeGlowTop.onRelease();
+ invalidate();
+ absorbed = true;
+ }
newScrollY = 0;
} else if (newScrollY > range) {
+ if (canOverscroll) {
+ mEdgeGlowBottom.onPullDistance(
+ (float) (newScrollY - range) / getHeight(), 0.5f);
+ mEdgeGlowBottom.onRelease();
+ invalidate();
+ absorbed = true;
+ }
newScrollY = range;
}
if (newScrollY != oldScrollY) {
super.scrollTo(mScrollX, newScrollY);
return true;
}
+ if (absorbed) {
+ return true;
+ }
}
break;
}
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index a60b31078a86..73a4f1c4a154 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -62,7 +62,9 @@ import java.nio.file.FileVisitor;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
@@ -232,9 +234,9 @@ public abstract class FileSystemProvider extends DocumentsProvider {
throw new FileNotFoundException(doc + " is not found under " + parent);
}
- LinkedList<String> path = new LinkedList<>();
+ List<String> path = new ArrayList<>();
while (doc != null && FileUtils.contains(parent, doc)) {
- path.addFirst(getDocIdForFile(doc));
+ path.add(0, getDocIdForFile(doc));
doc = doc.getParentFile();
}
@@ -448,10 +450,10 @@ public abstract class FileSystemProvider extends DocumentsProvider {
File folder, String[] projection, Set<String> exclusion, Bundle queryArgs)
throws FileNotFoundException {
final MatrixCursor result = new MatrixCursor(resolveProjection(projection));
- final LinkedList<File> pending = new LinkedList<>();
+ final List<File> pending = new ArrayList<>();
pending.add(folder);
while (!pending.isEmpty() && result.getCount() < 24) {
- final File file = pending.removeFirst();
+ final File file = pending.remove(0);
if (shouldHide(file)) continue;
if (file.isDirectory()) {
diff --git a/core/java/com/android/internal/logging/InstanceId.java b/core/java/com/android/internal/logging/InstanceId.java
deleted file mode 100644
index c90d851201a2..000000000000
--- a/core/java/com/android/internal/logging/InstanceId.java
+++ /dev/null
@@ -1,98 +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.internal.logging;
-
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-
-import android.annotation.Nullable;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-/**
- * An opaque identifier used to disambiguate which logs refer to a particular instance of some
- * UI element. Useful when there might be multiple instances simultaneously active.
- * Obtain from InstanceIdSequence. Clipped to range [0, INSTANCE_ID_MAX].
- */
-public final class InstanceId implements Parcelable {
- // At most 20 bits: ~1m possibilities, ~0.5% probability of collision in 100 values
- static final int INSTANCE_ID_MAX = 1 << 20;
-
- private final int mId;
- InstanceId(int id) {
- mId = min(max(0, id), INSTANCE_ID_MAX);
- }
-
- private InstanceId(Parcel in) {
- this(in.readInt());
- }
-
- @VisibleForTesting
- public int getId() {
- return mId;
- }
-
- /**
- * Create a fake instance ID for testing purposes. Not for production use. See also
- * InstanceIdSequenceFake, which is a testing replacement for InstanceIdSequence.
- * @param id The ID you want to assign.
- * @return new InstanceId.
- */
- @VisibleForTesting
- public static InstanceId fakeInstanceId(int id) {
- return new InstanceId(id);
- }
-
- @Override
- public int hashCode() {
- return mId;
- }
-
- @Override
- public boolean equals(@Nullable Object obj) {
- if (!(obj instanceof InstanceId)) {
- return false;
- }
- return mId == ((InstanceId) obj).mId;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(Parcel out, int flags) {
- out.writeInt(mId);
- }
-
- public static final Parcelable.Creator<InstanceId> CREATOR =
- new Parcelable.Creator<InstanceId>() {
- @Override
- public InstanceId createFromParcel(Parcel in) {
- return new InstanceId(in);
- }
-
- @Override
- public InstanceId[] newArray(int size) {
- return new InstanceId[size];
- }
- };
-
-}
diff --git a/core/java/com/android/internal/logging/InstanceIdSequence.java b/core/java/com/android/internal/logging/InstanceIdSequence.java
deleted file mode 100644
index 34643105b965..000000000000
--- a/core/java/com/android/internal/logging/InstanceIdSequence.java
+++ /dev/null
@@ -1,62 +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.internal.logging;
-
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.security.SecureRandom;
-import java.util.Random;
-
-/**
- * Generates random InstanceIds in range [1, instanceIdMax] for passing to
- * UiEventLogger.logWithInstanceId(). Holds a SecureRandom, which self-seeds on
- * first use; try to give it a long lifetime. Safe for concurrent use.
- */
-public class InstanceIdSequence {
- protected final int mInstanceIdMax;
- private final Random mRandom = new SecureRandom();
-
- /**
- * Constructs a sequence with identifiers [1, instanceIdMax]. Capped at INSTANCE_ID_MAX.
- * @param instanceIdMax Limiting value of identifiers. Normally positive: otherwise you get
- * an all-1 sequence.
- */
- public InstanceIdSequence(int instanceIdMax) {
- mInstanceIdMax = min(max(1, instanceIdMax), InstanceId.INSTANCE_ID_MAX);
- }
-
- /**
- * Gets the next instance from the sequence. Safe for concurrent use.
- * @return new InstanceId
- */
- public InstanceId newInstanceId() {
- return newInstanceIdInternal(1 + mRandom.nextInt(mInstanceIdMax));
- }
-
- /**
- * Factory function for instance IDs, used for testing.
- * @param id
- * @return new InstanceId(id)
- */
- @VisibleForTesting
- protected InstanceId newInstanceIdInternal(int id) {
- return new InstanceId(id);
- }
-}
diff --git a/core/java/com/android/internal/logging/UiEvent.java b/core/java/com/android/internal/logging/UiEvent.java
deleted file mode 100644
index 0407b0704e80..000000000000
--- a/core/java/com/android/internal/logging/UiEvent.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.logging;
-
-import static java.lang.annotation.ElementType.FIELD;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.Target;
-
-@Retention(SOURCE)
-@Target(FIELD)
-public @interface UiEvent {
- /** An explanation, suitable for Android analysts, of the UI event that this log represents. */
- String doc();
-}
diff --git a/core/java/com/android/internal/logging/UiEventLogger.java b/core/java/com/android/internal/logging/UiEventLogger.java
deleted file mode 100644
index 5378b03fe1c5..000000000000
--- a/core/java/com/android/internal/logging/UiEventLogger.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.internal.logging;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-
-/**
- * Logging interface for UI events. Normal implementation is UiEventLoggerImpl.
- * For testing, use fake implementation UiEventLoggerFake.
- *
- * See go/sysui-event-logs and UiEventReported atom in atoms.proto.
- */
-public interface UiEventLogger {
- /** Put your Event IDs in enums that implement this interface, and document them using the
- * UiEventEnum annotation.
- * Event IDs must be globally unique. This will be enforced by tooling (forthcoming).
- * OEMs should use event IDs above 100000 and below 1000000 (1 million).
- */
- interface UiEventEnum {
-
- /**
- * Tag used to request new UI Event IDs via presubmit analysis.
- *
- * <p>Use RESERVE_NEW_UI_EVENT_ID as the constructor parameter for a new {@link EventEnum}
- * to signal the presubmit analyzer to reserve a new ID for the event. The new ID will be
- * returned as a Gerrit presubmit finding. Do not submit {@code RESERVE_NEW_UI_EVENT_ID} as
- * the constructor parameter for any event.
- *
- * <pre>
- * &#064;UiEvent(doc = "Briefly describe the interaction when this event will be logged")
- * UNIQUE_EVENT_NAME(RESERVE_NEW_UI_EVENT_ID);
- * </pre>
- */
- int RESERVE_NEW_UI_EVENT_ID = Integer.MIN_VALUE; // Negative IDs are ignored by the logger.
-
- int getId();
- }
-
- /**
- * Log a simple event, with no package information. Does nothing if event.getId() <= 0.
- * @param event an enum implementing UiEventEnum interface.
- */
- void log(@NonNull UiEventEnum event);
-
- /**
- * Log a simple event with an instance id, without package information.
- * Does nothing if event.getId() <= 0.
- * @param event an enum implementing UiEventEnum interface.
- * @param instance An identifier obtained from an InstanceIdSequence. If null, reduces to log().
- */
- void log(@NonNull UiEventEnum event, @Nullable InstanceId instance);
-
- /**
- * Log an event with package information. Does nothing if event.getId() <= 0.
- * Give both uid and packageName if both are known, but one may be omitted if unknown.
- * @param event an enum implementing UiEventEnum interface.
- * @param uid the uid of the relevant app, if known (0 otherwise).
- * @param packageName the package name of the relevant app, if known (null otherwise).
- */
- void log(@NonNull UiEventEnum event, int uid, @Nullable String packageName);
-
- /**
- * Log an event with package information and an instance ID.
- * Does nothing if event.getId() <= 0.
- * @param event an enum implementing UiEventEnum interface.
- * @param uid the uid of the relevant app, if known (0 otherwise).
- * @param packageName the package name of the relevant app, if known (null otherwise).
- * @param instance An identifier obtained from an InstanceIdSequence. If null, reduces to log().
- */
- void logWithInstanceId(@NonNull UiEventEnum event, int uid, @Nullable String packageName,
- @Nullable InstanceId instance);
-
- /**
- * Log an event with ranked-choice information along with package.
- * Does nothing if event.getId() <= 0.
- * @param event an enum implementing UiEventEnum interface.
- * @param uid the uid of the relevant app, if known (0 otherwise).
- * @param packageName the package name of the relevant app, if known (null otherwise).
- * @param position the position picked.
- */
- void logWithPosition(@NonNull UiEventEnum event, int uid, @Nullable String packageName,
- int position);
-
- /**
- * Log an event with ranked-choice information along with package and instance ID.
- * Does nothing if event.getId() <= 0.
- * @param event an enum implementing UiEventEnum interface.
- * @param uid the uid of the relevant app, if known (0 otherwise).
- * @param packageName the package name of the relevant app, if known (null otherwise).
- * @param instance An identifier obtained from an InstanceIdSequence. If null, reduces to
- * logWithPosition().
- * @param position the position picked.
- */
- void logWithInstanceIdAndPosition(@NonNull UiEventEnum event, int uid,
- @Nullable String packageName, @Nullable InstanceId instance, int position);
-}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3b46f627265b..fe2f80cf72df 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -5429,7 +5429,6 @@ public class BatteryStatsImpl extends BatteryStats {
@GuardedBy("this")
public void noteLongPartialWakelockStart(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
- uid = mapUid(uid);
noteLongPartialWakeLockStartInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
@@ -5464,15 +5463,21 @@ public class BatteryStatsImpl extends BatteryStats {
@GuardedBy("this")
private void noteLongPartialWakeLockStartInternal(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
+ final int mappedUid = mapUid(uid);
if (historyName == null) {
historyName = name;
}
- if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid,
- 0)) {
+ if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName,
+ mappedUid, 0)) {
return;
}
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
- historyName, uid);
+ historyName, mappedUid);
+ if (mappedUid != uid) {
+ // Prevent the isolated uid mapping from being removed while the wakelock is
+ // being held.
+ incrementIsolatedUidRefCount(uid);
+ }
}
@GuardedBy("this")
@@ -5484,7 +5489,6 @@ public class BatteryStatsImpl extends BatteryStats {
@GuardedBy("this")
public void noteLongPartialWakelockFinish(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
- uid = mapUid(uid);
noteLongPartialWakeLockFinishInternal(name, historyName, uid, elapsedRealtimeMs, uptimeMs);
}
@@ -5519,15 +5523,20 @@ public class BatteryStatsImpl extends BatteryStats {
@GuardedBy("this")
private void noteLongPartialWakeLockFinishInternal(String name, String historyName, int uid,
long elapsedRealtimeMs, long uptimeMs) {
+ final int mappedUid = mapUid(uid);
if (historyName == null) {
historyName = name;
}
- if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid,
- 0)) {
+ if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName,
+ mappedUid, 0)) {
return;
}
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
- historyName, uid);
+ historyName, mappedUid);
+ if (mappedUid != uid) {
+ // Decrement the ref count for the isolated uid and delete the mapping if uneeded.
+ maybeRemoveIsolatedUidLocked(uid, elapsedRealtimeMs, uptimeMs);
+ }
}
@GuardedBy("this")
diff --git a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
index d0df45c9af65..525004a8b415 100644
--- a/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
+++ b/core/java/com/android/internal/os/MobileRadioPowerCalculator.java
@@ -111,9 +111,9 @@ public class MobileRadioPowerCalculator extends PowerCalculator {
calculateApp(app, uid, total, query, keys);
}
- final long consumptionUC = batteryStats.getMobileRadioMeasuredBatteryConsumptionUC();
- final int powerModel = getPowerModel(consumptionUC, query);
- calculateRemaining(total, powerModel, batteryStats, rawRealtimeUs, consumptionUC);
+ final long totalConsumptionUC = batteryStats.getMobileRadioMeasuredBatteryConsumptionUC();
+ final int powerModel = getPowerModel(totalConsumptionUC, query);
+ calculateRemaining(total, powerModel, batteryStats, rawRealtimeUs, totalConsumptionUC);
if (total.remainingPowerMah != 0 || total.totalAppPowerMah != 0) {
builder.getAggregateBatteryConsumerBuilder(
@@ -187,12 +187,13 @@ public class MobileRadioPowerCalculator extends PowerCalculator {
private void calculateRemaining(PowerAndDuration total,
@BatteryConsumer.PowerModel int powerModel, BatteryStats batteryStats,
- long rawRealtimeUs, long consumptionUC) {
+ long rawRealtimeUs, long totalConsumptionUC) {
long signalTimeMs = 0;
double powerMah = 0;
if (powerModel == BatteryConsumer.POWER_MODEL_MEASURED_ENERGY) {
- powerMah = uCtoMah(consumptionUC);
+ powerMah = uCtoMah(totalConsumptionUC) - total.totalAppPowerMah;
+ if (powerMah < 0) powerMah = 0;
}
for (int i = 0; i < NUM_SIGNAL_STRENGTH_LEVELS; i++) {
diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
index bf3e8d56b6bc..a0f7905771a2 100644
--- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
+++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java
@@ -1,11 +1,5 @@
package com.android.internal.view.menu;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.LinkedList;
-import java.util.List;
-
import android.annotation.AttrRes;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -22,16 +16,16 @@ import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
-import android.view.ViewTreeObserver;
import android.view.View.OnAttachStateChangeListener;
import android.view.View.OnKeyListener;
+import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.AbsListView;
import android.widget.FrameLayout;
import android.widget.HeaderViewListAdapter;
import android.widget.ListAdapter;
-import android.widget.MenuItemHoverListener;
import android.widget.ListView;
+import android.widget.MenuItemHoverListener;
import android.widget.MenuPopupWindow;
import android.widget.PopupWindow;
import android.widget.PopupWindow.OnDismissListener;
@@ -40,6 +34,11 @@ import android.widget.TextView;
import com.android.internal.R;
import com.android.internal.util.Preconditions;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* A popup for a menu which will allow multiple submenus to appear in a cascading fashion, side by
* side.
@@ -70,7 +69,7 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey
private final Handler mSubMenuHoverHandler;
/** List of menus that were added before this popup was shown. */
- private final List<MenuBuilder> mPendingMenus = new LinkedList<>();
+ private final List<MenuBuilder> mPendingMenus = new ArrayList<>();
/**
* List of open menus. The first item is the root menu and each
diff --git a/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
index 481183e700a2..c1e2840f0a8b 100644
--- a/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
+++ b/core/java/com/android/internal/widget/ConversationHeaderLinearLayout.java
@@ -23,6 +23,7 @@ import android.view.View;
import android.widget.LinearLayout;
import android.widget.RemoteViews;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -96,7 +97,7 @@ public class ConversationHeaderLinearLayout extends LinearLayout {
continue;
}
if (visibleChildrenToShorten == null) {
- visibleChildrenToShorten = new LinkedList<>();
+ visibleChildrenToShorten = new ArrayList<>(count);
}
visibleChildrenToShorten.add(new ViewInfo(child));
remainingWeight += Math.max(0, weight);
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index a94b30707604..6771cdf84717 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -39,7 +39,6 @@ import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.os.Build;
import android.os.Handler;
-import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
@@ -47,7 +46,6 @@ import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.storage.IStorageManager;
import android.os.storage.StorageManager;
import android.provider.Settings;
import android.text.TextUtils;
diff --git a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
index 8c61a12b47e6..95a4e1238e06 100644
--- a/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
+++ b/core/java/com/android/internal/widget/floatingtoolbar/LocalFloatingToolbarPopup.java
@@ -61,10 +61,10 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -950,9 +950,9 @@ public final class LocalFloatingToolbarPopup implements FloatingToolbarPopup {
int availableWidth = toolbarWidth;
- final LinkedList<MenuItem> remainingMenuItems = new LinkedList<>();
+ final ArrayList<MenuItem> remainingMenuItems = new ArrayList<>();
// add the overflow menu items to the end of the remainingMenuItems list.
- final LinkedList<MenuItem> overflowMenuItems = new LinkedList();
+ final ArrayList<MenuItem> overflowMenuItems = new ArrayList<>();
for (MenuItem menuItem : menuItems) {
if (menuItem.getItemId() != android.R.id.textAssist
&& menuItem.requiresOverflow()) {
@@ -969,7 +969,7 @@ public final class LocalFloatingToolbarPopup implements FloatingToolbarPopup {
int lastGroupId = -1;
boolean isFirstItem = true;
while (!remainingMenuItems.isEmpty()) {
- final MenuItem menuItem = remainingMenuItems.peek();
+ final MenuItem menuItem = remainingMenuItems.get(0);
// if this is the first item, regardless of requiresOverflow(), it should be
// displayed on the main panel. Otherwise all items including this one will be
@@ -1022,7 +1022,7 @@ public final class LocalFloatingToolbarPopup implements FloatingToolbarPopup {
params.width = menuItemButtonWidth;
menuItemButton.setLayoutParams(params);
availableWidth -= menuItemButtonWidth;
- remainingMenuItems.pop();
+ remainingMenuItems.remove(0);
} else {
break;
}
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index e281853d31bf..db41d333e1d4 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -31,6 +31,7 @@ import android.os.FileUtils;
import android.os.Process;
import android.os.SystemProperties;
import android.os.Trace;
+import android.os.VintfRuntimeInfo;
import android.os.incremental.IncrementalManager;
import android.os.storage.StorageManager;
import android.permission.PermissionManager.SplitPermissionInfo;
@@ -57,7 +58,10 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -1447,6 +1451,14 @@ public class SystemConfig {
addFeature(PackageManager.FEATURE_IPSEC_TUNNELS, 0);
}
+ if (isFilesystemSupported("erofs")) {
+ if (isKernelVersionAtLeast(5, 10)) {
+ addFeature(PackageManager.FEATURE_EROFS, 0);
+ } else if (isKernelVersionAtLeast(4, 19)) {
+ addFeature(PackageManager.FEATURE_EROFS_LEGACY, 0);
+ }
+ }
+
for (String featureName : mUnavailableFeatures) {
removeFeature(featureName);
}
@@ -1816,4 +1828,29 @@ public class SystemConfig {
private static boolean isSystemProcess() {
return Process.myUid() == Process.SYSTEM_UID;
}
+
+ private static boolean isFilesystemSupported(String fs) {
+ try {
+ final byte[] fsTableData = Files.readAllBytes(Paths.get("/proc/filesystems"));
+ final String fsTable = new String(fsTableData, StandardCharsets.UTF_8);
+ return fsTable.contains("\t" + fs + "\n");
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ private static boolean isKernelVersionAtLeast(int major, int minor) {
+ final String kernelVersion = VintfRuntimeInfo.getKernelVersion();
+ final String[] parts = kernelVersion.split("\\.");
+ if (parts.length < 2) {
+ return false;
+ }
+ try {
+ final int majorVersion = Integer.parseInt(parts[0]);
+ final int minorVersion = Integer.parseInt(parts[1]);
+ return majorVersion > major || (majorVersion == major && minorVersion >= minor);
+ } catch (NumberFormatException e) {
+ return false;
+ }
+ }
}
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index a4463e4e96c5..907093343a3f 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -16,6 +16,7 @@ roosa@google.com
per-file package_item_info.proto = toddke@google.com,patb@google.com
per-file usagestatsservice.proto, usagestatsservice_v2.proto = file:/core/java/android/app/usage/OWNERS
per-file apphibernationservice.proto = file:/core/java/android/apphibernation/OWNERS
+per-file android/hardware/sensorprivacy.proto = ntmyren@google.com,evanseverson@google.com,ewol@google.com
# Biometrics
jaggies@google.com
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index d652b2ff4f4a..efa3c23d5d8c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4346,13 +4346,13 @@
<permission android:name="android.permission.TUNER_RESOURCE_ACCESS"
android:protectionLevel="signature|privileged|vendorPrivileged" />
- <!-- This permission is required by Media Resource Manager Service when
- accessing its overridePid Api.
- <p>Protection level: signature
+ <!-- @SystemApi This permission is required by Media Resource Manager Service when
+ system services create MediaCodecs on behalf of other processes and apps.
+ <p>Protection level: signature|privileged|vendorPrivileged
<p>Not for use by third-party applications.
@hide -->
<permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID"
- android:protectionLevel="signature" />
+ android:protectionLevel="signature|privileged|vendorPrivileged" />
<uses-permission android:name="android.permission.MEDIA_RESOURCE_OVERRIDE_PID" />
<!-- This permission is required by Media Resource Observer Service when
@@ -5998,7 +5998,7 @@
<!-- @SystemApi Allows an application to turn on / off quiet mode.
@hide -->
<permission android:name="android.permission.MODIFY_QUIET_MODE"
- android:protectionLevel="signature|privileged|development" />
+ android:protectionLevel="signature|privileged|development|role" />
<!-- Allows internal management of the camera framework
@hide -->
diff --git a/core/res/res/values/colors_car.xml b/core/res/res/values/colors_car.xml
index 82caa265e7ec..d7d222c07b17 100644
--- a/core/res/res/values/colors_car.xml
+++ b/core/res/res/values/colors_car.xml
@@ -133,8 +133,8 @@
<!-- The color of the seekbar track background in SeekbarListItem. This color is assumed to be
on a light-colored background. -->
<color name="car_seekbar_track_background">@color/car_seekbar_track_background_dark</color>
- <!-- background is car_grey_868 with .9 alpha -->
- <color name="car_toast_background">#E6282a2d</color>
+ <!-- background is car_grey_868 with -->
+ <color name="car_toast_background">@color/car_grey_868</color>
<!-- Misc colors -->
<color name="car_highlight_light">#ff66b5ff</color>
diff --git a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
index cf78646a466f..29ab4acb05ff 100644
--- a/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ChooserActivityTest.java
@@ -81,7 +81,6 @@ import android.net.Uri;
import android.os.UserHandle;
import android.provider.DeviceConfig;
import android.service.chooser.ChooserTarget;
-import android.util.Log;
import android.view.View;
import androidx.annotation.CallSuper;
@@ -2023,7 +2022,7 @@ public class ChooserActivityTest {
.check(matches(isDisplayed()));
}
- @Test
+ @Test @Ignore("b/222124533")
public void testAppTargetLogging() throws InterruptedException {
Intent sendIntent = createSendTextIntent();
List<ResolvedComponentInfo> resolvedComponentInfos = createResolvedComponentsForTest(2);
@@ -2042,6 +2041,10 @@ public class ChooserActivityTest {
mActivityRule.launchActivity(Intent.createChooser(sendIntent, null));
waitForIdle();
+ // TODO(b/222124533): other test cases use a timeout to make sure that the UI is fully
+ // populated; without one, this test flakes. Ideally we should address the need for a
+ // timeout everywhere instead of introducing one to fix this particular test.
+
assertThat(activity.getAdapter().getCount(), is(2));
onView(withIdFromRuntimeResource("profile_button")).check(doesNotExist());
@@ -2324,7 +2327,7 @@ public class ChooserActivityTest {
assertThat(logger.numCalls(), is(6));
}
- @Test
+ @Test @Ignore("b/222124533")
public void testSwitchProfileLogging() throws InterruptedException {
// enable the work tab feature flag
ResolverActivity.ENABLE_TABBED_VIEW = true;
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index e7a23f262753..43fba529182e 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -516,8 +516,6 @@ public class ResolverActivityTest {
onView(withText(R.string.resolver_work_tab))
.perform(click());
waitForIdle();
- // wait for the share sheet to expand
- Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
onView(first(allOf(withText(workResolvedComponentInfos.get(0)
.getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
.perform(click());
@@ -616,8 +614,6 @@ public class ResolverActivityTest {
onView(withText(R.string.resolver_work_tab))
.perform(click());
waitForIdle();
- // wait for the share sheet to expand
- Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
onView(first(allOf(
withText(workResolvedComponentInfos.get(0)
.getResolveInfoAt(0).activityInfo.applicationInfo.name),
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
index 7ccb9d963ee6..dbe1e8132e1d 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsNoteTest.java
@@ -26,6 +26,8 @@ import static android.os.BatteryStats.WAKE_TYPE_PARTIAL;
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_CPU;
import static com.android.internal.os.BatteryStatsImpl.ExternalStatsSync.UPDATE_DISPLAY;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.mockito.Mockito.mock;
import android.app.ActivityManager;
@@ -228,6 +230,116 @@ public class BatteryStatsNoteTest extends TestCase {
assertEquals(120_000, bgTime);
}
+ /**
+ * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid.
+ */
+ @SmallTest
+ public void testNoteLongPartialWakelockStart_isolatedUid() throws Exception {
+ final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
+ MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+
+
+ bi.setRecordAllHistoryLocked(true);
+ bi.forceRecordAllHistory();
+
+ int pid = 10;
+ String name = "name";
+ String historyName = "historyName";
+
+ WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
+ isolatedWorkChain.addNode(ISOLATED_UID, name);
+
+ // Map ISOLATED_UID to UID.
+ bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+
+ bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
+ bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID);
+
+ clocks.realtime = clocks.uptime = 100;
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+ clocks.realtime = clocks.uptime = 220;
+ bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID);
+
+ final BatteryStatsHistoryIterator iterator =
+ bi.createBatteryStatsHistoryIterator();
+
+ BatteryStats.HistoryItem item = new BatteryStats.HistoryItem();
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+ }
+
+ /**
+ * Test BatteryStatsImpl.Uid.noteLongPartialWakelockStart for an isolated uid.
+ */
+ @SmallTest
+ public void testNoteLongPartialWakelockStart_isolatedUidRace() throws Exception {
+ final MockClock clocks = new MockClock(); // holds realtime and uptime in ms
+ MockBatteryStatsImpl bi = new MockBatteryStatsImpl(clocks);
+
+
+ bi.setRecordAllHistoryLocked(true);
+ bi.forceRecordAllHistory();
+
+ int pid = 10;
+ String name = "name";
+ String historyName = "historyName";
+
+ WorkSource.WorkChain isolatedWorkChain = new WorkSource.WorkChain();
+ isolatedWorkChain.addNode(ISOLATED_UID, name);
+
+ // Map ISOLATED_UID to UID.
+ bi.addIsolatedUidLocked(ISOLATED_UID, UID);
+
+ bi.updateTimeBasesLocked(true, Display.STATE_OFF, 0, 0);
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_TOP);
+ bi.noteLongPartialWakelockStart(name, historyName, ISOLATED_UID);
+
+ clocks.realtime = clocks.uptime = 100;
+ bi.noteUidProcessStateLocked(UID, ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND);
+
+ clocks.realtime = clocks.uptime = 150;
+ bi.maybeRemoveIsolatedUidLocked(ISOLATED_UID, clocks.realtime, clocks.uptime);
+
+ clocks.realtime = clocks.uptime = 220;
+ bi.noteLongPartialWakelockFinish(name, historyName, ISOLATED_UID);
+
+ final BatteryStatsHistoryIterator iterator =
+ bi.createBatteryStatsHistoryIterator();
+
+ BatteryStats.HistoryItem item = new BatteryStats.HistoryItem();
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_START) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_START);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+
+ while (iterator.next(item)) {
+ if (item.eventCode == HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH) break;
+ }
+ assertThat(item.eventCode).isEqualTo(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH);
+ assertThat(item.eventTag).isNotNull();
+ assertThat(item.eventTag.string).isEqualTo(historyName);
+ assertThat(item.eventTag.uid).isEqualTo(UID);
+ }
/**
* Test BatteryStatsImpl.noteUidProcessStateLocked.
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 95225b2e4f39..00ac1985f897 100644
--- a/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/MobileRadioPowerCalculatorTest.java
@@ -269,8 +269,9 @@ public class MobileRadioPowerCalculatorTest {
.isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
BatteryConsumer deviceConsumer = mStatsRule.getDeviceBatteryConsumer();
+ // 10_000_000 micro-Coulomb * 1/1000 milli/micro * 1/3600 hour/second = 2.77778 mAh
assertThat(deviceConsumer.getConsumedPower(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
- .isWithin(PRECISION).of(4.31711);
+ .isWithin(PRECISION).of(2.77778);
assertThat(deviceConsumer.getPowerModel(BatteryConsumer.POWER_COMPONENT_MOBILE_RADIO))
.isEqualTo(BatteryConsumer.POWER_MODEL_MEASURED_ENERGY);
diff --git a/errorprone/Android.bp b/errorprone/Android.bp
index a927f53e3b5f..8f32f0eab37f 100644
--- a/errorprone/Android.bp
+++ b/errorprone/Android.bp
@@ -1,4 +1,3 @@
-
package {
// See: http://go/android-license-faq
// A large-scale-change added 'default_applicable_licenses' to import
@@ -42,8 +41,10 @@ java_test_host {
static_libs: [
"truth-prebuilt",
"kxml2-2.3.0",
+ "compile-testing-prebuilt",
"error_prone_android_framework_lib",
"error_prone_test_helpers",
+ "google_java_format",
"hamcrest-library",
"hamcrest",
"platform-test-annotations",
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/HideInCommentsChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/HideInCommentsChecker.java
new file mode 100644
index 000000000000..07f1d4a09006
--- /dev/null
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/HideInCommentsChecker.java
@@ -0,0 +1,158 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.google.errorprone.bugpatterns.android;
+
+import static com.google.errorprone.BugPattern.LinkType.NONE;
+import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
+import static com.google.errorprone.matchers.Description.NO_MATCH;
+import static com.google.errorprone.util.ASTHelpers.getStartPosition;
+import static com.google.errorprone.util.ASTHelpers.getSymbol;
+
+import com.google.auto.service.AutoService;
+import com.google.errorprone.BugPattern;
+import com.google.errorprone.VisitorState;
+import com.google.errorprone.bugpatterns.BugChecker;
+import com.google.errorprone.fixes.SuggestedFix;
+import com.google.errorprone.matchers.Description;
+import com.google.errorprone.util.ASTHelpers;
+import com.google.errorprone.util.ErrorProneToken;
+import com.google.errorprone.util.ErrorProneTokens;
+import com.sun.source.tree.ClassTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.MethodTree;
+import com.sun.source.tree.NewClassTree;
+import com.sun.source.tree.Tree;
+import com.sun.source.tree.VariableTree;
+import com.sun.tools.javac.parser.Tokens;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+import javax.lang.model.element.ElementKind;
+
+/**
+ * Bug checker to warn about {@code @hide} directives in comments.
+ *
+ * {@code @hide} tags are only meaningful inside of Javadoc comments. Errorprone has checks for
+ * standard Javadoc tags but doesn't know anything about {@code @hide} since it's an Android
+ * specific tag.
+ */
+@AutoService(BugChecker.class)
+@BugPattern(
+ name = "AndroidHideInComments",
+ summary = "Warns when there are @hide declarations in comments rather than javadoc",
+ linkType = NONE,
+ severity = WARNING)
+public class HideInCommentsChecker extends BugChecker implements
+ BugChecker.CompilationUnitTreeMatcher {
+
+ @Override
+ public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
+ final Map<Integer, Tree> javadocableTrees = findJavadocableTrees(tree);
+ final String sourceCode = state.getSourceCode().toString();
+ for (ErrorProneToken token : ErrorProneTokens.getTokens(sourceCode, state.context)) {
+ for (Tokens.Comment comment : token.comments()) {
+ if (!javadocableTrees.containsKey(token.pos())) {
+ continue;
+ }
+ generateFix(comment).ifPresent(fix -> {
+ final Tree javadocableTree = javadocableTrees.get(token.pos());
+ state.reportMatch(describeMatch(javadocableTree, fix));
+ });
+ }
+ }
+ // We might have multiple matches, so report them via VisitorState rather than the return
+ // value from the match function.
+ return NO_MATCH;
+ }
+
+ private static Optional<SuggestedFix> generateFix(Tokens.Comment comment) {
+ final String text = comment.getText();
+ if (text.startsWith("/**")) {
+ return Optional.empty();
+ }
+
+ if (!text.contains("@hide")) {
+ return Optional.empty();
+ }
+
+ if (text.startsWith("/*")) {
+ final int pos = comment.getSourcePos(1);
+ return Optional.of(SuggestedFix.replace(pos, pos, "*"));
+ } else if (text.startsWith("//")) {
+ final int endPos = comment.getSourcePos(text.length() - 1);
+ final char endChar = text.charAt(text.length() - 1);
+ String javadocClose = " */";
+ if (endChar != ' ') {
+ javadocClose = endChar + javadocClose;
+ }
+ final SuggestedFix fix = SuggestedFix.builder()
+ .replace(comment.getSourcePos(1), comment.getSourcePos(2), "**")
+ .replace(endPos, endPos + 1, javadocClose)
+ .build();
+ return Optional.of(fix);
+ }
+
+ return Optional.empty();
+ }
+
+
+ private Map<Integer, Tree> findJavadocableTrees(CompilationUnitTree tree) {
+ Map<Integer, Tree> javadoccableTrees = new HashMap<>();
+ new SuppressibleTreePathScanner<Void, Void>() {
+ @Override
+ public Void visitClass(ClassTree classTree, Void unused) {
+ javadoccableTrees.put(getStartPosition(classTree), classTree);
+ return super.visitClass(classTree, null);
+ }
+
+ @Override
+ public Void visitMethod(MethodTree methodTree, Void unused) {
+ // Generated constructors never have comments
+ if (!ASTHelpers.isGeneratedConstructor(methodTree)) {
+ javadoccableTrees.put(getStartPosition(methodTree), methodTree);
+ }
+ return super.visitMethod(methodTree, null);
+ }
+
+ @Override
+ public Void visitVariable(VariableTree variableTree, Void unused) {
+ ElementKind kind = getSymbol(variableTree).getKind();
+ if (kind == ElementKind.FIELD) {
+ javadoccableTrees.put(getStartPosition(variableTree), variableTree);
+ }
+ if (kind == ElementKind.ENUM_CONSTANT) {
+ javadoccableTrees.put(getStartPosition(variableTree), variableTree);
+ if (variableTree.getInitializer() instanceof NewClassTree) {
+ // Skip the generated class definition
+ ClassTree classBody =
+ ((NewClassTree) variableTree.getInitializer()).getClassBody();
+ if (classBody != null) {
+ scan(classBody.getMembers(), null);
+ }
+ return null;
+ }
+ }
+ return super.visitVariable(variableTree, null);
+ }
+
+ }.scan(tree, null);
+ return javadoccableTrees;
+ }
+
+}
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/HideInCommentsCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/HideInCommentsCheckerTest.java
new file mode 100644
index 000000000000..f3e6c72756e0
--- /dev/null
+++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/HideInCommentsCheckerTest.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.google.errorprone.bugpatterns.android;
+
+import static com.google.errorprone.BugCheckerRefactoringTestHelper.TestMode.TEXT_MATCH;
+
+import com.google.errorprone.BugCheckerRefactoringTestHelper;
+import com.google.errorprone.CompilationTestHelper;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class HideInCommentsCheckerTest {
+ private static final String REFACTORING_FILE = "Test.java";
+
+ private BugCheckerRefactoringTestHelper mRefactoringHelper;
+ private CompilationTestHelper mCompilationHelper;
+
+ @Before
+ public void setUp() {
+ mRefactoringHelper = BugCheckerRefactoringTestHelper.newInstance(
+ HideInCommentsChecker.class, HideInCommentsCheckerTest.class);
+ mCompilationHelper = CompilationTestHelper.newInstance(
+ HideInCommentsChecker.class, HideInCommentsCheckerTest.class);
+ }
+
+
+ @Test
+ public void refactorSingleLineComment() {
+ mRefactoringHelper
+ .addInputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " // Foo @hide",
+ " void foo() {}",
+ "}")
+ .addOutputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /** Foo @hide */",
+ " void foo() {}",
+ "}")
+ .doTest(TEXT_MATCH);
+ }
+
+ @Test
+ public void refactorSingleLineComment_doesntAddUnnecessarySpace() {
+ mRefactoringHelper
+ .addInputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " // Foo @hide ",
+ " void foo() {}",
+ "}")
+ .addOutputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /** Foo @hide */",
+ " void foo() {}",
+ "}")
+ .doTest(TEXT_MATCH);
+ }
+
+ @Test
+ public void refactorSingleLineBlockComment() {
+ mRefactoringHelper
+ .addInputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /* Foo @hide */",
+ " void foo() {}",
+ "}")
+ .addOutputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /** Foo @hide */",
+ " void foo() {}",
+ "}")
+ .doTest(TEXT_MATCH);
+ }
+
+ @Test
+ public void refactorMultiLineBlockComment() {
+ mRefactoringHelper
+ .addInputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /*",
+ " * Foo.",
+ " *",
+ " * @hide",
+ " */",
+ " void foo(int foo) {}",
+ "}")
+ .addOutputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /**",
+ " * Foo.",
+ " *",
+ " * @hide",
+ " */",
+ " void foo(int foo) {}",
+ "}")
+ .doTest(TEXT_MATCH);
+ }
+
+ @Test
+ public void refactorFieldComment() {
+ mRefactoringHelper
+ .addInputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /* Foo @hide */",
+ " public int foo = 0;",
+ "}")
+ .addOutputLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /** Foo @hide */",
+ " public int foo = 0;",
+ "}")
+ .doTest(TEXT_MATCH);
+ }
+
+ @Test
+ public void refactorClassComment() {
+ mRefactoringHelper
+ .addInputLines(
+ REFACTORING_FILE,
+ "/* Foo @hide */",
+ "public class Test {}")
+ .addOutputLines(
+ REFACTORING_FILE,
+ "/** Foo @hide */",
+ "public class Test {}")
+ .doTest(TEXT_MATCH);
+ }
+
+ @Test
+ public void refactorEnumComment() {
+ mRefactoringHelper
+ .addInputLines(
+ REFACTORING_FILE,
+ "public enum Test {",
+ " /* Foo @hide */",
+ " FOO",
+ "}")
+ .addOutputLines(
+ REFACTORING_FILE,
+ "public enum Test {",
+ " /** Foo @hide */",
+ " FOO",
+ "}")
+ .doTest(TEXT_MATCH);
+ }
+
+ @Test
+ public void canBeSuppressed() {
+ mCompilationHelper
+ .addSourceLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /* Foo @hide */",
+ " @SuppressWarnings(\"AndroidHideInComments\")",
+ " void foo() {}",
+ "}")
+ .doTest();
+ }
+
+ @Test
+ public void isInJavadoc() {
+ mCompilationHelper
+ .addSourceLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /** Foo @hide */",
+ " void foo() {}",
+ "}")
+ .doTest();
+ }
+
+ @Test
+ public void isInMultilineJavadoc() {
+ mCompilationHelper
+ .addSourceLines(
+ REFACTORING_FILE,
+ "public class Test {",
+ " /**",
+ " * Foo.",
+ " *",
+ " * @hide",
+ " */",
+ " void foo(int foo) {}",
+ "}")
+ .doTest();
+ }
+
+ @Test
+ public void noHidePresent() {
+ mCompilationHelper
+ .addSourceLines(
+ "test/" + REFACTORING_FILE,
+ "package test;",
+ "// Foo.",
+ "public class Test {",
+ " // Foo.",
+ " public int a;",
+ " /*",
+ " * Foo.",
+ " *",
+ " */",
+ " void foo(int foo) {}",
+ "}")
+ .doTest();
+ }
+
+}
diff --git a/identity/java/android/security/identity/CredstoreIdentityCredential.java b/identity/java/android/security/identity/CredstoreIdentityCredential.java
index 8e011053d2a7..c591c879059c 100644
--- a/identity/java/android/security/identity/CredstoreIdentityCredential.java
+++ b/identity/java/android/security/identity/CredstoreIdentityCredential.java
@@ -38,8 +38,9 @@ import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Instant;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import javax.crypto.BadPaddingException;
@@ -227,7 +228,7 @@ class CredstoreIdentityCredential extends IdentityCredential {
throw new RuntimeException("Error decoding certificates", e);
}
- LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+ ArrayList<X509Certificate> x509Certs = new ArrayList<>();
for (Certificate cert : certs) {
x509Certs.add((X509Certificate) cert);
}
@@ -384,7 +385,7 @@ class CredstoreIdentityCredential extends IdentityCredential {
public @NonNull Collection<X509Certificate> getAuthKeysNeedingCertification() {
try {
AuthKeyParcel[] authKeyParcels = mBinder.getAuthKeysNeedingCertification();
- LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+ ArrayList<X509Certificate> x509Certs = new ArrayList<>();
CertificateFactory factory = CertificateFactory.getInstance("X.509");
for (AuthKeyParcel authKeyParcel : authKeyParcels) {
Collection<? extends Certificate> certs = null;
diff --git a/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java b/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
index d2e7984ce19f..1ad70edb7c6f 100644
--- a/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
+++ b/identity/java/android/security/identity/CredstoreWritableIdentityCredential.java
@@ -25,8 +25,9 @@ import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.LinkedList;
+import java.util.List;
class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
@@ -61,7 +62,7 @@ class CredstoreWritableIdentityCredential extends WritableIdentityCredential {
throw new RuntimeException("Error decoding certificates", e);
}
- LinkedList<X509Certificate> x509Certs = new LinkedList<>();
+ ArrayList<X509Certificate> x509Certs = new ArrayList<>();
for (Certificate cert : certs) {
x509Certs.add((X509Certificate) cert);
}
diff --git a/identity/java/android/security/identity/PersonalizationData.java b/identity/java/android/security/identity/PersonalizationData.java
index b34f2505a6a6..bdb00fdfb341 100644
--- a/identity/java/android/security/identity/PersonalizationData.java
+++ b/identity/java/android/security/identity/PersonalizationData.java
@@ -18,10 +18,11 @@ package android.security.identity;
import android.annotation.NonNull;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashMap;
-import java.util.LinkedList;
+import java.util.List;
/**
* An object that holds personalization data.
@@ -38,7 +39,7 @@ public class PersonalizationData {
private PersonalizationData() {
}
- private LinkedList<AccessControlProfile> mProfiles = new LinkedList<>();
+ private ArrayList<AccessControlProfile> mProfiles = new ArrayList<>();
private LinkedHashMap<String, NamespaceData> mNamespaces = new LinkedHashMap<>();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
index 84429948c643..ae5565e9bceb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/ShellTaskOrganizer.java
@@ -435,6 +435,7 @@ public class ShellTaskOrganizer extends TaskOrganizer implements
}
notifyLocusVisibilityIfNeeded(info.getTaskInfo());
notifyCompatUI(info.getTaskInfo(), listener);
+ mRecentTasks.ifPresent(recentTasks -> recentTasks.onTaskAdded(info.getTaskInfo()));
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
index 6e78fcba4a00..b71cc32a0347 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
@@ -16,6 +16,8 @@
package com.android.wm.shell.recents;
+import android.app.ActivityManager;
+
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.util.GroupedRecentTaskInfo;
@@ -38,4 +40,9 @@ interface IRecentTasks {
* Gets the set of recent tasks.
*/
GroupedRecentTaskInfo[] getRecentTasks(int maxNum, int flags, int userId) = 3;
+
+ /**
+ * Gets the set of running tasks.
+ */
+ ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) = 4;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
index 8efa42830d80..59f72335678e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasksListener.aidl
@@ -16,6 +16,8 @@
package com.android.wm.shell.recents;
+import android.app.ActivityManager;
+
/**
* Listener interface that Launcher attaches to SystemUI to get split-screen callbacks.
*/
@@ -25,4 +27,14 @@ oneway interface IRecentTasksListener {
* Called when the set of recent tasks change.
*/
void onRecentTasksChanged();
+
+ /**
+ * Called when a running task appears.
+ */
+ void onRunningTaskAppeared(in ActivityManager.RunningTaskInfo taskInfo);
+
+ /**
+ * Called when a running task vanishes.
+ */
+ void onRunningTaskVanished(in ActivityManager.RunningTaskInfo taskInfo);
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index c166178e9bbd..d903d5b33780 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -17,6 +17,7 @@
package com.android.wm.shell.recents;
import static android.app.ActivityTaskManager.INVALID_TASK_ID;
+import static android.content.pm.PackageManager.FEATURE_PC;
import static com.android.wm.shell.common.ExecutorUtils.executeRemoteCallWithTaskPermission;
@@ -63,8 +64,9 @@ public class RecentTasksController implements TaskStackListenerCallback,
private final ShellExecutor mMainExecutor;
private final TaskStackListenerImpl mTaskStackListener;
private final RecentTasks mImpl = new RecentTasksImpl();
+ private IRecentTasksListener mListener;
+ private final boolean mIsDesktopMode;
- private final ArrayList<Runnable> mCallbacks = new ArrayList<>();
// Mapping of split task ids, mappings are symmetrical (ie. if t1 is the taskid of a task in a
// pair, then mSplitTasks[t1] = t2, and mSplitTasks[t2] = t1)
private final SparseIntArray mSplitTasks = new SparseIntArray();
@@ -95,6 +97,7 @@ public class RecentTasksController implements TaskStackListenerCallback,
RecentTasksController(Context context, TaskStackListenerImpl taskStackListener,
ShellExecutor mainExecutor) {
mContext = context;
+ mIsDesktopMode = mContext.getPackageManager().hasSystemFeature(FEATURE_PC);
mTaskStackListener = taskStackListener;
mMainExecutor = mainExecutor;
}
@@ -176,10 +179,15 @@ public class RecentTasksController implements TaskStackListenerCallback,
notifyRecentTasksChanged();
}
- public void onTaskRemoved(TaskInfo taskInfo) {
+ public void onTaskAdded(ActivityManager.RunningTaskInfo taskInfo) {
+ notifyRunningTaskAppeared(taskInfo);
+ }
+
+ public void onTaskRemoved(ActivityManager.RunningTaskInfo taskInfo) {
// Remove any split pairs associated with this task
removeSplitPair(taskInfo.taskId);
notifyRecentTasksChanged();
+ notifyRunningTaskVanished(taskInfo);
}
public void onTaskWindowingModeChanged(TaskInfo taskInfo) {
@@ -189,19 +197,50 @@ public class RecentTasksController implements TaskStackListenerCallback,
@VisibleForTesting
void notifyRecentTasksChanged() {
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_RECENT_TASKS, "Notify recent tasks changed");
- for (int i = 0; i < mCallbacks.size(); i++) {
- mCallbacks.get(i).run();
+ if (mListener == null) {
+ return;
+ }
+ try {
+ mListener.onRecentTasksChanged();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed call notifyRecentTasksChanged", e);
}
}
- private void registerRecentTasksListener(Runnable listener) {
- if (!mCallbacks.contains(listener)) {
- mCallbacks.add(listener);
+ /**
+ * Notify the running task listener that a task appeared on desktop environment.
+ */
+ private void notifyRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
+ return;
+ }
+ try {
+ mListener.onRunningTaskAppeared(taskInfo);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed call onRunningTaskAppeared", e);
+ }
+ }
+
+ /**
+ * Notify the running task listener that a task was removed on desktop environment.
+ */
+ private void notifyRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ if (mListener == null || !mIsDesktopMode || taskInfo.realActivity == null) {
+ return;
+ }
+ try {
+ mListener.onRunningTaskVanished(taskInfo);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed call onRunningTaskVanished", e);
}
}
- private void unregisterRecentTasksListener(Runnable listener) {
- mCallbacks.remove(listener);
+ private void registerRecentTasksListener(IRecentTasksListener listener) {
+ mListener = listener;
+ }
+
+ private void unregisterRecentTasksListener() {
+ mListener = null;
}
@VisibleForTesting
@@ -280,19 +319,28 @@ public class RecentTasksController implements TaskStackListenerCallback,
private RecentTasksController mController;
private final SingleInstanceRemoteListener<RecentTasksController,
IRecentTasksListener> mListener;
- private final Runnable mRecentTasksListener =
- new Runnable() {
- @Override
- public void run() {
- mListener.call(l -> l.onRecentTasksChanged());
- }
- };
+ private final IRecentTasksListener mRecentTasksListener = new IRecentTasksListener.Stub() {
+ @Override
+ public void onRecentTasksChanged() throws RemoteException {
+ mListener.call(l -> l.onRecentTasksChanged());
+ }
+
+ @Override
+ public void onRunningTaskAppeared(ActivityManager.RunningTaskInfo taskInfo) {
+ mListener.call(l -> l.onRunningTaskAppeared(taskInfo));
+ }
+
+ @Override
+ public void onRunningTaskVanished(ActivityManager.RunningTaskInfo taskInfo) {
+ mListener.call(l -> l.onRunningTaskVanished(taskInfo));
+ }
+ };
public IRecentTasksImpl(RecentTasksController controller) {
mController = controller;
mListener = new SingleInstanceRemoteListener<>(controller,
c -> c.registerRecentTasksListener(mRecentTasksListener),
- c -> c.unregisterRecentTasksListener(mRecentTasksListener));
+ c -> c.unregisterRecentTasksListener());
}
/**
@@ -331,5 +379,16 @@ public class RecentTasksController implements TaskStackListenerCallback,
true /* blocking */);
return out[0];
}
+
+ @Override
+ public ActivityManager.RunningTaskInfo[] getRunningTasks(int maxNum) {
+ final ActivityManager.RunningTaskInfo[][] tasks =
+ new ActivityManager.RunningTaskInfo[][] {null};
+ executeRemoteCallWithTaskPermission(mController, "getRunningTasks",
+ (controller) -> tasks[0] = ActivityTaskManager.getInstance().getTasks(maxNum)
+ .toArray(new ActivityManager.RunningTaskInfo[0]),
+ true /* blocking */);
+ return tasks[0];
+ }
}
} \ No newline at end of file
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
index 50f6bd7b4927..9ef8c322d105 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/recents/RecentTasksControllerTest.java
@@ -30,11 +30,13 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import static java.lang.Integer.MAX_VALUE;
import android.app.ActivityManager;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.graphics.Rect;
import android.view.SurfaceControl;
@@ -77,6 +79,7 @@ public class RecentTasksControllerTest extends ShellTestCase {
@Before
public void setUp() {
mMainExecutor = new TestShellExecutor();
+ when(mContext.getPackageManager()).thenReturn(mock(PackageManager.class));
mRecentTasksController = spy(new RecentTasksController(mContext, mTaskStackListener,
mMainExecutor));
mShellTaskOrganizer = new ShellTaskOrganizer(mMainExecutor, mContext,
diff --git a/libs/androidfw/Android.bp b/libs/androidfw/Android.bp
index c80fb188e70f..8a379d581532 100644
--- a/libs/androidfw/Android.bp
+++ b/libs/androidfw/Android.bp
@@ -33,6 +33,7 @@ license {
cc_defaults {
name: "libandroidfw_defaults",
+ cpp_std: "gnu++2b",
cflags: [
"-Werror",
"-Wunreachable-code",
diff --git a/libs/androidfw/include/androidfw/StringPiece.h b/libs/androidfw/include/androidfw/StringPiece.h
index 921877dc4982..fac2fa4fa575 100644
--- a/libs/androidfw/include/androidfw/StringPiece.h
+++ b/libs/androidfw/include/androidfw/StringPiece.h
@@ -288,12 +288,12 @@ inline ::std::basic_string<TChar>& operator+=(::std::basic_string<TChar>& lhs,
template <typename TChar>
inline bool operator==(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) {
- return rhs == lhs;
+ return BasicStringPiece<TChar>(lhs) == rhs;
}
template <typename TChar>
inline bool operator!=(const ::std::basic_string<TChar>& lhs, const BasicStringPiece<TChar>& rhs) {
- return rhs != lhs;
+ return BasicStringPiece<TChar>(lhs) != rhs;
}
} // namespace android
diff --git a/libs/hwui/HardwareBitmapUploader.cpp b/libs/hwui/HardwareBitmapUploader.cpp
index c24cabb287de..7291cab364e2 100644
--- a/libs/hwui/HardwareBitmapUploader.cpp
+++ b/libs/hwui/HardwareBitmapUploader.cpp
@@ -22,8 +22,11 @@
#include <GLES2/gl2ext.h>
#include <GLES3/gl3.h>
#include <GrDirectContext.h>
+#include <SkBitmap.h>
#include <SkCanvas.h>
#include <SkImage.h>
+#include <SkImageInfo.h>
+#include <SkRefCnt.h>
#include <gui/TraceUtils.h>
#include <utils/GLUtils.h>
#include <utils/NdkUtils.h>
diff --git a/libs/hwui/HardwareBitmapUploader.h b/libs/hwui/HardwareBitmapUploader.h
index 81057a24c29c..00ee99648889 100644
--- a/libs/hwui/HardwareBitmapUploader.h
+++ b/libs/hwui/HardwareBitmapUploader.h
@@ -17,6 +17,9 @@
#pragma once
#include <hwui/Bitmap.h>
+#include <SkRefCnt.h>
+
+class SkBitmap;
namespace android::uirenderer {
diff --git a/libs/hwui/Readback.cpp b/libs/hwui/Readback.cpp
index 4cce87ad1a2f..79953aa6adc9 100644
--- a/libs/hwui/Readback.cpp
+++ b/libs/hwui/Readback.cpp
@@ -26,6 +26,18 @@
#include "pipeline/skia/LayerDrawable.h"
#include "renderthread/EglManager.h"
#include "renderthread/VulkanManager.h"
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkColorSpace.h>
+#include <SkImage.h>
+#include <SkImageInfo.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkSamplingOptions.h>
+#include <SkSurface.h>
#include "utils/Color.h"
#include "utils/MathUtils.h"
#include "utils/NdkUtils.h"
diff --git a/libs/hwui/Readback.h b/libs/hwui/Readback.h
index d0d748ff5c16..aa6e43c3bc27 100644
--- a/libs/hwui/Readback.h
+++ b/libs/hwui/Readback.h
@@ -20,7 +20,11 @@
#include "Rect.h"
#include "renderthread/RenderThread.h"
-#include <SkBitmap.h>
+#include <SkRefCnt.h>
+
+class SkBitmap;
+class SkImage;
+struct SkRect;
namespace android {
class Bitmap;
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index a285462eef74..f5ebfd5d9e23 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -29,10 +29,14 @@
#include "SkDrawShadowInfo.h"
#include "SkImage.h"
#include "SkImageFilter.h"
+#include "SkImageInfo.h"
#include "SkLatticeIter.h"
#include "SkMath.h"
+#include "SkPaint.h"
#include "SkPicture.h"
+#include "SkRRect.h"
#include "SkRSXform.h"
+#include "SkRect.h"
#include "SkRegion.h"
#include "SkTextBlob.h"
#include "SkVertices.h"
diff --git a/libs/hwui/RecordingCanvas.h b/libs/hwui/RecordingCanvas.h
index 212b4e72dcb2..35bec9335d7c 100644
--- a/libs/hwui/RecordingCanvas.h
+++ b/libs/hwui/RecordingCanvas.h
@@ -34,6 +34,8 @@
#include <SkRuntimeEffect.h>
#include <vector>
+class SkRRect;
+
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 53c6db0cdf3a..023d6bf0b673 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -27,6 +27,7 @@
#include <SkAndroidFrameworkUtils.h>
#include <SkAnimatedImage.h>
+#include <SkBitmap.h>
#include <SkCanvasPriv.h>
#include <SkCanvasStateUtils.h>
#include <SkColorFilter.h>
@@ -36,8 +37,13 @@
#include <SkGraphics.h>
#include <SkImage.h>
#include <SkImagePriv.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
#include <SkPicture.h>
#include <SkRSXform.h>
+#include <SkRRect.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
#include <SkShader.h>
#include <SkTemplates.h>
#include <SkTextBlob.h>
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 715007cdcd3b..c6313f6c3a88 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -33,6 +33,8 @@
#include <cassert>
#include <optional>
+class SkRRect;
+
namespace android {
// Holds an SkCanvas reference plus additional native data.
diff --git a/libs/hwui/VectorDrawable.cpp b/libs/hwui/VectorDrawable.cpp
index 983c7766273a..536ff781badc 100644
--- a/libs/hwui/VectorDrawable.cpp
+++ b/libs/hwui/VectorDrawable.cpp
@@ -21,9 +21,10 @@
#include <utils/Log.h>
#include "PathParser.h"
-#include "SkColorFilter.h"
+#include "SkImage.h"
#include "SkImageInfo.h"
-#include "SkShader.h"
+#include "SkSamplingOptions.h"
+#include "SkScalar.h"
#include "hwui/Paint.h"
#ifdef __ANDROID__
diff --git a/libs/hwui/VectorDrawable.h b/libs/hwui/VectorDrawable.h
index 30bb04ae8361..c92654c479c1 100644
--- a/libs/hwui/VectorDrawable.h
+++ b/libs/hwui/VectorDrawable.h
@@ -31,6 +31,7 @@
#include <SkPath.h>
#include <SkPathMeasure.h>
#include <SkRect.h>
+#include <SkRefCnt.h>
#include <SkShader.h>
#include <SkSurface.h>
diff --git a/libs/hwui/apex/android_bitmap.cpp b/libs/hwui/apex/android_bitmap.cpp
index bc6bc456ba5a..c442a7b1d17c 100644
--- a/libs/hwui/apex/android_bitmap.cpp
+++ b/libs/hwui/apex/android_bitmap.cpp
@@ -24,6 +24,11 @@
#include <GraphicsJNI.h>
#include <hwui/Bitmap.h>
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkImageInfo.h>
+#include <SkRefCnt.h>
+#include <SkStream.h>
#include <utils/Color.h>
using namespace android;
diff --git a/libs/hwui/canvas/CanvasOps.h b/libs/hwui/canvas/CanvasOps.h
index fdc97a4fd8ba..2dcbca8273e7 100644
--- a/libs/hwui/canvas/CanvasOps.h
+++ b/libs/hwui/canvas/CanvasOps.h
@@ -17,13 +17,19 @@
#pragma once
#include <SkAndroidFrameworkUtils.h>
+#include <SkBlendMode.h>
#include <SkCanvas.h>
-#include <SkPath.h>
-#include <SkRegion.h>
-#include <SkVertices.h>
+#include <SkClipOp.h>
#include <SkImage.h>
+#include <SkPaint.h>
+#include <SkPath.h>
#include <SkPicture.h>
+#include <SkRRect.h>
+#include <SkRect.h>
+#include <SkRegion.h>
#include <SkRuntimeEffect.h>
+#include <SkSamplingOptions.h>
+#include <SkVertices.h>
#include <log/log.h>
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 67f47580a70f..feafc2372442 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -35,9 +35,15 @@
#endif
#include <SkCanvas.h>
+#include <SkColor.h>
+#include <SkEncodedImageFormat.h>
+#include <SkHighContrastFilter.h>
+#include <SkImageEncoder.h>
#include <SkImagePriv.h>
+#include <SkPixmap.h>
+#include <SkRect.h>
+#include <SkStream.h>
#include <SkWebpEncoder.h>
-#include <SkHighContrastFilter.h>
#include <limits>
namespace android {
diff --git a/libs/hwui/hwui/Bitmap.h b/libs/hwui/hwui/Bitmap.h
index 94a047c06ced..133f1fe0a1e7 100644
--- a/libs/hwui/hwui/Bitmap.h
+++ b/libs/hwui/hwui/Bitmap.h
@@ -19,9 +19,9 @@
#include <SkColorFilter.h>
#include <SkColorSpace.h>
#include <SkImage.h>
-#include <SkImage.h>
#include <SkImageInfo.h>
#include <SkPixelRef.h>
+#include <SkRefCnt.h>
#include <cutils/compiler.h>
#ifdef __ANDROID__ // Layoutlib does not support hardware acceleration
#include <android/hardware_buffer.h>
diff --git a/libs/hwui/hwui/Canvas.cpp b/libs/hwui/hwui/Canvas.cpp
index b046f45d9c57..cd8af3d933b1 100644
--- a/libs/hwui/hwui/Canvas.cpp
+++ b/libs/hwui/hwui/Canvas.cpp
@@ -26,6 +26,7 @@
#include "hwui/PaintFilter.h"
#include <SkFontMetrics.h>
+#include <SkRRect.h>
namespace android {
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index 82777646f3a2..7378351ef771 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -31,6 +31,7 @@
class SkAnimatedImage;
class SkCanvasState;
+class SkRRect;
class SkRuntimeShaderBuilder;
class SkVertices;
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 2db3ace1cd43..34cb4aef70d9 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -16,10 +16,13 @@
#include "MinikinSkia.h"
-#include <SkFontDescriptor.h>
#include <SkFont.h>
+#include <SkFontDescriptor.h>
#include <SkFontMetrics.h>
#include <SkFontMgr.h>
+#include <SkRect.h>
+#include <SkScalar.h>
+#include <SkStream.h>
#include <SkTypeface.h>
#include <log/log.h>
diff --git a/libs/hwui/jni/AnimatedImageDrawable.cpp b/libs/hwui/jni/AnimatedImageDrawable.cpp
index c40b858268be..373e893b9a25 100644
--- a/libs/hwui/jni/AnimatedImageDrawable.cpp
+++ b/libs/hwui/jni/AnimatedImageDrawable.cpp
@@ -21,8 +21,11 @@
#include <SkAndroidCodec.h>
#include <SkAnimatedImage.h>
#include <SkColorFilter.h>
+#include <SkEncodedImageFormat.h>
#include <SkPicture.h>
#include <SkPictureRecorder.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
#include <hwui/AnimatedImageDrawable.h>
#include <hwui/ImageDecoder.h>
#include <hwui/Canvas.h>
diff --git a/libs/hwui/jni/Bitmap.cpp b/libs/hwui/jni/Bitmap.cpp
index 5db0783cf83e..94cea65897cf 100755
--- a/libs/hwui/jni/Bitmap.cpp
+++ b/libs/hwui/jni/Bitmap.cpp
@@ -2,17 +2,25 @@
#define LOG_TAG "Bitmap"
#include "Bitmap.h"
+#include "GraphicsJNI.h"
#include "SkBitmap.h"
+#include "SkBlendMode.h"
#include "SkCanvas.h"
#include "SkColor.h"
#include "SkColorSpace.h"
-#include "SkPixelRef.h"
+#include "SkData.h"
#include "SkImageEncoder.h"
#include "SkImageInfo.h"
-#include "GraphicsJNI.h"
+#include "SkPaint.h"
+#include "SkPixelRef.h"
+#include "SkPixmap.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
#include "SkStream.h"
+#include "SkTypes.h"
#include "SkWebpEncoder.h"
+
#include "android_nio_utils.h"
#include "CreateJavaOutputStreamAdaptor.h"
#include <hwui/Paint.h>
diff --git a/libs/hwui/jni/Bitmap.h b/libs/hwui/jni/Bitmap.h
index 73eca3aa8ef8..21a93f066d9b 100644
--- a/libs/hwui/jni/Bitmap.h
+++ b/libs/hwui/jni/Bitmap.h
@@ -19,7 +19,6 @@
#include <jni.h>
#include <android/bitmap.h>
-class SkBitmap;
struct SkImageInfo;
namespace android {
diff --git a/libs/hwui/jni/BitmapFactory.cpp b/libs/hwui/jni/BitmapFactory.cpp
index 4e9daa4b0c16..320d3322904f 100644
--- a/libs/hwui/jni/BitmapFactory.cpp
+++ b/libs/hwui/jni/BitmapFactory.cpp
@@ -8,9 +8,19 @@
#include "MimeType.h"
#include "NinePatchPeeker.h"
#include "SkAndroidCodec.h"
+#include "SkBitmap.h"
+#include "SkBlendMode.h"
#include "SkCanvas.h"
+#include "SkColorSpace.h"
+#include "SkEncodedImageFormat.h"
+#include "SkImageInfo.h"
#include "SkMath.h"
+#include "SkPaint.h"
#include "SkPixelRef.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
+#include "SkSamplingOptions.h"
+#include "SkSize.h"
#include "SkStream.h"
#include "SkString.h"
#include "SkUtils.h"
diff --git a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp
index b10540cb3fbd..97dbc9ac171f 100644
--- a/libs/hwui/jni/ByteBufferStreamAdaptor.cpp
+++ b/libs/hwui/jni/ByteBufferStreamAdaptor.cpp
@@ -2,6 +2,7 @@
#include "GraphicsJNI.h"
#include "Utils.h"
+#include <SkData.h>
#include <SkStream.h>
using namespace android;
diff --git a/libs/hwui/jni/FontFamily.cpp b/libs/hwui/jni/FontFamily.cpp
index ce5ac382aeff..acc1b0424030 100644
--- a/libs/hwui/jni/FontFamily.cpp
+++ b/libs/hwui/jni/FontFamily.cpp
@@ -24,6 +24,7 @@
#include "SkData.h"
#include "SkFontMgr.h"
#include "SkRefCnt.h"
+#include "SkStream.h"
#include "SkTypeface.h"
#include "Utils.h"
#include "fonts/Font.h"
diff --git a/libs/hwui/jni/GIFMovie.cpp b/libs/hwui/jni/GIFMovie.cpp
index fef51b8d2f79..ae6ac4ce4ecc 100644
--- a/libs/hwui/jni/GIFMovie.cpp
+++ b/libs/hwui/jni/GIFMovie.cpp
@@ -7,9 +7,11 @@
#include "Movie.h"
+#include "SkBitmap.h"
#include "SkColor.h"
#include "SkColorPriv.h"
#include "SkStream.h"
+#include "SkTypes.h"
#include "gif_lib.h"
diff --git a/libs/hwui/jni/Graphics.cpp b/libs/hwui/jni/Graphics.cpp
index 33669ac0a34e..6a3bc8fe1152 100644
--- a/libs/hwui/jni/Graphics.cpp
+++ b/libs/hwui/jni/Graphics.cpp
@@ -8,10 +8,18 @@
#include <nativehelper/JNIHelp.h>
#include "GraphicsJNI.h"
+#include "include/private/SkTemplates.h" // SkTAddOffset
+#include "SkBitmap.h"
#include "SkCanvas.h"
+#include "SkColorSpace.h"
#include "SkFontMetrics.h"
+#include "SkImageInfo.h"
#include "SkMath.h"
+#include "SkPixelRef.h"
+#include "SkPoint.h"
+#include "SkRect.h"
#include "SkRegion.h"
+#include "SkTypes.h"
#include <cutils/ashmem.h>
#include <hwui/Canvas.h>
diff --git a/libs/hwui/jni/ImageDecoder.cpp b/libs/hwui/jni/ImageDecoder.cpp
index f7b8c014be6e..bad710dec274 100644
--- a/libs/hwui/jni/ImageDecoder.cpp
+++ b/libs/hwui/jni/ImageDecoder.cpp
@@ -29,8 +29,12 @@
#include <FrontBufferedStream.h>
#include <SkAndroidCodec.h>
-#include <SkEncodedImageFormat.h>
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkImageInfo.h>
+#include <SkRect.h>
#include <SkStream.h>
+#include <SkString.h>
#include <androidfw/Asset.h>
#include <fcntl.h>
diff --git a/libs/hwui/jni/Movie.h b/libs/hwui/jni/Movie.h
index 736890d5215e..02113dd58ec8 100644
--- a/libs/hwui/jni/Movie.h
+++ b/libs/hwui/jni/Movie.h
@@ -13,6 +13,7 @@
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkRefCnt.h"
+#include "SkTypes.h"
class SkStreamRewindable;
diff --git a/libs/hwui/jni/MovieImpl.cpp b/libs/hwui/jni/MovieImpl.cpp
index ae9e04e617b0..abb75fa99c94 100644
--- a/libs/hwui/jni/MovieImpl.cpp
+++ b/libs/hwui/jni/MovieImpl.cpp
@@ -5,11 +5,12 @@
* found in the LICENSE file.
*/
#include "Movie.h"
-#include "SkCanvas.h"
-#include "SkPaint.h"
+#include "SkBitmap.h"
+#include "SkStream.h"
+#include "SkTypes.h"
// We should never see this in normal operation since our time values are
-// 0-based. So we use it as a sentinal.
+// 0-based. So we use it as a sentinel.
#define UNINITIALIZED_MSEC ((SkMSec)-1)
Movie::Movie()
@@ -81,8 +82,6 @@ const SkBitmap& Movie::bitmap()
////////////////////////////////////////////////////////////////////
-#include "SkStream.h"
-
Movie* Movie::DecodeMemory(const void* data, size_t length) {
SkMemoryStream stream(data, length, false);
return Movie::DecodeStream(&stream);
diff --git a/libs/hwui/jni/NinePatch.cpp b/libs/hwui/jni/NinePatch.cpp
index 08fc80fbdafd..d50a8a22b5cb 100644
--- a/libs/hwui/jni/NinePatch.cpp
+++ b/libs/hwui/jni/NinePatch.cpp
@@ -24,8 +24,10 @@
#include <hwui/Paint.h>
#include <utils/Log.h>
+#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkLatticeIter.h"
+#include "SkRect.h"
#include "SkRegion.h"
#include "GraphicsJNI.h"
#include "NinePatchPeeker.h"
diff --git a/libs/hwui/jni/NinePatchPeeker.cpp b/libs/hwui/jni/NinePatchPeeker.cpp
index 9171fc687276..d85ede5dc6d2 100644
--- a/libs/hwui/jni/NinePatchPeeker.cpp
+++ b/libs/hwui/jni/NinePatchPeeker.cpp
@@ -16,7 +16,7 @@
#include "NinePatchPeeker.h"
-#include <SkBitmap.h>
+#include <SkScalar.h>
#include <cutils/compiler.h>
using namespace android;
diff --git a/libs/hwui/jni/Shader.cpp b/libs/hwui/jni/Shader.cpp
index 0bbd8a8cf97c..fa8e2e79c831 100644
--- a/libs/hwui/jni/Shader.cpp
+++ b/libs/hwui/jni/Shader.cpp
@@ -2,11 +2,21 @@
#define LOG_TAG "ShaderJNI"
#include "GraphicsJNI.h"
+#include "SkBitmap.h"
+#include "SkBlendMode.h"
+#include "SkColor.h"
#include "SkColorFilter.h"
#include "SkGradientShader.h"
+#include "SkImage.h"
#include "SkImagePriv.h"
+#include "SkMatrix.h"
+#include "SkPoint.h"
+#include "SkRefCnt.h"
+#include "SkSamplingOptions.h"
+#include "SkScalar.h"
#include "SkShader.h"
-#include "SkBlendMode.h"
+#include "SkString.h"
+#include "SkTileMode.h"
#include "include/effects/SkRuntimeEffect.h"
#include <vector>
@@ -16,7 +26,7 @@ using namespace android::uirenderer;
/**
* By default Skia gradients will interpolate their colors in unpremul space
* and then premultiply each of the results. We must set this flag to preserve
- * backwards compatiblity by premultiplying the colors of the gradient first,
+ * backwards compatibility by premultiplying the colors of the gradient first,
* and then interpolating between them.
*/
static const uint32_t sGradientShaderFlags = SkGradientShader::kInterpolateColorsInPremul_Flag;
diff --git a/libs/hwui/jni/Utils.h b/libs/hwui/jni/Utils.h
index 6cdf44d85a5a..f6e3a0eeaa0e 100644
--- a/libs/hwui/jni/Utils.h
+++ b/libs/hwui/jni/Utils.h
@@ -17,8 +17,11 @@
#ifndef _ANDROID_GRAPHICS_UTILS_H_
#define _ANDROID_GRAPHICS_UTILS_H_
+#include "SkRefCnt.h"
#include "SkStream.h"
+class SkData;
+
#include <jni.h>
#include <androidfw/Asset.h>
diff --git a/libs/hwui/jni/YuvToJpegEncoder.cpp b/libs/hwui/jni/YuvToJpegEncoder.cpp
index 77f42ae70268..87eda7e9f96f 100644
--- a/libs/hwui/jni/YuvToJpegEncoder.cpp
+++ b/libs/hwui/jni/YuvToJpegEncoder.cpp
@@ -1,5 +1,7 @@
#include "CreateJavaOutputStreamAdaptor.h"
#include "SkJPEGWriteUtility.h"
+#include "SkStream.h"
+#include "SkTypes.h"
#include "YuvToJpegEncoder.h"
#include <ui/PixelFormat.h>
#include <hardware/hardware.h>
diff --git a/libs/hwui/jni/YuvToJpegEncoder.h b/libs/hwui/jni/YuvToJpegEncoder.h
index 7e7b935df276..a69726b17e9d 100644
--- a/libs/hwui/jni/YuvToJpegEncoder.h
+++ b/libs/hwui/jni/YuvToJpegEncoder.h
@@ -1,13 +1,13 @@
#ifndef _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
#define _ANDROID_GRAPHICS_YUV_TO_JPEG_ENCODER_H_
-#include "SkTypes.h"
-#include "SkStream.h"
extern "C" {
#include "jpeglib.h"
#include "jerror.h"
}
+class SkWStream;
+
class YuvToJpegEncoder {
public:
/** Create an encoder based on the YUV format.
diff --git a/libs/hwui/jni/android_graphics_Canvas.cpp b/libs/hwui/jni/android_graphics_Canvas.cpp
index 0ef80ee10708..61bb66557adc 100644
--- a/libs/hwui/jni/android_graphics_Canvas.cpp
+++ b/libs/hwui/jni/android_graphics_Canvas.cpp
@@ -32,10 +32,22 @@
#include "FontUtils.h"
#include "Bitmap.h"
+#include "SkBitmap.h"
+#include "SkBlendMode.h"
+#include "SkClipOp.h"
+#include "SkColor.h"
+#include "SkColorSpace.h"
#include "SkGraphics.h"
+#include "SkImageInfo.h"
+#include "SkMatrix.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRect.h"
+#include "SkRefCnt.h"
#include "SkRegion.h"
-#include "SkVertices.h"
#include "SkRRect.h"
+#include "SkScalar.h"
+#include "SkVertices.h"
namespace minikin {
class MeasuredText;
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index 27865b3972d7..3122e72f22d8 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -23,8 +23,16 @@
#include <Picture.h>
#include <Properties.h>
#include <RootRenderNode.h>
+#include <SkBitmap.h>
+#include <SkColorSpace.h>
+#include <SkData.h>
+#include <SkImage.h>
#include <SkImagePriv.h>
+#include <SkPicture.h>
+#include <SkPixmap.h>
#include <SkSerialProcs.h>
+#include <SkStream.h>
+#include <SkTypeface.h>
#include <dlfcn.h>
#include <gui/TraceUtils.h>
#include <inttypes.h>
@@ -444,7 +452,7 @@ struct PictureCaptureState {
};
// TODO: This & Multi-SKP & Single-SKP should all be de-duped into
-// a single "make a SkPicture serailizable-safe" utility somewhere
+// a single "make a SkPicture serializable-safe" utility somewhere
class PictureWrapper : public Picture {
public:
PictureWrapper(sk_sp<SkPicture>&& src, const std::shared_ptr<PictureCaptureState>& state)
diff --git a/libs/hwui/jni/fonts/Font.cpp b/libs/hwui/jni/fonts/Font.cpp
index 09be630dc741..2c421f8727a8 100644
--- a/libs/hwui/jni/fonts/Font.cpp
+++ b/libs/hwui/jni/fonts/Font.cpp
@@ -22,7 +22,10 @@
#include "SkFont.h"
#include "SkFontMetrics.h"
#include "SkFontMgr.h"
+#include "SkRect.h"
#include "SkRefCnt.h"
+#include "SkScalar.h"
+#include "SkStream.h"
#include "SkTypeface.h"
#include "GraphicsJNI.h"
#include <nativehelper/ScopedUtfChars.h>
diff --git a/libs/hwui/pipeline/skia/DumpOpsCanvas.h b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
index 3f89c0712407..6a052dbb7cea 100644
--- a/libs/hwui/pipeline/skia/DumpOpsCanvas.h
+++ b/libs/hwui/pipeline/skia/DumpOpsCanvas.h
@@ -19,6 +19,8 @@
#include "RenderNode.h"
#include "SkiaDisplayList.h"
+class SkRRect;
+
namespace android {
namespace uirenderer {
namespace skiapipeline {
diff --git a/libs/hwui/pipeline/skia/HolePunch.h b/libs/hwui/pipeline/skia/HolePunch.h
index 92c6f7721a08..d0e1ca35049a 100644
--- a/libs/hwui/pipeline/skia/HolePunch.h
+++ b/libs/hwui/pipeline/skia/HolePunch.h
@@ -17,7 +17,6 @@
#pragma once
#include <string>
-#include "SkRRect.h"
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
index 507d3dcdcde9..3bf2b2e63a47 100644
--- a/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
+++ b/libs/hwui/pipeline/skia/RenderNodeDrawable.cpp
@@ -15,7 +15,11 @@
*/
#include "RenderNodeDrawable.h"
+#include <SkPaint.h>
#include <SkPaintFilterCanvas.h>
+#include <SkPoint.h>
+#include <SkRRect.h>
+#include <SkRect.h>
#include <gui/TraceUtils.h>
#include "RenderNode.h"
#include "SkiaDisplayList.h"
diff --git a/libs/hwui/pipeline/skia/ShaderCache.cpp b/libs/hwui/pipeline/skia/ShaderCache.cpp
index e7432ac5f216..ef3f1ca3c41d 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.cpp
+++ b/libs/hwui/pipeline/skia/ShaderCache.cpp
@@ -16,6 +16,7 @@
#include "ShaderCache.h"
#include <GrDirectContext.h>
+#include <SkData.h>
#include <gui/TraceUtils.h>
#include <log/log.h>
#include <openssl/sha.h>
diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h
index 4dcc9fb49802..dd57d428ba31 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.h
+++ b/libs/hwui/pipeline/skia/ShaderCache.h
@@ -17,12 +17,15 @@
#pragma once
#include <GrContextOptions.h>
+#include <SkRefCnt.h>
#include <cutils/compiler.h>
#include <memory>
#include <mutex>
#include <string>
#include <vector>
+class SkData;
+
namespace android {
class BlobCache;
@@ -45,7 +48,7 @@ public:
* and puts the ShaderCache into an initialized state, such that it is
* able to insert and retrieve entries from the cache. If identity is
* non-null and validation fails, the cache is initialized but contains
- * no data. If size is less than zero, the cache is initilaized but
+ * no data. If size is less than zero, the cache is initialized but
* contains no data.
*
* This should be called when HWUI pipeline is initialized. When not in
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index bc386feb2d6f..c546adaaf779 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -16,15 +16,25 @@
#include "SkiaPipeline.h"
+#include <SkCanvas.h>
+#include <SkColor.h>
+#include <SkColorSpace.h>
+#include <SkData.h>
+#include <SkImage.h>
#include <SkImageEncoder.h>
#include <SkImageInfo.h>
#include <SkImagePriv.h>
+#include <SkMatrix.h>
#include <SkMultiPictureDocument.h>
#include <SkOverdrawCanvas.h>
#include <SkOverdrawColorFilter.h>
#include <SkPicture.h>
#include <SkPictureRecorder.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
#include <SkSerialProcs.h>
+#include <SkStream.h>
+#include <SkString.h>
#include <SkTypeface.h>
#include <android-base/properties.h>
#include <unistd.h>
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.h b/libs/hwui/pipeline/skia/SkiaPipeline.h
index bc8a5659dd83..370c7b379de2 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.h
@@ -24,6 +24,7 @@
#include "renderthread/CanvasContext.h"
#include "renderthread/IRenderPipeline.h"
+class SkFILEWStream;
class SkPictureRecorder;
struct SkSharingSerialContext;
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 9c51e628e04a..5c6117d86415 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -16,7 +16,20 @@
#include "SkiaRecordingCanvas.h"
#include "hwui/Paint.h"
+#include <include/private/SkTemplates.h> // SkAutoSTMalloc
+#include <SkBlendMode.h>
+#include <SkData.h>
+#include <SkDrawable.h>
+#include <SkImage.h>
#include <SkImagePriv.h>
+#include <SkMatrix.h>
+#include <SkPaint.h>
+#include <SkPoint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkRRect.h>
+#include <SkSamplingOptions.h>
+#include <SkTypes.h>
#include "CanvasTransform.h"
#ifdef __ANDROID__ // Layoutlib does not support Layers
#include "Layer.h"
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
index 1445a27e4248..89e3a2c24e1e 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.h
@@ -22,6 +22,11 @@
#include "SkiaDisplayList.h"
#include "pipeline/skia/AnimatedDrawables.h"
+class SkBitmap;
+class SkMatrix;
+class SkPaint;
+class SkRRect;
+
namespace android {
namespace uirenderer {
namespace skiapipeline {
diff --git a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
index 56d42e013f31..a721be3c60d1 100644
--- a/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
+++ b/libs/hwui/pipeline/skia/SkiaVulkanPipeline.h
@@ -22,6 +22,11 @@
#include "renderstate/RenderState.h"
+#include "SkRefCnt.h"
+
+class SkBitmap;
+struct SkRect;
+
namespace android {
namespace uirenderer {
namespace skiapipeline {
diff --git a/libs/hwui/pipeline/skia/TransformCanvas.cpp b/libs/hwui/pipeline/skia/TransformCanvas.cpp
index 41e36874b862..33160d05e2d0 100644
--- a/libs/hwui/pipeline/skia/TransformCanvas.cpp
+++ b/libs/hwui/pipeline/skia/TransformCanvas.cpp
@@ -19,6 +19,10 @@
#include "HolePunch.h"
#include "SkData.h"
#include "SkDrawable.h"
+#include "SkMatrix.h"
+#include "SkPaint.h"
+#include "SkRect.h"
+#include "SkRRect.h"
using namespace android::uirenderer::skiapipeline;
diff --git a/libs/hwui/pipeline/skia/TransformCanvas.h b/libs/hwui/pipeline/skia/TransformCanvas.h
index 685b71d017e9..15f0c1abc55a 100644
--- a/libs/hwui/pipeline/skia/TransformCanvas.h
+++ b/libs/hwui/pipeline/skia/TransformCanvas.h
@@ -19,6 +19,13 @@
#include "SkPaintFilterCanvas.h"
#include <effects/StretchEffect.h>
+class SkData;
+class SkDrawable;
+class SkMatrix;
+class SkPaint;
+enum class SkBlendMode;
+struct SkRect;
+
class TransformCanvas : public SkPaintFilterCanvas {
public:
TransformCanvas(SkCanvas* target, SkBlendMode blendmode) :
diff --git a/libs/hwui/renderthread/RenderProxy.cpp b/libs/hwui/renderthread/RenderProxy.cpp
index 026699c63e16..65b51b4f2c08 100644
--- a/libs/hwui/renderthread/RenderProxy.cpp
+++ b/libs/hwui/renderthread/RenderProxy.cpp
@@ -29,6 +29,10 @@
#include "utils/Macros.h"
#include "utils/TimeUtils.h"
+#include <SkBitmap.h>
+#include <SkImage.h>
+#include <SkPicture.h>
+
#include <pthread.h>
namespace android {
diff --git a/libs/hwui/renderthread/RenderProxy.h b/libs/hwui/renderthread/RenderProxy.h
index 491dbd72a14d..5e2b4577e7f5 100644
--- a/libs/hwui/renderthread/RenderProxy.h
+++ b/libs/hwui/renderthread/RenderProxy.h
@@ -17,7 +17,7 @@
#ifndef RENDERPROXY_H_
#define RENDERPROXY_H_
-#include <SkBitmap.h>
+#include <SkRefCnt.h>
#include <android/native_window.h>
#include <cutils/compiler.h>
#include <android/surface_control.h>
@@ -30,6 +30,10 @@
#include "SwapBehavior.h"
#include "hwui/Bitmap.h"
+class SkBitmap;
+class SkPicture;
+class SkImage;
+
namespace android {
class GraphicBuffer;
class Surface;
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 491af4336f97..a4890ede8faa 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -26,7 +26,13 @@
#include <renderthread/VulkanManager.h>
#include <utils/Unicode.h>
+#include "SkCanvas.h"
#include "SkColorData.h"
+#include "SkMatrix.h"
+#include "SkPath.h"
+#include "SkPixmap.h"
+#include "SkRect.h"
+#include "SkSurface.h"
#include "SkUnPreMultiply.h"
namespace android {
diff --git a/libs/hwui/tests/common/TestUtils.h b/libs/hwui/tests/common/TestUtils.h
index 5092675a8104..75865c751d52 100644
--- a/libs/hwui/tests/common/TestUtils.h
+++ b/libs/hwui/tests/common/TestUtils.h
@@ -27,10 +27,20 @@
#include <renderstate/RenderState.h>
#include <renderthread/RenderThread.h>
+#include <SkBitmap.h>
+#include <SkColor.h>
+#include <SkImageInfo.h>
+#include <SkRefCnt.h>
+
#include <gtest/gtest.h>
#include <memory>
#include <unordered_map>
+class SkCanvas;
+class SkMatrix;
+class SkPath;
+struct SkRect;
+
namespace android {
namespace uirenderer {
diff --git a/libs/hwui/tests/common/scenes/BitmapShaders.cpp b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
index 03aeb55f129b..a07cdf720b50 100644
--- a/libs/hwui/tests/common/scenes/BitmapShaders.cpp
+++ b/libs/hwui/tests/common/scenes/BitmapShaders.cpp
@@ -14,7 +14,17 @@
* limitations under the License.
*/
-#include <SkImagePriv.h>
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkImage.h>
+#include <SkImageInfo.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkSamplingOptions.h>
+#include <SkShader.h>
+#include <SkTileMode.h>
#include "hwui/Paint.h"
#include "TestSceneBase.h"
#include "tests/common/BitmapAllocationTestUtils.h"
diff --git a/libs/hwui/tests/common/scenes/HwBitmap565.cpp b/libs/hwui/tests/common/scenes/HwBitmap565.cpp
index cbdb756b8fa7..de0ef6d595f8 100644
--- a/libs/hwui/tests/common/scenes/HwBitmap565.cpp
+++ b/libs/hwui/tests/common/scenes/HwBitmap565.cpp
@@ -18,6 +18,12 @@
#include "tests/common/BitmapAllocationTestUtils.h"
#include "utils/Color.h"
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkCanvas.h>
+#include <SkPaint.h>
+#include <SkRefCnt.h>
+
class HwBitmap565;
static TestScene::Registrar _HwBitmap565(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
index d031923a112b..4a5d9468cd88 100644
--- a/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/ListViewAnimation.cpp
@@ -17,7 +17,16 @@
#include "TestSceneBase.h"
#include "tests/common/TestListViewSceneBase.h"
#include "hwui/Paint.h"
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
#include <SkFont.h>
+#include <SkFontTypes.h>
+#include <SkPaint.h>
+#include <SkPoint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+#include <SkScalar.h>
#include <cstdio>
class ListViewAnimation;
@@ -48,7 +57,7 @@ class ListViewAnimation : public TestListViewSceneBase {
128 * 3;
paint.setColor(bgDark ? Color::White : Color::Grey_700);
- SkFont font;
+ SkFont font;
font.setSize(size / 2);
char charToShow = 'A' + (rand() % 26);
const SkPoint pos = {SkIntToScalar(size / 2),
diff --git a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
index edadf78db051..070a339a86a1 100644
--- a/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/MagnifierAnimation.cpp
@@ -19,6 +19,10 @@
#include "utils/Color.h"
#include "hwui/Paint.h"
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkFont.h>
+
class MagnifierAnimation;
static TestScene::Registrar _Magnifier(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
index 716d3979bdcb..3caaf8236d8a 100644
--- a/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
+++ b/libs/hwui/tests/common/scenes/ReadbackFromHardwareBitmap.cpp
@@ -16,6 +16,12 @@
#include "TestSceneBase.h"
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkPaint.h>
+#include <SkRect.h>
+#include <SkRefCnt.h>
+
class ReadbackFromHardware;
static TestScene::Registrar _SaveLayer(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
index 1c2507867f6e..27948f8b4b43 100644
--- a/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/RecentsAnimation.cpp
@@ -17,6 +17,11 @@
#include "TestSceneBase.h"
#include "utils/Color.h"
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkColor.h>
+#include <SkRefCnt.h>
+
class RecentsAnimation;
static TestScene::Registrar _Recents(TestScene::Info{
diff --git a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
index e677549b7894..59230a754f4e 100644
--- a/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
+++ b/libs/hwui/tests/common/scenes/StretchyListViewAnimation.cpp
@@ -14,7 +14,15 @@
* limitations under the License.
*/
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkColor.h>
#include <SkFont.h>
+#include <SkFontTypes.h>
+#include <SkPaint.h>
+#include <SkPoint.h>
+#include <SkRefCnt.h>
+#include <SkRRect.h>
#include <cstdio>
#include "TestSceneBase.h"
#include "hwui/Paint.h"
diff --git a/libs/hwui/tests/common/scenes/TvApp.cpp b/libs/hwui/tests/common/scenes/TvApp.cpp
index c6219c485b85..aff8ca1e26c7 100644
--- a/libs/hwui/tests/common/scenes/TvApp.cpp
+++ b/libs/hwui/tests/common/scenes/TvApp.cpp
@@ -14,7 +14,12 @@
* limitations under the License.
*/
+#include "SkBitmap.h"
#include "SkBlendMode.h"
+#include "SkColorFilter.h"
+#include "SkFont.h"
+#include "SkImageInfo.h"
+#include "SkRefCnt.h"
#include "TestSceneBase.h"
#include "tests/common/BitmapAllocationTestUtils.h"
#include "hwui/Paint.h"
diff --git a/libs/hwui/tests/unit/CanvasOpTests.cpp b/libs/hwui/tests/unit/CanvasOpTests.cpp
index 2cf3456694b0..d2b1ef91a898 100644
--- a/libs/hwui/tests/unit/CanvasOpTests.cpp
+++ b/libs/hwui/tests/unit/CanvasOpTests.cpp
@@ -23,9 +23,17 @@
#include <tests/common/CallCountingCanvas.h>
-#include "SkPictureRecorder.h"
+#include "SkBitmap.h"
+#include "SkCanvas.h"
#include "SkColor.h"
+#include "SkImageInfo.h"
#include "SkLatticeIter.h"
+#include "SkPaint.h"
+#include "SkPath.h"
+#include "SkPictureRecorder.h"
+#include "SkRRect.h"
+#include "SkRect.h"
+#include "SkRegion.h"
#include "pipeline/skia/AnimatedDrawables.h"
#include <SkNoDrawCanvas.h>
diff --git a/libs/hwui/tests/unit/FatalTestCanvas.h b/libs/hwui/tests/unit/FatalTestCanvas.h
index 2a74afc5bb7a..96a0c6114682 100644
--- a/libs/hwui/tests/unit/FatalTestCanvas.h
+++ b/libs/hwui/tests/unit/FatalTestCanvas.h
@@ -19,6 +19,8 @@
#include <SkCanvas.h>
#include <gtest/gtest.h>
+class SkRRect;
+
namespace {
class TestCanvasBase : public SkCanvas {
diff --git a/libs/hwui/tests/unit/ShaderCacheTests.cpp b/libs/hwui/tests/unit/ShaderCacheTests.cpp
index 87981f115763..105fea408736 100644
--- a/libs/hwui/tests/unit/ShaderCacheTests.cpp
+++ b/libs/hwui/tests/unit/ShaderCacheTests.cpp
@@ -25,6 +25,8 @@
#include <cstdint>
#include "FileBlobCache.h"
#include "pipeline/skia/ShaderCache.h"
+#include <SkData.h>
+#include <SkRefCnt.h>
using namespace android::uirenderer::skiapipeline;
diff --git a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
index dc1b2e668dd0..c1ddbd36bcfd 100644
--- a/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
+++ b/libs/hwui/tests/unit/SkiaBehaviorTests.cpp
@@ -16,9 +16,14 @@
#include "tests/common/TestUtils.h"
+#include <SkBitmap.h>
+#include <SkBlendMode.h>
+#include <SkColor.h>
#include <SkColorMatrixFilter.h>
#include <SkColorSpace.h>
-#include <SkImagePriv.h>
+#include <SkImageInfo.h>
+#include <SkPaint.h>
+#include <SkPath.h>
#include <SkPathOps.h>
#include <SkShader.h>
#include <gtest/gtest.h>
diff --git a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
index 15ecf5831f3a..ced667eb76e5 100644
--- a/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
+++ b/libs/hwui/tests/unit/SkiaRenderPropertiesTests.cpp
@@ -17,6 +17,7 @@
#include <VectorDrawable.h>
#include <gtest/gtest.h>
+#include <SkCanvas.h>
#include <SkClipStack.h>
#include <SkSurface_Base.h>
#include <string.h>
diff --git a/libs/hwui/tests/unit/TypefaceTests.cpp b/libs/hwui/tests/unit/TypefaceTests.cpp
index ab23448ab93f..9295a938f397 100644
--- a/libs/hwui/tests/unit/TypefaceTests.cpp
+++ b/libs/hwui/tests/unit/TypefaceTests.cpp
@@ -21,8 +21,11 @@
#include <sys/stat.h>
#include <utils/Log.h>
+#include "SkData.h"
#include "SkFontMgr.h"
+#include "SkRefCnt.h"
#include "SkStream.h"
+#include "SkTypeface.h"
#include "hwui/MinikinSkia.h"
#include "hwui/Typeface.h"
diff --git a/libs/hwui/tests/unit/VectorDrawableTests.cpp b/libs/hwui/tests/unit/VectorDrawableTests.cpp
index 6d4c57413f00..c1c21bd7dfbf 100644
--- a/libs/hwui/tests/unit/VectorDrawableTests.cpp
+++ b/libs/hwui/tests/unit/VectorDrawableTests.cpp
@@ -21,6 +21,12 @@
#include "utils/MathUtils.h"
#include "utils/VectorDrawableUtils.h"
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkPath.h>
+#include <SkRefCnt.h>
+#include <SkShader.h>
+
#include <functional>
namespace android {
diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp
index 45da008c3e8e..956101e7a2a4 100644
--- a/libs/input/MouseCursorController.cpp
+++ b/libs/input/MouseCursorController.cpp
@@ -24,12 +24,6 @@
#include <log/log.h>
-#include <SkBitmap.h>
-#include <SkBlendMode.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-
namespace {
// Time to spend fading out the pointer completely.
const nsecs_t POINTER_FADE_DURATION = 500 * 1000000LL; // 500 ms
diff --git a/libs/input/TouchSpotController.cpp b/libs/input/TouchSpotController.cpp
index f7c685ff8ba6..4ac66c4ffb6a 100644
--- a/libs/input/TouchSpotController.cpp
+++ b/libs/input/TouchSpotController.cpp
@@ -23,12 +23,6 @@
#include <log/log.h>
-#include <SkBitmap.h>
-#include <SkBlendMode.h>
-#include <SkCanvas.h>
-#include <SkColor.h>
-#include <SkPaint.h>
-
namespace {
// Time to spend fading out the spot completely.
const nsecs_t SPOT_FADE_DURATION = 200 * 1000000LL; // 200 ms
diff --git a/media/aidl/android/media/audio/common/AudioPort.aidl b/media/aidl/android/media/audio/common/AudioPort.aidl
index 84675e3a00a6..d32b840ebfe8 100644
--- a/media/aidl/android/media/audio/common/AudioPort.aidl
+++ b/media/aidl/android/media/audio/common/AudioPort.aidl
@@ -23,8 +23,9 @@ import android.media.audio.common.AudioProfile;
import android.media.audio.common.ExtraAudioDescriptor;
/**
- * Audio port structure describes the capabilities of an audio port
- * as well as its current configuration.
+ * Audio port structure describes the capabilities of an audio port.
+ * This is a "blueprint" which contains all the possible configurations
+ * that are supported by the port.
*
* {@hide}
*/
diff --git a/media/aidl/android/media/audio/common/AudioPortExt.aidl b/media/aidl/android/media/audio/common/AudioPortExt.aidl
index c4681cbb182e..eadc0ab7c7c5 100644
--- a/media/aidl/android/media/audio/common/AudioPortExt.aidl
+++ b/media/aidl/android/media/audio/common/AudioPortExt.aidl
@@ -34,6 +34,9 @@ union AudioPortExt {
AudioPortDeviceExt device;
/** Information specific to mix ports. */
AudioPortMixExt mix;
- /** Audio session identifier. */
+ /**
+ * NOT USED. Framework audio session identifier.
+ * Use android.media.AudioPortExtSys.session on the system side.
+ */
int session;
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 69fe5ee49872..8959db4d6216 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -60,7 +60,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
@@ -484,7 +483,7 @@ public final class TvInputManager {
private final Object mLock = new Object();
// @GuardedBy("mLock")
- private final List<TvInputCallbackRecord> mCallbackRecords = new LinkedList<>();
+ private final List<TvInputCallbackRecord> mCallbackRecords = new ArrayList<>();
// A mapping from TV input ID to the state of corresponding input.
// @GuardedBy("mLock")
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
index 83ff0f50f1a3..e458d2490a54 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppManager.java
@@ -51,8 +51,8 @@ import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
@@ -293,7 +293,7 @@ public final class TvInteractiveAppManager {
new SparseArray<>();
// @GuardedBy("mLock")
- private final List<TvInteractiveAppCallbackRecord> mCallbackRecords = new LinkedList<>();
+ private final List<TvInteractiveAppCallbackRecord> mCallbackRecords = new ArrayList<>();
// A sequence number for the next session to be created. Should be protected by a lock
// {@code mSessionCallbackRecordMap}.
diff --git a/native/graphics/jni/imagedecoder.cpp b/native/graphics/jni/imagedecoder.cpp
index bb25274e3136..cd6ed2391608 100644
--- a/native/graphics/jni/imagedecoder.cpp
+++ b/native/graphics/jni/imagedecoder.cpp
@@ -25,6 +25,12 @@
#include <hwui/ImageDecoder.h>
#include <log/log.h>
#include <SkAndroidCodec.h>
+#include <SkCodec.h>
+#include <SkColorSpace.h>
+#include <SkImageInfo.h>
+#include <SkRect.h>
+#include <SkSize.h>
+#include <SkStream.h>
#include <utils/Color.h>
#include <fcntl.h>
diff --git a/packages/CompanionDeviceManager/AndroidManifest.xml b/packages/CompanionDeviceManager/AndroidManifest.xml
index 8b5d214f7a10..c1fce7c3dd23 100644
--- a/packages/CompanionDeviceManager/AndroidManifest.xml
+++ b/packages/CompanionDeviceManager/AndroidManifest.xml
@@ -48,6 +48,14 @@
android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
android:theme="@style/ChooserActivity"/>
+ <activity
+ android:name=".CompanionDeviceDataTransferActivity"
+ android:exported="true"
+ android:launchMode="singleInstance"
+ android:excludeFromRecents="true"
+ android:permission="android.permission.BIND_COMPANION_DEVICE_MANAGER_SERVICE"
+ android:theme="@style/ChooserActivity"/>
+
<service
android:name=".CompanionDeviceDiscoveryService"
android:exported="false" />
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java
index 67efa03b645f..036ea2e62aff 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDataTransferActivity.java
@@ -27,9 +27,7 @@ import android.os.Bundle;
import android.os.ResultReceiver;
import android.text.Html;
import android.util.Log;
-import android.view.View;
import android.widget.Button;
-import android.widget.ListView;
import android.widget.TextView;
/**
@@ -61,8 +59,6 @@ public class CompanionDeviceDataTransferActivity extends Activity {
TextView titleView = findViewById(R.id.title);
TextView summaryView = findViewById(R.id.summary);
- ListView listView = findViewById(R.id.device_list);
- listView.setVisibility(View.GONE);
Button allowButton = findViewById(R.id.btn_positive);
Button disallowButton = findViewById(R.id.btn_negative);
@@ -73,7 +69,7 @@ public class CompanionDeviceDataTransferActivity extends Activity {
requireNonNull(mRequest);
requireNonNull(mCdmServiceReceiver);
- if (mRequest.isPermissionSyncAllPackages()
+ if (mRequest.getPermissionSyncAllPackages()
|| !mRequest.getPermissionSyncPackages().isEmpty()) {
titleView.setText(Html.fromHtml(getString(
R.string.permission_sync_confirmation_title), 0));
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
index f28572f5f71d..69484ed527b5 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/users/EditUserInfoControllerTest.java
@@ -37,9 +37,9 @@ import android.widget.ImageView;
import androidx.fragment.app.FragmentActivity;
import com.android.settingslib.R;
+import com.android.settingslib.RestrictedLockUtils;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
@@ -55,7 +55,6 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
@RunWith(RobolectricTestRunner.class)
-@Ignore
public class EditUserInfoControllerTest {
private static final int MAX_USER_NAME_LENGTH = 100;
@@ -87,6 +86,11 @@ public class EditUserInfoControllerTest {
}
@Override
+ RestrictedLockUtils.EnforcedAdmin getChangePhotoAdminRestriction(Context context) {
+ return null;
+ }
+
+ @Override
boolean isChangePhotoRestrictedByBase(Context context) {
return mPhotoRestrictedByBase;
}
@@ -98,7 +102,7 @@ public class EditUserInfoControllerTest {
mActivity = spy(ActivityController.of(new FragmentActivity()).get());
mActivity.setTheme(R.style.Theme_AppCompat_DayNight);
mController = new TestEditUserInfoController();
- mPhotoRestrictedByBase = true;
+ mPhotoRestrictedByBase = false;
}
@Test
@@ -262,7 +266,7 @@ public class EditUserInfoControllerTest {
@Test
public void createDialog_canNotChangePhoto_nullPhotoController() {
- mPhotoRestrictedByBase = false;
+ mPhotoRestrictedByBase = true;
mController.createDialog(mActivity, mActivityStarter, mCurrentIcon,
"test", "title", null, null);
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
index 716ee845bea6..a6bfc408be7e 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SystemSettings.java
@@ -43,7 +43,6 @@ public class SystemSettings {
Settings.System.FONT_SCALE,
Settings.System.DIM_SCREEN,
Settings.System.SCREEN_OFF_TIMEOUT,
- Settings.System.SCREEN_OFF_TIMEOUT_DOCKED,
Settings.System.SCREEN_BRIGHTNESS_MODE,
Settings.System.SCREEN_AUTO_BRIGHTNESS_ADJ,
Settings.System.SCREEN_BRIGHTNESS_FOR_VR,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
index bbfab0bfa792..a7966eb52be4 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/GlobalSettingsValidators.java
@@ -315,6 +315,7 @@ public class GlobalSettingsValidators {
VALIDATORS.put(Global.USER_PREFERRED_RESOLUTION_WIDTH, ANY_INTEGER_VALIDATOR);
VALIDATORS.put(Global.Wearable.WET_MODE_ON, BOOLEAN_VALIDATOR);
VALIDATORS.put(Global.Wearable.COOLDOWN_MODE_ON, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE, BOOLEAN_VALIDATOR);
}
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index d4302963f2d3..06712cc68b89 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -111,7 +111,6 @@ public class SystemSettingsValidators {
});
VALIDATORS.put(System.DISPLAY_COLOR_MODE_VENDOR_HINT, ANY_STRING_VALIDATOR);
VALIDATORS.put(System.SCREEN_OFF_TIMEOUT, NON_NEGATIVE_INTEGER_VALIDATOR);
- VALIDATORS.put(System.SCREEN_OFF_TIMEOUT_DOCKED, NON_NEGATIVE_INTEGER_VALIDATOR);
VALIDATORS.put(System.SCREEN_BRIGHTNESS_FOR_VR, new InclusiveIntegerRangeValidator(0, 255));
VALIDATORS.put(System.SCREEN_BRIGHTNESS_MODE, BOOLEAN_VALIDATOR);
VALIDATORS.put(System.ADAPTIVE_SLEEP, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 077337cdc8c3..700c04cf34ec 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -5220,7 +5220,7 @@ public class SettingsProvider extends ContentProvider {
.getResources()
.getBoolean(R.bool.def_wearable_hotwordDetectionEnabled));
initGlobalSettingsDefaultValForWearLocked(
- Global.Wearable.SMART_REPLIES_ENABLED, false);
+ Global.Wearable.SMART_REPLIES_ENABLED, true);
Setting locationMode =
getSecureSettingsLocked(userId).getSettingLocked(Secure.LOCATION_MODE);
initGlobalSettingsDefaultValForWearLocked(
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 057a9b05de58..3a49481e97dc 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -662,7 +662,8 @@ public class SettingsBackupTest {
Settings.Global.Wearable.CLOCKWORK_LONG_PRESS_TO_ASSISTANT_ENABLED,
Settings.Global.Wearable.WEAR_ACTIVITY_AUTO_RESUME_TIMEOUT_SET_BY_USER,
Settings.Global.Wearable.WET_MODE_ON,
- Settings.Global.Wearable.COOLDOWN_MODE_ON);
+ Settings.Global.Wearable.COOLDOWN_MODE_ON,
+ Settings.Global.Wearable.TOUCH_AND_HOLD_WATCH_FACE);
private static final Set<String> BACKUP_DENY_LIST_SECURE_SETTINGS =
newHashSet(
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index e93371d3690c..f5e02aa5243c 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -110,7 +110,7 @@
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
<uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" />
<uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" />
- <uses-permission android:name="android.permission.SEND_LOST_MODE_LOCATION_UPDATES" />
+ <uses-permission android:name="android.permission.TRIGGER_LOST_MODE" />
<!-- ACCESS_BACKGROUND_LOCATION is needed for testing purposes only. -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- ACCESS_MTP is needed for testing purposes only. -->
diff --git a/packages/Shell/src/com/android/shell/BugreportProgressService.java b/packages/Shell/src/com/android/shell/BugreportProgressService.java
index 0b8bd9784b7d..3fdd8c851733 100644
--- a/packages/Shell/src/com/android/shell/BugreportProgressService.java
+++ b/packages/Shell/src/com/android/shell/BugreportProgressService.java
@@ -570,6 +570,7 @@ public class BugreportProgressService extends Service {
break;
case INTENT_BUGREPORT_DONE:
maybeShowWarningMessageAndCloseNotification(id);
+ break;
case INTENT_BUGREPORT_CANCEL:
cancel(id);
break;
@@ -840,16 +841,11 @@ public class BugreportProgressService extends Service {
PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_UPDATE_CURRENT);
}
- @GuardedBy("mLock")
- private void stopProgressLocked(int id) {
- stopProgressLocked(id, /* cancelNotification */ true);
- }
-
/**
* Finalizes the progress on a given bugreport and cancel its notification.
*/
@GuardedBy("mLock")
- private void stopProgressLocked(int id, boolean cancelNotification) {
+ private void stopProgressLocked(int id) {
if (mBugreportInfos.indexOfKey(id) < 0) {
Log.w(TAG, "ID not watched: " + id);
} else {
@@ -859,12 +855,10 @@ public class BugreportProgressService extends Service {
// Must stop foreground service first, otherwise notif.cancel() will fail below.
stopForegroundWhenDoneLocked(id);
- if (cancelNotification) {
- Log.d(TAG, "stopProgress(" + id + "): cancel notification");
- NotificationManager.from(mContext).cancel(id);
- } else {
- Log.d(TAG, "stopProgress(" + id + ")");
- }
+
+ Log.d(TAG, "stopProgress(" + id + "): cancel notification");
+ NotificationManager.from(mContext).cancel(id);
+
stopSelfWhenDoneLocked();
}
@@ -1109,30 +1103,7 @@ public class BugreportProgressService extends Service {
return;
}
- if (mIsWatch) {
- // Wear wants to send the notification directly and not wait for the user to tap on the
- // notification.
- triggerShareBugreportAndLocalNotification(info);
- } else {
- triggerLocalNotification(info);
- }
- }
-
- /**
- * Responsible for starting the bugerport sharing process and posting a notification which
- * shows that the bugreport has been taken and that the sharing process has kicked-off.
- */
- private void triggerShareBugreportAndLocalNotification(final BugreportInfo info) {
- boolean isPlainText = info.bugreportFile.getName().toLowerCase().endsWith(".txt");
- if (!isPlainText) {
- // Already zipped, share it right away.
- shareBugreport(info.id, info, /* showWarning */ false,
- /* cancelNotificationWhenStoppingProgress */ false);
- sendBugreportNotification(info, mTakingScreenshot);
- } else {
- // Asynchronously zip the file first, then share it.
- shareAndPostNotificationForZippedBugreport(info, mTakingScreenshot);
- }
+ triggerLocalNotification(info);
}
/**
@@ -1246,16 +1217,14 @@ public class BugreportProgressService extends Service {
}
private void shareBugreport(int id, BugreportInfo sharedInfo) {
- shareBugreport(id, sharedInfo, !hasUserDecidedNotToGetWarningMessage(),
- /* cancelNotificationWhenStoppingProgress */ true);
+ shareBugreport(id, sharedInfo, !hasUserDecidedNotToGetWarningMessage());
}
/**
* Shares the bugreport upon user's request by issuing a {@link Intent#ACTION_SEND_MULTIPLE}
* intent, but issuing a warning dialog the first time.
*/
- private void shareBugreport(int id, BugreportInfo sharedInfo, boolean showWarning,
- boolean cancelNotificationWhenStoppingProgress) {
+ private void shareBugreport(int id, BugreportInfo sharedInfo, boolean showWarning) {
MetricsLogger.action(this, MetricsEvent.ACTION_BUGREPORT_NOTIFICATION_ACTION_SHARE);
BugreportInfo info;
synchronized (mLock) {
@@ -1304,7 +1273,7 @@ public class BugreportProgressService extends Service {
}
synchronized (mLock) {
// ... and stop watching this process.
- stopProgressLocked(id, cancelNotificationWhenStoppingProgress);
+ stopProgressLocked(id);
}
}
@@ -1359,7 +1328,7 @@ public class BugreportProgressService extends Service {
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE))
.setDeleteIntent(newCancelIntent(mContext, info));
} else {
- // Device is a watch.
+ // Device is a watch
if (hasUserDecidedNotToGetWarningMessage()) {
// No action button needed for the notification. User can swipe to dimiss.
builder.setActions(new Action[0]);
@@ -1430,24 +1399,6 @@ public class BugreportProgressService extends Service {
}
/**
- * Zips a bugreport, shares it, and sends for it a bugreport notification.
- */
- private void shareAndPostNotificationForZippedBugreport(final BugreportInfo info,
- final boolean takingScreenshot) {
- new AsyncTask<Void, Void, Void>() {
- @Override
- protected Void doInBackground(Void... params) {
- Looper.prepare();
- zipBugreport(info);
- shareBugreport(info.id, info, /* showWarning */ false,
- /* cancelNotificationWhenStoppingProgress */ false);
- sendBugreportNotification(info, mTakingScreenshot);
- return null;
- }
- }.execute();
- }
-
- /**
* Zips a bugreport file, returning the path to the new file (or to the
* original in case of failure).
*/
diff --git a/packages/SystemUI/res/drawable/ic_circular_unchecked.xml b/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
index 779ab816d925..9b43cf64f116 100644
--- a/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
+++ b/packages/SystemUI/res/drawable/ic_circular_unchecked.xml
@@ -4,6 +4,6 @@
android:viewportWidth="24"
android:viewportHeight="24">
<path
- android:fillColor="@color/media_dialog_item_main_content"
+ android:fillColor="@color/media_dialog_inactive_item_main_content"
android:pathData="M12,22q-2.075,0 -3.9,-0.788 -1.825,-0.787 -3.175,-2.137 -1.35,-1.35 -2.137,-3.175Q2,14.075 2,12t0.788,-3.9q0.787,-1.825 2.137,-3.175 1.35,-1.35 3.175,-2.137Q9.925,2 12,2t3.9,0.788q1.825,0.787 3.175,2.137 1.35,1.35 2.137,3.175Q22,9.925 22,12t-0.788,3.9q-0.787,1.825 -2.137,3.175 -1.35,1.35 -3.175,2.137Q14.075,22 12,22zM12,12zM12,20q3.325,0 5.663,-2.337Q20,15.325 20,12t-2.337,-5.662Q15.325,4 12,4T6.338,6.338Q4,8.675 4,12q0,3.325 2.338,5.663Q8.675,20 12,20z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_check.xml b/packages/SystemUI/res/drawable/media_output_status_check.xml
index 5fbc42b245b8..1b750f8959b9 100644
--- a/packages/SystemUI/res/drawable/media_output_status_check.xml
+++ b/packages/SystemUI/res/drawable/media_output_status_check.xml
@@ -21,6 +21,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
- android:fillColor="@color/media_dialog_item_main_content"
+ android:fillColor="@color/media_dialog_item_status"
android:pathData="M9,16.2L4.8,12l-1.4,1.4L9,19 21,7l-1.4,-1.4L9,16.2z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/media_output_status_failed.xml b/packages/SystemUI/res/drawable/media_output_status_failed.xml
index 0599e239a9ee..05c635833441 100644
--- a/packages/SystemUI/res/drawable/media_output_status_failed.xml
+++ b/packages/SystemUI/res/drawable/media_output_status_failed.xml
@@ -21,6 +21,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
- android:fillColor="@color/media_dialog_item_main_content"
+ android:fillColor="@color/media_dialog_inactive_item_main_content"
android:pathData="M11,7h2v2h-2zM11,11h2v6h-2zM12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8 8,3.59 8,8 -3.59,8 -8,8z"/>
</vector>
diff --git a/packages/SystemUI/res/layout/media_output_dialog.xml b/packages/SystemUI/res/layout/media_output_dialog.xml
index 05343e75b448..51211a0c0d2a 100644
--- a/packages/SystemUI/res/layout/media_output_dialog.xml
+++ b/packages/SystemUI/res/layout/media_output_dialog.xml
@@ -129,7 +129,7 @@
style="@style/Widget.Dialog.Button.BorderButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="@string/media_output_dialog_button_stop_casting"
+ android:text="@string/keyboard_key_media_stop"
android:visibility="gone"/>
<Space
diff --git a/packages/SystemUI/res/layout/media_output_list_item.xml b/packages/SystemUI/res/layout/media_output_list_item.xml
index 20747fad021b..eeb37c7b062d 100644
--- a/packages/SystemUI/res/layout/media_output_list_item.xml
+++ b/packages/SystemUI/res/layout/media_output_list_item.xml
@@ -83,7 +83,7 @@
android:ellipsize="end"
android:maxLines="1"
android:fontFamily="@*android:string/config_headlineFontFamilyMedium"
- android:textColor="@color/media_dialog_item_main_content"
+ android:textColor="@color/media_dialog_inactive_item_main_content"
android:textSize="16sp"/>
<TextView
android:id="@+id/subtitle"
@@ -91,7 +91,7 @@
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxLines="1"
- android:textColor="@color/media_dialog_item_main_content"
+ android:textColor="@color/media_dialog_inactive_item_main_content"
android:textSize="14sp"
android:fontFamily="@*android:string/config_bodyFontFamily"
android:visibility="gone"/>
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index c0fdf689cfc2..fc4ede861a58 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Hou op uitsaai"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 43ad0057d2ba..45e784c398d2 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"አስገባ"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"የኋሊት መደምሰሻ"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"አጫውት/ለአፍታ አቁም"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"አቁም"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Cast ማድረግ አቁም"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ቀጣይ"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ቀዳሚ"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ወደኋላ አጠንጥን"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 5ec5e9b537f0..c813bbeb5479 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -569,7 +569,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"تشغيل / إيقاف مؤقت"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"إيقاف"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"إيقاف البث"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"التالي"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"السابق"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ترجيع"</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index 00f7790e384d..1aeffcd3631e 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"এণ্টাৰ"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"বেকস্পেচ"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"প্লে/পজ কৰক"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"বন্ধ কৰক"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"কাষ্ট কৰাটো বন্ধ কৰক"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"পৰৱৰ্তী"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"পূৰ্বৱৰ্তী"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ৰিৱাইণ্ড কৰক"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index a1956b30c54c..0c861c5296ad 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Daxil olun"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Gerisil"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Oxut/Durdur"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Dayandırın"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Yayımı dayandırın"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Növbəti"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Öncəki"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Geri ötürmə"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 2019e9dbcb8a..ec3cd79256b7 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -554,7 +554,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Taster za brisanje unazad"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Taster za reprodukciju/pauziranje"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Taster za zaustavljanje"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Zaustavi prebacivanje"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Taster Sledeća"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Taster Prethodna"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Taster za premotavanje unazad"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index c10a36d66373..d2b1f13bff65 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Прайграванне/Паўза"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Спыніць"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Спыніць трансляцыю"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Наступны"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Папярэдні"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Перамотка назад"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index a10750401a05..0dbc74e93c28 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Пускане/пауза"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Спиране"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Спиране на предаването"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Напред"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Назад"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Превъртане назад"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index b5040e959a34..71fa03eeafe8 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"এন্টার"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"ব্যাকস্পেস"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"প্লে/বিরতি"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"থামান"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"কাস্ট করা বন্ধ করুন"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"পরবর্তী"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"পূর্ববর্তী"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"পেছনের দিকে যান"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index b0691fe6b5b0..b9559df1471d 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -554,7 +554,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Tipka za novi red"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Tipka za brisanje"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Pokreni/pauziraj"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Zaustavi"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Zaustavi emitiranje"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Naprijed"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Prethodno"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Premotaj"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index da4cba76a427..5fa24eb3c14e 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Retorn"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Retrocés"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reprodueix/Pausa"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Atura"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Atura l\'emissió"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Següent"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rebobina"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index e93fc2937913..84aa05b6383b 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Přehrát/Pozastavit"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Zastavit"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Zastavit odesílání"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Další"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Předchozí"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Přetočit zpět"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index bf460fe05c6b..0910357e160b 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Afspil/pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Stop med at caste"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Næste"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Forrige"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Spol tilbage"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index 6197b3fbae0c..8d7a7349a94e 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Eingabetaste"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Rücktaste"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Wiedergabe/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stopp"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Streaming beenden"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Weiter"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Zurück"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Zurückspulen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index dc0d98bc7caf..fae0345223e4 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Αναπαραγωγή/Παύση"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Διακοπή"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Διακοπή μετάδοσης"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Επόμενο"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Προηγούμενο"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Επαναφορά"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index fcbe0a6927aa..43fb80652304 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -546,7 +546,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Stop casting"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index 2e6514a3f77d..7a9b3d983a7c 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -546,7 +546,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Stop casting"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index fcbe0a6927aa..43fb80652304 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -546,7 +546,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Stop casting"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index fcbe0a6927aa..43fb80652304 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -546,7 +546,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Stop casting"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index f05e75b187e4..238884aa9654 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -546,7 +546,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‏‏‏‏‎‎‏‏‏‏‏‏‎‏‏‏‎‏‏‏‏‎‎‎‎‏‎‎‏‏‏‎‏‎‎‏‏‎‎‏‏‏‎‎‏‏‎‎‎‏‎‏‎‏‏‏‏‎‎Enter‎‏‎‎‏‎"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‎‏‎‏‎‏‎‏‏‎‎‏‏‏‏‎‏‏‎‏‎‏‎‏‎‏‎‏‎‏‏‏‏‎‏‏‏‎‏‏‏‏‎‏‎‎‏‎‏‎‏‎‎Backspace‎‏‎‎‏‎"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‎‎‏‏‎‏‏‏‏‎‎‏‏‎‏‏‎‎‎‏‏‎‏‎‏‎‎‏‎‎‏‏‏‎‎‏‎‎‎‏‎‏‎‏‏‏‎‏‎‏‏‏‎‎‏‏‎‎Play/Pause‎‏‎‎‏‎"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‎‏‎‎‎‏‏‎‎‏‎‏‏‏‎‏‎‏‏‎‎‎‎‏‎‏‏‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‏‎Stop‎‏‎‎‏‎"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‎‏‎‎‎‏‎‏‎‏‏‎‎‏‎‎‎‎‎‎‏‎‏‏‎‎‎‏‎‎‎‎‏‏‏‎‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎‎‏‎‏‎‏‏‎Stop casting‎‏‎‎‏‎"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‏‎‏‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‎‏‎‏‏‏‎‏‎‏‏‎‏‏‎‏‏‎‎‏‎‏‏‎‎‏‎‎‎‎Next‎‏‎‎‏‎"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‎‏‏‏‎‎‎‏‏‏‏‎‏‏‏‎‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‏‏‎‏‏‎‎‎‏‎‎‎‎‏‎‏‏‎‎‎‎‏‎‏‎‏‎‏‏‏‎Previous‎‏‎‎‏‎"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‏‎‎‎‎‏‏‏‏‏‏‎‏‎‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‏‎‏‎‏‎‏‏‏‎‏‎‎‎‎‎‎‏‏‏‏‎‎‏‏‏‎‎‏‎‏‎‎‏‏‏‎‎‏‏‎‎‏‎Rewind‎‏‎‎‏‎"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 4363ce9c298f..26987bae00ed 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Intro"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Retroceso"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reproducir/pausar"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Detener"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Detener transmisión"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Siguiente"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Retroceder"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 0e7be44a61e0..e44d1f22c46e 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Intro"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Tecla de retroceso"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reproducir/Pausa"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Detener"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Dejar de enviar"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Siguiente"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rebobinar"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 0c9d46ed868e..46561c9441aa 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Sisestusklahv"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Tagasilüke"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Esita/peata"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Peata"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Lõpeta ülekanne"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Järgmine"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Eelmine"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Keri tagasi"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 90d24e507ba2..c48f0560306d 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Sartu"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Atzera"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Erreproduzitu/Pausatu"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Gelditu"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Utzi igortzeari"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Hurrengoa"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Aurrekoa"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Atzeratu"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 99e214b77fe2..103ef7849830 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"ورود"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"پس‌بر"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"پخش/مکث"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"توقف"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"توقف ارسال محتوا"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"بعدی"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"قبلی"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"عقب بردن"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 5aca1cea9f7c..393d65d4c012 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Askelpalautin"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Toisto/keskeytys"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Pysäytä"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Lopeta striimaus"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Seuraava"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Edellinen"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Kelaa taaksepäin"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 1a599b5ecaf7..f8ef8bc49846 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Entrée"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Retour arrière"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Lecture/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Arrêter"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Arrêter la diffusion"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Suivant"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Précédent"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Reculer"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 1465bdbc508b..05b1f0f9dc3d 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Entrée"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Retour arrière"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Lire ou suspendre la lecture"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Arrêter"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Arrêter la diffusion"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Suivant"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Précédent"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Retour arrière"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 5faa3df65171..29c6db2ba96a 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Intro"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Retroceso"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reproducir/Pausar"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Deter"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Deter emisión"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Seguinte"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Retroceder"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 763d39de4913..5e503534ba1e 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"કાસ્ટ કરવાનું રોકો"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 27e5091cdc59..cd5160b0077b 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"कास्टिंग करना रोकें"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index d3905e7bb820..a8ff91a732a5 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -554,7 +554,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Unos"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Povratna tipka"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reprodukcija/pauza"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Zaustavi"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Zaustavi emitiranje"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Sljedeće"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Prethodno"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Unatrag"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 3b94d8f15d90..f378cc4a8d36 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Visszatörlés"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Lejátszás/szünet"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Leállítás"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Átküldés leállítása"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Következő"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Előző"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Visszatekerés"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 488aa7674805..0f804aa7c441 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Մուտք"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Հետշարժ"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Նվագարկում/դադար"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Դադարեցնել"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Դադարեցնել հեռարձակումը"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Հաջորդը"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Նախորդը"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Հետ անցնել"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 0913166cc1eb..3013d05a0254 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Hentikan transmisi"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index cddb8f81fc09..e3975ed63054 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Bakklykill"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Spila/gera hlé"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stöðva"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Stöðva útsendingu"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Áfram"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Fyrri"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Spóla til baka"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index ed125cd306e8..02c2f650390a 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Invio"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pausa"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Interrompi"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Interrompi trasmissione"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Avanti"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Precedente"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Riavvolgi"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index f88605a90adf..9307c60d7f33 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"BACKSPACE"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"הפעלה/השהיה"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"עצירה"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"‏עצירת ההעברה (cast)"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"הבא"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"הקודם"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"הרצה אחורה"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index b946344c8af5..8639892ca535 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"再生 / 一時停止"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"停止"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"キャストを停止"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"次へ"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"前へ"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"巻き戻し"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 31d760611843..8a1cab3de10c 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"დაკვრა/პაუზა"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"შეწყვეტა"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"ტრანსლირების შეწყვეტა"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"შემდეგი"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"წინა"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"უკან გადახვევა"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index c8abf951d255..da085f82eb00 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Ойнату/кідірту"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Тоқтату"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Трансляциялауды тоқтату"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Келесі"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Алдыңғы"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Кері айналдыру"</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index 78e6c8439f12..bb8368100d6a 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"ឈប់បញ្ជូន"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index e10f5d393787..b90014a5f02c 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"ಬಿತ್ತರಿಸುವುದನ್ನು ನಿಲ್ಲಿಸಿ"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ಮುಂದೆ"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ಹಿಂದೆ"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index ba6ef05d7ba1..d4ddc9c063a8 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"재생/일시중지"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"중지"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"전송 중지"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"다음"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"이전"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"되감기"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a31ab6d3f0bf..23d242dd1078 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Киргизүү"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Артка өчүрүү"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Ойнотуу/Тындыруу"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Токтотуу"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Тышкы экранга чыгарууну токтотуу"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Кийинки"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Мурунку"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Артка түрүү"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 204e3d92a3a6..24c6bb568cc1 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"ຫຼິ້ນ/ຢຸດຊົ່ວຄາວ"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"ຢຸດ"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"ຢຸດການສົ່ງສັນຍານ"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ຕໍ່ໄປ"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ກ່ອນໜ້າ"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ຣີວາຍກັບ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 6bcfa0e91678..35368b7ab2b5 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Įvesti"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Naikinimo klavišas"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Leisti / pristabdyti"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Sustabdyti"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Sustabdyti perdavimą"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Kitas"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Ankstesnis"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Sukti atgal"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 286cdecc6c4b..386651d31c51 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -554,7 +554,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Ievadīšanas taustiņš"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Atpakaļatkāpes taustiņš"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Atskaņot/apturēt"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Apturēt"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Apturēt apraidi"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Nākamais"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Iepriekšējais"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Attīt atpakaļ"</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index ffa0e58b88b5..c4d4376c2e34 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Внеси"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Бришење наназад"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Пушти/Паузирај"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Сопри"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Сопри со емитување"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Следно"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Претходно"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Премотување наназад"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index 6aeb7e75e0da..40e6413f9997 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"എന്റർ"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"ബാക്ക്‌സ്‍പെയ്‍സ്"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"പ്ലേ ചെയ്യുക/താൽക്കാലികമായി നിർത്തുക"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"നിർത്തുക"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"കാസ്റ്റ് ചെയ്യുന്നത് നിർത്തുക"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"അടുത്തത്"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"മുമ്പത്തേത്"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"റിവൈൻഡ്"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 4abfe1b0bb48..0f32f6d4ca09 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Оруулах"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Арилгах"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Тоглуулах/Түр зогсоох"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Зогсоох"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Дамжуулахыг зогсоох"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Дараах"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Өмнөх"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Буцааж хураах"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index 2ec0073808b2..2d7b3497d7d0 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"प्ले करा/विराम द्या"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"थांबा"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"कास्ट करणे थांबवा"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"पुढील"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"मागील"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"मागे न्या"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 06270d71427e..1453fe03dcfa 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Undur ruang"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Main/Jeda"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Berhenti"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Berhenti menghantar"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Seterusnya"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Sebelumnya"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Mandir"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index 4a4f1a16f517..b6371fa395b0 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter ခလုတ်"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"နောက်ပြန်ဖျက်ပါ"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"ဖွင့်ပါ/ခဏရပ်ပါ"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"ရပ်ပါ"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"ကာစ်လုပ်ခြင်း ရပ်ရန်"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ရှေ့သို့"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ယခင်"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"နောက်သို့ရစ်ပါ"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 5ccf52890432..c3dfe5f8fb1b 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Tilbaketasten"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Spill av / sett på pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stopp"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Stopp castingen"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Neste"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Forrige"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Spol tilbake"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index 471bf14152d8..78f45e11d0eb 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"ब्याकस्पेस"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"प्ले गर्नुहोस्/पज गर्नुहोस्"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"रोक्नुहोस्"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"कास्ट गर्न छाड्नुहोस्"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"अर्को"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"अघिल्लो"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"रिवाइन्ड गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res/values-night/colors.xml b/packages/SystemUI/res/values-night/colors.xml
index 3a638b1e5098..4b96d5d660ee 100644
--- a/packages/SystemUI/res/values-night/colors.xml
+++ b/packages/SystemUI/res/values-night/colors.xml
@@ -67,12 +67,10 @@
<!-- media output dialog-->
<color name="media_dialog_background">@color/material_dynamic_neutral10</color>
- <color name="media_dialog_item_main_content">@color/material_dynamic_primary90</color>
- <color name="media_dialog_item_background">@color/material_dynamic_neutral_variant20</color>
- <color name="media_dialog_connected_item_background">@color/material_dynamic_secondary20</color>
- <color name="media_dialog_seekbar_progress">@color/material_dynamic_secondary40</color>
- <color name="media_dialog_button_background">@color/material_dynamic_primary70</color>
- <color name="media_dialog_solid_button_text">@color/material_dynamic_secondary20</color>
+ <color name="media_dialog_active_item_main_content">@color/material_dynamic_neutral10</color>
+ <color name="media_dialog_inactive_item_main_content">@color/material_dynamic_neutral10</color>
+ <color name="media_dialog_item_status">@color/material_dynamic_neutral10</color>
+ <color name="media_dialog_item_background">@color/material_dynamic_secondary95</color>
<!-- Biometric dialog colors -->
<color name="biometric_dialog_gray">#ffcccccc</color>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 047f99f130b7..bd15146d9020 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Afspelen/Onderbreken"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stoppen"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Casten stoppen"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Volgende"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Vorige"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Terugspoelen"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index 0dca918eccce..2364c778b604 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"ଏଣ୍ଟର୍"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"ବ୍ୟାକସ୍ପେସ୍‍"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"ପ୍ଲେ କରନ୍ତୁ/ପଜ୍‍ କରନ୍ତୁ"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"ବନ୍ଦ କରନ୍ତୁ"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"କାଷ୍ଟ କରିବା ବନ୍ଦ କରନ୍ତୁ"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ପରବର୍ତ୍ତୀ"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ପୂର୍ବବର୍ତ୍ତୀ"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ରିୱାଇଣ୍ଡ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index faa206224214..afb3f4f985f1 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"ਕਾਸਟ ਕਰਨਾ ਬੰਦ ਕਰੋ"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ਅੱਗੇ"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ਪਿਛਲਾ"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 5d61dfe567d2..4530043bbadf 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Odtwórz/wstrzymaj"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Zatrzymaj"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Zatrzymaj przesyłanie"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Następny"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Poprzedni"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Przewiń do tyłu"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index d9bb15b66a11..1c888985008c 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Barra de espaço"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reproduzir/pausar"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Parar"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Parar transmissão"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Avançar"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Voltar"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 73ef834df64d..18113aa8313f 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Retrocesso"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reproduzir/interromper"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Parar"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Parar transmissão"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Seguinte"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Recuar"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index d9bb15b66a11..1c888985008c 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Barra de espaço"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Reproduzir/pausar"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Parar"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Parar transmissão"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Avançar"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Anterior"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Voltar"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index ff409d33fc94..c0950a5bffac 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -554,7 +554,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Redați/Întrerupeți"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Opriți"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Nu mai proiectați"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Înainte"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Înapoi"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Derulați înapoi"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index a79c247b882c..fa3a11fc7a2e 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Ввод"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Воспроизведение/пауза"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Стоп"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Остановить трансляцию"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Следующий трек"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Предыдущий трек"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Перемотка назад"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index ffaa4bfccf92..37ccc42d4f71 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter යතුර"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace යතුර"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"ධාවනය කරන්න/විරාම කරන්න"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"නතර කරන්න"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"විකාශය කිරීම නවතන්න"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ඊළඟ"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"පෙර"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"නැවත ඔතන්න"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 2c2a7c881ff6..6c49c1e7a617 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Prehrať/pozastaviť"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Zastaviť"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Zastaviť prenos"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Ďalej"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Predchádzajúce"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Pretočiť späť"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 6996d56f2861..29315794053a 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Vnesi"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Premik nazaj"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Predvajaj/zaustavi"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Ustavi"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Ustavi predvajanje"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Naslednji"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Prejšnji"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Previj nazaj"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index bea8d835c39b..f39ed2469009 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Kthim prapa"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Luaj/pauzë"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Ndalo"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Ndalo transmetimin"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Përpara"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Prapa"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rikthe me shpejtësi"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index f373eea9d8e3..598b49526311 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -554,7 +554,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Тастер за брисање уназад"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Тастер за репродукцију/паузирање"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Тастер за заустављање"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Заустави пребацивање"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Тастер Следећа"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Тастер Претходна"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Тастер за премотавање уназад"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index 638ba9f7e4f2..ec36df5c0f1f 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Retur"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backsteg"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Spela upp/Pausa"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Avsluta"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Sluta casta"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Nästa"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Föregående"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Spola tillbaka"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 931f6343b7df..b578841dceae 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Nafasinyuma"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Cheza/Sitisha"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Simamisha"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Acha kutuma"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Inayofuata"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Iliyotangulia"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rudisha nyuma"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index e856294f2ed3..5a280065c944 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"என்டர்"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"பேக்ஸ்பேஸ்"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"பிளே/பாஸ்"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"ஸ்டாப்"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"அலைபரப்புவதை நிறுத்து"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"நெக்ஸ்ட்"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ப்ரீவியஸ்"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ரீவைன்ட்"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 6ef8f5086535..e7ff23bd2fb3 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"ప్లే చేయి/పాజ్ చేయి"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"ఆపివేయి"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"ప్రసారాన్ని ఆపివేయండి"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"తర్వాత"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"మునుపటి"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"రివైండ్ చేయి"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index 9072db444912..297288959349 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"ลบถอยหลัง"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"เล่น/หยุดชั่วคราว"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"หยุด"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"หยุดแคสต์"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"ถัดไป"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"ก่อนหน้า"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"กรอกลับ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index b518c603458d..c1039e63636e 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Play/Pause"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Stop"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Ihinto ang pag-cast"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Next"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Previous"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Rewind"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 0f56057ef082..2ec848501d3e 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Geri tuşu"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Oynat/Duraklat"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Durdur"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Yayını durdur"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Sonraki"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Önceki"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Geri Sar"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index fa9af2e1c77f..da616f550257 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -559,7 +559,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Відтворити/призупинити"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Зупинити"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Припинити трансляцію"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Далі"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Назад"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Перемотати назад"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 35760212155d..a3f2762d2750 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"چلائیں/موقوف کریں"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"روکیں"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"کاسٹ کرنا بند کریں"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"اگلا"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"گزشتہ"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"ریوائینڈ کریں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 0cead719b0a4..b664e15af4ff 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Ijro/Pauza"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"To‘xtatish"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Translatsiyani toʻxtatish"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Keyingisi"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Avvalgi"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Orqaga qaytarish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index a5609eb8a6d7..3021d3fe5555 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Phát/Tạm dừng"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Dừng"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Dừng truyền"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Tiếp theo"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Trước"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Tua lại"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index 0610b5917f46..e955c78579c2 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"退格"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"播放/暂停"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"停止"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"停止投射"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"下一曲"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"上一曲"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"快退"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 860085974d4f..ee66cd44ea07 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"輸入 (Enter)"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"播放/暫停"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"停止"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"停止投放"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"下一首"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"上一首"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"倒帶"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 0206a9e30360..6acae2815473 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Enter 鍵"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Backspace 鍵"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"播放/暫停"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"停止"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"停止投放"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"下一個"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"上一個"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"倒轉"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 98e7fc40e7ab..3f2484736909 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -549,7 +549,7 @@
<string name="keyboard_key_enter" msgid="8633362970109751646">"Faka"</string>
<string name="keyboard_key_backspace" msgid="4095278312039628074">"Isikhala"</string>
<string name="keyboard_key_media_play_pause" msgid="8389984232732277478">"Dlala/Misa okwesikhashana"</string>
- <string name="keyboard_key_media_stop" msgid="1509943745250377699">"Misa"</string>
+ <string name="keyboard_key_media_stop" msgid="5344400947407134507">"Misa ukusakaza"</string>
<string name="keyboard_key_media_next" msgid="8502476691227914952">"Okulandelayo"</string>
<string name="keyboard_key_media_previous" msgid="5637875709190955351">"Okwangaphambilini"</string>
<string name="keyboard_key_media_rewind" msgid="3450387734224327577">"Buyisela emuva"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 49fc8482712a..1edaaadfb433 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -176,12 +176,10 @@
<!-- media output dialog-->
<color name="media_dialog_background" android:lstar="98">@color/material_dynamic_neutral90</color>
- <color name="media_dialog_item_main_content">@color/material_dynamic_primary20</color>
+ <color name="media_dialog_active_item_main_content">@color/material_dynamic_primary10</color>
+ <color name="media_dialog_inactive_item_main_content">@color/material_dynamic_primary40</color>
+ <color name="media_dialog_item_status">@color/material_dynamic_primary10</color>
<color name="media_dialog_item_background">@color/material_dynamic_secondary95</color>
- <color name="media_dialog_connected_item_background">@color/material_dynamic_primary90</color>
- <color name="media_dialog_seekbar_progress">@color/material_dynamic_secondary40</color>
- <color name="media_dialog_button_background">@color/material_dynamic_primary40</color>
- <color name="media_dialog_solid_button_text">@color/material_dynamic_neutral95</color>
<!-- controls -->
<color name="control_primary_text">#E6FFFFFF</color>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index d230f33f4939..50883f9edd13 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2223,8 +2223,6 @@
<string name="media_output_dialog_launch_app_text">To cast this session, please open the app.</string>
<!-- App name when can't get app name [CHAR LIMIT=60] -->
<string name="media_output_dialog_unknown_launch_app_name">Unknown app</string>
- <!-- Button text for stopping casting [CHAR LIMIT=60] -->
- <string name="media_output_dialog_button_stop_casting">Stop casting</string>
<!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index f5c1382b9ae9..3ae21e08005d 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -486,7 +486,7 @@
<style name="MediaOutputItemInactiveTitle">
<item name="android:textSize">16sp</item>
- <item name="android:textColor">@color/media_dialog_item_main_content</item>
+ <item name="android:textColor">@color/media_dialog_inactive_item_main_content</item>
</style>
<style name="TunerSettings" parent="@android:style/Theme.DeviceDefault.Settings">
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java b/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java
index 4394ecbf79eb..98212e1d91b6 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/tracing/FrameProtoTracer.java
@@ -25,8 +25,8 @@ import com.android.internal.util.TraceBuffer;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
+import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.LinkedList;
import java.util.Queue;
import java.util.function.Consumer;
@@ -50,7 +50,7 @@ public class FrameProtoTracer<P, S extends P, T extends P, R>
private final File mTraceFile;
private final ProtoTraceParams<P, S, T, R> mParams;
private Choreographer mChoreographer;
- private final Queue<T> mPool = new LinkedList<>();
+ private final Queue<T> mPool = new ArrayDeque<>();
private final ArrayList<ProtoTraceable<R>> mTraceables = new ArrayList<>();
private final ArrayList<ProtoTraceable<R>> mTmpTraceables = new ArrayList<>();
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
index e5da38936593..4773f2a3b13e 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/TimeLimitedMotionEventBuffer.java
@@ -18,9 +18,9 @@ package com.android.systemui.classifier;
import android.view.MotionEvent;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
-import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
@@ -33,13 +33,13 @@ import java.util.ListIterator;
*/
public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
- private final LinkedList<MotionEvent> mMotionEvents;
+ private final List<MotionEvent> mMotionEvents;
private final long mMaxAgeMs;
public TimeLimitedMotionEventBuffer(long maxAgeMs) {
super();
mMaxAgeMs = maxAgeMs;
- mMotionEvents = new LinkedList<>();
+ mMotionEvents = new ArrayList<>();
}
private void ejectOldEvents() {
@@ -47,7 +47,7 @@ public class TimeLimitedMotionEventBuffer implements List<MotionEvent> {
return;
}
Iterator<MotionEvent> iter = listIterator();
- long mostRecentMs = mMotionEvents.getLast().getEventTime();
+ long mostRecentMs = mMotionEvents.get(mMotionEvents.size() - 1).getEventTime();
while (iter.hasNext()) {
MotionEvent ev = iter.next();
if (mostRecentMs - ev.getEventTime() > mMaxAgeMs) {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
index f9115b20ca06..3eb58bba1ca4 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
@@ -343,7 +343,7 @@ private class ControlHolderAccessibilityDelegate(
info.className = Switch::class.java.name
}
- override fun performAccessibilityAction(host: View?, action: Int, args: Bundle?): Boolean {
+ override fun performAccessibilityAction(host: View, action: Int, args: Bundle?): Boolean {
if (super.performAccessibilityAction(host, action, args)) {
return true
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
index 5d154c3b4f6b..c870b89d9e0a 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIDefaultModule.java
@@ -178,7 +178,8 @@ public abstract class SystemUIDefaultModule {
KeyguardBypassController bypassController,
GroupMembershipManager groupManager,
VisualStabilityProvider visualStabilityProvider,
- ConfigurationController configurationController) {
+ ConfigurationController configurationController,
+ @Main Handler handler) {
return new HeadsUpManagerPhone(
context,
headsUpManagerLogger,
@@ -186,7 +187,8 @@ public abstract class SystemUIDefaultModule {
bypassController,
groupManager,
visualStabilityProvider,
- configurationController
+ configurationController,
+ handler
);
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
index 0ad2807bed55..cf713652ddb5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardIndicationRotateTextViewController.java
@@ -35,8 +35,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -72,7 +72,7 @@ public class KeyguardIndicationRotateTextViewController extends
@Nullable private ShowNextIndication mShowNextIndicationRunnable;
// List of indication types to show. The next indication to show is always at index 0
- private final List<Integer> mIndicationQueue = new LinkedList<>();
+ private final List<Integer> mIndicationQueue = new ArrayList<>();
private @IndicationType int mCurrIndicationType = INDICATION_TYPE_NONE;
private CharSequence mCurrMessage;
private long mLastIndicationSwitch;
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
index a6464829623f..0b23ad50a726 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputAdapter.java
@@ -119,9 +119,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCheckBox.setVisibility(View.GONE);
mStatusIcon.setVisibility(View.GONE);
mContainerLayout.setOnClickListener(null);
- mTitleText.setTextColor(mController.getColorItemContent());
- mSubTitleText.setTextColor(mController.getColorItemContent());
- mTwoLineTitleText.setTextColor(mController.getColorItemContent());
+ mTitleText.setTextColor(mController.getColorInactiveItem());
mSeekBar.getProgressDrawable().setColorFilter(
new PorterDuffColorFilter(mController.getColorSeekbarProgress(),
PorterDuff.Mode.SRC_IN));
@@ -142,7 +140,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
&& !mController.hasAdjustVolumeUserRestriction()) {
mProgressBar.getIndeterminateDrawable().setColorFilter(
new PorterDuffColorFilter(
- mController.getColorItemContent(),
+ mController.getColorInactiveItem(),
PorterDuff.Mode.SRC_IN));
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
false /* showSeekBar*/,
@@ -157,7 +155,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mTitleIcon.setAlpha(DEVICE_CONNECTED_ALPHA);
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_failed));
- mStatusIcon.setColorFilter(mController.getColorItemContent());
+ mStatusIcon.setColorFilter(mController.getColorInactiveItem());
setTwoLineLayout(device, false /* bFocused */,
false /* showSeekBar */, false /* showProgressBar */,
true /* showSubtitle */, true /* showStatus */);
@@ -165,7 +163,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mContainerLayout.setOnClickListener(v -> onItemClick(v, device));
} else if (mController.getSelectedMediaDevice().size() > 1
&& isDeviceIncluded(mController.getSelectedMediaDevice(), device)) {
- mTitleText.setTextColor(mController.getColorItemContent());
+ mTitleText.setTextColor(mController.getColorActiveItem());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
@@ -175,13 +173,13 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
onCheckBoxClicked(false, device);
});
- setCheckBoxColor(mCheckBox, mController.getColorItemContent());
+ setCheckBoxColor(mCheckBox, mController.getColorActiveItem());
initSeekbar(device);
} else if (!mController.hasAdjustVolumeUserRestriction() && currentlyConnected) {
mStatusIcon.setImageDrawable(
mContext.getDrawable(R.drawable.media_output_status_check));
- mStatusIcon.setColorFilter(mController.getColorItemContent());
- mTitleText.setTextColor(mController.getColorItemContent());
+ mStatusIcon.setColorFilter(mController.getColorActiveItem());
+ mTitleText.setTextColor(mController.getColorActiveItem());
setSingleLineLayout(getItemTitle(device), true /* bFocused */,
true /* showSeekBar */,
false /* showProgressBar */, true /* showStatus */);
@@ -194,7 +192,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
mCheckBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
onCheckBoxClicked(true, device);
});
- setCheckBoxColor(mCheckBox, mController.getColorItemContent());
+ setCheckBoxColor(mCheckBox, mController.getColorInactiveItem());
setSingleLineLayout(getItemTitle(device), false /* bFocused */,
false /* showSeekBar */,
false /* showProgressBar */, false /* showStatus */);
@@ -216,7 +214,7 @@ public class MediaOutputAdapter extends MediaOutputBaseAdapter {
@Override
void onBind(int customizedItem, boolean topMargin, boolean bottomMargin) {
if (customizedItem == CUSTOMIZED_ITEM_PAIR_NEW) {
- mTitleText.setTextColor(mController.getColorItemContent());
+ mTitleText.setTextColor(mController.getColorInactiveItem());
mCheckBox.setVisibility(View.GONE);
setSingleLineLayout(mContext.getText(R.string.media_output_dialog_pairing_new),
false /* bFocused */);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
index df0c14b25c26..62d5c8e51005 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseAdapter.java
@@ -170,16 +170,14 @@ public abstract class MediaOutputBaseAdapter extends
void setSingleLineLayout(CharSequence title, boolean bFocused, boolean showSeekBar,
boolean showProgressBar, boolean showStatus) {
mTwoLineLayout.setVisibility(View.GONE);
- boolean isActive = showSeekBar || showProgressBar;
final Drawable backgroundDrawable =
- isActive
+ showSeekBar || showProgressBar
? mContext.getDrawable(R.drawable.media_output_item_background_active)
.mutate() : mContext.getDrawable(
R.drawable.media_output_item_background)
.mutate();
backgroundDrawable.setColorFilter(new PorterDuffColorFilter(
- isActive ? mController.getColorConnectedItemBackground()
- : mController.getColorItemBackground(),
+ mController.getColorItemBackground(),
PorterDuff.Mode.SRC_IN));
mItemLayout.setBackground(backgroundDrawable);
mProgressBar.setVisibility(showProgressBar ? View.VISIBLE : View.GONE);
@@ -368,7 +366,7 @@ public abstract class MediaOutputBaseAdapter extends
.mutate();
drawable.setColorFilter(
new PorterDuffColorFilter(Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_item_main_content),
+ R.color.media_dialog_active_item_main_content),
PorterDuff.Mode.SRC_IN));
return drawable;
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index dcb1c7c4637c..c0fb694ed59e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -214,9 +214,10 @@ public abstract class MediaOutputBaseDialog extends SystemUIDialog implements
ColorFilter buttonColorFilter = new PorterDuffColorFilter(
mAdapter.getController().getColorButtonBackground(),
PorterDuff.Mode.SRC_IN);
+ ColorFilter onlineButtonColorFilter = new PorterDuffColorFilter(
+ mAdapter.getController().getColorInactiveItem(), PorterDuff.Mode.SRC_IN);
mDoneButton.getBackground().setColorFilter(buttonColorFilter);
- mStopButton.getBackground().setColorFilter(buttonColorFilter);
- mDoneButton.setTextColor(mAdapter.getController().getColorPositiveButtonText());
+ mStopButton.getBackground().setColorFilter(onlineButtonColorFilter);
}
mHeaderIcon.setVisibility(View.VISIBLE);
mHeaderIcon.setImageIcon(icon);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index ea7f7f2bb646..0b6c68d17a4c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -110,12 +110,11 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
private MediaOutputMetricLogger mMetricLogger;
- private int mColorItemContent;
+ private int mColorActiveItem;
+ private int mColorInactiveItem;
private int mColorSeekbarProgress;
private int mColorButtonBackground;
private int mColorItemBackground;
- private int mColorConnectedItemBackground;
- private int mColorPositiveButtonText;
@Inject
public MediaOutputController(@NonNull Context context, String packageName,
@@ -134,18 +133,16 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
mMetricLogger = new MediaOutputMetricLogger(mContext, mPackageName);
mDialogLaunchAnimator = dialogLaunchAnimator;
mNearbyMediaDevicesManager = nearbyMediaDevicesManagerOptional.orElse(null);
- mColorItemContent = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_item_main_content);
+ mColorActiveItem = Utils.getColorStateListDefaultColor(mContext,
+ R.color.media_dialog_active_item_main_content);
+ mColorInactiveItem = Utils.getColorStateListDefaultColor(mContext,
+ R.color.media_dialog_inactive_item_main_content);
mColorSeekbarProgress = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_seekbar_progress);
+ android.R.color.system_accent1_200);
mColorButtonBackground = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_button_background);
- mColorItemBackground = Utils.getColorStateListDefaultColor(mContext,
R.color.media_dialog_item_background);
- mColorConnectedItemBackground = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_connected_item_background);
- mColorPositiveButtonText = Utils.getColorStateListDefaultColor(mContext,
- R.color.media_dialog_solid_button_text);
+ mColorItemBackground = Utils.getColorStateListDefaultColor(mContext,
+ android.R.color.system_accent2_50);
}
void start(@NonNull Callback cb) {
@@ -325,7 +322,8 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
}
void setColorFilter(Drawable drawable, boolean isActive) {
- drawable.setColorFilter(new PorterDuffColorFilter(mColorItemContent,
+ drawable.setColorFilter(new PorterDuffColorFilter(isActive
+ ? mColorActiveItem : mColorInactiveItem,
PorterDuff.Mode.SRC_IN));
}
@@ -360,32 +358,26 @@ public class MediaOutputController implements LocalMediaManager.DeviceCallback,
ColorScheme mCurrentColorScheme = new ColorScheme(wallpaperColors,
isDarkTheme);
if (isDarkTheme) {
- mColorItemContent = mCurrentColorScheme.getAccent1().get(2); // A1-100
- mColorSeekbarProgress = mCurrentColorScheme.getAccent2().get(7); // A2-600
- mColorButtonBackground = mCurrentColorScheme.getAccent1().get(4); // A1-300
- mColorItemBackground = mCurrentColorScheme.getNeutral2().get(9); // N2-800
- mColorConnectedItemBackground = mCurrentColorScheme.getAccent2().get(9); // A2-800
- mColorPositiveButtonText = mCurrentColorScheme.getAccent2().get(9); // A2-800
+ mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
+ mColorInactiveItem = mCurrentColorScheme.getNeutral1().get(10);
+ mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(2);
+ mColorButtonBackground = mCurrentColorScheme.getAccent1().get(2);
+ mColorItemBackground = mCurrentColorScheme.getAccent2().get(0);
} else {
- mColorItemContent = mCurrentColorScheme.getAccent1().get(9); // A1-800
- mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(4); // A1-300
- mColorButtonBackground = mCurrentColorScheme.getAccent1().get(7); // A1-600
- mColorItemBackground = mCurrentColorScheme.getAccent2().get(1); // A2-50
- mColorConnectedItemBackground = mCurrentColorScheme.getAccent1().get(2); // A1-100
- mColorPositiveButtonText = mCurrentColorScheme.getNeutral1().get(1); // N1-50
+ mColorActiveItem = mCurrentColorScheme.getNeutral1().get(10);
+ mColorInactiveItem = mCurrentColorScheme.getAccent1().get(7);
+ mColorSeekbarProgress = mCurrentColorScheme.getAccent1().get(3);
+ mColorButtonBackground = mCurrentColorScheme.getAccent1().get(3);
+ mColorItemBackground = mCurrentColorScheme.getAccent2().get(0);
}
}
- public int getColorConnectedItemBackground() {
- return mColorConnectedItemBackground;
- }
-
- public int getColorPositiveButtonText() {
- return mColorPositiveButtonText;
+ public int getColorActiveItem() {
+ return mColorActiveItem;
}
- public int getColorItemContent() {
- return mColorItemContent;
+ public int getColorInactiveItem() {
+ return mColorInactiveItem;
}
public int getColorSeekbarProgress() {
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
index 61071235db0b..8147877a8a29 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
@@ -150,24 +150,27 @@ class PrivacyDialogController(
packageName: String,
userId: Int,
permGroupName: CharSequence,
- attributionTag: CharSequence?
+ attributionTag: CharSequence?,
+ isAttributionSupported: Boolean
): Intent
{
lateinit var intent: Intent
- if (attributionTag != null) {
+ if (attributionTag != null && isAttributionSupported) {
intent = Intent(Intent.ACTION_MANAGE_PERMISSION_USAGE)
intent.setPackage(packageName)
intent.putExtra(Intent.EXTRA_PERMISSION_GROUP_NAME, permGroupName.toString())
intent.putExtra(Intent.EXTRA_ATTRIBUTION_TAGS, arrayOf(attributionTag.toString()))
intent.putExtra(Intent.EXTRA_SHOWING_ATTRIBUTION, true)
val resolveInfo = packageManager.resolveActivity(
- intent, PackageManager.ResolveInfoFlags.of(0))
- ?: return getDefaultManageAppPermissionsIntent(packageName, userId)
- intent.component = ComponentName(packageName, resolveInfo.activityInfo.name)
- return intent
- } else {
- return getDefaultManageAppPermissionsIntent(packageName, userId)
+ intent, PackageManager.ResolveInfoFlags.of(0))
+ if (resolveInfo != null && resolveInfo.activityInfo != null &&
+ resolveInfo.activityInfo.permission ==
+ android.Manifest.permission.START_VIEW_PERMISSION_USAGE) {
+ intent.component = ComponentName(packageName, resolveInfo.activityInfo.name)
+ return intent
+ }
}
+ return getDefaultManageAppPermissionsIntent(packageName, userId)
}
fun getDefaultManageAppPermissionsIntent(packageName: String, userId: Int): Intent {
@@ -226,9 +229,15 @@ class PrivacyDialogController(
userInfo?.isManagedProfile ?: false,
it.isPhoneCall,
it.permissionGroupName,
- getManagePermissionIntent(it.packageName, userId,
- it.permissionGroupName,
- it.attributionTag)
+ getManagePermissionIntent(
+ it.packageName,
+ userId,
+ it.permissionGroupName,
+ it.attributionTag,
+ // attributionLabel is set only when subattribution policies
+ // are supported and satisfied
+ it.attributionLabel != null
+ )
)
}
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
index 5510eb172cd7..09c4cb760c90 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
+++ b/packages/SystemUI/src/com/android/systemui/privacy/television/TvOngoingPrivacyChip.java
@@ -57,7 +57,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.LinkedList;
import java.util.List;
import javax.inject.Inject;
@@ -126,7 +125,7 @@ public class TvOngoingPrivacyChip extends CoreStartable implements PrivacyItemCo
private final Runnable mCollapseRunnable = this::collapseChip;
private final Runnable mAccessibilityRunnable = this::makeAccessibilityAnnouncement;
- private final List<PrivacyItem> mItemsBeforeLastAnnouncement = new LinkedList<>();
+ private final List<PrivacyItem> mItemsBeforeLastAnnouncement = new ArrayList<>();
@State
private int mState = STATE_NOT_SHOWN;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
index 6cfbb43fa25a..1ffa6f41d8a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlertingNotificationManager.java
@@ -19,13 +19,12 @@ package com.android.systemui.statusbar;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Handler;
-import android.os.Looper;
import android.os.SystemClock;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.view.accessibility.AccessibilityEvent;
-import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
@@ -43,8 +42,9 @@ public abstract class AlertingNotificationManager implements NotificationLifetim
protected final ArrayMap<String, AlertEntry> mAlertEntries = new ArrayMap<>();
protected final HeadsUpManagerLogger mLogger;
- public AlertingNotificationManager(HeadsUpManagerLogger logger) {
+ public AlertingNotificationManager(HeadsUpManagerLogger logger, @Main Handler handler) {
mLogger = logger;
+ mHandler = handler;
}
/**
@@ -57,8 +57,7 @@ public abstract class AlertingNotificationManager implements NotificationLifetim
protected NotificationSafeToRemoveCallback mNotificationLifetimeFinishedCallback;
protected int mMinimumDisplayTime;
protected int mAutoDismissNotificationDecay;
- @VisibleForTesting
- public Handler mHandler = new Handler(Looper.getMainLooper());
+ private final Handler mHandler;
/**
* Called when posting a new notification that should alert the user and appear on screen.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
index 1237c70fcbe3..54cfb5d44a3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinator.java
@@ -19,12 +19,12 @@ package com.android.systemui.statusbar.notification.collection.coordinator;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarState;
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider;
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
import javax.inject.Inject;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
index 57fd1975e13a..5ac481341d43 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinator.java
@@ -20,7 +20,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.SectionClassifier;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -28,6 +27,7 @@ import com.android.systemui.statusbar.notification.collection.coordinator.dagger
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
import com.android.systemui.statusbar.notification.collection.render.NodeController;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
import com.android.systemui.statusbar.notification.dagger.AlertingHeader;
@@ -51,7 +51,7 @@ public class RankingCoordinator implements Coordinator {
public static final boolean SHOW_ALL_SECTIONS = false;
private final StatusBarStateController mStatusBarStateController;
private final HighPriorityProvider mHighPriorityProvider;
- private final SectionClassifier mSectionClassifier;
+ private final SectionStyleProvider mSectionStyleProvider;
private final NodeController mSilentNodeController;
private final SectionHeaderController mSilentHeaderController;
private final NodeController mAlertingHeaderController;
@@ -62,13 +62,13 @@ public class RankingCoordinator implements Coordinator {
public RankingCoordinator(
StatusBarStateController statusBarStateController,
HighPriorityProvider highPriorityProvider,
- SectionClassifier sectionClassifier,
+ SectionStyleProvider sectionStyleProvider,
@AlertingHeader NodeController alertingHeaderController,
@SilentHeader SectionHeaderController silentHeaderController,
@SilentHeader NodeController silentNodeController) {
mStatusBarStateController = statusBarStateController;
mHighPriorityProvider = highPriorityProvider;
- mSectionClassifier = sectionClassifier;
+ mSectionStyleProvider = sectionStyleProvider;
mAlertingHeaderController = alertingHeaderController;
mSilentNodeController = silentNodeController;
mSilentHeaderController = silentHeaderController;
@@ -77,7 +77,7 @@ public class RankingCoordinator implements Coordinator {
@Override
public void attach(NotifPipeline pipeline) {
mStatusBarStateController.addCallback(mStatusBarStateCallback);
- mSectionClassifier.setMinimizedSections(Collections.singleton(mMinimizedNotifSectioner));
+ mSectionStyleProvider.setMinimizedSections(Collections.singleton(mMinimizedNotifSectioner));
pipeline.addPreGroupFilter(mSuspendedFilter);
pipeline.addPreGroupFilter(mDndVisualEffectsFilter);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
index 4e9d3ac07a96..9e8b35af1bce 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
@@ -19,11 +19,11 @@ package com.android.systemui.statusbar.notification.collection.coordinator
import android.content.Context
import com.android.systemui.R
import com.android.systemui.statusbar.notification.AssistantFeedbackController
-import com.android.systemui.statusbar.notification.SectionClassifier
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.coordinator.dagger.CoordinatorScope
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
import com.android.systemui.statusbar.notification.collection.render.NotifRowController
import javax.inject.Inject
@@ -35,7 +35,7 @@ import javax.inject.Inject
class RowAppearanceCoordinator @Inject internal constructor(
context: Context,
private var mAssistantFeedbackController: AssistantFeedbackController,
- private var mSectionClassifier: SectionClassifier
+ private var mSectionStyleProvider: SectionStyleProvider
) : Coordinator {
private var entryToExpand: NotificationEntry? = null
@@ -55,7 +55,7 @@ class RowAppearanceCoordinator @Inject internal constructor(
private fun onBeforeRenderList(list: List<ListEntry>) {
entryToExpand = list.firstOrNull()?.representativeEntry?.takeIf { entry ->
- !mSectionClassifier.isMinimizedSection(entry.section!!)
+ !mSectionStyleProvider.isMinimizedSection(entry.section!!)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
index 497691d18844..2227be120309 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
@@ -17,9 +17,9 @@
package com.android.systemui.statusbar.notification.collection.inflation
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.SectionClassifier
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
import javax.inject.Inject
/**
@@ -28,13 +28,13 @@ import javax.inject.Inject
*/
@SysUISingleton
open class NotifUiAdjustmentProvider @Inject constructor(
- private val sectionClassifier: SectionClassifier
+ private val sectionStyleProvider: SectionStyleProvider
) {
private fun isEntryMinimized(entry: NotificationEntry): Boolean {
val section = entry.section ?: error("Entry must have a section to determine if minimized")
val parent = entry.parent ?: error("Entry must have a parent to determine if minimized")
- val isMinimizedSection = sectionClassifier.isMinimizedSection(section)
+ val isMinimizedSection = sectionStyleProvider.isMinimizedSection(section)
val isTopLevelEntry = parent == GroupEntry.ROOT_ENTRY
val isGroupSummary = parent.summary == entry
return isMinimizedSection && (isTopLevelEntry || isGroupSummary)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
index 68bdd18c9881..2148d3bb336a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionHeaderVisibilityProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification
+package com.android.systemui.statusbar.notification.collection.provider
import android.content.Context
import com.android.systemui.dagger.SysUISingleton
@@ -34,7 +34,7 @@ import javax.inject.Inject
class SectionHeaderVisibilityProvider @Inject constructor(
context: Context
) {
- var neverShowSectionHeaders = context.resources.getBoolean(R.bool.config_notification_never_show_section_headers)
- private set
+ val neverShowSectionHeaders =
+ context.resources.getBoolean(R.bool.config_notification_never_show_section_headers)
var sectionHeadersVisible = true
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
index 1f2d0fe6c46e..50e7d1ce4ba0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/SectionClassifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.systemui.statusbar.notification
+package com.android.systemui.statusbar.notification.collection.provider
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
@@ -26,7 +26,7 @@ import javax.inject.Inject
* NOTE: This class exists to avoid putting metadata like "isMinimized" on the NotifSection
*/
@SysUISingleton
-class SectionClassifier @Inject constructor() {
+class SectionStyleProvider @Inject constructor() {
private lateinit var lowPrioritySections: Set<NotifSectioner>
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
index 6db544c77f87..75a71af7a0d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
@@ -16,12 +16,12 @@
package com.android.systemui.statusbar.notification.collection.render
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
import com.android.systemui.util.Compile
import com.android.systemui.util.traceSection
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
index 6ed81078c3a4..51dc72848d9e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
@@ -19,10 +19,10 @@ package com.android.systemui.statusbar.notification.collection.render
import android.content.Context
import android.view.View
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.ListEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntry
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
import com.android.systemui.util.traceSection
import dagger.assisted.Assisted
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
index 2a76418b1f03..235b810a61e6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhone.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Region;
+import android.os.Handler;
import android.util.Pools;
import androidx.collection.ArraySet;
@@ -29,6 +30,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.StatusBarState;
@@ -105,8 +107,9 @@ public class HeadsUpManagerPhone extends HeadsUpManager implements Dumpable,
KeyguardBypassController bypassController,
GroupMembershipManager groupMembershipManager,
VisualStabilityProvider visualStabilityProvider,
- ConfigurationController configurationController) {
- super(context, logger);
+ ConfigurationController configurationController,
+ @Main Handler handler) {
+ super(context, logger, handler);
Resources resources = mContext.getResources();
mExtensionTime = resources.getInteger(R.integer.ambient_notification_extension_time);
statusBarStateController.addCallback(mStatusBarStateListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 784a54681484..01348977e374 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -24,6 +24,7 @@ import android.app.Notification;
import android.content.Context;
import android.content.res.Resources;
import android.database.ContentObserver;
+import android.os.Handler;
import android.provider.Settings;
import android.util.ArrayMap;
import android.view.accessibility.AccessibilityManager;
@@ -34,6 +35,7 @@ import com.android.internal.logging.UiEventLogger;
import com.android.systemui.Dependency;
import com.android.systemui.EventLogTags;
import com.android.systemui.R;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.NotificationRowContentBinder.InflationFlag;
@@ -80,8 +82,9 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
}
}
- public HeadsUpManager(@NonNull final Context context, HeadsUpManagerLogger logger) {
- super(logger);
+ public HeadsUpManager(@NonNull final Context context, HeadsUpManagerLogger logger,
+ @Main Handler handler) {
+ super(logger, handler);
mContext = context;
mAccessibilityMgr = Dependency.get(AccessibilityManagerWrapper.class);
mUiEventLogger = Dependency.get(UiEventLogger.class);
@@ -95,7 +98,7 @@ public abstract class HeadsUpManager extends AlertingNotificationManager {
mSnoozeLengthMs = Settings.Global.getInt(context.getContentResolver(),
SETTING_HEADS_UP_SNOOZE_LENGTH_MS, defaultSnoozeLengthMs);
- ContentObserver settingsObserver = new ContentObserver(mHandler) {
+ ContentObserver settingsObserver = new ContentObserver(handler) {
@Override
public void onChange(boolean selfChange) {
final int packageSnoozeLengthMs = Settings.Global.getInt(
diff --git a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
index b7f90a479518..c92491e58e00 100644
--- a/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
+++ b/packages/SystemUI/src/com/android/systemui/tv/TvSystemUIModule.java
@@ -169,7 +169,8 @@ public abstract class TvSystemUIModule {
KeyguardBypassController bypassController,
GroupMembershipManager groupManager,
VisualStabilityProvider visualStabilityProvider,
- ConfigurationController configurationController) {
+ ConfigurationController configurationController,
+ @Main Handler handler) {
return new HeadsUpManagerPhone(
context,
headsUpManagerLogger,
@@ -177,7 +178,8 @@ public abstract class TvSystemUIModule {
bypassController,
groupManager,
visualStabilityProvider,
- configurationController
+ configurationController,
+ handler
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
index 350822691121..38b448fb362c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
@@ -19,8 +19,11 @@ package com.android.systemui.privacy
import android.app.ActivityManager
import android.content.Context
import android.content.Intent
+import android.content.pm.ActivityInfo
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.ResolveInfoFlags
+import android.content.pm.ResolveInfo
import android.content.pm.UserInfo
import android.os.Process.SYSTEM_UID
import android.os.UserHandle
@@ -648,6 +651,77 @@ class PrivacyDialogControllerTest : SysuiTestCase() {
}
}
+ @Test
+ fun testCorrectIntentSubAttribution() {
+ val usage = createMockPermGroupUsage(
+ attributionTag = TEST_ATTRIBUTION_TAG,
+ attributionLabel = "TEST_LABEL"
+ )
+
+ val activityInfo = createMockActivityInfo()
+ val resolveInfo = createMockResolveInfo(activityInfo)
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
+ `when`(packageManager.resolveActivity(any(), any<ResolveInfoFlags>()))
+ .thenAnswer { resolveInfo }
+ controller.showDialog(context)
+ exhaustExecutors()
+
+ dialogProvider.list?.let { list ->
+ val navigationIntent = list.get(0).navigationIntent!!
+ assertThat(navigationIntent.action).isEqualTo(Intent.ACTION_MANAGE_PERMISSION_USAGE)
+ assertThat(navigationIntent.getStringExtra(Intent.EXTRA_PERMISSION_GROUP_NAME))
+ .isEqualTo(PERM_CAMERA)
+ assertThat(navigationIntent.getStringArrayExtra(Intent.EXTRA_ATTRIBUTION_TAGS))
+ .isEqualTo(arrayOf(TEST_ATTRIBUTION_TAG.toString()))
+ assertThat(navigationIntent.getBooleanExtra(Intent.EXTRA_SHOWING_ATTRIBUTION, false))
+ .isTrue()
+ }
+ }
+
+ @Test
+ fun testDefaultIntentOnMissingAttributionLabel() {
+ val usage = createMockPermGroupUsage(
+ attributionTag = TEST_ATTRIBUTION_TAG
+ )
+
+ val activityInfo = createMockActivityInfo()
+ val resolveInfo = createMockResolveInfo(activityInfo)
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
+ `when`(packageManager.resolveActivity(any(), any<ResolveInfoFlags>()))
+ .thenAnswer { resolveInfo }
+ controller.showDialog(context)
+ exhaustExecutors()
+
+ dialogProvider.list?.let { list ->
+ assertThat(isIntentEqual(list.get(0).navigationIntent!!,
+ controller.getDefaultManageAppPermissionsIntent(TEST_PACKAGE_NAME, USER_ID)))
+ .isTrue()
+ }
+ }
+
+ @Test
+ fun testDefaultIntentOnIncorrectPermission() {
+ val usage = createMockPermGroupUsage(
+ attributionTag = TEST_ATTRIBUTION_TAG
+ )
+
+ val activityInfo = createMockActivityInfo(
+ permission = "INCORRECT_PERMISSION"
+ )
+ val resolveInfo = createMockResolveInfo(activityInfo)
+ `when`(permissionManager.getIndicatorAppOpUsageData(anyBoolean())).thenReturn(listOf(usage))
+ `when`(packageManager.resolveActivity(any(), any<ResolveInfoFlags>()))
+ .thenAnswer { resolveInfo }
+ controller.showDialog(context)
+ exhaustExecutors()
+
+ dialogProvider.list?.let { list ->
+ assertThat(isIntentEqual(list.get(0).navigationIntent!!,
+ controller.getDefaultManageAppPermissionsIntent(TEST_PACKAGE_NAME, USER_ID)))
+ .isTrue()
+ }
+ }
+
private fun exhaustExecutors() {
FakeExecutor.exhaustExecutors(backgroundExecutor, uiExecutor)
}
@@ -680,6 +754,24 @@ class PrivacyDialogControllerTest : SysuiTestCase() {
return user * UserHandle.PER_USER_RANGE + nextUid++
}
+ private fun createMockResolveInfo(
+ activityInfo: ActivityInfo? = null
+ ): ResolveInfo {
+ val resolveInfo = mock(ResolveInfo::class.java)
+ resolveInfo.activityInfo = activityInfo
+ return resolveInfo
+ }
+
+ private fun createMockActivityInfo(
+ permission: String = android.Manifest.permission.START_VIEW_PERMISSION_USAGE,
+ className: String = "TEST_CLASS_NAME"
+ ): ActivityInfo {
+ val activityInfo = mock(ActivityInfo::class.java)
+ activityInfo.permission = permission
+ activityInfo.name = className
+ return activityInfo
+ }
+
private fun createMockPermGroupUsage(
packageName: String = TEST_PACKAGE_NAME,
uid: Int = generateUidForUser(USER_ID),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
index 8a388479c0e7..65d0adc99739 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/AlertingNotificationManagerTest.java
@@ -83,12 +83,10 @@ public class AlertingNotificationManagerTest extends SysuiTestCase {
private final class TestableAlertingNotificationManager extends AlertingNotificationManager {
private AlertEntry mLastCreatedEntry;
- private TestableAlertingNotificationManager() {
- super(mock(HeadsUpManagerLogger.class));
+ private TestableAlertingNotificationManager(Handler handler) {
+ super(mock(HeadsUpManagerLogger.class), handler);
mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
- mHandler.removeCallbacksAndMessages(null);
- mHandler = mTestHandler;
}
@Override
@@ -109,8 +107,8 @@ public class AlertingNotificationManagerTest extends SysuiTestCase {
}
}
- protected AlertingNotificationManager createAlertingNotificationManager() {
- return new TestableAlertingNotificationManager();
+ protected AlertingNotificationManager createAlertingNotificationManager(Handler handler) {
+ return new TestableAlertingNotificationManager(handler);
}
protected StatusBarNotification createNewSbn(int id, Notification.Builder n) {
@@ -144,7 +142,7 @@ public class AlertingNotificationManagerTest extends SysuiTestCase {
.build();
mEntry.setRow(mRow);
- mAlertingNotificationManager = createAlertingNotificationManager();
+ mAlertingNotificationManager = createAlertingNotificationManager(mTestHandler);
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index ad643fed969b..0b02143cb305 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -811,8 +811,11 @@ public class KeyguardIndicationControllerTest extends SysuiTestCase {
mExecutor.runAllReady();
reset(mRotateTextViewController);
- // GIVEN keyguard is showing
+ // GIVEN keyguard is showing and not dozing
when(mKeyguardStateController.isShowing()).thenReturn(true);
+ mController.setVisible(true);
+ mExecutor.runAllReady();
+ reset(mRotateTextViewController);
// WHEN keyguard showing changed called
mKeyguardStateControllerCallback.onKeyguardShowingChanged();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
index 52bacd2360b3..d8a98d1e8ea4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.java
@@ -29,12 +29,12 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider;
import com.android.systemui.statusbar.notification.interruption.KeyguardNotificationVisibilityProvider;
import com.android.systemui.statusbar.policy.KeyguardStateController;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
index 3b034f7af9a6..fc74f3954dc9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorTest.java
@@ -41,7 +41,6 @@ import androidx.test.filters.SmallTest;
import com.android.internal.statusbar.IStatusBarService;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.RankingBuilder;
-import com.android.systemui.statusbar.notification.SectionClassifier;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
import com.android.systemui.statusbar.notification.collection.ListEntry;
@@ -56,6 +55,7 @@ import com.android.systemui.statusbar.notification.collection.listbuilder.OnBefo
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
import com.android.systemui.statusbar.notification.collection.render.NotifViewBarn;
import com.android.systemui.statusbar.notification.row.NotifInflationErrorManager;
@@ -96,9 +96,9 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
@Mock private IStatusBarService mService;
@Mock private BindEventManagerImpl mBindEventManagerImpl;
@Spy private FakeNotifInflater mNotifInflater = new FakeNotifInflater();
- private final SectionClassifier mSectionClassifier = new SectionClassifier();
+ private final SectionStyleProvider mSectionStyleProvider = new SectionStyleProvider();
private final NotifUiAdjustmentProvider mAdjustmentProvider =
- new NotifUiAdjustmentProvider(mSectionClassifier);
+ new NotifUiAdjustmentProvider(mSectionStyleProvider);
@NonNull
private NotificationEntryBuilder getNotificationEntryBuilder() {
@@ -487,7 +487,7 @@ public class PreparationCoordinatorTest extends SysuiTestCase {
private static final int TEST_MAX_GROUP_DELAY = 100;
private void setSectionIsLowPriority(boolean minimized) {
- mSectionClassifier.setMinimizedSections(minimized
+ mSectionStyleProvider.setMinimizedSections(minimized
? Collections.singleton(mNotifSection.getSectioner())
: Collections.emptyList());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
index f4d8405a796e..ff08bc38c944 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RankingCoordinatorTest.java
@@ -40,7 +40,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.SbnBuilder;
-import com.android.systemui.statusbar.notification.SectionClassifier;
import com.android.systemui.statusbar.notification.collection.ListEntry;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -48,6 +47,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifFilter;
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner;
import com.android.systemui.statusbar.notification.collection.provider.HighPriorityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider;
import com.android.systemui.statusbar.notification.collection.render.NodeController;
import com.android.systemui.statusbar.notification.collection.render.SectionHeaderController;
@@ -68,7 +68,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
@Mock private StatusBarStateController mStatusBarStateController;
@Mock private HighPriorityProvider mHighPriorityProvider;
- @Mock private SectionClassifier mSectionClassifier;
+ @Mock private SectionStyleProvider mSectionStyleProvider;
@Mock private NotifPipeline mNotifPipeline;
@Mock private NodeController mAlertingHeaderController;
@Mock private NodeController mSilentNodeController;
@@ -92,7 +92,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
mRankingCoordinator = new RankingCoordinator(
mStatusBarStateController,
mHighPriorityProvider,
- mSectionClassifier,
+ mSectionStyleProvider,
mAlertingHeaderController,
mSilentHeaderController,
mSilentNodeController);
@@ -100,7 +100,7 @@ public class RankingCoordinatorTest extends SysuiTestCase {
mEntry.setRanking(getRankingForUnfilteredNotif().build());
mRankingCoordinator.attach(mNotifPipeline);
- verify(mSectionClassifier).setMinimizedSections(any());
+ verify(mSectionStyleProvider).setMinimizedSections(any());
verify(mNotifPipeline, times(2)).addPreGroupFilter(mNotifFilterCaptor.capture());
mCapturedSuspendedFilter = mNotifFilterCaptor.getAllValues().get(0);
mCapturedDozingFilter = mNotifFilterCaptor.getAllValues().get(1);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
index 447ba1510e13..40859d0e6304 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
@@ -21,13 +21,13 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.AssistantFeedbackController
import com.android.systemui.statusbar.notification.FeedbackIcon
-import com.android.systemui.statusbar.notification.SectionClassifier
import com.android.systemui.statusbar.notification.collection.NotifPipeline
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
import com.android.systemui.statusbar.notification.collection.listbuilder.OnAfterRenderEntryListener
import com.android.systemui.statusbar.notification.collection.listbuilder.OnBeforeRenderListListener
+import com.android.systemui.statusbar.notification.collection.provider.SectionStyleProvider
import com.android.systemui.statusbar.notification.collection.render.NotifRowController
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.eq
@@ -53,7 +53,7 @@ class RowAppearanceCoordinatorTest : SysuiTestCase() {
@Mock private lateinit var pipeline: NotifPipeline
@Mock private lateinit var assistantFeedbackController: AssistantFeedbackController
- @Mock private lateinit var sectionClassifier: SectionClassifier
+ @Mock private lateinit var sectionStyleProvider: SectionStyleProvider
@Mock private lateinit var section1: NotifSection
@Mock private lateinit var section2: NotifSection
@@ -66,7 +66,7 @@ class RowAppearanceCoordinatorTest : SysuiTestCase() {
coordinator = RowAppearanceCoordinator(
mContext,
assistantFeedbackController,
- sectionClassifier
+ sectionStyleProvider
)
coordinator.attach(pipeline)
beforeRenderListListener = withArgCaptor {
@@ -82,8 +82,8 @@ class RowAppearanceCoordinatorTest : SysuiTestCase() {
@Test
fun testSetSystemExpandedOnlyOnFirst() {
- whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
- whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(false)
+ whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(false)
+ whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(false)
beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
verify(controller1).setSystemExpanded(eq(true))
@@ -93,8 +93,8 @@ class RowAppearanceCoordinatorTest : SysuiTestCase() {
@Test
fun testSetSystemExpandedNeverIfMinimized() {
- whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
- whenever(sectionClassifier.isMinimizedSection(eq(section1))).thenReturn(true)
+ whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(true)
+ whenever(sectionStyleProvider.isMinimizedSection(eq(section1))).thenReturn(true)
beforeRenderListListener.onBeforeRenderList(listOf(entry1, entry2))
afterRenderEntryListener.onAfterRenderEntry(entry1, controller1)
verify(controller1).setSystemExpanded(eq(false))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
index 0e1865861cae..ff601938d544 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.notification.collection.render
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.collection.GroupEntry
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder
import com.android.systemui.statusbar.notification.collection.ListEntry
@@ -28,6 +27,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntryB
import com.android.systemui.statusbar.notification.collection.getAttachState
import com.android.systemui.statusbar.notification.collection.listbuilder.NotifSection
import com.android.systemui.statusbar.notification.collection.listbuilder.pluggable.NotifSectioner
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider
import com.android.systemui.statusbar.notification.stack.BUCKET_ALERTING
import com.android.systemui.statusbar.notification.stack.BUCKET_PEOPLE
import com.android.systemui.statusbar.notification.stack.BUCKET_SILENT
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
index de9ea27e7c13..01aa0f2acb01 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProviderTest.java
@@ -40,7 +40,7 @@ import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.RankingBuilder;
-import com.android.systemui.statusbar.notification.SectionHeaderVisibilityProvider;
+import com.android.systemui.statusbar.notification.collection.provider.SectionHeaderVisibilityProvider;
import com.android.systemui.statusbar.notification.collection.GroupEntry;
import com.android.systemui.statusbar.notification.collection.GroupEntryBuilder;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
index 1ecb09bc8514..3d57f66c5dc4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationTestHelper.java
@@ -144,10 +144,9 @@ public class NotificationTestHelper {
mock(KeyguardBypassController.class),
mock(NotificationGroupManagerLegacy.class),
mock(VisualStabilityProvider.class),
- mock(ConfigurationControllerImpl.class)
+ mock(ConfigurationControllerImpl.class),
+ new Handler(mTestLooper.getLooper())
);
- mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
- mHeadsUpManager.mHandler = new Handler(mTestLooper.getLooper());
mGroupMembershipManager.setHeadsUpManager(mHeadsUpManager);
mIconManager = new IconManager(
mock(CommonNotifCollection.class),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
index db5741c90ebc..b8c8b5f26f0f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpManagerPhoneTest.java
@@ -23,6 +23,7 @@ import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.os.Handler;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
@@ -76,7 +77,8 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
VisualStabilityProvider visualStabilityProvider,
StatusBarStateController statusBarStateController,
KeyguardBypassController keyguardBypassController,
- ConfigurationController configurationController
+ ConfigurationController configurationController,
+ Handler handler
) {
super(
context,
@@ -85,7 +87,8 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
keyguardBypassController,
groupManager,
visualStabilityProvider,
- configurationController
+ configurationController,
+ handler
);
mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
@@ -105,6 +108,8 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
when(mVSProvider.isReorderingAllowed()).thenReturn(true);
mDependency.injectMockDependency(NotificationShadeWindowController.class);
mDependency.injectMockDependency(ConfigurationController.class);
+ super.setUp();
+
mHeadsUpManager = new TestableHeadsUpManagerPhone(
mContext,
mHeadsUpManagerLogger,
@@ -112,11 +117,9 @@ public class HeadsUpManagerPhoneTest extends AlertingNotificationManagerTest {
mVSProvider,
mStatusBarStateController,
mBypassController,
- mConfigurationController
+ mConfigurationController,
+ mTestHandler
);
- super.setUp();
- mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
- mHeadsUpManager.mHandler = mTestHandler;
}
@After
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
index 7070bc19db62..56dfb0cee520 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationGroupAlertTransferHelperTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.Notification;
+import android.os.Handler;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -51,7 +52,6 @@ import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.HeadsUpManagerLogger;
import com.android.wm.shell.bubbles.Bubbles;
-import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -89,7 +89,8 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
- mHeadsUpManager = new HeadsUpManager(mContext, mock(HeadsUpManagerLogger.class)) {};
+ mHeadsUpManager = new HeadsUpManager(mContext, mock(HeadsUpManagerLogger.class),
+ mock(Handler.class)) {};
when(mNotificationEntryManager.getPendingNotificationsIterator())
.thenReturn(mPendingEntries.values());
@@ -114,11 +115,6 @@ public class NotificationGroupAlertTransferHelperTest extends SysuiTestCase {
mHeadsUpManager.addListener(mGroupAlertTransferHelper);
}
- @After
- public void tearDown() {
- mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
- }
-
private void mockHasHeadsUpContentView(NotificationEntry entry,
boolean hasHeadsUpContentView) {
RowContentBindParams params = new RowContentBindParams();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
index 424a40058997..f39d6875cffc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/HeadsUpManagerTest.java
@@ -36,6 +36,7 @@ import android.app.PendingIntent;
import android.app.Person;
import android.content.Context;
import android.content.Intent;
+import android.os.Handler;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -73,8 +74,8 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest {
@Mock private HeadsUpManagerLogger mLogger;
private final class TestableHeadsUpManager extends HeadsUpManager {
- TestableHeadsUpManager(Context context, HeadsUpManagerLogger logger) {
- super(context, logger);
+ TestableHeadsUpManager(Context context, HeadsUpManagerLogger logger, Handler handler) {
+ super(context, logger, handler);
mMinimumDisplayTime = TEST_MINIMUM_DISPLAY_TIME;
mAutoDismissNotificationDecay = TEST_AUTO_DISMISS_TIME;
}
@@ -91,10 +92,9 @@ public class HeadsUpManagerTest extends AlertingNotificationManagerTest {
mDependency.injectTestDependency(UiEventLogger.class, mUiEventLoggerFake);
when(mEntry.getSbn()).thenReturn(mSbn);
when(mSbn.getNotification()).thenReturn(mNotification);
- mHeadsUpManager = new TestableHeadsUpManager(mContext, mLogger);
+
super.setUp();
- mHeadsUpManager.mHandler.removeCallbacksAndMessages(null);
- mHeadsUpManager.mHandler = mTestHandler;
+ mHeadsUpManager = new TestableHeadsUpManager(mContext, mLogger, mTestHandler);
}
@After
diff --git a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
index e80a6d9e0907..9f0deea503cf 100644
--- a/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
+++ b/services/backup/java/com/android/server/backup/PackageManagerBackupAgent.java
@@ -235,60 +235,7 @@ public class PackageManagerBackupAgent extends BackupAgent {
return;
}
- long homeVersion = 0;
- ArrayList<byte[]> homeSigHashes = null;
- PackageInfo homeInfo = null;
- String homeInstaller = null;
- ComponentName home = getPreferredHomeComponent();
- if (home != null) {
- try {
- homeInfo = mPackageManager.getPackageInfoAsUser(home.getPackageName(),
- PackageManager.GET_SIGNING_CERTIFICATES, mUserId);
- homeInstaller = mPackageManager.getInstallerPackageName(home.getPackageName());
- homeVersion = homeInfo.getLongVersionCode();
- SigningInfo signingInfo = homeInfo.signingInfo;
- if (signingInfo == null) {
- Slog.e(TAG, "Home app has no signing information");
- } else {
- // retrieve the newest sigs to back up
- // TODO (b/73988180) use entire signing history in case of rollbacks
- Signature[] homeInfoSignatures = signingInfo.getApkContentsSigners();
- homeSigHashes = BackupUtils.hashSignatureArray(homeInfoSignatures);
- }
- } catch (NameNotFoundException e) {
- Slog.w(TAG, "Can't access preferred home info");
- // proceed as though there were no preferred home set
- home = null;
- }
- }
-
try {
- // We need to push a new preferred-home-app record if:
- // 1. the version of the home app has changed since our last backup;
- // 2. the home app [or absence] we now use differs from the prior state,
- // OR 3. it looks like we use the same home app + version as before, but
- // the signatures don't match so we treat them as different apps.
- PackageManagerInternal pmi = LocalServices.getService(PackageManagerInternal.class);
- final boolean needHomeBackup = (homeVersion != mStoredHomeVersion)
- || !Objects.equals(home, mStoredHomeComponent)
- || (home != null
- && !BackupUtils.signaturesMatch(mStoredHomeSigHashes, homeInfo, pmi));
- if (needHomeBackup) {
- if (DEBUG) {
- Slog.i(TAG, "Home preference changed; backing up new state " + home);
- }
- if (home != null) {
- outputBuffer.reset();
- outputBufferStream.writeUTF(home.flattenToString());
- outputBufferStream.writeLong(homeVersion);
- outputBufferStream.writeUTF(homeInstaller != null ? homeInstaller : "" );
- writeSignatureHashArray(outputBufferStream, homeSigHashes);
- writeEntity(data, DEFAULT_HOME_KEY, outputBuffer.toByteArray());
- } else {
- data.writeEntityHeader(DEFAULT_HOME_KEY, -1);
- }
- }
-
/*
* Global metadata:
*
@@ -403,7 +350,7 @@ public class PackageManagerBackupAgent extends BackupAgent {
}
// Finally, write the new state blob -- just the list of all apps we handled
- writeStateFile(mAllPackages, home, homeVersion, homeSigHashes, newState);
+ writeStateFile(mAllPackages, newState);
}
private static void writeEntity(BackupDataOutput data, String key, byte[] bytes)
@@ -623,8 +570,7 @@ public class PackageManagerBackupAgent extends BackupAgent {
}
// Util: write out our new backup state file
- private void writeStateFile(List<PackageInfo> pkgs, ComponentName preferredHome,
- long homeVersion, ArrayList<byte[]> homeSigHashes, ParcelFileDescriptor stateFile) {
+ private void writeStateFile(List<PackageInfo> pkgs, ParcelFileDescriptor stateFile) {
FileOutputStream outstream = new FileOutputStream(stateFile.getFileDescriptor());
BufferedOutputStream outbuf = new BufferedOutputStream(outstream);
DataOutputStream out = new DataOutputStream(outbuf);
@@ -635,14 +581,6 @@ public class PackageManagerBackupAgent extends BackupAgent {
out.writeUTF(STATE_FILE_HEADER);
out.writeInt(STATE_FILE_VERSION);
- // If we remembered a preferred home app, record that
- if (preferredHome != null) {
- out.writeUTF(DEFAULT_HOME_KEY);
- out.writeUTF(preferredHome.flattenToString());
- out.writeLong(homeVersion);
- writeSignatureHashArray(out, homeSigHashes);
- }
-
// Conclude with the metadata block
out.writeUTF(GLOBAL_METADATA_KEY);
out.writeInt(Build.VERSION.SDK_INT);
@@ -789,6 +727,8 @@ public class PackageManagerBackupAgent extends BackupAgent {
+ Build.VERSION.INCREMENTAL + ")");
}
} else if (key.equals(DEFAULT_HOME_KEY)) {
+ // Default home app data is no longer backed up by this agent. This code is
+ // kept to handle restore of old backups that still contain home app data.
String cn = inputBufferStream.readUTF();
mRestoredHome = ComponentName.unflattenFromString(cn);
mRestoredHomeVersion = inputBufferStream.readLong();
diff --git a/services/backup/java/com/android/server/backup/UserBackupManagerService.java b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
index 1af35af9fc17..99b500d6983e 100644
--- a/services/backup/java/com/android/server/backup/UserBackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/UserBackupManagerService.java
@@ -85,7 +85,6 @@ import android.os.PowerSaveState;
import android.os.Process;
import android.os.RemoteException;
import android.os.SELinux;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
@@ -4144,6 +4143,24 @@ public class UserBackupManagerService {
pw.print(" : ");
pw.println(entry.packageName);
}
+ pw.println(userPrefix + "Agent timeouts:");
+ pw.println(" KvBackupAgentTimeoutMillis: "
+ + mAgentTimeoutParameters.getKvBackupAgentTimeoutMillis());
+ pw.println(" FullBackupAgentTimeoutMillis: "
+ + mAgentTimeoutParameters.getFullBackupAgentTimeoutMillis());
+ pw.println(" SharedBackupAgentTimeoutMillis: "
+ + mAgentTimeoutParameters.getSharedBackupAgentTimeoutMillis());
+ pw.println(" RestoreAgentTimeoutMillis (system): "
+ + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis(
+ Process.FIRST_APPLICATION_UID - 1));
+ pw.println(" RestoreAgentTimeoutMillis: "
+ + mAgentTimeoutParameters.getRestoreAgentTimeoutMillis(
+ Process.FIRST_APPLICATION_UID));
+ pw.println(" RestoreAgentFinishedTimeoutMillis: "
+ + mAgentTimeoutParameters.getRestoreAgentFinishedTimeoutMillis());
+ pw.println(" QuotaExceededTimeoutMillis: "
+ + mAgentTimeoutParameters.getQuotaExceededTimeoutMillis());
+
}
}
diff --git a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
index 76df8b9f84e8..e78c8d1ddcac 100644
--- a/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
+++ b/services/backup/java/com/android/server/backup/restore/FullRestoreEngine.java
@@ -24,8 +24,10 @@ import static com.android.server.backup.UserBackupManagerService.BACKUP_METADATA
import static com.android.server.backup.UserBackupManagerService.SHARED_BACKUP_AGENT_PACKAGE;
import static com.android.server.backup.internal.BackupHandler.MSG_RESTORE_OPERATION_TIMEOUT;
+import android.annotation.NonNull;
import android.app.ApplicationThreadConstants;
import android.app.IBackupAgent;
+import android.app.backup.BackupAgent;
import android.app.backup.BackupManager;
import android.app.backup.FullBackup;
import android.app.backup.IBackupManagerMonitor;
@@ -38,10 +40,12 @@ import android.content.pm.Signature;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
import android.provider.Settings;
+import android.system.OsConstants;
import android.text.TextUtils;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
import com.android.server.backup.BackupAgentTimeoutParameters;
import com.android.server.backup.BackupRestoreTask;
@@ -57,6 +61,7 @@ import com.android.server.backup.utils.FullBackupRestoreObserverUtils;
import com.android.server.backup.utils.RestoreUtils;
import com.android.server.backup.utils.TarBackupReader;
+import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -135,6 +140,8 @@ public class FullRestoreEngine extends RestoreEngine {
private boolean mPipesClosed;
private final BackupEligibilityRules mBackupEligibilityRules;
+ private FileMetadata mReadOnlyParent = null;
+
public FullRestoreEngine(
UserBackupManagerService backupManagerService, OperationStorage operationStorage,
BackupRestoreTask monitorTask, IFullBackupRestoreObserver observer,
@@ -158,6 +165,22 @@ public class FullRestoreEngine extends RestoreEngine {
mBackupEligibilityRules = backupEligibilityRules;
}
+ @VisibleForTesting
+ FullRestoreEngine() {
+ mIsAdbRestore = false;
+ mAllowApks = false;
+ mEphemeralOpToken = 0;
+ mUserId = 0;
+ mBackupEligibilityRules = null;
+ mAgentTimeoutParameters = null;
+ mBuffer = null;
+ mBackupManagerService = null;
+ mOperationStorage = null;
+ mMonitor = null;
+ mMonitorTask = null;
+ mOnlyPackage = null;
+ }
+
public IBackupAgent getAgent() {
return mAgent;
}
@@ -397,6 +420,11 @@ public class FullRestoreEngine extends RestoreEngine {
okay = false;
}
+ if (shouldSkipReadOnlyDir(info)) {
+ // b/194894879: We don't support restore of read-only dirs.
+ okay = false;
+ }
+
// At this point we have an agent ready to handle the full
// restore data as well as a pipe for sending data to
// that agent. Tell the agent to start reading from the
@@ -573,6 +601,45 @@ public class FullRestoreEngine extends RestoreEngine {
return (info != null);
}
+ boolean shouldSkipReadOnlyDir(FileMetadata info) {
+ if (isValidParent(mReadOnlyParent, info)) {
+ // This file has a read-only parent directory, we shouldn't
+ // restore it.
+ return true;
+ } else {
+ // We're now in a different branch of the file tree, update the parent
+ // value.
+ if (isReadOnlyDir(info)) {
+ // Current directory is read-only. Remember it so that we can skip all
+ // of its contents.
+ mReadOnlyParent = info;
+ Slog.w(TAG, "Skipping restore of " + info.path + " and its contents as "
+ + "read-only dirs are currently not supported.");
+ return true;
+ } else {
+ mReadOnlyParent = null;
+ }
+ }
+
+ return false;
+ }
+
+ private static boolean isValidParent(FileMetadata parentDir, @NonNull FileMetadata childDir) {
+ return parentDir != null
+ && childDir.packageName.equals(parentDir.packageName)
+ && childDir.domain.equals(parentDir.domain)
+ && childDir.path.startsWith(getPathWithTrailingSeparator(parentDir.path));
+ }
+
+ private static String getPathWithTrailingSeparator(String path) {
+ return path.endsWith(File.separator) ? path : path + File.separator;
+ }
+
+ private static boolean isReadOnlyDir(FileMetadata file) {
+ // Check if owner has 'write' bit in the file's mode value (see 'man -7 inode' for details).
+ return file.type == BackupAgent.TYPE_DIRECTORY && (file.mode & OsConstants.S_IWUSR) == 0;
+ }
+
private void setUpPipes() throws IOException {
synchronized (mPipesLock) {
mPipes = ParcelFileDescriptor.createPipe();
diff --git a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
index bf8b18ce3157..52e341cd157f 100644
--- a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
+++ b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java
@@ -26,6 +26,7 @@ import static com.android.server.companion.CompanionDeviceManagerService.DEBUG;
import static com.android.server.companion.PackageUtils.enforceUsesCompanionDeviceFeature;
import static com.android.server.companion.PermissionsUtils.enforcePermissionsForAssociation;
import static com.android.server.companion.RolesUtils.isRoleHolder;
+import static com.android.server.companion.Utils.prepareForIpc;
import static java.util.Objects.requireNonNull;
@@ -47,7 +48,6 @@ import android.net.MacAddress;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
-import android.os.Parcel;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
@@ -400,20 +400,4 @@ class AssociationRequestsProcessor {
return sameOemPackageCerts;
}
-
- /**
- * Convert an instance of a "locally-defined" ResultReceiver to an instance of
- * {@link android.os.ResultReceiver} itself, which the receiving process will be able to
- * unmarshall.
- */
- private static <T extends ResultReceiver> ResultReceiver prepareForIpc(T resultReceiver) {
- final Parcel parcel = Parcel.obtain();
- resultReceiver.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
-
- final ResultReceiver ipcFriendly = ResultReceiver.CREATOR.createFromParcel(parcel);
- parcel.recycle();
-
- return ipcFriendly;
- }
}
diff --git a/services/companion/java/com/android/server/companion/DataStoreUtils.java b/services/companion/java/com/android/server/companion/DataStoreUtils.java
index 8ac741a44ee5..73e68ec0bf97 100644
--- a/services/companion/java/com/android/server/companion/DataStoreUtils.java
+++ b/services/companion/java/com/android/server/companion/DataStoreUtils.java
@@ -33,15 +33,24 @@ import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
import java.io.FileOutputStream;
-final class DataStoreUtils {
+/**
+ * Util class for CDM data stores
+ */
+public final class DataStoreUtils {
private static final String TAG = "CompanionDevice_DataStoreUtils";
- static boolean isStartOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
+ /**
+ * Check if the parser pointer is at the start of the tag
+ */
+ public static boolean isStartOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
throws XmlPullParserException {
return parser.getEventType() == START_TAG && tag.equals(parser.getName());
}
- static boolean isEndOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
+ /**
+ * Check if the parser pointer is at the end of the tag
+ */
+ public static boolean isEndOfTag(@NonNull XmlPullParser parser, @NonNull String tag)
throws XmlPullParserException {
return parser.getEventType() == END_TAG && tag.equals(parser.getName());
}
@@ -57,7 +66,7 @@ final class DataStoreUtils {
* @return an AtomicFile for the user
*/
@NonNull
- static AtomicFile createStorageFileForUser(@UserIdInt int userId, String fileName) {
+ public static AtomicFile createStorageFileForUser(@UserIdInt int userId, String fileName) {
return new AtomicFile(getBaseStorageFileForUser(userId, fileName));
}
@@ -70,7 +79,7 @@ final class DataStoreUtils {
* Writing to file could fail, for example, if the user has been recently removed and so was
* their DE (/data/system_de/<user-id>/) directory.
*/
- static void writeToFileSafely(
+ public static void writeToFileSafely(
@NonNull AtomicFile file, @NonNull ThrowingConsumer<FileOutputStream> consumer) {
try {
file.write(consumer);
diff --git a/services/companion/java/com/android/server/companion/PackageUtils.java b/services/companion/java/com/android/server/companion/PackageUtils.java
index a2b20593a9cb..42c7687f0f28 100644
--- a/services/companion/java/com/android/server/companion/PackageUtils.java
+++ b/services/companion/java/com/android/server/companion/PackageUtils.java
@@ -41,8 +41,8 @@ import android.util.Slog;
import com.android.internal.util.ArrayUtils;
+import java.util.ArrayList;
import java.util.HashMap;
-import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -87,7 +87,8 @@ final class PackageUtils {
final List<ResolveInfo> companionServices = pm.queryIntentServicesAsUser(
COMPANION_SERVICE_INTENT, ResolveInfoFlags.of(0), userId);
- final Map<String, List<ComponentName>> packageNameToServiceInfoList = new HashMap<>();
+ final Map<String, List<ComponentName>> packageNameToServiceInfoList =
+ new HashMap<>(companionServices.size());
for (ResolveInfo resolveInfo : companionServices) {
final ServiceInfo service = resolveInfo.serviceInfo;
@@ -101,19 +102,19 @@ final class PackageUtils {
continue;
}
- // Use LinkedList, because we'll need to prepend "primary" services, while appending the
- // other (non-primary) services to the list.
- final LinkedList<ComponentName> services =
- (LinkedList<ComponentName>) packageNameToServiceInfoList.computeIfAbsent(
- service.packageName, it -> new LinkedList<>());
+ // We'll need to prepend "primary" services, while appending the other (non-primary)
+ // services to the list.
+ final ArrayList<ComponentName> services =
+ (ArrayList<ComponentName>) packageNameToServiceInfoList.computeIfAbsent(
+ service.packageName, it -> new ArrayList<>(1));
final ComponentName componentName = service.getComponentName();
if (isPrimaryCompanionDeviceService(pm, componentName)) {
// "Primary" service should be at the head of the list.
- services.addFirst(componentName);
+ services.add(0, componentName);
} else {
- services.addLast(componentName);
+ services.add(componentName);
}
}
diff --git a/services/companion/java/com/android/server/companion/PersistentDataStore.java b/services/companion/java/com/android/server/companion/PersistentDataStore.java
index d0cc12286b12..2487befecf52 100644
--- a/services/companion/java/com/android/server/companion/PersistentDataStore.java
+++ b/services/companion/java/com/android/server/companion/PersistentDataStore.java
@@ -101,7 +101,7 @@ import java.util.concurrent.ConcurrentMap;
* Since Android T the data is stored to "companion_device_manager.xml" file in
* {@link Environment#getDataSystemDeDirectory(int) /data/system_de/}.
*
- * See {@link #getBaseStorageFileForUser(int) getBaseStorageFileForUser()}
+ * See {@link #getStorageFileForUser(int)}
*
* <p>
* Since Android T the data is stored using the v1 schema.
diff --git a/services/companion/java/com/android/server/companion/Utils.java b/services/companion/java/com/android/server/companion/Utils.java
new file mode 100644
index 000000000000..b9f61ecd8c4f
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/Utils.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.companion;
+
+import android.os.Parcel;
+import android.os.ResultReceiver;
+
+/**
+ * A miscellaneous util class for CDM
+ *
+ * @hide
+ */
+public final class Utils {
+
+ /**
+ * Convert an instance of a "locally-defined" ResultReceiver to an instance of
+ * {@link android.os.ResultReceiver} itself, which the receiving process will be able to
+ * unmarshall.
+ * @hide
+ */
+ public static <T extends ResultReceiver> ResultReceiver prepareForIpc(T resultReceiver) {
+ final Parcel parcel = Parcel.obtain();
+ resultReceiver.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
+
+ final ResultReceiver ipcFriendly = ResultReceiver.CREATOR.createFromParcel(parcel);
+ parcel.recycle();
+
+ return ipcFriendly;
+ }
+
+ private Utils() {}
+}
diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
new file mode 100644
index 000000000000..c3b861689587
--- /dev/null
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.companion.datatransfer;
+
+import static android.app.PendingIntent.FLAG_CANCEL_CURRENT;
+import static android.app.PendingIntent.FLAG_IMMUTABLE;
+import static android.app.PendingIntent.FLAG_ONE_SHOT;
+import static android.companion.CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME;
+import static android.content.ComponentName.createRelative;
+
+import static com.android.server.companion.Utils.prepareForIpc;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.UserIdInt;
+import android.app.PendingIntent;
+import android.companion.AssociationInfo;
+import android.companion.DeviceNotAssociatedException;
+import android.companion.SystemDataTransferRequest;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.Slog;
+
+import com.android.server.companion.AssociationStore;
+import com.android.server.companion.CompanionDeviceManagerService;
+
+import java.util.List;
+
+/**
+ * This processor builds user consent intent for a given SystemDataTransferRequest and processes the
+ * request when the system is ready (a secure channel is established between the handhold and the
+ * companion device).
+ */
+public class SystemDataTransferProcessor {
+
+ private static final String LOG_TAG = SystemDataTransferProcessor.class.getSimpleName();
+
+ // Values from UI to SystemDataTransferProcessor via ResultReceiver
+ private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED = 0;
+ private static final int RESULT_CODE_SYSTEM_DATA_TRANSFER_DISALLOWED = 1;
+ private static final String EXTRA_SYSTEM_DATA_TRANSFER_REQUEST = "system_data_transfer_request";
+ private static final String EXTRA_SYSTEM_DATA_TRANSFER_RESULT_RECEIVER =
+ "system_data_transfer_result_receiver";
+ private static final ComponentName SYSTEM_DATA_TRANSFER_REQUEST_APPROVAL_ACTIVITY =
+ createRelative(COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME,
+ ".CompanionDeviceDataTransferActivity");
+
+ private final Context mContext;
+ private final AssociationStore mAssociationStore;
+ private final SystemDataTransferRequestStore mSystemDataTransferRequestStore;
+
+ public SystemDataTransferProcessor(CompanionDeviceManagerService service,
+ AssociationStore associationStore,
+ SystemDataTransferRequestStore systemDataTransferRequestStore) {
+ mContext = service.getContext();
+ mAssociationStore = associationStore;
+ mSystemDataTransferRequestStore = systemDataTransferRequestStore;
+ }
+
+ /**
+ * Build a PendingIntent of user consent dialog
+ */
+ public PendingIntent buildSystemDataTransferConfirmationIntent(@UserIdInt int userId,
+ SystemDataTransferRequest request) throws RemoteException {
+ // The association must exist and either belong to the calling package,
+ // or the calling package must hold REQUEST_SYSTEM_DATA_TRANSFER permission.
+ int associationId = request.getAssociationId();
+ AssociationInfo association = mAssociationStore.getAssociationById(associationId);
+ if (association == null) {
+ throw new RemoteException(new DeviceNotAssociatedException(
+ "Association id: " + associationId + " doesn't exist."));
+ } else {
+ // If the package is not the companion app which owns the association,
+ // it must hold REQUEST_SYSTEM_DATA_TRANSFER permission.
+ // TODO(b/204593788): uncomment the following with the API changes
+// if (!association.getPackageName()
+// .equals(mContext.getPackageManager().getNameForUid(Binder.getCallingUid()))) {
+// mContext.enforceCallingOrSelfPermission(
+// Manifest.permission.REQUEST_COMPANION_DEVICE_SYSTEM_DATA_TRANSFER,
+// "requestSystemDataTransfer requires REQUEST_SYSTEM_DATA_TRANSFER "
+// + "permission if the package doesn't own the association.");
+// }
+
+ // Check if the request's data type has been requested before.
+ List<SystemDataTransferRequest> storedRequests =
+ mSystemDataTransferRequestStore.readRequestsByAssociationId(userId,
+ associationId);
+ for (SystemDataTransferRequest storedRequest : storedRequests) {
+ if (request.hasSameDataType(storedRequest)) {
+ Slog.e(LOG_TAG, "The request has been sent before, you can not send "
+ + "the same request type again.");
+ return null;
+ }
+ }
+ }
+
+ Slog.i(LOG_TAG, "Creating PendingIntent for associationId: " + associationId + ", request: "
+ + request);
+
+ // Create an internal intent to launch the user consent dialog
+ final Bundle extras = new Bundle();
+ request.setUserId(userId);
+ extras.putParcelable(EXTRA_SYSTEM_DATA_TRANSFER_REQUEST, request);
+ extras.putParcelable(EXTRA_SYSTEM_DATA_TRANSFER_RESULT_RECEIVER,
+ prepareForIpc(mOnSystemDataTransferRequestConfirmationReceiver));
+
+ final Intent intent = new Intent();
+ intent.setComponent(SYSTEM_DATA_TRANSFER_REQUEST_APPROVAL_ACTIVITY);
+ intent.putExtras(extras);
+
+ // Create a PendingIntent
+ final long token = Binder.clearCallingIdentity();
+ try {
+ return PendingIntent.getActivity(mContext, /*requestCode */ associationId, intent,
+ FLAG_ONE_SHOT | FLAG_CANCEL_CURRENT | FLAG_IMMUTABLE);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ private final ResultReceiver mOnSystemDataTransferRequestConfirmationReceiver =
+ new ResultReceiver(Handler.getMain()) {
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle data) {
+ Slog.d(LOG_TAG, "onReceiveResult() code=" + resultCode + ", "
+ + "data=" + data);
+
+ if (resultCode == RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED
+ || resultCode == RESULT_CODE_SYSTEM_DATA_TRANSFER_DISALLOWED) {
+ final SystemDataTransferRequest request =
+ data.getParcelable(EXTRA_SYSTEM_DATA_TRANSFER_REQUEST);
+ requireNonNull(request);
+
+ request.setUserConsented(
+ resultCode == RESULT_CODE_SYSTEM_DATA_TRANSFER_ALLOWED);
+ Slog.i(LOG_TAG, "Recording request: " + request);
+ mSystemDataTransferRequestStore.writeRequest(request.getUserId(), request);
+
+ return;
+ }
+
+ Slog.e(LOG_TAG, "Unknown result code:" + resultCode);
+ }
+ };
+}
diff --git a/services/companion/java/com/android/server/companion/SystemDataTransferRequestDataStore.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferRequestStore.java
index 38e5d16842b9..204fb3df686f 100644
--- a/services/companion/java/com/android/server/companion/SystemDataTransferRequestDataStore.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferRequestStore.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.companion;
+package com.android.server.companion.datatransfer;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
@@ -33,10 +33,12 @@ import android.annotation.UserIdInt;
import android.companion.SystemDataTransferRequest;
import android.util.AtomicFile;
import android.util.Slog;
+import android.util.SparseArray;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.XmlUtils;
import org.xmlpull.v1.XmlPullParserException;
@@ -45,19 +47,26 @@ import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* The class is responsible for reading/writing SystemDataTransferRequest records from/to the disk.
- *
+ * <p>
* The following snippet is a sample XML file stored in the disk.
* <pre>{@code
* <requests>
* <request
* association_id="1"
+ * user_id="12"
+ * is_user_consented="true"
* is_permission_sync_all_packages="false">
* <list name="permission_sync_packages">
* <string>com.sample.app1</string>
@@ -67,9 +76,9 @@ import java.util.concurrent.ConcurrentMap;
* </requests>
* }</pre>
*/
-public class SystemDataTransferRequestDataStore {
+public class SystemDataTransferRequestStore {
- private static final String LOG_TAG = SystemDataTransferRequestDataStore.class.getSimpleName();
+ private static final String LOG_TAG = SystemDataTransferRequestStore.class.getSimpleName();
private static final String FILE_NAME = "companion_device_system_data_transfer_requests.xml";
@@ -78,13 +87,79 @@ public class SystemDataTransferRequestDataStore {
private static final String XML_TAG_LIST = "list";
private static final String XML_ATTR_ASSOCIATION_ID = "association_id";
+ private static final String XML_ATTR_USER_ID = "user_id";
+ private static final String XML_ATTR_IS_USER_CONSENTED = "is_user_consented";
private static final String XML_ATTR_IS_PERMISSION_SYNC_ALL_PACKAGES =
"is_permission_sync_all_packages";
private static final String XML_ATTR_PERMISSION_SYNC_PACKAGES = "permission_sync_packages";
+ private static final int READ_FROM_DISK_TIMEOUT = 5; // in seconds
+
+ private final ExecutorService mExecutor;
private final ConcurrentMap<Integer, AtomicFile> mUserIdToStorageFile =
new ConcurrentHashMap<>();
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ private final SparseArray<ArrayList<SystemDataTransferRequest>> mCachedPerUser =
+ new SparseArray<>();
+
+ public SystemDataTransferRequestStore() {
+ mExecutor = Executors.newSingleThreadExecutor();
+ }
+
+ @NonNull
+ List<SystemDataTransferRequest> readRequestsByAssociationId(@UserIdInt int userId,
+ int associationId) {
+ List<SystemDataTransferRequest> cachedRequests;
+ synchronized (mLock) {
+ cachedRequests = readRequestsFromCache(userId);
+ }
+
+ List<SystemDataTransferRequest> requestsByAssociationId = new ArrayList<>();
+ for (SystemDataTransferRequest request : cachedRequests) {
+ if (request.getAssociationId() == associationId) {
+ requestsByAssociationId.add(request);
+ }
+ }
+ return requestsByAssociationId;
+ }
+
+ void writeRequest(@UserIdInt int userId, SystemDataTransferRequest request) {
+ ArrayList<SystemDataTransferRequest> cachedRequests;
+ synchronized (mLock) {
+ // Write to cache
+ cachedRequests = readRequestsFromCache(userId);
+ cachedRequests.add(request);
+ mCachedPerUser.set(userId, cachedRequests);
+ }
+ // Write to store
+ mExecutor.execute(() -> writeRequestsToStore(userId, cachedRequests));
+ }
+
+ @GuardedBy("mLock")
+ private ArrayList<SystemDataTransferRequest> readRequestsFromCache(@UserIdInt int userId) {
+ ArrayList<SystemDataTransferRequest> cachedRequests = mCachedPerUser.get(userId);
+ if (cachedRequests == null) {
+ Future<ArrayList<SystemDataTransferRequest>> future =
+ mExecutor.submit(() -> readRequestsFromStore(userId));
+ try {
+ cachedRequests = future.get(READ_FROM_DISK_TIMEOUT, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ Slog.e(LOG_TAG, "Thread reading SystemDataTransferRequest from disk is "
+ + "interrupted.");
+ } catch (ExecutionException e) {
+ Slog.e(LOG_TAG, "Error occurred while reading SystemDataTransferRequest "
+ + "from disk.");
+ } catch (TimeoutException e) {
+ Slog.e(LOG_TAG, "Reading SystemDataTransferRequest from disk timed out.");
+ }
+ mCachedPerUser.set(userId, cachedRequests);
+ }
+ return cachedRequests;
+ }
+
/**
* Reads previously persisted data for the given user
*
@@ -92,7 +167,7 @@ public class SystemDataTransferRequestDataStore {
* @return a list of SystemDataTransferRequest
*/
@NonNull
- List<SystemDataTransferRequest> readRequestsForUser(@UserIdInt int userId) {
+ private ArrayList<SystemDataTransferRequest> readRequestsFromStore(@UserIdInt int userId) {
final AtomicFile file = getStorageFileForUser(userId);
Slog.i(LOG_TAG, "Reading SystemDataTransferRequests for user " + userId + " from "
+ "file=" + file.getBaseFile().getPath());
@@ -102,47 +177,51 @@ public class SystemDataTransferRequestDataStore {
synchronized (file) {
if (!file.getBaseFile().exists()) {
Slog.d(LOG_TAG, "File does not exist -> Abort");
- return Collections.emptyList();
+ return new ArrayList<>();
}
try (FileInputStream in = file.openRead()) {
final TypedXmlPullParser parser = Xml.resolvePullParser(in);
XmlUtils.beginDocument(parser, XML_TAG_REQUESTS);
- return readRequests(parser);
+ return readRequestsFromXml(parser);
} catch (XmlPullParserException | IOException e) {
Slog.e(LOG_TAG, "Error while reading requests file", e);
- return Collections.emptyList();
+ return new ArrayList<>();
}
}
}
@NonNull
- private List<SystemDataTransferRequest> readRequests(@NonNull TypedXmlPullParser parser)
- throws XmlPullParserException, IOException {
+ private ArrayList<SystemDataTransferRequest> readRequestsFromXml(
+ @NonNull TypedXmlPullParser parser) throws XmlPullParserException, IOException {
if (!isStartOfTag(parser, XML_TAG_REQUESTS)) {
throw new XmlPullParserException("The XML doesn't have start tag: " + XML_TAG_REQUESTS);
}
- List<SystemDataTransferRequest> requests = new ArrayList<>();
+ ArrayList<SystemDataTransferRequest> requests = new ArrayList<>();
while (true) {
parser.nextTag();
- if (isEndOfTag(parser, XML_TAG_REQUESTS)) break;
+ if (isEndOfTag(parser, XML_TAG_REQUESTS)) {
+ break;
+ }
if (isStartOfTag(parser, XML_TAG_REQUEST)) {
- requests.add(readRequest(parser));
+ requests.add(readRequestFromXml(parser));
}
}
return requests;
}
- private SystemDataTransferRequest readRequest(@NonNull TypedXmlPullParser parser)
+ private SystemDataTransferRequest readRequestFromXml(@NonNull TypedXmlPullParser parser)
throws XmlPullParserException, IOException {
if (!isStartOfTag(parser, XML_TAG_REQUEST)) {
throw new XmlPullParserException("XML doesn't have start tag: " + XML_TAG_REQUEST);
}
final int associationId = readIntAttribute(parser, XML_ATTR_ASSOCIATION_ID);
+ final int userId = readIntAttribute(parser, XML_ATTR_USER_ID);
+ final boolean isUserConsented = readBooleanAttribute(parser, XML_ATTR_IS_USER_CONSENTED);
final boolean isPermissionSyncAllPackages = readBooleanAttribute(parser,
XML_ATTR_IS_PERMISSION_SYNC_ALL_PACKAGES);
parser.nextTag();
@@ -153,8 +232,13 @@ public class SystemDataTransferRequestDataStore {
new String[1]);
}
- return new SystemDataTransferRequest(associationId, isPermissionSyncAllPackages,
- permissionSyncPackages);
+ SystemDataTransferRequest request =
+ new SystemDataTransferRequest(associationId, isPermissionSyncAllPackages,
+ permissionSyncPackages);
+ request.setUserId(userId);
+ request.setUserConsented(isUserConsented);
+
+ return request;
}
/**
@@ -163,7 +247,7 @@ public class SystemDataTransferRequestDataStore {
* @param userId Android UserID
* @param requests a list of user's SystemDataTransferRequest.
*/
- void writeRequestsForUser(@UserIdInt int userId,
+ void writeRequestsToStore(@UserIdInt int userId,
@NonNull List<SystemDataTransferRequest> requests) {
final AtomicFile file = getStorageFileForUser(userId);
Slog.i(LOG_TAG, "Writing SystemDataTransferRequests for user " + userId + " to file="
@@ -177,30 +261,32 @@ public class SystemDataTransferRequestDataStore {
serializer.setFeature(
"http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startDocument(null, true);
- writeRequests(serializer, requests);
+ writeRequestsToXml(serializer, requests);
serializer.endDocument();
});
}
}
- private void writeRequests(@NonNull TypedXmlSerializer serializer,
+ private void writeRequestsToXml(@NonNull TypedXmlSerializer serializer,
@Nullable Collection<SystemDataTransferRequest> requests) throws IOException {
serializer.startTag(null, XML_TAG_REQUESTS);
for (SystemDataTransferRequest request : requests) {
- writeRequest(serializer, request);
+ writeRequestToXml(serializer, request);
}
serializer.endTag(null, XML_TAG_REQUESTS);
}
- private void writeRequest(@NonNull TypedXmlSerializer serializer,
+ private void writeRequestToXml(@NonNull TypedXmlSerializer serializer,
@NonNull SystemDataTransferRequest request) throws IOException {
serializer.startTag(null, XML_TAG_REQUEST);
writeIntAttribute(serializer, XML_ATTR_ASSOCIATION_ID, request.getAssociationId());
+ writeIntAttribute(serializer, XML_ATTR_USER_ID, request.getUserId());
+ writeBooleanAttribute(serializer, XML_ATTR_IS_USER_CONSENTED, request.isUserConsented());
writeBooleanAttribute(serializer, XML_ATTR_IS_PERMISSION_SYNC_ALL_PACKAGES,
- request.isPermissionSyncAllPackages());
+ request.getPermissionSyncAllPackages());
try {
writeListXml(request.getPermissionSyncPackages(), XML_ATTR_PERMISSION_SYNC_PACKAGES,
serializer);
@@ -215,11 +301,12 @@ public class SystemDataTransferRequestDataStore {
/**
* Creates and caches {@link AtomicFile} object that represents the back-up file for the given
* user.
- *
+ * <p>
* IMPORTANT: the method will ALWAYS return the same {@link AtomicFile} object, which makes it
* possible to synchronize reads and writes to the file using the returned object.
*/
- private @NonNull AtomicFile getStorageFileForUser(@UserIdInt int userId) {
+ @NonNull
+ private AtomicFile getStorageFileForUser(@UserIdInt int userId) {
return mUserIdToStorageFile.computeIfAbsent(userId,
u -> createStorageFileForUser(userId, FILE_NAME));
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9d9ee8c7a03b..51488307d750 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8676,8 +8676,8 @@ public class ActivityManagerService extends IActivityManager.Stub
sb.append("Foreground: ")
.append(process.isInterestingToUserLocked() ? "Yes" : "No")
.append("\n");
- if (process.getStartTime() > 0) {
- long runtimeMillis = SystemClock.elapsedRealtime() - process.getStartTime();
+ if (process.getStartUptime() > 0) {
+ long runtimeMillis = SystemClock.uptimeMillis() - process.getStartUptime();
sb.append("Process-Runtime: ").append(runtimeMillis).append("\n");
}
}
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 361629b0a629..f35d7929a8f7 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2783,7 +2783,9 @@ public class AppOpsService extends IAppOpsService.Stub {
@Nullable IAppOpsCallback permissionPolicyCallback) {
enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
verifyIncomingOp(code);
- verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+ if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+ return;
+ }
ArraySet<ModeCallback> repCbs = null;
code = AppOpsManager.opToSwitch(code);
@@ -3218,7 +3220,9 @@ public class AppOpsService extends IAppOpsService.Stub {
private int checkOperationImpl(int code, int uid, String packageName,
@Nullable String attributionTag, boolean raw) {
verifyIncomingOp(code);
- verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+ if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+ return AppOpsManager.opToDefaultMode(code);
+ }
String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
@@ -3330,8 +3334,7 @@ public class AppOpsService extends IAppOpsService.Stub {
}
private boolean isPackageExisted(String packageName) {
- return LocalServices.getService(PackageManagerInternal.class)
- .getPackageStateInternal(packageName) != null;
+ return getPackageManagerInternal().getPackageStateInternal(packageName) != null;
}
/**
@@ -3366,8 +3369,11 @@ public class AppOpsService extends IAppOpsService.Stub {
verifyIncomingProxyUid(attributionSource);
verifyIncomingOp(code);
- verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
- verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
+ if (!isIncomingPackageValid(proxiedPackageName, UserHandle.getUserId(proxiedUid))
+ || !isIncomingPackageValid(proxyPackageName, UserHandle.getUserId(proxyUid))) {
+ return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, proxiedAttributionTag,
+ proxiedPackageName);
+ }
skipProxyOperation = skipProxyOperation
&& isCallerAndAttributionTrusted(attributionSource);
@@ -3424,7 +3430,10 @@ public class AppOpsService extends IAppOpsService.Stub {
@Nullable String message, boolean shouldCollectMessage) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
- verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+ if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+ return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
+ packageName);
+ }
String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
@@ -3830,7 +3839,10 @@ public class AppOpsService extends IAppOpsService.Stub {
int attributionChainId) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
- verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+ if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+ return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
+ packageName);
+ }
String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
@@ -3884,8 +3896,11 @@ public class AppOpsService extends IAppOpsService.Stub {
verifyIncomingProxyUid(attributionSource);
verifyIncomingOp(code);
- verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
- verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
+ if (!isIncomingPackageValid(proxyPackageName, UserHandle.getUserId(proxyUid))
+ || !isIncomingPackageValid(proxiedPackageName, UserHandle.getUserId(proxiedUid))) {
+ return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, proxiedAttributionTag,
+ proxiedPackageName);
+ }
boolean isCallerTrusted = isCallerAndAttributionTrusted(attributionSource);
skipProxyOperation = isCallerTrusted && skipProxyOperation;
@@ -4070,7 +4085,9 @@ public class AppOpsService extends IAppOpsService.Stub {
String attributionTag) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
- verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+ if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+ return;
+ }
String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
@@ -4103,8 +4120,10 @@ public class AppOpsService extends IAppOpsService.Stub {
verifyIncomingProxyUid(attributionSource);
verifyIncomingOp(code);
- verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid));
- verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid));
+ if (!isIncomingPackageValid(proxyPackageName, UserHandle.getUserId(proxyUid))
+ || !isIncomingPackageValid(proxiedPackageName, UserHandle.getUserId(proxiedUid))) {
+ return null;
+ }
String resolvedProxyPackageName = AppOpsManager.resolvePackageName(proxyUid,
proxyPackageName);
@@ -4377,12 +4396,32 @@ public class AppOpsService extends IAppOpsService.Stub {
throw new IllegalArgumentException("Bad operation #" + op);
}
- private void verifyIncomingPackage(@Nullable String packageName, @UserIdInt int userId) {
- if (packageName != null && getPackageManagerInternal().filterAppAccess(packageName,
- Binder.getCallingUid(), userId)) {
- throw new IllegalArgumentException(
- packageName + " not found from " + Binder.getCallingUid());
+ private boolean isIncomingPackageValid(@Nullable String packageName, @UserIdInt int userId) {
+ final int callingUid = Binder.getCallingUid();
+ // Handle the special UIDs that don't have actual packages (audioserver, cameraserver, etc).
+ if (packageName == null || isSpecialPackage(callingUid, packageName)) {
+ return true;
}
+
+ // If the package doesn't exist, #verifyAndGetBypass would throw a SecurityException in
+ // the end. Although that exception would be caught and return, we could make it return
+ // early.
+ if (!isPackageExisted(packageName)) {
+ return false;
+ }
+
+ if (getPackageManagerInternal().filterAppAccess(packageName, callingUid, userId)) {
+ Slog.w(TAG, packageName + " not found from " + callingUid);
+ return false;
+ }
+
+ return true;
+ }
+
+ private boolean isSpecialPackage(int callingUid, @Nullable String packageName) {
+ final String resolvedPackage = AppOpsManager.resolvePackageName(callingUid, packageName);
+ return callingUid == Process.SYSTEM_UID
+ || resolveUid(resolvedPackage) != Process.INVALID_UID;
}
private boolean isCallerAndAttributionTrusted(@NonNull AttributionSource attributionSource) {
@@ -6672,7 +6711,9 @@ public class AppOpsService extends IAppOpsService.Stub {
}
}
verifyIncomingOp(code);
- verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
+ if (!isIncomingPackageValid(packageName, UserHandle.getUserId(uid))) {
+ return false;
+ }
final String resolvedPackageName = AppOpsManager.resolvePackageName(uid, packageName);
if (resolvedPackageName == null) {
@@ -7077,7 +7118,7 @@ public class AppOpsService extends IAppOpsService.Stub {
private static int resolveUid(String packageName) {
if (packageName == null) {
- return -1;
+ return Process.INVALID_UID;
}
switch (packageName) {
case "root":
@@ -7092,7 +7133,7 @@ public class AppOpsService extends IAppOpsService.Stub {
case "cameraserver":
return Process.CAMERASERVER_UID;
}
- return -1;
+ return Process.INVALID_UID;
}
private static String[] getPackagesForUid(int uid) {
diff --git a/services/core/java/com/android/server/attention/AttentionManagerService.java b/services/core/java/com/android/server/attention/AttentionManagerService.java
index 567d1aef3272..d16fe1240d0c 100644
--- a/services/core/java/com/android/server/attention/AttentionManagerService.java
+++ b/services/core/java/com/android/server/attention/AttentionManagerService.java
@@ -74,6 +74,8 @@ import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Objects;
import java.util.Set;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* An attention service implementation that runs in System Server process.
@@ -87,6 +89,9 @@ public class AttentionManagerService extends SystemService {
/** Service will unbind if connection is not used for that amount of time. */
private static final long CONNECTION_TTL_MILLIS = 60_000;
+ /** How long AttentionManagerService will wait for service binding after lazy binding. */
+ private static final long SERVICE_BINDING_WAIT_MILLIS = 1000;
+
/** DeviceConfig flag name, if {@code true}, enables AttentionManagerService features. */
@VisibleForTesting
static final String KEY_SERVICE_ENABLED = "service_enabled";
@@ -129,6 +134,7 @@ public class AttentionManagerService extends SystemService {
@GuardedBy("mLock")
private boolean mBinding;
private AttentionHandler mAttentionHandler;
+ private CountDownLatch mServiceBindingLatch;
@VisibleForTesting
ComponentName mComponentName;
@@ -161,6 +167,7 @@ public class AttentionManagerService extends SystemService {
mLock = lock;
mAttentionHandler = handler;
mPrivacyManager = SensorPrivacyManager.getInstance(context);
+ mServiceBindingLatch = new CountDownLatch(1);
}
@Override
@@ -275,13 +282,16 @@ public class AttentionManagerService extends SystemService {
}
synchronized (mLock) {
- final long now = SystemClock.uptimeMillis();
// schedule shutting down the connection if no one resets this timer
freeIfInactiveLocked();
// lazily start the service, which should be very lightweight to start
bindLocked();
-
+ }
+ final long now = SystemClock.uptimeMillis();
+ // Proceed when the service binding is complete.
+ awaitServiceBinding(Math.min(SERVICE_BINDING_WAIT_MILLIS, timeout));
+ synchronized (mLock) {
// throttle frequent requests
final AttentionCheckCache cache = mAttentionCheckCacheBuffer == null ? null
: mAttentionCheckCacheBuffer.getLast();
@@ -361,7 +371,10 @@ public class AttentionManagerService extends SystemService {
// lazily start the service, which should be very lightweight to start
bindLocked();
-
+ }
+ // Proceed when the service binding is complete.
+ awaitServiceBinding(SERVICE_BINDING_WAIT_MILLIS);
+ synchronized (mLock) {
/*
Prevent spamming with multiple requests, only one at a time is allowed.
If there are use-cases for keeping track of multiple requests, we
@@ -419,6 +432,14 @@ public class AttentionManagerService extends SystemService {
return context.getPackageManager().getAttentionServicePackageName();
}
+ private void awaitServiceBinding(long millis) {
+ try {
+ mServiceBindingLatch.await(millis, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.e(LOG_TAG, "Interrupted while waiting to bind Attention Service.", e);
+ }
+ }
+
/**
* Provides attention service component name at runtime, making sure it's provided by the
* system.
@@ -711,6 +732,7 @@ public class AttentionManagerService extends SystemService {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
init(IAttentionService.Stub.asInterface(service));
+ mServiceBindingLatch.countDown();
}
@Override
@@ -730,6 +752,7 @@ public class AttentionManagerService extends SystemService {
void cleanupService() {
init(null);
+ mServiceBindingLatch = new CountDownLatch(1);
}
private void init(@Nullable IAttentionService service) {
diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java
index 9067f2e25152..accdd5610921 100644
--- a/services/core/java/com/android/server/display/DisplayPowerController.java
+++ b/services/core/java/com/android/server/display/DisplayPowerController.java
@@ -63,6 +63,7 @@ import com.android.internal.display.BrightnessSynchronizer;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.util.RingBuffer;
import com.android.server.LocalServices;
import com.android.server.am.BatteryStatsService;
import com.android.server.display.RampAnimator.DualRampAnimator;
@@ -155,6 +156,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private static final int REPORTED_TO_POLICY_SCREEN_ON = 2;
private static final int REPORTED_TO_POLICY_SCREEN_TURNING_OFF = 3;
+ private static final int RINGBUFFER_MAX = 100;
+
private final String TAG;
private final Object mLock = new Object();
@@ -212,6 +215,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private final float mScreenBrightnessDefault;
+ // Previously logged screen brightness. Used for autobrightness event dumpsys.
+ private float mPreviousScreenBrightness = Float.NaN;
+
// The minimum allowed brightness while in VR.
private final float mScreenBrightnessForVrRangeMinimum;
@@ -387,6 +393,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
private final Runnable mOnBrightnessChangeRunnable;
+ // Used for keeping record in dumpsys for when and to which brightness auto adaptions were made.
+ private RingBuffer<AutobrightnessEvent> mAutobrightnessEventRingBuffer;
+
// A record of state for skipping brightness ramps.
private int mSkipRampState = RAMP_STATE_SKIP_NONE;
@@ -988,6 +997,9 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
mHbmController, mBrightnessThrottler, mIdleModeBrightnessMapper,
mDisplayDeviceConfig.getAmbientHorizonShort(),
mDisplayDeviceConfig.getAmbientHorizonLong());
+
+ mAutobrightnessEventRingBuffer =
+ new RingBuffer<>(AutobrightnessEvent.class, RINGBUFFER_MAX);
} else {
mUseSoftwareAutoBrightnessConfig = false;
}
@@ -1558,6 +1570,15 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
Slog.v(TAG, "Brightness [" + brightnessState + "] manual adjustment.");
}
+ // Add any automatic changes to autobrightness ringbuffer for dumpsys.
+ if (mBrightnessReason.reason == BrightnessReason.REASON_AUTOMATIC
+ && !BrightnessSynchronizer.floatEquals(
+ mPreviousScreenBrightness, brightnessState)) {
+ mPreviousScreenBrightness = brightnessState;
+ mAutobrightnessEventRingBuffer.append(new AutobrightnessEvent(
+ System.currentTimeMillis(), brightnessState));
+ }
+
// Update display white-balance.
if (mDisplayWhiteBalanceController != null) {
if (state == Display.STATE_ON && mDisplayWhiteBalanceSettings.isEnabled()) {
@@ -2491,6 +2512,7 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
if (mAutomaticBrightnessController != null) {
mAutomaticBrightnessController.dump(pw);
+ dumpAutobrightnessEvents(pw);
}
if (mHbmController != null) {
@@ -2547,6 +2569,20 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
+ private void dumpAutobrightnessEvents(PrintWriter pw) {
+ int size = mAutobrightnessEventRingBuffer.size();
+ if (size < 1) {
+ pw.println("No Automatic Brightness Adjustments");
+ return;
+ }
+
+ pw.println("Automatic Brightness Adjustments Last " + size + " Events: ");
+ AutobrightnessEvent[] eventArray = mAutobrightnessEventRingBuffer.toArray();
+ for (int i = 0; i < mAutobrightnessEventRingBuffer.size(); i++) {
+ pw.println(" " + eventArray[i].toString());
+ }
+ }
+
private static float clampAbsoluteBrightness(float value) {
return MathUtils.constrain(value, PowerManager.BRIGHTNESS_MIN,
PowerManager.BRIGHTNESS_MAX);
@@ -2615,6 +2651,21 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call
}
}
+ private static class AutobrightnessEvent {
+ final long mTime;
+ final float mBrightness;
+
+ AutobrightnessEvent(long time, float brightness) {
+ mTime = time;
+ mBrightness = brightness;
+ }
+
+ @Override
+ public String toString() {
+ return TimeUtils.formatForLogging(mTime) + " - Brightness: " + mBrightness;
+ }
+ }
+
private final class DisplayControllerHandler extends Handler {
public DisplayControllerHandler(Looper looper) {
super(looper, null, true /*async*/);
diff --git a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
index a9b2570a3dda..e09f7b09b4d1 100644
--- a/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
+++ b/services/core/java/com/android/server/notification/NotificationHistoryDatabase.java
@@ -40,11 +40,12 @@ import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
-import java.util.LinkedList;
+import java.util.List;
import java.util.Set;
/**
@@ -76,7 +77,7 @@ public class NotificationHistoryDatabase {
private final Handler mFileWriteHandler;
@VisibleForTesting
// List of files holding history information, sorted newest to oldest
- final LinkedList<AtomicFile> mHistoryFiles;
+ final List<AtomicFile> mHistoryFiles;
private final File mHistoryDir;
private final File mVersionFile;
// Current version of the database files schema
@@ -94,7 +95,7 @@ public class NotificationHistoryDatabase {
mFileWriteHandler = fileWriteHandler;
mVersionFile = new File(dir, "version");
mHistoryDir = new File(dir, "history");
- mHistoryFiles = new LinkedList<>();
+ mHistoryFiles = new ArrayList<>();
mBuffer = new NotificationHistory();
mWriteBufferRunnable = new WriteBufferRunnable();
@@ -133,7 +134,7 @@ public class NotificationHistoryDatabase {
safeParseLong(lhs.getName())));
for (File file : files) {
- mHistoryFiles.addLast(new AtomicFile(file));
+ mHistoryFiles.add(new AtomicFile(file));
}
}
@@ -411,7 +412,7 @@ public class NotificationHistoryDatabase {
+ file.getBaseFile().getAbsolutePath());
try {
writeLocked(file, mBuffer);
- mHistoryFiles.addFirst(file);
+ mHistoryFiles.add(0, file);
mBuffer = new NotificationHistory();
scheduleDeletion(file.getBaseFile(), time, HISTORY_RETENTION_DAYS);
diff --git a/services/core/java/com/android/server/pm/ApexManager.java b/services/core/java/com/android/server/pm/ApexManager.java
index 76d3d233d49a..ae7fedcd68de 100644
--- a/services/core/java/com/android/server/pm/ApexManager.java
+++ b/services/core/java/com/android/server/pm/ApexManager.java
@@ -119,16 +119,18 @@ public abstract class ApexManager {
@Nullable public final String apexModuleName;
public final File apexDirectory;
public final File preInstalledApexPath;
+ public final boolean isFactory;
private ActiveApexInfo(File apexDirectory, File preInstalledApexPath) {
- this(null, apexDirectory, preInstalledApexPath);
+ this(null, apexDirectory, preInstalledApexPath, true);
}
private ActiveApexInfo(@Nullable String apexModuleName, File apexDirectory,
- File preInstalledApexPath) {
+ File preInstalledApexPath, boolean isFactory) {
this.apexModuleName = apexModuleName;
this.apexDirectory = apexDirectory;
this.preInstalledApexPath = preInstalledApexPath;
+ this.isFactory = isFactory;
}
private ActiveApexInfo(ApexInfo apexInfo) {
@@ -136,7 +138,8 @@ public abstract class ApexManager {
apexInfo.moduleName,
new File(Environment.getApexDirectory() + File.separator
+ apexInfo.moduleName),
- new File(apexInfo.preinstalledModulePath));
+ new File(apexInfo.preinstalledModulePath),
+ apexInfo.isFactory);
}
}
diff --git a/services/core/java/com/android/server/pm/InitAppsHelper.java b/services/core/java/com/android/server/pm/InitAppsHelper.java
index 15f26e7a6d6c..a0aac2d64198 100644
--- a/services/core/java/com/android/server/pm/InitAppsHelper.java
+++ b/services/core/java/com/android/server/pm/InitAppsHelper.java
@@ -21,6 +21,7 @@ import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_DATA_APP_AVG_SCAN_TIME;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_DURATION__EVENT__OTA_PACKAGE_MANAGER_SYSTEM_APP_AVG_SCAN_TIME;
import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY;
import static com.android.server.pm.PackageManagerService.SCAN_AS_PRIVILEGED;
import static com.android.server.pm.PackageManagerService.SCAN_AS_SYSTEM;
import static com.android.server.pm.PackageManagerService.SCAN_BOOTING;
@@ -31,6 +32,7 @@ import static com.android.server.pm.PackageManagerService.SCAN_REQUIRE_KNOWN;
import static com.android.server.pm.PackageManagerService.SYSTEM_PARTITIONS;
import static com.android.server.pm.PackageManagerService.TAG;
import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_CHECK_MAX_SDK_VERSION;
+import static com.android.server.pm.pkg.parsing.ParsingPackageUtils.PARSE_FRAMEWORK_RES_SPLITS;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -167,7 +169,11 @@ final class InitAppsHelper {
sp.getFolder().getAbsolutePath())
|| apexInfo.preInstalledApexPath.getAbsolutePath().startsWith(
sp.getFolder().getAbsolutePath() + File.separator)) {
- return new ScanPartition(apexInfo.apexDirectory, sp, SCAN_AS_APK_IN_APEX);
+ int additionalScanFlag = SCAN_AS_APK_IN_APEX;
+ if (apexInfo.isFactory) {
+ additionalScanFlag |= SCAN_AS_FACTORY;
+ }
+ return new ScanPartition(apexInfo.apexDirectory, sp, additionalScanFlag);
}
}
return null;
@@ -317,8 +323,9 @@ final class InitAppsHelper {
packageParser, executorService);
}
- scanDirTracedLI(frameworkDir, null,
- mSystemParseFlags,
+ List<File> frameworkSplits = getFrameworkResApkSplitFiles();
+ scanDirTracedLI(frameworkDir, frameworkSplits,
+ mSystemParseFlags | PARSE_FRAMEWORK_RES_SPLITS,
mSystemScanFlags | SCAN_NO_DEX | SCAN_AS_PRIVILEGED,
packageParser, executorService);
if (!mPm.mPackages.containsKey("android")) {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 870a11ac2d61..b6c71ae24992 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -60,6 +60,7 @@ import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
import static com.android.server.pm.PackageManagerService.POST_INSTALL;
import static com.android.server.pm.PackageManagerService.PRECOMPILE_LAYOUTS;
import static com.android.server.pm.PackageManagerService.SCAN_AS_APK_IN_APEX;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_FACTORY;
import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP;
import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
import static com.android.server.pm.PackageManagerService.SCAN_AS_ODM;
@@ -315,6 +316,12 @@ final class InstallPackageHelper {
pkgSetting.setInstallSource(installSource);
}
+ if ((scanFlags & SCAN_AS_APK_IN_APEX) != 0) {
+ boolean isFactory = (scanFlags & SCAN_AS_FACTORY) != 0;
+ pkgSetting.getPkgState().setApkInApex(true);
+ pkgSetting.getPkgState().setApkInUpdatedApex(!isFactory);
+ }
+
// TODO(toddke): Consider a method specifically for modifying the Package object
// post scan; or, moving this stuff out of the Package object since it has nothing
// to do with the package on disk.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b1b05bedfcad..0746a970b911 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -377,6 +377,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
static final int SCAN_AS_ODM = 1 << 22;
static final int SCAN_AS_APK_IN_APEX = 1 << 23;
+ static final int SCAN_AS_FACTORY = 1 << 24;
@IntDef(flag = true, prefix = { "SCAN_" }, value = {
SCAN_NO_DEX,
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 2bae00f91b82..f84db1f7abbe 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -1227,6 +1227,11 @@ public class PackageSetting extends SettingBase implements PackageStateInternal
return pkgState.isUpdatedSystemApp();
}
+ @Override
+ public boolean isApkInUpdatedApex() {
+ return pkgState.isApkInUpdatedApex();
+ }
+
public PackageSetting setDomainSetId(@NonNull UUID domainSetId) {
mDomainSetId = domainSetId;
onChanged();
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index 8921fee6c8e0..3bd88d7ce349 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -341,7 +341,7 @@ class ShortcutPackage extends ShortcutPackageItem {
public void ensureAllShortcutsVisibleToLauncher(@NonNull List<ShortcutInfo> shortcuts) {
for (ShortcutInfo shortcut : shortcuts) {
- if (!shortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER)) {
+ if (shortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
throw new IllegalArgumentException("Shortcut ID=" + shortcut.getId()
+ " is hidden from launcher and may not be manipulated via APIs");
}
@@ -402,7 +402,7 @@ class ShortcutPackage extends ShortcutPackageItem {
& (ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_CACHED_ALL));
}
- if (!newShortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER)) {
+ if (newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
if (isAppSearchEnabled()) {
synchronized (mLock) {
mTransientShortcuts.put(newShortcut.getId(), newShortcut);
@@ -480,7 +480,7 @@ class ShortcutPackage extends ShortcutPackageItem {
& (ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_CACHED_ALL));
}
- if (!newShortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER)) {
+ if (newShortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER)) {
if (isAppSearchEnabled()) {
synchronized (mLock) {
mTransientShortcuts.put(newShortcut.getId(), newShortcut);
@@ -490,14 +490,18 @@ class ShortcutPackage extends ShortcutPackageItem {
forceReplaceShortcutInner(newShortcut);
}
if (isAppSearchEnabled()) {
- runAsSystem(() -> fromAppSearch().thenAccept(session ->
- session.reportUsage(new ReportUsageRequest.Builder(
- getPackageName(), newShortcut.getId()).build(), mExecutor, result -> {
- if (!result.isSuccess()) {
- Slog.e(TAG, "Failed to report usage via AppSearch. "
- + result.getErrorMessage());
- }
- })));
+ runAsSystem(() -> fromAppSearch().thenAccept(session -> {
+ if (!verifyIsUserUnlockingOrUnlocked()) {
+ return;
+ }
+ session.reportUsage(new ReportUsageRequest.Builder(
+ getPackageName(), newShortcut.getId()).build(), mExecutor, result -> {
+ if (!result.isSuccess()) {
+ Slog.e(TAG, "Failed to report usage via AppSearch. "
+ + result.getErrorMessage());
+ }
+ });
+ }));
}
return deleted;
}
@@ -2322,18 +2326,28 @@ class ShortcutPackage extends ShortcutPackageItem {
AppSearchShortcutInfo.SCHEMA_TYPE, true, pi);
}
final AndroidFuture<AppSearchSession> future = new AndroidFuture<>();
+ if (!verifyIsUserUnlockingOrUnlocked()) {
+ future.completeExceptionally(new RuntimeException(
+ "User " + mShortcutUser.getUserId() + " is locked"));
+ return future;
+ }
session.setSchema(
schemaBuilder.build(), mExecutor, mShortcutUser.mExecutor, result -> {
- if (!result.isSuccess()) {
- future.completeExceptionally(
- new IllegalArgumentException(result.getErrorMessage()));
- return;
- }
- future.complete(session);
- });
+ if (!result.isSuccess()) {
+ future.completeExceptionally(
+ new IllegalArgumentException(result.getErrorMessage()));
+ return;
+ }
+ future.complete(session);
+ });
return future;
}
+ private boolean verifyIsUserUnlockingOrUnlocked() {
+ return mShortcutUser.mService.mUserManagerInternal.isUserUnlockingOrUnlocked(
+ mShortcutUser.getUserId());
+ }
+
@NonNull
private SearchSpec getSearchSpec() {
return new SearchSpec.Builder()
@@ -2367,13 +2381,17 @@ class ShortcutPackage extends ShortcutPackageItem {
if (!isAppSearchEnabled()) {
return;
}
- runAsSystem(() -> fromAppSearch().thenAccept(session ->
- session.remove("", getSearchSpec(), mShortcutUser.mExecutor, result -> {
- if (!result.isSuccess()) {
- Slog.e(TAG, "Failed to remove shortcuts from AppSearch. "
- + result.getErrorMessage());
- }
- })));
+ runAsSystem(() -> fromAppSearch().thenAccept(session -> {
+ if (!verifyIsUserUnlockingOrUnlocked()) {
+ return;
+ }
+ session.remove("", getSearchSpec(), mShortcutUser.mExecutor, result -> {
+ if (!result.isSuccess()) {
+ Slog.e(TAG, "Failed to remove shortcuts from AppSearch. "
+ + result.getErrorMessage());
+ }
+ });
+ }));
}
void getShortcutByIdsAsync(@NonNull final Set<String> ids,
@@ -2383,6 +2401,9 @@ class ShortcutPackage extends ShortcutPackageItem {
return;
}
runAsSystem(() -> fromAppSearch().thenAccept(session -> {
+ if (!verifyIsUserUnlockingOrUnlocked()) {
+ return;
+ }
session.getByDocumentId(new GetByDocumentIdRequest.Builder(getPackageName())
.addIds(ids).build(), mShortcutUser.mExecutor, result -> {
final List<ShortcutInfo> ret = result.getSuccesses().values()
@@ -2404,19 +2425,23 @@ class ShortcutPackage extends ShortcutPackageItem {
if (!isAppSearchEnabled()) {
return;
}
- runAsSystem(() -> fromAppSearch().thenAccept(session ->
- session.remove(
- new RemoveByDocumentIdRequest.Builder(getPackageName()).addIds(ids).build(),
- mShortcutUser.mExecutor, result -> {
- if (!result.isSuccess()) {
- final Map<String, AppSearchResult<Void>> failures =
- result.getFailures();
- for (String key : failures.keySet()) {
- Slog.e(TAG, "Failed deleting " + key + ", error message:"
- + failures.get(key).getErrorMessage());
- }
+ runAsSystem(() -> fromAppSearch().thenAccept(session -> {
+ if (!verifyIsUserUnlockingOrUnlocked()) {
+ return;
+ }
+ session.remove(
+ new RemoveByDocumentIdRequest.Builder(getPackageName()).addIds(ids).build(),
+ mShortcutUser.mExecutor, result -> {
+ if (!result.isSuccess()) {
+ final Map<String, AppSearchResult<Void>> failures =
+ result.getFailures();
+ for (String key : failures.keySet()) {
+ Slog.e(TAG, "Failed deleting " + key + ", error message:"
+ + failures.get(key).getErrorMessage());
}
- })));
+ }
+ });
+ }));
}
void persistsAllShortcutsAsync() {
@@ -2444,7 +2469,7 @@ class ShortcutPackage extends ShortcutPackageItem {
.map(ShortcutInfo::getId).collect(Collectors.joining(",", "[", "]")));
}
runAsSystem(() -> fromAppSearch().thenAccept(session -> {
- if (shortcuts.isEmpty()) {
+ if (shortcuts.isEmpty() || !verifyIsUserUnlockingOrUnlocked()) {
return;
}
session.put(new PutDocumentsRequest.Builder()
@@ -2468,6 +2493,11 @@ class ShortcutPackage extends ShortcutPackageItem {
cb.complete(null);
}
runAsSystem(() -> fromAppSearch().thenAccept(session -> {
+ if (!verifyIsUserUnlockingOrUnlocked()) {
+ cb.completeExceptionally(new IllegalStateException(
+ "User " + mShortcutUser.getUserId() + " is locked."));
+ return;
+ }
SearchResults res = session.search("", getSearchSpec());
res.getNextPage(mShortcutUser.mExecutor, results -> {
if (!results.isSuccess()) {
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 25fe0007ec4b..9ca4f247891d 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -2228,7 +2228,7 @@ public class ShortcutService extends IShortcutService.Stub {
Objects.requireNonNull(shortcut);
Preconditions.checkArgument(shortcut.isEnabled(), "Shortcut must be enabled");
Preconditions.checkArgument(
- shortcut.isIncludedIn(ShortcutInfo.SURFACE_LAUNCHER),
+ !shortcut.isExcludedFromSurfaces(ShortcutInfo.SURFACE_LAUNCHER),
"Shortcut excluded from launcher cannot be pinned");
ret.complete(String.valueOf(requestPinItem(
packageName, userId, shortcut, null, null, resultIntent)));
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 5a05134bed81..5d6ebec6cc30 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -277,10 +277,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
private boolean checkAutoRevokeAccess(AndroidPackage pkg, int callingUid) {
- if (pkg == null) {
- return false;
- }
-
final boolean isCallerPrivileged = mContext.checkCallingOrSelfPermission(
Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS)
== PackageManager.PERMISSION_GRANTED;
@@ -292,6 +288,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
+ Manifest.permission.WHITELIST_AUTO_REVOKE_PERMISSIONS
+ " or be the installer on record");
}
+
+ if (pkg == null || mPackageManagerInt.filterAppAccess(pkg, callingUid,
+ UserHandle.getUserId(callingUid))) {
+ return false;
+ }
+
return true;
}
@@ -301,9 +303,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
final int callingUid = Binder.getCallingUid();
- if (mPackageManagerInt.filterAppAccess(packageName, callingUid, userId)) {
- return false;
- }
if (!checkAutoRevokeAccess(pkg, callingUid)) {
return false;
diff --git a/services/core/java/com/android/server/pm/pkg/PackageState.java b/services/core/java/com/android/server/pm/pkg/PackageState.java
index 7726d7fc226b..b5e0e4416fe4 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -303,6 +303,11 @@ public interface PackageState {
boolean isUpdatedSystemApp();
/**
+ * Whether this app is packaged in an updated apex.
+ */
+ boolean isApkInUpdatedApex();
+
+ /**
* @see AndroidPackageApi#isVendor()
*/
boolean isVendor();
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
index 3170304985b5..878a837585ca 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
@@ -71,6 +71,7 @@ public class PackageStateImpl implements PackageState {
INSTALL_PERMISSIONS_FIXED,
UPDATE_AVAILABLE,
UPDATED_SYSTEM_APP,
+ APK_IN_UPDATED_APEX,
})
public @interface Flags {
}
@@ -89,6 +90,7 @@ public class PackageStateImpl implements PackageState {
private static final int INSTALL_PERMISSIONS_FIXED = 1 << 11;
private static final int UPDATE_AVAILABLE = 1 << 12;
private static final int UPDATED_SYSTEM_APP = 1 << 13;
+ private static final int APK_IN_UPDATED_APEX = 1 << 14;
}
private int mBooleans;
@@ -187,6 +189,7 @@ public class PackageStateImpl implements PackageState {
setBoolean(Booleans.UPDATE_AVAILABLE, pkgState.isUpdateAvailable());
mLastPackageUsageTime = pkgState.getLastPackageUsageTime();
setBoolean(Booleans.UPDATED_SYSTEM_APP, pkgState.isUpdatedSystemApp());
+ setBoolean(Booleans.APK_IN_UPDATED_APEX, pkgState.isApkInUpdatedApex());
mSigningInfo = pkgState.getSigningInfo();
SparseArray<? extends PackageUserState> userStates = pkgState.getUserStates();
@@ -264,6 +267,11 @@ public class PackageStateImpl implements PackageState {
}
@Override
+ public boolean isApkInUpdatedApex() {
+ return getBoolean(Booleans.APK_IN_UPDATED_APEX);
+ }
+
+ @Override
public boolean isVendor() {
return getBoolean(Booleans.VENDOR);
}
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
index 7bd720acc799..fad2f857f656 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
@@ -52,6 +52,8 @@ public class PackageStateUnserialized {
private List<String> usesLibraryFiles = emptyList();
private boolean updatedSystemApp;
+ private boolean apkInApex;
+ private boolean apkInUpdatedApex;
@NonNull
private volatile long[] lastPackageUsageTimeInMills;
@@ -116,6 +118,8 @@ public class PackageStateUnserialized {
}
this.updatedSystemApp = other.updatedSystemApp;
+ this.apkInApex = other.apkInApex;
+ this.apkInUpdatedApex = other.apkInUpdatedApex;
this.lastPackageUsageTimeInMills = other.lastPackageUsageTimeInMills;
this.overrideSeInfo = other.overrideSeInfo;
mPackageSetting.onChanged();
@@ -150,6 +154,18 @@ public class PackageStateUnserialized {
return this;
}
+ public PackageStateUnserialized setApkInApex(boolean value) {
+ apkInApex = value;
+ mPackageSetting.onChanged();
+ return this;
+ }
+
+ public PackageStateUnserialized setApkInUpdatedApex(boolean value) {
+ apkInUpdatedApex = value;
+ mPackageSetting.onChanged();
+ return this;
+ }
+
public PackageStateUnserialized setLastPackageUsageTimeInMills(@NonNull long... value) {
lastPackageUsageTimeInMills = value;
mPackageSetting.onChanged();
@@ -198,6 +214,16 @@ public class PackageStateUnserialized {
}
@DataClass.Generated.Member
+ public boolean isApkInApex() {
+ return apkInApex;
+ }
+
+ @DataClass.Generated.Member
+ public boolean isApkInUpdatedApex() {
+ return apkInUpdatedApex;
+ }
+
+ @DataClass.Generated.Member
public @NonNull long[] getLastPackageUsageTimeInMills() {
long[] _lastPackageUsageTimeInMills = lastPackageUsageTimeInMills;
if (_lastPackageUsageTimeInMills == null) {
@@ -222,10 +248,10 @@ public class PackageStateUnserialized {
}
@DataClass.Generated(
- time = 1642554781099L,
+ time = 1646203523807L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java",
- inputSignatures = "private boolean hiddenUntilInstalled\nprivate @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> usesLibraryInfos\nprivate @android.annotation.NonNull java.util.List<java.lang.String> usesLibraryFiles\nprivate boolean updatedSystemApp\nprivate volatile @android.annotation.NonNull long[] lastPackageUsageTimeInMills\nprivate @android.annotation.Nullable java.lang.String overrideSeInfo\nprivate @android.annotation.NonNull com.android.server.pm.PackageSetting mPackageSetting\nprivate long[] lazyInitLastPackageUsageTimeInMills()\npublic com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(int,long)\npublic long getLatestPackageUseTimeInMills()\npublic long getLatestForegroundPackageUseTimeInMills()\npublic void updateFrom(com.android.server.pm.pkg.PackageStateUnserialized)\npublic @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> getNonNativeUsesLibraryInfos()\npublic com.android.server.pm.pkg.PackageStateUnserialized setHiddenUntilInstalled(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryInfos(java.util.List<android.content.pm.SharedLibraryInfo>)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryFiles(java.util.List<java.lang.String>)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUpdatedSystemApp(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(long)\npublic com.android.server.pm.pkg.PackageStateUnserialized setOverrideSeInfo(java.lang.String)\nclass PackageStateUnserialized extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genConstructor=false, genBuilder=false)")
+ inputSignatures = "private boolean hiddenUntilInstalled\nprivate @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> usesLibraryInfos\nprivate @android.annotation.NonNull java.util.List<java.lang.String> usesLibraryFiles\nprivate boolean updatedSystemApp\nprivate boolean apkInApex\nprivate boolean apkInUpdatedApex\nprivate volatile @android.annotation.NonNull long[] lastPackageUsageTimeInMills\nprivate @android.annotation.Nullable java.lang.String overrideSeInfo\nprivate final @android.annotation.NonNull com.android.server.pm.PackageSetting mPackageSetting\nprivate long[] lazyInitLastPackageUsageTimeInMills()\npublic com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(int,long)\npublic long getLatestPackageUseTimeInMills()\npublic long getLatestForegroundPackageUseTimeInMills()\npublic void updateFrom(com.android.server.pm.pkg.PackageStateUnserialized)\npublic @android.annotation.NonNull java.util.List<android.content.pm.SharedLibraryInfo> getNonNativeUsesLibraryInfos()\npublic com.android.server.pm.pkg.PackageStateUnserialized setHiddenUntilInstalled(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryInfos(java.util.List<android.content.pm.SharedLibraryInfo>)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUsesLibraryFiles(java.util.List<java.lang.String>)\npublic com.android.server.pm.pkg.PackageStateUnserialized setUpdatedSystemApp(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setApkInApex(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setApkInUpdatedApex(boolean)\npublic com.android.server.pm.pkg.PackageStateUnserialized setLastPackageUsageTimeInMills(long)\npublic com.android.server.pm.pkg.PackageStateUnserialized setOverrideSeInfo(java.lang.String)\nclass PackageStateUnserialized extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genSetters=true, genConstructor=false, genBuilder=false)")
@Deprecated
private void __metadata() {}
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index 048f8d6a04fa..1a816220670a 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -522,9 +522,6 @@ public final class PowerManagerService extends SystemService
// The screen off timeout setting value in milliseconds.
private long mScreenOffTimeoutSetting;
- // The screen off timeout setting value in milliseconds to apply while device is docked.
- private long mScreenOffTimeoutDockedSetting;
-
// Default for attentive warning duration.
private long mAttentiveWarningDurationConfig;
@@ -1281,9 +1278,6 @@ public final class PowerManagerService extends SystemService
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.System.getUriFor(
- Settings.System.SCREEN_OFF_TIMEOUT_DOCKED),
- false, mSettingsObserver, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.SLEEP_TIMEOUT),
false, mSettingsObserver, UserHandle.USER_ALL);
@@ -1406,9 +1400,6 @@ public final class PowerManagerService extends SystemService
mScreenOffTimeoutSetting = Settings.System.getIntForUser(resolver,
Settings.System.SCREEN_OFF_TIMEOUT, DEFAULT_SCREEN_OFF_TIMEOUT,
UserHandle.USER_CURRENT);
- mScreenOffTimeoutDockedSetting = Settings.System.getLongForUser(resolver,
- Settings.System.SCREEN_OFF_TIMEOUT_DOCKED, mScreenOffTimeoutSetting,
- UserHandle.USER_CURRENT);
mSleepTimeoutSetting = Settings.Secure.getIntForUser(resolver,
Settings.Secure.SLEEP_TIMEOUT, DEFAULT_SLEEP_TIMEOUT,
UserHandle.USER_CURRENT);
@@ -1972,7 +1963,7 @@ public final class PowerManagerService extends SystemService
private boolean dozePowerGroupLocked(final PowerGroup powerGroup, long eventTime,
int reason, int uid) {
if (DEBUG_SPEW) {
- Slog.d(TAG, "sleepDisplayGroupNoUpdateLocked: eventTime=" + eventTime
+ Slog.d(TAG, "dozePowerGroup: eventTime=" + eventTime
+ ", groupId=" + powerGroup.getGroupId() + ", reason=" + reason
+ ", uid=" + uid);
}
@@ -2931,9 +2922,7 @@ public final class PowerManagerService extends SystemService
@GuardedBy("mLock")
private long getScreenOffTimeoutLocked(long sleepTimeout, long attentiveTimeout) {
- long timeout = mDockState == Intent.EXTRA_DOCK_STATE_UNDOCKED
- ? mScreenOffTimeoutSetting
- : mScreenOffTimeoutDockedSetting;
+ long timeout = mScreenOffTimeoutSetting;
if (isMaximumScreenOffTimeoutFromDeviceAdminEnforcedLocked()) {
timeout = Math.min(timeout, mMaximumScreenOffTimeoutFromDeviceAdmin);
}
@@ -3101,7 +3090,7 @@ public final class PowerManagerService extends SystemService
Message msg = mHandler.obtainMessage(MSG_SANDMAN);
msg.arg1 = powerGroup.getGroupId();
msg.setAsynchronous(true);
- mHandler.sendMessage(msg);
+ mHandler.sendMessageAtTime(msg, mClock.uptimeMillis());
}
}
}
@@ -4878,8 +4867,7 @@ public final class PowerManagerService extends SystemService
}
}
- @VisibleForTesting
- final class DockReceiver extends BroadcastReceiver {
+ private final class DockReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index e3dcfd0c89c0..3f339aa5e135 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -404,7 +404,7 @@ public class SliceManagerService extends ISliceManager.Stub {
String providerName = getUriWithoutUserId(uri).getAuthority();
ProviderInfo provider = mContext.getPackageManager().resolveContentProviderAsUser(
providerName, 0, getUserIdFromUri(uri, user));
- return provider.packageName;
+ return provider == null ? null : provider.packageName;
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -629,7 +629,7 @@ public class SliceManagerService extends ISliceManager.Stub {
.scheme(ContentResolver.SCHEME_CONTENT)
.authority(authority)
.build(), 0);
- return mPermissions.getAllPackagesGranted(pkg);
+ return pkg == null ? new String[0] : mPermissions.getAllPackagesGranted(pkg);
}
/**
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 7f84f61a91ff..3b8677d70be2 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -68,6 +68,7 @@ import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_METRICS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
import static com.android.server.wm.EventLogTags.WM_ACTIVITY_LAUNCH_TIME;
@@ -102,6 +103,7 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.FrameworkStatsLog;
+import com.android.internal.util.LatencyTracker;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import com.android.server.LocalServices;
@@ -771,6 +773,12 @@ class ActivityMetricsLogger {
info.mReason = activityToReason.valueAt(index);
info.mLoggedTransitionStarting = true;
if (info.mIsDrawn) {
+ if (info.mReason == APP_TRANSITION_RECENTS_ANIM) {
+ final LatencyTracker latencyTracker = r.mWmService.mLatencyTracker;
+ final int duration = info.mSourceEventDelayMs + info.mCurrentTransitionDelayMs;
+ mLoggerHandler.post(() -> latencyTracker.logAction(
+ LatencyTracker.ACTION_START_RECENTS_ANIMATION, duration));
+ }
done(false /* abort */, info, "notifyTransitionStarting drawn", timestampNs);
}
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 21ca4bb6038b..2d15e1529b9b 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -52,6 +52,7 @@ import static android.window.TransitionInfo.FLAG_SHOW_WALLPAPER;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
import static android.window.TransitionInfo.FLAG_TRANSLUCENT;
+import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_RECENTS_ANIM;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_SPLASH_SCREEN;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_WINDOWS_DRAWN;
@@ -650,8 +651,6 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
handleNonAppWindowsInTransition(dc, mType, mFlags);
- reportStartReasonsToLogger();
-
// The callback is only populated for custom activity-level client animations
sendRemoteCallback(mClientAnimationStartCallback);
@@ -740,6 +739,8 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
}
mSyncId = -1;
mOverrideOptions = null;
+
+ reportStartReasonsToLogger();
}
/**
@@ -952,11 +953,15 @@ class Transition extends Binder implements BLASTSyncEngine.TransactionReadyListe
for (int i = mParticipants.size() - 1; i >= 0; --i) {
ActivityRecord r = mParticipants.valueAt(i).asActivityRecord();
if (r == null || !r.mVisibleRequested) continue;
+ int transitionReason = APP_TRANSITION_WINDOWS_DRAWN;
// At this point, r is "ready", but if it's not "ALL ready" then it is probably only
// ready due to starting-window.
- reasons.put(r, (r.mStartingData instanceof SplashScreenStartingData
- && !r.mLastAllReadyAtSync)
- ? APP_TRANSITION_SPLASH_SCREEN : APP_TRANSITION_WINDOWS_DRAWN);
+ if (r.mStartingData instanceof SplashScreenStartingData && !r.mLastAllReadyAtSync) {
+ transitionReason = APP_TRANSITION_SPLASH_SCREEN;
+ } else if (r.isActivityTypeHomeOrRecents() && isTransientLaunch(r)) {
+ transitionReason = APP_TRANSITION_RECENTS_ANIM;
+ }
+ reasons.put(r, transitionReason);
}
mController.mAtm.mTaskSupervisor.getActivityMetricsLogger().notifyTransitionStarting(
reasons);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index 850fdee0c733..630ca91a7acf 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -7233,7 +7233,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
return;
}
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.SEND_LOST_MODE_LOCATION_UPDATES));
+ hasCallingOrSelfPermission(permission.TRIGGER_LOST_MODE));
synchronized (getLockObject()) {
final ActiveAdmin admin = getDeviceOwnerOrProfileOwnerOfOrganizationOwnedDeviceLocked(
diff --git a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
index a2e813aed720..82334f29099d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -59,6 +59,7 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.dx.mockito.inline.extended.StaticMockitoSession;
import com.android.server.LocalServices;
import com.android.server.pm.parsing.pkg.AndroidPackage;
+import com.android.server.pm.pkg.PackageStateInternal;
import org.junit.After;
import org.junit.Before;
@@ -136,14 +137,17 @@ public class AppOpsServiceTest {
.spyStatic(Settings.Global.class)
.startMocking();
- // Mock LocalServices.getService(PackageManagerInternal.class).getPackage dependency
- // needed by AppOpsService
+ // Mock LocalServices.getService(PackageManagerInternal.class).getPackageStateInternal
+ // and getPackage dependency needed by AppOpsService
PackageManagerInternal mockPackageManagerInternal = mock(PackageManagerInternal.class);
+ PackageStateInternal mockMyPSInternal = mock(PackageStateInternal.class);
AndroidPackage mockMyPkg = mock(AndroidPackage.class);
when(mockMyPkg.isPrivileged()).thenReturn(false);
when(mockMyPkg.getUid()).thenReturn(mMyUid);
when(mockMyPkg.getAttributions()).thenReturn(Collections.emptyList());
+ when(mockPackageManagerInternal.getPackageStateInternal(sMyPackageName))
+ .thenReturn(mockMyPSInternal);
when(mockPackageManagerInternal.getPackage(sMyPackageName)).thenReturn(mockMyPkg);
doReturn(mockPackageManagerInternal).when(
() -> LocalServices.getService(PackageManagerInternal.class));
diff --git a/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java b/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java
new file mode 100644
index 000000000000..049c745fc128
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/backup/restore/FullRestoreEngineTest.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.backup.restore;
+
+import static com.google.common.truth.Truth.assertWithMessage;
+
+import android.app.backup.BackupAgent;
+import android.platform.test.annotations.Presubmit;
+import android.system.OsConstants;
+
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.server.backup.FileMetadata;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@RunWith(AndroidJUnit4.class)
+public class FullRestoreEngineTest {
+ private static final String DEFAULT_PACKAGE_NAME = "package";
+ private static final String DEFAULT_DOMAIN_NAME = "domain";
+ private static final String NEW_PACKAGE_NAME = "new_package";
+ private static final String NEW_DOMAIN_NAME = "new_domain";
+
+ private FullRestoreEngine mRestoreEngine;
+
+ @Before
+ public void setUp() {
+ mRestoreEngine = new FullRestoreEngine();
+ }
+
+ @Test
+ public void shouldSkipReadOnlyDir_skipsAllReadonlyDirsAndTheirChildren() {
+ // Create the file tree.
+ TestFile[] testFiles = new TestFile[] {
+ TestFile.dir("root"),
+ TestFile.file("root/auth_token"),
+ TestFile.dir("root/media"),
+ TestFile.file("root/media/picture1.png"),
+ TestFile.file("root/push_token.txt"),
+ TestFile.dir("root/read-only-dir-1").markReadOnly().expectSkipped(),
+ TestFile.dir("root/read-only-dir-1/writable-subdir").expectSkipped(),
+ TestFile.file("root/read-only-dir-1/writable-subdir/writable-file").expectSkipped(),
+ TestFile.dir("root/read-only-dir-1/writable-subdir/read-only-subdir-2")
+ .markReadOnly().expectSkipped(),
+ TestFile.file("root/read-only-dir-1/writable-file").expectSkipped(),
+ TestFile.file("root/random-stuff.txt"),
+ TestFile.dir("root/database"),
+ TestFile.file("root/database/users.db"),
+ TestFile.dir("root/read-only-dir-2").markReadOnly().expectSkipped(),
+ TestFile.file("root/read-only-dir-2/writable-file-1").expectSkipped(),
+ TestFile.file("root/read-only-dir-2/writable-file-2").expectSkipped(),
+ };
+
+ assertCorrectItemsAreSkipped(testFiles);
+ }
+
+ @Test
+ public void shouldSkipReadOnlyDir_onlySkipsChildrenUnderTheSamePackage() {
+ TestFile[] testFiles = new TestFile[]{
+ TestFile.dir("read-only-dir").markReadOnly().expectSkipped(),
+ TestFile.file("read-only-dir/file").expectSkipped(),
+ TestFile.file("read-only-dir/file-from-different-package")
+ .setPackage(NEW_PACKAGE_NAME),
+ };
+
+ assertCorrectItemsAreSkipped(testFiles);
+ }
+
+ @Test
+ public void shouldSkipReadOnlyDir_onlySkipsChildrenUnderTheSameDomain() {
+ TestFile[] testFiles = new TestFile[]{
+ TestFile.dir("read-only-dir").markReadOnly().expectSkipped(),
+ TestFile.file("read-only-dir/file").expectSkipped(),
+ TestFile.file("read-only-dir/file-from-different-domain")
+ .setDomain(NEW_DOMAIN_NAME),
+ };
+
+ assertCorrectItemsAreSkipped(testFiles);
+ }
+
+ private void assertCorrectItemsAreSkipped(TestFile[] testFiles) {
+ // Verify all directories marked with .expectSkipped are skipped.
+ for (TestFile testFile : testFiles) {
+ boolean actualExcluded = mRestoreEngine.shouldSkipReadOnlyDir(testFile.mMetadata);
+ boolean expectedExcluded = testFile.mShouldSkip;
+ assertWithMessage(testFile.mMetadata.path).that(actualExcluded).isEqualTo(
+ expectedExcluded);
+ }
+ }
+
+ private static class TestFile {
+ private final FileMetadata mMetadata;
+ private boolean mShouldSkip;
+
+ static TestFile dir(String path) {
+ return new TestFile(path, BackupAgent.TYPE_DIRECTORY);
+ }
+
+ static TestFile file(String path) {
+ return new TestFile(path, BackupAgent.TYPE_FILE);
+ }
+
+ TestFile markReadOnly() {
+ mMetadata.mode = 0;
+ return this;
+ }
+
+ TestFile expectSkipped() {
+ mShouldSkip = true;
+ return this;
+ }
+
+ TestFile setPackage(String packageName) {
+ mMetadata.packageName = packageName;
+ return this;
+ }
+
+ TestFile setDomain(String domain) {
+ mMetadata.domain = domain;
+ return this;
+ }
+
+ private TestFile(String path, int type) {
+ FileMetadata metadata = new FileMetadata();
+ metadata.path = path;
+ metadata.type = type;
+ metadata.packageName = DEFAULT_PACKAGE_NAME;
+ metadata.domain = DEFAULT_DOMAIN_NAME;
+ metadata.mode = OsConstants.S_IWUSR; // Mark as writable.
+ mMetadata = metadata;
+ }
+ }
+}
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 8438afcfe5e4..663496a5536d 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -8453,7 +8453,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
@Test
public void testSendLostModeLocationUpdate_notOrganizationOwnedDevice() {
- mContext.callerPermissions.add(permission.SEND_LOST_MODE_LOCATION_UPDATES);
+ mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE);
assertThrows(IllegalStateException.class, () -> dpm.sendLostModeLocationUpdate(
getServices().executor, /* empty callback */ result -> {}));
}
@@ -8461,7 +8461,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
@Test
public void testSendLostModeLocationUpdate_asDeviceOwner() throws Exception {
final String TEST_PROVIDER = "network";
- mContext.callerPermissions.add(permission.SEND_LOST_MODE_LOCATION_UPDATES);
+ mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE);
setDeviceOwner();
when(getServices().locationManager.getAllProviders()).thenReturn(List.of(TEST_PROVIDER));
when(getServices().locationManager.isProviderEnabled(TEST_PROVIDER)).thenReturn(true);
@@ -8478,7 +8478,7 @@ public class DevicePolicyManagerTest extends DpmTestBase {
final int MANAGED_PROFILE_ADMIN_UID =
UserHandle.getUid(CALLER_USER_HANDLE, DpmMockContext.SYSTEM_UID);
mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID;
- mContext.callerPermissions.add(permission.SEND_LOST_MODE_LOCATION_UPDATES);
+ mContext.callerPermissions.add(permission.TRIGGER_LOST_MODE);
addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1);
configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
when(getServices().locationManager.getAllProviders()).thenReturn(List.of(TEST_PROVIDER));
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index fe3034dc569d..ce7b367ec7ec 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -243,6 +243,7 @@ public final class DeviceStateManagerServiceTest {
assertEquals(info.currentState, DEFAULT_DEVICE_STATE.getIdentifier());
}
+ @FlakyTest(bugId = 223153452)
@Test
public void registerCallback() throws RemoteException {
TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
diff --git a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
index b2f506a5b1f9..0b2ebbc69cb7 100644
--- a/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/power/PowerManagerServiceTest.java
@@ -87,7 +87,6 @@ import com.android.server.lights.LightsManager;
import com.android.server.policy.WindowManagerPolicy;
import com.android.server.power.PowerManagerService.BatteryReceiver;
import com.android.server.power.PowerManagerService.BinderService;
-import com.android.server.power.PowerManagerService.DockReceiver;
import com.android.server.power.PowerManagerService.Injector;
import com.android.server.power.PowerManagerService.NativeWrapper;
import com.android.server.power.PowerManagerService.UserSwitchedReceiver;
@@ -151,7 +150,6 @@ public class PowerManagerServiceTest {
private Resources mResourcesSpy;
private OffsettableClock mClock;
private TestLooper mTestLooper;
- private DockReceiver mDockReceiver;
private static class IntentFilterMatcher implements ArgumentMatcher<IntentFilter> {
private final IntentFilter mFilter;
@@ -210,6 +208,8 @@ public class PowerManagerServiceTest {
Settings.Global.putInt(mContextSpy.getContentResolver(),
Settings.Global.STAY_ON_WHILE_PLUGGED_IN, 0);
+ Settings.Secure.putInt(mContextSpy.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 0);
mClock = new OffsettableClock.Stopped();
mTestLooper = new TestLooper(mClock::now);
@@ -336,14 +336,6 @@ public class PowerManagerServiceTest {
argThat(new IntentFilterMatcher(usFilter)), isNull(), isA(Handler.class));
mUserSwitchedReceiver = userSwitchedCaptor.getValue();
- // Grab the DockReceiver
- ArgumentCaptor<DockReceiver> dockReceiverCaptor =
- ArgumentCaptor.forClass(DockReceiver.class);
- IntentFilter dockFilter = new IntentFilter(Intent.ACTION_DOCK_EVENT);
- verify(mContextSpy).registerReceiver(dockReceiverCaptor.capture(),
- argThat(new IntentFilterMatcher(dockFilter)), isNull(), isA(Handler.class));
- mDockReceiver = dockReceiverCaptor.getValue();
-
mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
}
@@ -392,16 +384,6 @@ public class PowerManagerServiceTest {
.thenReturn(minimumScreenOffTimeoutConfigMillis);
}
- private void setScreenOffTimeout(int screenOffTimeoutMillis) {
- Settings.System.putInt(mContextSpy.getContentResolver(), Settings.System.SCREEN_OFF_TIMEOUT,
- screenOffTimeoutMillis);
- }
-
- private void setScreenOffTimeoutDocked(int screenOffTimeoutMillis) {
- Settings.System.putInt(mContextSpy.getContentResolver(),
- Settings.System.SCREEN_OFF_TIMEOUT_DOCKED, screenOffTimeoutMillis);
- }
-
private void advanceTime(long timeMs) {
mClock.fastForward(timeMs);
mTestLooper.dispatchAll();
@@ -709,6 +691,48 @@ public class PowerManagerServiceTest {
assertThat(mService.getBinderServiceInstance().forceSuspend()).isFalse();
}
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testScreensaverActivateOnSleepDisabled_powered_afterTimeout_goesToDozing() {
+ when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(true);
+
+ doAnswer(inv -> {
+ when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
+ return null;
+ }).when(mDreamManagerInternalMock).startDream(anyBoolean());
+
+ setMinimumScreenOffTimeoutConfig(5);
+ createService();
+ startSystem();
+
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ advanceTime(15000);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DOZING);
+ }
+
+ @SuppressWarnings("GuardedBy")
+ @Test
+ public void testScreensaverActivateOnSleepEnabled_powered_afterTimeout_goesToDreaming() {
+ when(mBatteryManagerInternalMock.isPowered(anyInt())).thenReturn(true);
+ Settings.Secure.putInt(mContextSpy.getContentResolver(),
+ Settings.Secure.SCREENSAVER_ACTIVATE_ON_SLEEP, 1);
+
+ doAnswer(inv -> {
+ when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
+ return null;
+ }).when(mDreamManagerInternalMock).startDream(anyBoolean());
+
+ setMinimumScreenOffTimeoutConfig(5);
+ createService();
+ startSystem();
+
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
+
+ advanceTime(15000);
+ assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_DREAMING);
+ }
+
@Test
public void testSetDozeOverrideFromDreamManager_triggersSuspendBlocker() {
final String suspendBlockerName = "PowerManagerService.Display";
@@ -887,71 +911,6 @@ public class PowerManagerServiceTest {
}
@Test
- public void testScreenOffTimeout_goesToSleepAfterTimeout() {
- final DisplayInfo info = new DisplayInfo();
- info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
- when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
-
- setMinimumScreenOffTimeoutConfig(10);
- setScreenOffTimeout(10);
-
- createService();
- startSystem();
-
- mService.getBinderServiceInstance().userActivity(Display.DEFAULT_DISPLAY, mClock.now(),
- PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
- assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
- advanceTime(15);
- assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_AWAKE);
- }
-
- @Test
- public void testScreenOffTimeout_usesRegularTimeoutWhenNotDocked() {
- final DisplayInfo info = new DisplayInfo();
- info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
- when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
-
- setMinimumScreenOffTimeoutConfig(10);
- setScreenOffTimeout(10);
- setScreenOffTimeoutDocked(30);
-
- createService();
- startSystem();
-
- mService.getBinderServiceInstance().userActivity(Display.DEFAULT_DISPLAY, mClock.now(),
- PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
- assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
- advanceTime(15);
- assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_AWAKE);
- }
-
- @Test
- public void testScreenOffTimeout_usesDockedTimeoutWhenDocked() {
- final DisplayInfo info = new DisplayInfo();
- info.displayGroupId = Display.DEFAULT_DISPLAY_GROUP;
- when(mDisplayManagerInternalMock.getDisplayInfo(Display.DEFAULT_DISPLAY)).thenReturn(info);
-
- setMinimumScreenOffTimeoutConfig(10);
- setScreenOffTimeout(10);
- setScreenOffTimeoutDocked(30);
-
- createService();
- startSystem();
-
- mService.getBinderServiceInstance().userActivity(Display.DEFAULT_DISPLAY, mClock.now(),
- PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
- mDockReceiver.onReceive(mContextSpy,
- new Intent(Intent.ACTION_DOCK_EVENT).putExtra(Intent.EXTRA_DOCK_STATE,
- Intent.EXTRA_DOCK_STATE_DESK));
-
- assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
- advanceTime(15);
- assertThat(mService.getGlobalWakefulnessLocked()).isEqualTo(WAKEFULNESS_AWAKE);
- advanceTime(20);
- assertThat(mService.getGlobalWakefulnessLocked()).isNotEqualTo(WAKEFULNESS_AWAKE);
- }
-
- @Test
public void testInattentiveSleep_goesToSleepWithWakeLock() {
final String pkg = mContextSpy.getOpPackageName();
final Binder token = new Binder();
@@ -1136,6 +1095,11 @@ public class PowerManagerServiceTest {
info.displayGroupId = nonDefaultDisplayGroupId;
when(mDisplayManagerInternalMock.getDisplayInfo(nonDefaultDisplay)).thenReturn(info);
+ doAnswer(inv -> {
+ when(mDreamManagerInternalMock.isDreaming()).thenReturn(true);
+ return null;
+ }).when(mDreamManagerInternalMock).startDream(anyBoolean());
+
final String pkg = mContextSpy.getOpPackageName();
final Binder token = new Binder();
final String tag = "testRemovedDisplayGroupWakeLock_affectsNoDisplayGroups";
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
index bd7186e74354..a7d18eeba058 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationHistoryDatabaseTest.java
@@ -126,7 +126,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
when(file.getAbsolutePath()).thenReturn(String.valueOf(i));
AtomicFile af = new AtomicFile(file);
expectedFiles.add(af);
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
}
cal.add(Calendar.DATE, -1 * retainDays);
@@ -136,7 +136,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
when(file.getName()).thenReturn(String.valueOf(cal.getTimeInMillis() - i));
when(file.getAbsolutePath()).thenReturn(String.valueOf(cal.getTimeInMillis() - i));
AtomicFile af = new AtomicFile(file);
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
}
// back to today; trim everything a day + old
@@ -162,7 +162,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
when(file.getName()).thenReturn(i + ".bak");
when(file.getAbsolutePath()).thenReturn(i + ".bak");
AtomicFile af = new AtomicFile(file);
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
}
// trim everything a day+ old
@@ -224,7 +224,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
public void testReadNotificationHistory_readsAllFiles() throws Exception {
for (long i = 10; i >= 5; i--) {
AtomicFile af = mock(AtomicFile.class);
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
}
mDataBase.readNotificationHistory();
@@ -248,11 +248,11 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
public void testReadNotificationHistory_withNumFilterDoesNotReadExtraFiles() throws Exception {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
AtomicFile af2 = mock(AtomicFile.class);
when(af2.getBaseFile()).thenReturn(new File(mRootDir, "af2"));
- mDataBase.mHistoryFiles.addLast(af2);
+ mDataBase.mHistoryFiles.add(af2);
mDataBase.readNotificationHistory(null, null, 0);
@@ -269,7 +269,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
when(nh.removeNotificationFromWrite("pkg", 123)).thenReturn(true);
@@ -292,7 +292,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
when(nh.removeNotificationFromWrite("pkg", 123)).thenReturn(false);
@@ -315,7 +315,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
when(nh.removeConversationsFromWrite("pkg", Set.of("convo", "another"))).thenReturn(true);
@@ -338,7 +338,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
when(nh.removeConversationsFromWrite("pkg", Set.of("convo"))).thenReturn(false);
@@ -361,7 +361,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
when(nh.removeChannelFromWrite("pkg", "channel")).thenReturn(true);
@@ -384,7 +384,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af"));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
when(nh.removeChannelFromWrite("pkg", "channel")).thenReturn(false);
@@ -424,7 +424,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
for (int i = 0; i < 5; i++) {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
}
// Baseline size of history files
assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(5);
@@ -440,7 +440,7 @@ public class NotificationHistoryDatabaseTest extends UiServiceTestCase {
for (int i = 0; i < 5; i++) {
AtomicFile af = mock(AtomicFile.class);
when(af.getBaseFile()).thenReturn(new File(mRootDir, "af" + i));
- mDataBase.mHistoryFiles.addLast(af);
+ mDataBase.mHistoryFiles.add(af);
}
// Baseline size of history files
assertThat(mDataBase.mHistoryFiles.size()).isEqualTo(5);
diff --git a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
index 3beb7f2049df..88c7017e9942 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DimmerTests.java
@@ -283,6 +283,21 @@ public class DimmerTests extends WindowTestsBase {
verify(mTransaction).remove(dimLayer);
}
+ @Test
+ public void testDimmerWithBlurUpdatesTransaction() {
+ TestWindowContainer child = new TestWindowContainer(mWm);
+ mHost.addChild(child, 0);
+
+ final int blurRadius = 50;
+ mDimmer.dimBelow(mTransaction, child, 0, blurRadius);
+ SurfaceControl dimLayer = getDimLayer();
+
+ assertNotNull("Dimmer should have created a surface", dimLayer);
+
+ verify(mTransaction).setBackgroundBlurRadius(dimLayer, blurRadius);
+ verify(mTransaction).setRelativeLayer(dimLayer, child.mControl, -1);
+ }
+
private SurfaceControl getDimLayer() {
return mDimmer.mDimState.mDimLayer;
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 398889213ce5..0e7eb59a4d7b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -504,6 +504,7 @@ final class HotwordDetectionConnection {
if (mValidatingDspTrigger) {
mValidatingDspTrigger = false;
enforcePermissionsForDataDelivery();
+ enforceExtraKeyphraseIdNotLeaked(result, recognitionEvent);
externalCallback.onKeyphraseDetected(recognitionEvent, result);
if (result != null) {
Slog.i(TAG, "Egressed " + HotwordDetectedResult.getUsageSize(result)
@@ -579,6 +580,7 @@ final class HotwordDetectionConnection {
mValidatingDspTrigger = false;
try {
enforcePermissionsForDataDelivery();
+ enforceExtraKeyphraseIdNotLeaked(result, recognitionEvent);
} catch (SecurityException e) {
HotwordMetricsLogger.writeKeyphraseTriggerEvent(
mDetectorType,
@@ -1124,6 +1126,19 @@ final class HotwordDetectionConnection {
}
}
+ private static void enforceExtraKeyphraseIdNotLeaked(HotwordDetectedResult result,
+ SoundTrigger.KeyphraseRecognitionEvent recognitionEvent) {
+ // verify the phrase ID in HotwordDetectedResult is not exposing extra phrases
+ // the DSP did not detect
+ for (SoundTrigger.KeyphraseRecognitionExtra keyphrase : recognitionEvent.keyphraseExtras) {
+ if (keyphrase.getKeyphraseId() == result.getHotwordPhraseId()) {
+ return;
+ }
+ }
+ throw new SecurityException("Ignoring #onDetected due to trusted service "
+ + "sharing a keyphrase ID which the DSP did not detect");
+ }
+
private static final String OP_MESSAGE =
"Providing hotword detection result to VoiceInteractionService";
};
diff --git a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java
index 0d0b3e098750..076059f6b0f2 100644
--- a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java
+++ b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationManagerService.java
@@ -108,7 +108,7 @@ public class WallpaperEffectsGenerationManagerService extends
@Override
public void generateCinematicEffect(@NonNull CinematicEffectRequest request,
@NonNull ICinematicEffectListener listener) {
- if (!runForUserLocked("generateCinematicEffect", (service) ->
+ if (!runForUser("generateCinematicEffect", true, (service) ->
service.onGenerateCinematicEffectLocked(request, listener))) {
try {
listener.onCinematicEffectGenerated(
@@ -126,7 +126,7 @@ public class WallpaperEffectsGenerationManagerService extends
@Override
public void returnCinematicEffectResponse(@NonNull CinematicEffectResponse response) {
- runForUserLocked("returnCinematicResponse", (service) ->
+ runForUser("returnCinematicResponse", false, (service) ->
service.onReturnCinematicEffectResponseLocked(response));
}
@@ -140,30 +140,42 @@ public class WallpaperEffectsGenerationManagerService extends
}
/**
- * Execute the operation for the user locked. Return true if
- * WallpaperEffectsGenerationPerUserService is found for the user.
- * Otherwise return false.
+ * Execute the operation for the user.
+ *
+ * @param func The name of function for logging purpose.
+ * @param checkManageWallpaperEffectsPermission whether to check if caller has
+ * MANAGE_WALLPAPER_EFFECTS_GENERATION.
+ * If false, check the uid of caller matching bind service.
+ * @param c WallpaperEffectsGenerationPerUserService operation.
+ * @return whether WallpaperEffectsGenerationPerUserService is found.
*/
- private boolean runForUserLocked(@NonNull final String func,
+ private boolean runForUser(@NonNull final String func,
+ @NonNull final boolean checkManageWallpaperEffectsPermission,
@NonNull final Consumer<WallpaperEffectsGenerationPerUserService> c) {
ActivityManagerInternal am = LocalServices.getService(ActivityManagerInternal.class);
final int userId = am.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
Binder.getCallingUserHandle().getIdentifier(), false, ALLOW_NON_FULL,
null, null);
if (DEBUG) {
- Slog.d(TAG, "runForUserLocked:" + func + " from pid=" + Binder.getCallingPid()
+ Slog.d(TAG, "runForUser:" + func + " from pid=" + Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
}
- Context ctx = getContext();
- if (!(ctx.checkCallingPermission(MANAGE_WALLPAPER_EFFECTS_GENERATION)
- == PERMISSION_GRANTED
- || mServiceNameResolver.isTemporary(userId)
- || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) {
- String msg = "Permission Denial: Cannot call " + func + " from pid="
- + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
+ if (checkManageWallpaperEffectsPermission) {
+ // MANAGE_WALLPAPER_EFFECTS_GENERATION is required for all functions except for
+ // "returnCinematicResponse", whose calling permission checked in
+ // WallpaperEffectsGenerationPerUserService against remote binding.
+ Context ctx = getContext();
+ if (!(ctx.checkCallingPermission(MANAGE_WALLPAPER_EFFECTS_GENERATION)
+ == PERMISSION_GRANTED
+ || mServiceNameResolver.isTemporary(userId)
+ || mActivityTaskManagerInternal.isCallerRecents(Binder.getCallingUid()))) {
+ String msg = "Permission Denial: Cannot call " + func + " from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid();
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
}
+ final int origCallingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
boolean accepted = false;
try {
@@ -171,6 +183,16 @@ public class WallpaperEffectsGenerationManagerService extends
final WallpaperEffectsGenerationPerUserService service =
getServiceForUserLocked(userId);
if (service != null) {
+ // Check uid of caller matches bind service implementation if
+ // MANAGE_WALLPAPER_EFFECTS_GENERATION is skipped. This is useful
+ // for service implementation to return response.
+ if (!checkManageWallpaperEffectsPermission
+ && !service.isCallingUidAllowed(origCallingUid)) {
+ String msg = "Permission Denial: cannot call " + func + ", uid["
+ + origCallingUid + "] doesn't match service implementation";
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
accepted = true;
c.accept(service);
}
diff --git a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java
index d541051e5ab2..7ba72dbbd511 100644
--- a/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java
+++ b/services/wallpapereffectsgeneration/java/com/android/server/wallpapereffectsgeneration/WallpaperEffectsGenerationPerUserService.java
@@ -141,6 +141,13 @@ public class WallpaperEffectsGenerationPerUserService extends
invokeCinematicListenerAndCleanup(cinematicEffectResponse);
}
+ /**
+ * Checks whether the calling uid matches the bind service uid.
+ */
+ public boolean isCallingUidAllowed(int callingUid) {
+ return getServiceUidLocked() == callingUid;
+ }
+
@GuardedBy("mLock")
private void updateRemoteServiceLocked() {
if (mRemoteService != null) {
@@ -152,7 +159,6 @@ public class WallpaperEffectsGenerationPerUserService extends
invokeCinematicListenerAndCleanup(
createErrorCinematicEffectResponse(mCinematicEffectListenerWrapper.mTaskId));
}
-
}
void onPackageUpdatedLocked() {
diff --git a/telecomm/java/android/telecom/Connection.java b/telecomm/java/android/telecom/Connection.java
index 6a283df5b480..49ad58550db8 100644
--- a/telecomm/java/android/telecom/Connection.java
+++ b/telecomm/java/android/telecom/Connection.java
@@ -45,6 +45,7 @@ import android.os.Parcelable;
import android.os.RemoteException;
import android.os.SystemClock;
import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
import android.telephony.ims.ImsStreamMediaProfile;
import android.util.ArraySet;
import android.view.Surface;
@@ -837,10 +838,10 @@ public abstract class Connection extends Conferenceable {
"android.telecom.extra.AUDIO_CODEC_BANDWIDTH_KHZ";
/**
- * Last known cell identity key to be used to fill geo location header in case of an emergency
- * call. This entry will not be filled if call is not identified as an emergency call.
- * {@link Connection}. Only provided to the {@link ConnectionService} for the purpose
- * of placing an emergency call; will not be present in the {@link InCallService} layer.
+ * Last known cell identity key {@link CellIdentity} to be used to fill geo location header
+ * in case of an emergency call. This entry will not be filled if call is not identified as
+ * an emergency call. Only provided to the {@link ConnectionService} for the purpose of
+ * placing an emergency call; will not be present in the {@link InCallService} layer.
* The {@link ConnectionService}'s implementation will be logged for fine location access
* when an outgoing call is placed in this case.
*/
diff --git a/telecomm/java/android/telecom/Logging/EventManager.java b/telecomm/java/android/telecom/Logging/EventManager.java
index 1342038c6477..a74c0bb99549 100644
--- a/telecomm/java/android/telecom/Logging/EventManager.java
+++ b/telecomm/java/android/telecom/Logging/EventManager.java
@@ -180,7 +180,7 @@ public class EventManager {
}
}
- private final List<Event> mEvents = Collections.synchronizedList(new LinkedList<>());
+ private final List<Event> mEvents = Collections.synchronizedList(new ArrayList<>());
private final Loggable mRecordEntry;
public EventRecord(Loggable recordEntry) {
@@ -197,7 +197,7 @@ public class EventManager {
}
public List<Event> getEvents() {
- return new LinkedList<>(mEvents);
+ return new ArrayList<>(mEvents);
}
public List<EventTiming> extractEventTimings() {
@@ -205,7 +205,7 @@ public class EventManager {
return Collections.emptyList();
}
- LinkedList<EventTiming> result = new LinkedList<>();
+ ArrayList<EventTiming> result = new ArrayList<>();
Map<String, PendingResponse> pendingResponses = new HashMap<>();
synchronized (mEvents) {
for (Event event : mEvents) {
diff --git a/telecomm/java/android/telecom/ParcelableCallAnalytics.java b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
index b8ad9e2fbe6c..ff87ab00ae8b 100644
--- a/telecomm/java/android/telecom/ParcelableCallAnalytics.java
+++ b/telecomm/java/android/telecom/ParcelableCallAnalytics.java
@@ -359,7 +359,7 @@ public class ParcelableCallAnalytics implements Parcelable {
eventTimings = new ArrayList<>();
in.readTypedList(eventTimings, EventTiming.CREATOR);
isVideoCall = readByteAsBoolean(in);
- videoEvents = new LinkedList<>();
+ videoEvents = new ArrayList<>();
in.readTypedList(videoEvents, VideoEvent.CREATOR);
callSource = in.readInt();
}
diff --git a/telecomm/java/android/telecom/TelecomManager.java b/telecomm/java/android/telecom/TelecomManager.java
index df114dbabe5b..0bb1d73d0c3f 100644
--- a/telecomm/java/android/telecom/TelecomManager.java
+++ b/telecomm/java/android/telecom/TelecomManager.java
@@ -1179,7 +1179,7 @@ public class TelecomManager {
if (service != null) {
try {
return service.getSimCallManager(
- SubscriptionManager.getDefaultSubscriptionId());
+ SubscriptionManager.getDefaultSubscriptionId(), mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getSimCallManager");
}
@@ -1201,7 +1201,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getSimCallManager(subscriptionId);
+ return service.getSimCallManager(subscriptionId, mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getSimCallManager");
}
@@ -1225,7 +1225,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getSimCallManagerForUser(userId);
+ return service.getSimCallManagerForUser(userId, mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#getSimCallManagerForUser");
}
@@ -1500,7 +1500,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- service.registerPhoneAccount(account);
+ service.registerPhoneAccount(account, mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#registerPhoneAccount", e);
}
@@ -1516,7 +1516,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- service.unregisterPhoneAccount(accountHandle);
+ service.unregisterPhoneAccount(accountHandle, mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#unregisterPhoneAccount", e);
}
@@ -1597,7 +1597,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getDefaultDialerPackage();
+ return service.getDefaultDialerPackage(mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException attempting to get the default dialer package name.", e);
}
@@ -1671,7 +1671,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- return service.getSystemDialerPackage();
+ return service.getSystemDialerPackage(mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException attempting to get the system dialer package name.", e);
}
@@ -2076,7 +2076,8 @@ public class TelecomManager {
"acceptHandover for API > O-MR1");
return;
}
- service.addNewIncomingCall(phoneAccount, extras == null ? new Bundle() : extras);
+ service.addNewIncomingCall(phoneAccount, extras == null ? new Bundle() : extras,
+ mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException adding a new incoming call: " + phoneAccount, e);
}
@@ -2118,7 +2119,8 @@ public class TelecomManager {
if (service != null) {
try {
service.addNewIncomingConference(
- phoneAccount, extras == null ? new Bundle() : extras);
+ phoneAccount, extras == null ? new Bundle() : extras,
+ mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException adding a new incoming conference: " + phoneAccount, e);
}
@@ -2414,7 +2416,7 @@ public class TelecomManager {
Intent result = null;
if (service != null) {
try {
- result = service.createManageBlockedNumbersIntent();
+ result = service.createManageBlockedNumbersIntent(mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Error calling ITelecomService#createManageBlockedNumbersIntent", e);
}
@@ -2571,7 +2573,7 @@ public class TelecomManager {
ITelecomService service = getTelecomService();
if (service != null) {
try {
- service.acceptHandover(srcAddr, videoState, destAcct);
+ service.acceptHandover(srcAddr, videoState, destAcct, mContext.getPackageName());
} catch (RemoteException e) {
Log.e(TAG, "RemoteException acceptHandover: " + e);
}
diff --git a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
index 9999c897d1b6..35d53b02c550 100644
--- a/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
+++ b/telecomm/java/com/android/internal/telecom/ITelecomService.aidl
@@ -105,22 +105,22 @@ interface ITelecomService {
/**
* @see TelecomServiceImpl#getSimCallManager
*/
- PhoneAccountHandle getSimCallManager(int subId);
+ PhoneAccountHandle getSimCallManager(int subId, String callingPackage);
/**
* @see TelecomServiceImpl#getSimCallManagerForUser
*/
- PhoneAccountHandle getSimCallManagerForUser(int userId);
+ PhoneAccountHandle getSimCallManagerForUser(int userId, String callingPackage);
/**
* @see TelecomServiceImpl#registerPhoneAccount
*/
- void registerPhoneAccount(in PhoneAccount metadata);
+ void registerPhoneAccount(in PhoneAccount metadata, String callingPackage);
/**
* @see TelecomServiceImpl#unregisterPhoneAccount
*/
- void unregisterPhoneAccount(in PhoneAccountHandle account);
+ void unregisterPhoneAccount(in PhoneAccountHandle account, String callingPackage);
/**
* @see TelecomServiceImpl#clearAccounts
@@ -153,7 +153,7 @@ interface ITelecomService {
/**
* @see TelecomServiceImpl#getDefaultDialerPackage
*/
- String getDefaultDialerPackage();
+ String getDefaultDialerPackage(String callingPackage);
/**
* @see TelecomServiceImpl#getDefaultDialerPackage
@@ -163,7 +163,7 @@ interface ITelecomService {
/**
* @see TelecomServiceImpl#getSystemDialerPackage
*/
- String getSystemDialerPackage();
+ String getSystemDialerPackage(String callingPackage);
/**
* @see TelecomServiceImpl#dumpCallAnalytics
@@ -261,12 +261,15 @@ interface ITelecomService {
/**
* @see TelecomServiceImpl#addNewIncomingCall
*/
- void addNewIncomingCall(in PhoneAccountHandle phoneAccount, in Bundle extras);
+ void addNewIncomingCall(in PhoneAccountHandle phoneAccount, in Bundle extras,
+ String callingPackage);
/**
* @see TelecomServiceImpl#addNewIncomingConference
*/
- void addNewIncomingConference(in PhoneAccountHandle phoneAccount, in Bundle extras);
+ void addNewIncomingConference(in PhoneAccountHandle phoneAccount, in Bundle extras,
+ String callingPackage);
+
/**
* @see TelecomServiceImpl#addNewUnknownCall
@@ -302,7 +305,7 @@ interface ITelecomService {
/**
* @see TelecomServiceImpl#createManageBlockedNumbersIntent
**/
- Intent createManageBlockedNumbersIntent();
+ Intent createManageBlockedNumbersIntent(String callingPackage);
/**
* @see TelecomServiceImpl#createLaunchEmergencyDialerIntent
@@ -329,7 +332,8 @@ interface ITelecomService {
/**
* @see TelecomServiceImpl#acceptHandover
*/
- void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct);
+ void acceptHandover(in Uri srcAddr, int videoState, in PhoneAccountHandle destAcct,
+ String callingPackage);
/**
* @see TelecomServiceImpl#setTestEmergencyPhoneAccountPackageNameFilter
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index cff90bb9b848..33d50a8bddbf 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -176,7 +176,7 @@ public class CarrierConfigManager {
* This flag specifies whether VoLTE availability is based on provisioning. By default this is
* false.
* Used for UCE to determine if EAB provisioning checks should be based on provisioning.
- * @deprecated Use {@link Ims#KEY_MMTEL_REQUIRES_PROVISIONING_BUNDLE} instead.
+ * @deprecated Use {@link Ims#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL} instead.
*/
@Deprecated
public static final String
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3f430ab77df4..d0ae8e909c95 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -7703,7 +7703,7 @@ public class TelephonyManager {
* app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* TODO: remove this one. use {@link #rebootModem()} for reset type 1 and
- * {@link #resetRadioConfig()} for reset type 3
+ * {@link #resetRadioConfig()} for reset type 3 (b/116476729)
*
* @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
* @return true on success; false on any failure.
@@ -8942,7 +8942,7 @@ public class TelephonyManager {
public NetworkScan requestNetworkScan(
NetworkScanRequest request, Executor executor,
TelephonyScanManager.NetworkScanCallback callback) {
- return requestNetworkScan(false, request, executor, callback);
+ return requestNetworkScan(INCLUDE_LOCATION_DATA_FINE, request, executor, callback);
}
/**
@@ -8967,9 +8967,8 @@ public class TelephonyManager {
* and MCC/MNC info.</li>
* </ol>
*
- * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
- * location related information which will be sent if the caller already possess
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission
+ * @param includeLocationData Specifies if the caller would like to receive
+ * location related information.
* @param request Contains all the RAT with bands/channels that need to be scanned.
* @param executor The executor through which the callback should be invoked. Since the scan
* request may trigger multiple callbacks and they must be invoked in the same order as
@@ -8984,7 +8983,8 @@ public class TelephonyManager {
Manifest.permission.ACCESS_FINE_LOCATION
})
public @Nullable NetworkScan requestNetworkScan(
- boolean renounceFineLocationAccess, @NonNull NetworkScanRequest request,
+ @IncludeLocationData int includeLocationData,
+ @NonNull NetworkScanRequest request,
@NonNull Executor executor,
@NonNull TelephonyScanManager.NetworkScanCallback callback) {
synchronized (sCacheLock) {
@@ -8992,7 +8992,8 @@ public class TelephonyManager {
mTelephonyScanManager = new TelephonyScanManager();
}
}
- return mTelephonyScanManager.requestNetworkScan(getSubId(), renounceFineLocationAccess,
+ return mTelephonyScanManager.requestNetworkScan(getSubId(),
+ includeLocationData != INCLUDE_LOCATION_DATA_FINE,
request, executor, callback,
getOpPackageName(), getAttributionTag());
}
@@ -12152,10 +12153,15 @@ public class TelephonyManager {
})
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_RADIO_ACCESS)
public @Nullable ServiceState getServiceState() {
- return getServiceState(getRenouncedPermissions()
- .contains(Manifest.permission.ACCESS_FINE_LOCATION),
- getRenouncedPermissions()
- .contains(Manifest.permission.ACCESS_COARSE_LOCATION));
+ if (getRenouncedPermissions().contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
+ if (getRenouncedPermissions().contains(Manifest.permission.ACCESS_COARSE_LOCATION)) {
+ return getServiceState(INCLUDE_LOCATION_DATA_NONE);
+ } else {
+ return getServiceState(INCLUDE_LOCATION_DATA_COARSE);
+ }
+ }
+
+ return getServiceState(INCLUDE_LOCATION_DATA_FINE);
}
/**
@@ -12175,12 +12181,8 @@ public class TelephonyManager {
* <p>Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
* or that the calling app has carrier privileges (see {@link #hasCarrierPrivileges})
* and {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
- * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
- * location related information which will be sent if the caller already possess
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permission
- * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
- * receive location related information which will be sent if the caller already possess
- * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions.
+ * @param includeLocationData Specifies if the caller would like to receive
+ * location related information.
* May return {@code null} when the subscription is inactive or when there was an error
* communicating with the phone process.
*/
@@ -12189,10 +12191,10 @@ public class TelephonyManager {
Manifest.permission.READ_PHONE_STATE,
Manifest.permission.ACCESS_COARSE_LOCATION
})
- public @Nullable ServiceState getServiceState(boolean renounceFineLocationAccess,
- boolean renounceCoarseLocationAccess) {
- return getServiceStateForSubscriber(getSubId(), renounceFineLocationAccess,
- renounceCoarseLocationAccess);
+ public @Nullable ServiceState getServiceState(@IncludeLocationData int includeLocationData) {
+ return getServiceStateForSubscriber(getSubId(),
+ includeLocationData != INCLUDE_LOCATION_DATA_FINE,
+ includeLocationData == INCLUDE_LOCATION_DATA_NONE);
}
/**
@@ -16150,12 +16152,57 @@ public class TelephonyManager {
*/
public void registerTelephonyCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull TelephonyCallback callback) {
- registerTelephonyCallback(
- getRenouncedPermissions().contains(Manifest.permission.ACCESS_FINE_LOCATION),
- getRenouncedPermissions().contains(Manifest.permission.ACCESS_COARSE_LOCATION),
- executor, callback);
+ if (getRenouncedPermissions().contains(Manifest.permission.ACCESS_FINE_LOCATION)) {
+ if (getRenouncedPermissions().contains(Manifest.permission.ACCESS_COARSE_LOCATION)) {
+ registerTelephonyCallback(INCLUDE_LOCATION_DATA_NONE, executor, callback);
+ return;
+ } else {
+ registerTelephonyCallback(INCLUDE_LOCATION_DATA_COARSE, executor, callback);
+ return;
+ }
+ }
+
+ registerTelephonyCallback(INCLUDE_LOCATION_DATA_FINE, executor, callback);
}
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = {"INCLUDE_LOCATION_DATA_"}, value = {
+ INCLUDE_LOCATION_DATA_NONE,
+ INCLUDE_LOCATION_DATA_COARSE,
+ INCLUDE_LOCATION_DATA_FINE})
+ public @interface IncludeLocationData {}
+
+ /**
+ * Specifies to not include any location related data.
+ *
+ * Indicates whether the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the
+ * permissions.
+ */
+ public static final int INCLUDE_LOCATION_DATA_NONE = 0;
+
+ /**
+ * Include coarse location data.
+ *
+ * Indicates whether the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the
+ * permissions.
+ */
+ public static final int INCLUDE_LOCATION_DATA_COARSE = 1;
+
+ /**
+ * Include fine location data.
+ *
+ * Indicates whether the caller would not like to receive
+ * location related information which will be sent if the caller already possess
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the
+ * permissions.
+ */
+ public static final int INCLUDE_LOCATION_DATA_FINE = 2;
+
/**
* Registers a callback object to receive notification of changes in specified telephony states.
* <p>
@@ -16189,17 +16236,12 @@ public class TelephonyManager {
* apps. To avoid confusion, calling this method supersede renouncing permissions with a
* custom context.
*
- * @param renounceFineLocationAccess Set this to true if the caller would not like to receive
- * location related information which will be sent if the caller already possess
- * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and do not renounce the permissions.
- * @param renounceCoarseLocationAccess Set this to true if the caller would not like to
- * receive location related information which will be sent if the caller already possess
- * {@link Manifest.permission#ACCESS_COARSE_LOCATION} and do not renounce the permissions.
+ * @param includeLocationData Specifies if the caller would like to receive
+ * location related information.
* @param executor The executor of where the callback will execute.
* @param callback The {@link TelephonyCallback} object to register.
*/
- public void registerTelephonyCallback(boolean renounceFineLocationAccess,
- boolean renounceCoarseLocationAccess,
+ public void registerTelephonyCallback(@IncludeLocationData int includeLocationData,
@NonNull @CallbackExecutor Executor executor,
@NonNull TelephonyCallback callback) {
if (mContext == null) {
@@ -16212,8 +16254,10 @@ public class TelephonyManager {
mTelephonyRegistryMgr = (TelephonyRegistryManager)
mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
if (mTelephonyRegistryMgr != null) {
- mTelephonyRegistryMgr.registerTelephonyCallback(renounceFineLocationAccess,
- renounceCoarseLocationAccess, executor, mSubId, getOpPackageName(),
+ mTelephonyRegistryMgr.registerTelephonyCallback(
+ includeLocationData != INCLUDE_LOCATION_DATA_FINE,
+ includeLocationData == INCLUDE_LOCATION_DATA_NONE,
+ executor, mSubId, getOpPackageName(),
getAttributionTag(), callback, getITelephony() != null);
} else {
throw new IllegalStateException("telephony service is null.");
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index bce210fa22a0..f8048aa3731c 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -539,7 +539,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -601,7 +600,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -621,9 +619,9 @@ public class ImsMmTelManager implements RegistrationManager {
ITelephony iTelephony = getITelephony();
if (iTelephony == null) {
- throw new RuntimeException("Could not find Telephony Service.");
+ Log.w("ImsMmTelManager", "Could not find Telephony Service.");
+ return;
}
-
try {
iTelephony.unregisterMmTelCapabilityCallback(mSubId, c.getBinder());
} catch (RemoteException e) {
@@ -649,7 +647,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -862,7 +859,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -937,7 +933,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1111,7 +1106,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1226,7 +1220,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
@@ -1415,7 +1408,6 @@ public class ImsMmTelManager implements RegistrationManager {
* <li>The caller has carrier privileges (see
* {@link android.telephony.TelephonyManager#hasCarrierPrivileges}) on any
* active subscription.</li>
- * <li>The caller is the default SMS app for the device.</li>
* </ul>
* <p>The profile owner is an app that owns a managed profile on the device; for more details
* see <a href="https://developer.android.com/work/managed-profiles">Work profiles</a>.
diff --git a/telephony/java/android/telephony/ims/ImsRcsManager.java b/telephony/java/android/telephony/ims/ImsRcsManager.java
index 34158685b6d1..4439e5c35d83 100644
--- a/telephony/java/android/telephony/ims/ImsRcsManager.java
+++ b/telephony/java/android/telephony/ims/ImsRcsManager.java
@@ -18,6 +18,7 @@ package android.telephony.ims;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
@@ -43,6 +44,8 @@ import android.util.Log;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.ITelephony;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@@ -87,6 +90,46 @@ public class ImsRcsManager {
"android.telephony.ims.action.SHOW_CAPABILITY_DISCOVERY_OPT_IN";
/**
+ * This carrier supports User Capability Exchange as, defined by the framework using a
+ * presence server. If set, the RcsFeature should support capability exchange. If not set, this
+ * RcsFeature should not publish capabilities or service capability requests.
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "CAPABILITY_TYPE_", flag = true, value = {
+ CAPABILITY_TYPE_NONE,
+ CAPABILITY_TYPE_OPTIONS_UCE,
+ CAPABILITY_TYPE_PRESENCE_UCE
+ })
+ public @interface RcsImsCapabilityFlag {}
+
+ /**
+ * Undefined capability type for initialization
+ */
+ public static final int CAPABILITY_TYPE_NONE = 0;
+
+ /**
+ * This carrier supports User Capability Exchange using SIP OPTIONS as defined by the
+ * framework. If set, the RcsFeature should support capability exchange using SIP OPTIONS.
+ * If not set, this RcsFeature should not service capability requests.
+ */
+ public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
+
+ /**
+ * This carrier supports User Capability Exchange using a presence server as defined by the
+ * framework. If set, the RcsFeature should support capability exchange using a presence
+ * server. If not set, this RcsFeature should not publish capabilities or service capability
+ * requests using presence.
+ */
+ public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
+
+ /**
+ * This is used to check the upper range of RCS capability
+ * @hide
+ */
+ public static final int CAPABILITY_TYPE_MAX = CAPABILITY_TYPE_PRESENCE_UCE + 1;
+
+ /**
* An application can use {@link #addOnAvailabilityChangedListener} to register a
* {@link OnAvailabilityChangedListener}, which will notify the user when the RCS feature
* availability status updates from the ImsService.
@@ -104,7 +147,7 @@ public class ImsRcsManager {
*
* @param capabilities The new availability of the capabilities.
*/
- void onAvailabilityChanged(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities);
+ void onAvailabilityChanged(@RcsImsCapabilityFlag int capabilities);
}
/**
@@ -486,7 +529,7 @@ public class ImsRcsManager {
*/
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capability,
+ public boolean isCapable(@RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) throws ImsException {
IImsRcsController imsRcsController = getIImsRcsController();
if (imsRcsController == null) {
@@ -497,6 +540,8 @@ public class ImsRcsManager {
try {
return imsRcsController.isCapable(mSubId, capability, radioTech);
+ } catch (ServiceSpecificException e) {
+ throw new ImsException(e.getMessage(), e.errorCode);
} catch (RemoteException e) {
Log.w(TAG, "Error calling IImsRcsController#isCapable", e);
throw new ImsException("Remote IMS Service is not available",
@@ -522,7 +567,7 @@ public class ImsRcsManager {
*/
@SystemApi
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public boolean isAvailable(@RcsUceAdapter.RcsImsCapabilityFlag int capability,
+ public boolean isAvailable(@RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech)
throws ImsException {
IImsRcsController imsRcsController = getIImsRcsController();
@@ -534,6 +579,8 @@ public class ImsRcsManager {
try {
return imsRcsController.isAvailable(mSubId, capability, radioTech);
+ } catch (ServiceSpecificException e) {
+ throw new ImsException(e.getMessage(), e.errorCode);
} catch (RemoteException e) {
Log.w(TAG, "Error calling IImsRcsController#isAvailable", e);
throw new ImsException("Remote IMS Service is not available",
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 677c1a9a7d76..f2976f14d7a6 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -38,7 +38,6 @@ import android.telephony.ims.aidl.IFeatureProvisioningCallback;
import android.telephony.ims.aidl.IImsConfigCallback;
import android.telephony.ims.aidl.IRcsConfigCallback;
import android.telephony.ims.feature.MmTelFeature;
-import android.telephony.ims.feature.RcsFeature;
import android.telephony.ims.stub.ImsConfigImplBase;
import android.telephony.ims.stub.ImsRegistrationImplBase;
@@ -55,6 +54,9 @@ import java.util.concurrent.Executor;
* IMS provisioning keys are defined per carrier or OEM using OMA-DM or other provisioning
* applications and may vary. It is up to the carrier and OEM applications to ensure that the
* correct provisioning keys are being used when integrating with a vendor's ImsService.
+ *
+ * Use {@link android.telephony.ims.ImsManager#getProvisioningManager(int)} to get an instance of
+ * this manager.
*/
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_IMS)
public class ProvisioningManager {
@@ -970,7 +972,7 @@ public class ProvisioningManager {
/**
* Callback for IMS provisioning feature changes.
*/
- public static class FeatureProvisioningCallback {
+ public abstract static class FeatureProvisioningCallback {
private static class CallbackBinder extends IFeatureProvisioningCallback.Stub {
@@ -1024,12 +1026,10 @@ public class ProvisioningManager {
* specified, or {@code false} if the capability is not provisioned for the technology
* specified.
*/
- public void onFeatureProvisioningChanged(
+ public abstract void onFeatureProvisioningChanged(
@MmTelFeature.MmTelCapabilities.MmTelCapability int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int tech,
- boolean isProvisioned) {
- // Base Implementation
- }
+ boolean isProvisioned);
/**
* The IMS RCS provisioning has changed for a specific capability and IMS
@@ -1041,12 +1041,10 @@ public class ProvisioningManager {
* specified, or {@code false} if the capability is not provisioned for the technology
* specified.
*/
- public void onRcsFeatureProvisioningChanged(
- @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+ public abstract void onRcsFeatureProvisioningChanged(
+ @ImsRcsManager.RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int tech,
- boolean isProvisioned) {
- // Base Implementation
- }
+ boolean isProvisioned);
/**@hide*/
public final IFeatureProvisioningCallback getBinder() {
@@ -1505,7 +1503,7 @@ public class ProvisioningManager {
* Get the provisioning status for the IMS RCS capability specified.
*
* If provisioning is not required for the queried
- * {@link RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag} this method will always return
+ * {@link ImsRcsManager.RcsImsCapabilityFlag} this method will always return
* {@code true}.
*
* @see CarrierConfigManager.Ims#KEY_CARRIER_RCS_PROVISIONING_REQUIRED_BOOL
@@ -1522,7 +1520,7 @@ public class ProvisioningManager {
@WorkerThread
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean getRcsProvisioningStatusForCapability(
- @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability) {
+ @ImsRcsManager.RcsImsCapabilityFlag int capability) {
try {
return getITelephony().getRcsProvisioningStatusForCapability(mSubId, capability,
ImsRegistrationImplBase.REGISTRATION_TECH_LTE);
@@ -1535,7 +1533,7 @@ public class ProvisioningManager {
* Get the provisioning status for the IMS RCS capability specified.
*
* If provisioning is not required for the queried
- * {@link RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag} this method
+ * {@link ImsRcsManager.RcsImsCapabilityFlag} this method
* will always return {@code true}.
*
* <p> Requires Permission:
@@ -1553,7 +1551,7 @@ public class ProvisioningManager {
@WorkerThread
@RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
public boolean getRcsProvisioningStatusForCapability(
- @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+ @ImsRcsManager.RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int tech) {
try {
return getITelephony().getRcsProvisioningStatusForCapability(mSubId, capability, tech);
@@ -1590,7 +1588,7 @@ public class ProvisioningManager {
@WorkerThread
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setRcsProvisioningStatusForCapability(
- @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+ @ImsRcsManager.RcsImsCapabilityFlag int capability,
boolean isProvisioned) {
try {
getITelephony().setRcsProvisioningStatusForCapability(mSubId, capability,
@@ -1622,7 +1620,7 @@ public class ProvisioningManager {
@WorkerThread
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setRcsProvisioningStatusForCapability(
- @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+ @ImsRcsManager.RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int tech, boolean isProvisioned) {
try {
getITelephony().setRcsProvisioningStatusForCapability(mSubId, capability,
@@ -1676,7 +1674,7 @@ public class ProvisioningManager {
*/
@RequiresPermission(Manifest.permission.READ_PRECISE_PHONE_STATE)
public boolean isRcsProvisioningRequiredForCapability(
- @RcsFeature.RcsImsCapabilities.RcsImsCapabilityFlag int capability,
+ @ImsRcsManager.RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int tech) {
try {
return getITelephony().isRcsProvisioningRequiredForCapability(mSubId, capability, tech);
diff --git a/telephony/java/android/telephony/ims/RcsUceAdapter.java b/telephony/java/android/telephony/ims/RcsUceAdapter.java
index 154bb11db5e3..91dc38ff9ddb 100644
--- a/telephony/java/android/telephony/ims/RcsUceAdapter.java
+++ b/telephony/java/android/telephony/ims/RcsUceAdapter.java
@@ -55,20 +55,28 @@ public class RcsUceAdapter {
* This carrier supports User Capability Exchange as, defined by the framework using
* SIP OPTIONS. If set, the RcsFeature should support capability exchange. If not set, this
* RcsFeature should not publish capabilities or service capability requests.
+ * @deprecated Use {@link ImsRcsManager#CAPABILITY_TYPE_OPTIONS_UCE} instead.
* @hide
*/
+ @Deprecated
public static final int CAPABILITY_TYPE_OPTIONS_UCE = 1 << 0;
/**
* This carrier supports User Capability Exchange as, defined by the framework using a
* presence server. If set, the RcsFeature should support capability exchange. If not set, this
* RcsFeature should not publish capabilities or service capability requests.
+ * @deprecated Use {@link ImsRcsManager#CAPABILITY_TYPE_PRESENCE_UCE} instead.
* @hide
*/
+ @Deprecated
@SystemApi
public static final int CAPABILITY_TYPE_PRESENCE_UCE = 1 << 1;
- /**@hide*/
+ /**
+ * @deprecated Use {@link ImsRcsManager.RcsImsCapabilityFlag} instead.
+ * @hide
+ */
+ @Deprecated
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "CAPABILITY_TYPE_", value = {
CAPABILITY_TYPE_OPTIONS_UCE,
diff --git a/telephony/java/android/telephony/ims/feature/MmTelFeature.java b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
index ad2e9e133a11..fb0e659ec77b 100644
--- a/telephony/java/android/telephony/ims/feature/MmTelFeature.java
+++ b/telephony/java/android/telephony/ims/feature/MmTelFeature.java
@@ -396,7 +396,7 @@ public class MmTelFeature extends ImsFeature {
/**
* Undefined capability type for initialization
* This is used to check the upper range of MmTel capability
- * {@hide}
+ * @hide
*/
public static final int CAPABILITY_TYPE_NONE = 0;
@@ -427,7 +427,7 @@ public class MmTelFeature extends ImsFeature {
/**
* This is used to check the upper range of MmTel capability
- * {@hide}
+ * @hide
*/
public static final int CAPABILITY_TYPE_MAX = CAPABILITY_TYPE_CALL_COMPOSER + 1;
@@ -738,7 +738,7 @@ public class MmTelFeature extends ImsFeature {
* Enabling/Disabling a capability here indicates that the capability should be registered or
* deregistered (depending on the capability change) and become available or unavailable to
* the framework.
- * * @hide
+ * @hide
*/
@Override
@SystemApi
diff --git a/telephony/java/android/telephony/ims/feature/RcsFeature.java b/telephony/java/android/telephony/ims/feature/RcsFeature.java
index 70e4ef1f1a3a..843827befb65 100644
--- a/telephony/java/android/telephony/ims/feature/RcsFeature.java
+++ b/telephony/java/android/telephony/ims/feature/RcsFeature.java
@@ -24,7 +24,7 @@ import android.annotation.SystemApi;
import android.content.Context;
import android.net.Uri;
import android.os.RemoteException;
-import android.telephony.ims.RcsUceAdapter;
+import android.telephony.ims.ImsRcsManager;
import android.telephony.ims.aidl.CapabilityExchangeAidlWrapper;
import android.telephony.ims.aidl.ICapabilityExchangeEventListener;
import android.telephony.ims.aidl.IImsCapabilityCallback;
@@ -59,7 +59,9 @@ import java.util.function.Supplier;
/**
* Base implementation of the RcsFeature APIs. Any ImsService wishing to support RCS should extend
* this class and provide implementations of the RcsFeature methods that they support.
+ * @hide
*/
+@SystemApi
public class RcsFeature extends ImsFeature {
private static final String LOG_TAG = "RcsFeature";
@@ -184,18 +186,22 @@ public class RcsFeature extends ImsFeature {
* Contains the capabilities defined and supported by a {@link RcsFeature} in the
* form of a bitmask. The capabilities that are used in the RcsFeature are
* defined as:
- * {RcsUceAdapter.RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
- * {RcsUceAdapter.RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
+ * {@link ImsRcsManager.RcsImsCapabilityFlag#CAPABILITY_TYPE_OPTIONS_UCE}
+ * {@link ImsRcsManager.RcsImsCapabilityFlag#CAPABILITY_TYPE_PRESENCE_UCE}
*
* The enabled capabilities of this RcsFeature will be set by the framework
- * using {#changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
+ * using {@link #changeEnabledCapabilities(CapabilityChangeRequest, CapabilityCallbackProxy)}.
* After the capabilities have been set, the RcsFeature may then perform the necessary bring up
* of the capability and notify the capability status as true using
- * {#notifyCapabilitiesStatusChanged(RcsImsCapabilities)}. This will signal to the
+ * {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)}. This will signal to the
* framework that the capability is available for usage.
*/
public static class RcsImsCapabilities extends Capabilities {
- /** @hide*/
+
+ /**
+ * Use {@link ImsRcsManager.RcsImsCapabilityFlag} instead in case used for public API
+ * @hide
+ */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "CAPABILITY_TYPE_", flag = true, value = {
CAPABILITY_TYPE_NONE,
@@ -226,7 +232,7 @@ public class RcsFeature extends ImsFeature {
/**
* This is used to check the upper range of RCS capability
- * {@hide}
+ * @hide
*/
public static final int CAPABILITY_TYPE_MAX = CAPABILITY_TYPE_PRESENCE_UCE + 1;
@@ -234,10 +240,8 @@ public class RcsFeature extends ImsFeature {
* Create a new {@link RcsImsCapabilities} instance with the provided capabilities.
* @param capabilities The capabilities that are supported for RCS in the form of a
* bitfield.
- * @hide
*/
- @SystemApi
- public RcsImsCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+ public RcsImsCapabilities(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
super(capabilities);
}
@@ -249,30 +253,18 @@ public class RcsFeature extends ImsFeature {
super(capabilities.getMask());
}
- /**
- * @hide
- */
@Override
- @SystemApi
- public void addCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+ public void addCapabilities(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
super.addCapabilities(capabilities);
}
- /**
- * @hide
- */
@Override
- @SystemApi
- public void removeCapabilities(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+ public void removeCapabilities(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
super.removeCapabilities(capabilities);
}
- /**
- * @hide
- */
@Override
- @SystemApi
- public boolean isCapable(@RcsUceAdapter.RcsImsCapabilityFlag int capabilities) {
+ public boolean isCapable(@ImsRcsManager.RcsImsCapabilityFlag int capabilities) {
return super.isCapable(capabilities);
}
}
@@ -288,9 +280,7 @@ public class RcsFeature extends ImsFeature {
* Method stubs called from the framework will be called asynchronously. To specify the
* {@link Executor} that the methods stubs will be called, use
* {@link RcsFeature#RcsFeature(Executor)} instead.
- * @hide
*/
- @SystemApi
public RcsFeature() {
super();
// Run on the Binder threads that call them.
@@ -302,9 +292,7 @@ public class RcsFeature extends ImsFeature {
* framework.
* @param executor The executor for the framework to use when executing the methods overridden
* by the implementation of RcsFeature.
- * @hide
*/
- @SystemApi
public RcsFeature(@NonNull Executor executor) {
super();
if (executor == null) {
@@ -335,10 +323,8 @@ public class RcsFeature extends ImsFeature {
* requests. To change the status of the capabilities
* {@link #notifyCapabilitiesStatusChanged(RcsImsCapabilities)} should be called.
* @return A copy of the current RcsFeature capability status.
- * @hide
*/
@Override
- @SystemApi
public @NonNull final RcsImsCapabilities queryCapabilityStatus() {
return new RcsImsCapabilities(super.queryCapabilityStatus());
}
@@ -348,9 +334,7 @@ public class RcsFeature extends ImsFeature {
* this signals to the framework that the capability has been initialized and is ready.
* Call {@link #queryCapabilityStatus()} to return the current capability status.
* @param capabilities The current capability status of the RcsFeature.
- * @hide
*/
- @SystemApi
public final void notifyCapabilitiesStatusChanged(@NonNull RcsImsCapabilities capabilities) {
if (capabilities == null) {
throw new IllegalArgumentException("RcsImsCapabilities must be non-null!");
@@ -367,11 +351,9 @@ public class RcsFeature extends ImsFeature {
* @param capability The capability that we are querying the configuration for.
* @param radioTech The radio technology type that we are querying.
* @return true if the capability is enabled, false otherwise.
- * @hide
*/
- @SystemApi
public boolean queryCapabilityConfiguration(
- @RcsUceAdapter.RcsImsCapabilityFlag int capability,
+ @ImsRcsManager.RcsImsCapabilityFlag int capability,
@ImsRegistrationImplBase.ImsRegistrationTech int radioTech) {
// Base Implementation - Override to provide functionality
return false;
@@ -392,10 +374,8 @@ public class RcsFeature extends ImsFeature {
* be called for each capability change that resulted in an error.
* @param request The request to change the capability.
* @param callback To notify the framework that the result of the capability changes.
- * @hide
*/
@Override
- @SystemApi
public void changeEnabledCapabilities(@NonNull CapabilityChangeRequest request,
@NonNull CapabilityCallbackProxy callback) {
// Base Implementation - Override to provide functionality
@@ -415,9 +395,7 @@ public class RcsFeature extends ImsFeature {
* event to the framework.
* @return An instance of {@link RcsCapabilityExchangeImplBase} that implements capability
* exchange if it is supported by the device.
- * @hide
*/
- @SystemApi
public @NonNull RcsCapabilityExchangeImplBase createCapabilityExchangeImpl(
@NonNull CapabilityExchangeEventListener listener) {
// Base Implementation, override to implement functionality
@@ -427,28 +405,20 @@ public class RcsFeature extends ImsFeature {
/**
* Remove the given CapabilityExchangeImplBase instance.
* @param capExchangeImpl The {@link RcsCapabilityExchangeImplBase} instance to be destroyed.
- * @hide
*/
- @SystemApi
public void destroyCapabilityExchangeImpl(
@NonNull RcsCapabilityExchangeImplBase capExchangeImpl) {
// Override to implement the process of destroying RcsCapabilityExchangeImplBase instance.
}
- /**{@inheritDoc}
- * @hide
- */
+ /**{@inheritDoc}*/
@Override
- @SystemApi
public void onFeatureRemoved() {
}
- /**{@inheritDoc}
- * @hide
- */
+ /**{@inheritDoc}*/
@Override
- @SystemApi
public void onFeatureReady() {
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
index ac5565bea810..593f0807ef27 100644
--- a/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsRegistrationImplBase.java
@@ -93,7 +93,7 @@ public class ImsRegistrationImplBase {
/**
* This is used to check the upper range of registration tech
- * {@hide}
+ * @hide
*/
public static final int REGISTRATION_TECH_MAX = REGISTRATION_TECH_NR + 1;
diff --git a/tools/aapt2/Android.bp b/tools/aapt2/Android.bp
index bd0a4bc44e18..52c5d4827741 100644
--- a/tools/aapt2/Android.bp
+++ b/tools/aapt2/Android.bp
@@ -36,6 +36,7 @@ toolSources = [
cc_defaults {
name: "aapt2_defaults",
+ cpp_std: "gnu++2b",
cflags: [
"-Wall",
"-Werror",
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index f47d66ea5e87..41896f622228 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -273,7 +273,7 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions&
printer->Indent();
for (const auto& type : package.types) {
printer->Print("type ");
- printer->Print(to_string(type.type));
+ printer->Print(type.named_type.to_string());
if (type.id) {
printer->Print(StringPrintf(" id=%02x", type.id.value()));
}
@@ -287,7 +287,7 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions&
printer->Print(" ");
// Write the name without the package (this is obvious and too verbose).
- printer->Print(to_string(type.type));
+ printer->Print(type.named_type.to_string());
printer->Print("/");
printer->Print(entry.name);
@@ -547,7 +547,7 @@ void Debug::DumpOverlayable(const ResourceTable& table, text::Printer* printer)
const auto policy_subsection = StringPrintf(R"(policies="%s")",
android::idmap2::policy::PoliciesToDebugString(overlayable_item.policies).c_str());
const auto value =
- StringPrintf("%s/%s", to_string(type->type).data(), entry->name.c_str());
+ StringPrintf("%s/%s", type->named_type.to_string().data(), entry->name.c_str());
items.push_back(DumpOverlayableEntry{overlayable_section, policy_subsection, value});
}
}
diff --git a/tools/aapt2/Resource.cpp b/tools/aapt2/Resource.cpp
index 0bb330e26e6f..df8c3b9956d0 100644
--- a/tools/aapt2/Resource.cpp
+++ b/tools/aapt2/Resource.cpp
@@ -139,10 +139,10 @@ ResourceNamedTypeRef ResourceNamedTypeWithDefaultName(ResourceType t) {
}
std::optional<ResourceNamedTypeRef> ParseResourceNamedType(const android::StringPiece& s) {
- auto colon = std::find(s.begin(), s.end(), ':');
+ auto dot = std::find(s.begin(), s.end(), '.');
const ResourceType* parsedType;
- if (colon != s.end() && colon != std::prev(s.end())) {
- parsedType = ParseResourceType(s.substr(s.begin(), colon));
+ if (dot != s.end() && dot != std::prev(s.end())) {
+ parsedType = ParseResourceType(s.substr(s.begin(), dot));
} else {
parsedType = ParseResourceType(s);
}
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 8d35eeec2a93..a99e4b234c6b 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -981,12 +981,14 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
return false;
}
- std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(maybe_type.value());
- if (!parsed_type) {
+ std::optional<ResourceNamedTypeRef> maybe_parsed_type =
+ ParseResourceNamedType(maybe_type.value());
+ if (!maybe_parsed_type) {
diag->Error(DiagMessage(out_resource->source)
<< "invalid resource type '" << maybe_type.value() << "' in <" << tag_name << ">");
return false;
}
+ auto parsed_type = maybe_parsed_type->ToResourceNamedType();
std::optional<StringPiece> maybe_id_str = xml::FindNonEmptyAttribute(parser, "first-id");
if (!maybe_id_str) {
@@ -1046,7 +1048,7 @@ bool static ParseGroupImpl(xml::XmlPullParser* parser, ParsedResource* out_resou
}
ParsedResource& entry_res = out_resource->child_resources.emplace_back(ParsedResource{
- .name = ResourceName{{}, *parsed_type, maybe_name.value().to_string()},
+ .name = ResourceName{{}, parsed_type, maybe_name.value().to_string()},
.source = item_source,
.comment = std::move(comment),
});
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 98cce268e213..0f5118da9408 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -43,8 +43,9 @@ namespace aapt {
const char* Overlayable::kActorScheme = "overlay";
namespace {
-bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs, ResourceType rhs) {
- return lhs->type < rhs;
+bool less_than_type(const std::unique_ptr<ResourceTableType>& lhs,
+ const ResourceNamedTypeRef& rhs) {
+ return lhs->named_type < rhs;
}
template <typename T>
@@ -115,18 +116,24 @@ ResourceTablePackage* ResourceTable::FindOrCreatePackage(const android::StringPi
}
template <typename Func, typename Elements>
-static ResourceTableType* FindTypeRunAction(ResourceType type, Elements& entries, Func action) {
+static ResourceTableType* FindTypeRunAction(const ResourceNamedTypeRef& type, Elements& entries,
+ Func action) {
const auto iter = std::lower_bound(entries.begin(), entries.end(), type, less_than_type);
- const bool found = iter != entries.end() && type == (*iter)->type;
+ const bool found = iter != entries.end() && type == (*iter)->named_type;
return action(found, iter);
}
-ResourceTableType* ResourceTablePackage::FindType(ResourceType type) const {
+ResourceTableType* ResourceTablePackage::FindTypeWithDefaultName(const ResourceType type) const {
+ auto named_type = ResourceNamedTypeWithDefaultName(type);
+ return FindType(named_type);
+}
+
+ResourceTableType* ResourceTablePackage::FindType(const ResourceNamedTypeRef& type) const {
return FindTypeRunAction(type, types,
[&](bool found, auto& iter) { return found ? iter->get() : nullptr; });
}
-ResourceTableType* ResourceTablePackage::FindOrCreateType(ResourceType type) {
+ResourceTableType* ResourceTablePackage::FindOrCreateType(const ResourceNamedTypeRef& type) {
return FindTypeRunAction(type, types, [&](bool found, auto& iter) {
return found ? iter->get() : types.emplace(iter, new ResourceTableType(type))->get();
});
@@ -329,7 +336,7 @@ struct PackageViewComparer {
struct TypeViewComparer {
bool operator()(const ResourceTableTypeView& lhs, const ResourceTableTypeView& rhs) {
- return lhs.id != rhs.id ? lhs.id < rhs.id : lhs.type < rhs.type;
+ return lhs.id != rhs.id ? lhs.id < rhs.id : lhs.named_type < rhs.named_type;
}
};
@@ -355,7 +362,8 @@ void InsertEntryIntoTableView(ResourceTableView& table, const ResourceTablePacka
id ? id.value().package_id() : std::optional<uint8_t>{}};
auto view_package = package_inserter.Insert(table.packages, std::move(new_package));
- ResourceTableTypeView new_type{type->type, id ? id.value().type_id() : std::optional<uint8_t>{}};
+ ResourceTableTypeView new_type{type->named_type,
+ id ? id.value().type_id() : std::optional<uint8_t>{}};
auto view_type = type_inserter.Insert(view_package->types, std::move(new_type));
if (visibility.level == Visibility::Level::kPublic) {
@@ -420,13 +428,14 @@ ResourceTableView ResourceTable::GetPartitionedView(const ResourceTableViewOptio
// we can reuse those packages for other types that need to be extracted from this package.
// `start_index` is the index of the first newly created package that can be reused.
const size_t start_index = new_packages.size();
- std::map<ResourceType, size_t> type_new_package_index;
+ std::map<ResourceNamedType, size_t> type_new_package_index;
for (auto type_it = package.types.begin(); type_it != package.types.end();) {
auto& type = *type_it;
- auto type_index_iter = type_new_package_index.find(type.type);
+ auto type_index_iter = type_new_package_index.find(type.named_type);
if (type_index_iter == type_new_package_index.end()) {
// First occurrence of the resource type in this package. Keep it in this package.
- type_new_package_index.insert(type_index_iter, std::make_pair(type.type, start_index));
+ type_new_package_index.insert(type_index_iter,
+ std::make_pair(type.named_type, start_index));
++type_it;
continue;
}
@@ -440,7 +449,7 @@ ResourceTableView ResourceTable::GetPartitionedView(const ResourceTableViewOptio
// Move the type into a new package
auto& other_package = new_packages[index];
- type_new_package_index[type.type] = index + 1;
+ type_new_package_index[type.named_type] = index + 1;
type_inserter.Insert(other_package.types, std::move(type));
type_it = package.types.erase(type_it);
}
@@ -473,7 +482,7 @@ bool ResourceTable::AddResource(NewResource&& res, IDiagnostics* diag) {
}
auto package = FindOrCreatePackage(res.name.package);
- auto type = package->FindOrCreateType(res.name.type.type);
+ auto type = package->FindOrCreateType(res.name.type);
auto entry_it = std::equal_range(type->entries.begin(), type->entries.end(), res.name.entry,
NameEqualRange<ResourceEntry>{});
const size_t entry_count = std::distance(entry_it.first, entry_it.second);
@@ -593,7 +602,7 @@ std::optional<ResourceTable::SearchResult> ResourceTable::FindResource(
return {};
}
- ResourceTableType* type = package->FindType(name.type.type);
+ ResourceTableType* type = package->FindType(name.type);
if (type == nullptr) {
return {};
}
@@ -612,7 +621,7 @@ std::optional<ResourceTable::SearchResult> ResourceTable::FindResource(const Res
return {};
}
- ResourceTableType* type = package->FindType(name.type.type);
+ ResourceTableType* type = package->FindType(name.type);
if (type == nullptr) {
return {};
}
@@ -633,7 +642,7 @@ bool ResourceTable::RemoveResource(const ResourceNameRef& name, ResourceId id) c
return {};
}
- ResourceTableType* type = package->FindType(name.type.type);
+ ResourceTableType* type = package->FindType(name.type);
if (type == nullptr) {
return {};
}
@@ -655,7 +664,7 @@ std::unique_ptr<ResourceTable> ResourceTable::Clone() const {
for (const auto& pkg : packages) {
ResourceTablePackage* new_pkg = new_table->FindOrCreatePackage(pkg->name);
for (const auto& type : pkg->types) {
- ResourceTableType* new_type = new_pkg->FindOrCreateType(type->type);
+ ResourceTableType* new_type = new_pkg->FindOrCreateType(type->named_type);
new_type->visibility_level = type->visibility_level;
for (const auto& entry : type->entries) {
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 2e17659b0679..7aa8b0f0c8ef 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -168,7 +168,7 @@ class ResourceEntry {
class ResourceTableType {
public:
// The logical type of resource (string, drawable, layout, etc.).
- const ResourceType type;
+ const ResourceNamedType named_type;
// Whether this type is public (and must maintain the same type ID across builds).
Visibility::Level visibility_level = Visibility::Level::kUndefined;
@@ -176,7 +176,9 @@ class ResourceTableType {
// List of resources for this type.
std::vector<std::unique_ptr<ResourceEntry>> entries;
- explicit ResourceTableType(const ResourceType type) : type(type) {}
+ explicit ResourceTableType(const ResourceNamedTypeRef& type)
+ : named_type(type.ToResourceNamedType()) {
+ }
ResourceEntry* CreateEntry(const android::StringPiece& name);
ResourceEntry* FindEntry(const android::StringPiece& name) const;
@@ -196,8 +198,9 @@ class ResourceTablePackage {
}
ResourceTablePackage() = default;
- ResourceTableType* FindType(ResourceType type) const;
- ResourceTableType* FindOrCreateType(ResourceType type);
+ ResourceTableType* FindTypeWithDefaultName(const ResourceType type) const;
+ ResourceTableType* FindType(const ResourceNamedTypeRef& type) const;
+ ResourceTableType* FindOrCreateType(const ResourceNamedTypeRef& type);
private:
DISALLOW_COPY_AND_ASSIGN(ResourceTablePackage);
@@ -217,7 +220,7 @@ struct ResourceTableEntryView {
};
struct ResourceTableTypeView {
- ResourceType type;
+ ResourceNamedType named_type;
std::optional<uint8_t> id;
Visibility::Level visibility_level = Visibility::Level::kUndefined;
diff --git a/tools/aapt2/ResourceUtils.cpp b/tools/aapt2/ResourceUtils.cpp
index 23f6c88aad91..b4e79ca8ca08 100644
--- a/tools/aapt2/ResourceUtils.cpp
+++ b/tools/aapt2/ResourceUtils.cpp
@@ -40,6 +40,23 @@ using ::android::base::StringPrintf;
namespace aapt {
namespace ResourceUtils {
+static std::optional<ResourceNamedType> ToResourceNamedType(const char16_t* type16,
+ const char* type, size_t type_len) {
+ std::optional<ResourceNamedTypeRef> parsed_type;
+ if (type16) {
+ auto converted = util::Utf16ToUtf8(StringPiece16(type16, type_len));
+ parsed_type = ParseResourceNamedType(converted);
+ } else if (type) {
+ parsed_type = ParseResourceNamedType(StringPiece(type, type_len));
+ } else {
+ return {};
+ }
+ if (!parsed_type) {
+ return {};
+ }
+ return parsed_type->ToResourceNamedType();
+}
+
std::optional<ResourceName> ToResourceName(const android::ResTable::resource_name& name_in) {
// TODO: Remove this when ResTable and AssetManager(1) are removed from AAPT2
ResourceName name_out;
@@ -50,20 +67,12 @@ std::optional<ResourceName> ToResourceName(const android::ResTable::resource_nam
name_out.package =
util::Utf16ToUtf8(StringPiece16(name_in.package, name_in.packageLen));
- std::optional<ResourceNamedTypeRef> type;
- if (name_in.type) {
- type = ParseResourceNamedType(util::Utf16ToUtf8(StringPiece16(name_in.type, name_in.typeLen)));
- } else if (name_in.type8) {
- type = ParseResourceNamedType(StringPiece(name_in.type8, name_in.typeLen));
- } else {
- return {};
- }
-
+ std::optional<ResourceNamedType> type =
+ ToResourceNamedType(name_in.type, name_in.name8, name_in.typeLen);
if (!type) {
return {};
}
-
- name_out.type = type->ToResourceNamedType();
+ name_out.type = *type;
if (name_in.name) {
name_out.entry =
@@ -84,21 +93,12 @@ std::optional<ResourceName> ToResourceName(const android::AssetManager2::Resourc
name_out.package = std::string(name_in.package, name_in.package_len);
- std::optional<ResourceNamedTypeRef> type;
- if (name_in.type16) {
- type =
- ParseResourceNamedType(util::Utf16ToUtf8(StringPiece16(name_in.type16, name_in.type_len)));
- } else if (name_in.type) {
- type = ParseResourceNamedType(StringPiece(name_in.type, name_in.type_len));
- } else {
- return {};
- }
-
+ std::optional<ResourceNamedType> type =
+ ToResourceNamedType(name_in.type16, name_in.type, name_in.type_len);
if (!type) {
return {};
}
-
- name_out.type = type->ToResourceNamedType();
+ name_out.type = *type;
if (name_in.entry16) {
name_out.entry =
diff --git a/tools/aapt2/Resource_test.cpp b/tools/aapt2/Resource_test.cpp
index 2c55d1d548db..01d3c84e05ba 100644
--- a/tools/aapt2/Resource_test.cpp
+++ b/tools/aapt2/Resource_test.cpp
@@ -135,13 +135,13 @@ TEST(ResourceTypeTest, ParseResourceNamedType) {
type = ParseResourceNamedType("layout");
EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout", ResourceType::kLayout))));
- type = ParseResourceNamedType("layout:2");
- EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout:2", ResourceType::kLayout))));
+ type = ParseResourceNamedType("layout.2");
+ EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout.2", ResourceType::kLayout))));
- type = ParseResourceNamedType("layout:another");
- EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout:another", ResourceType::kLayout))));
+ type = ParseResourceNamedType("layout.another");
+ EXPECT_THAT(type, Optional(Eq(ResourceNamedType("layout.another", ResourceType::kLayout))));
- type = ParseResourceNamedType("layout:");
+ type = ParseResourceNamedType("layout.");
EXPECT_THAT(type, Eq(std::nullopt));
type = ParseResourceNamedType("layout2");
diff --git a/tools/aapt2/cmd/Compile.cpp b/tools/aapt2/cmd/Compile.cpp
index fe560180bd48..e27b9aae26fa 100644
--- a/tools/aapt2/cmd/Compile.cpp
+++ b/tools/aapt2/cmd/Compile.cpp
@@ -243,9 +243,9 @@ static bool CompileTable(IAaptContext* context, const CompileOptions& options,
r_txt_printer.Print("private ");
}
- if (type->type != ResourceType::kStyleable) {
+ if (type->named_type.type != ResourceType::kStyleable) {
r_txt_printer.Print("int ");
- r_txt_printer.Print(to_string(type->type));
+ r_txt_printer.Print(type->named_type.to_string());
r_txt_printer.Print(" ");
r_txt_printer.Println(entry->name);
} else {
diff --git a/tools/aapt2/cmd/Diff.cpp b/tools/aapt2/cmd/Diff.cpp
index d9e8c921dbc5..a854146c28f6 100644
--- a/tools/aapt2/cmd/Diff.cpp
+++ b/tools/aapt2/cmd/Diff.cpp
@@ -105,7 +105,7 @@ static bool EmitResourceConfigValueDiff(
Value* value_b = config_value_b->value.get();
if (!value_a->Equals(value_b)) {
std::stringstream str_stream;
- str_stream << "value " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+ str_stream << "value " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
<< " config=" << config_value_a->config << " does not match:\n";
value_a->Print(&str_stream);
str_stream << "\n vs \n";
@@ -128,7 +128,7 @@ static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a,
auto config_value_b = entry_b.FindValue(config_value_a->config);
if (!config_value_b) {
std::stringstream str_stream;
- str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+ str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
<< " config=" << config_value_a->config;
EmitDiffLine(apk_b->GetSource(), str_stream.str());
diff = true;
@@ -143,7 +143,7 @@ static bool EmitResourceEntryDiff(IAaptContext* context, LoadedApk* apk_a,
auto config_value_a = entry_a.FindValue(config_value_b->config);
if (!config_value_a) {
std::stringstream str_stream;
- str_stream << "new config " << pkg_b.name << ":" << type_b.type << "/" << entry_b.name
+ str_stream << "new config " << pkg_b.name << ":" << type_b.named_type << "/" << entry_b.name
<< " config=" << config_value_b->config;
EmitDiffLine(apk_b->GetSource(), str_stream.str());
diff = true;
@@ -164,13 +164,15 @@ static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
if (entry_b_iter == type_b.entries.end()) {
// Type A contains a type that type B does not have.
std::stringstream str_stream;
- str_stream << "missing " << pkg_a.name << ":" << type_a.type << "/" << entry_a_iter->name;
+ str_stream << "missing " << pkg_a.name << ":" << type_a.named_type << "/"
+ << entry_a_iter->name;
EmitDiffLine(apk_a->GetSource(), str_stream.str());
diff = true;
} else if (entry_a_iter == type_a.entries.end()) {
// Type B contains a type that type A does not have.
std::stringstream str_stream;
- str_stream << "new entry " << pkg_b.name << ":" << type_b.type << "/" << entry_b_iter->name;
+ str_stream << "new entry " << pkg_b.name << ":" << type_b.named_type << "/"
+ << entry_b_iter->name;
EmitDiffLine(apk_b->GetSource(), str_stream.str());
diff = true;
} else {
@@ -178,7 +180,7 @@ static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
const auto& entry_b = *entry_b_iter;
if (IsSymbolVisibilityDifferent(entry_a.visibility, entry_b.visibility)) {
std::stringstream str_stream;
- str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+ str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
<< " has different visibility (";
if (entry_b.visibility.staged_api) {
str_stream << "STAGED ";
@@ -203,7 +205,7 @@ static bool EmitResourceTypeDiff(IAaptContext* context, LoadedApk* apk_a,
} else if (IsIdDiff(entry_a.visibility.level, entry_a.id, entry_b.visibility.level,
entry_b.id)) {
std::stringstream str_stream;
- str_stream << pkg_a.name << ":" << type_a.type << "/" << entry_a.name
+ str_stream << pkg_a.name << ":" << type_a.named_type << "/" << entry_a.name
<< " has different public ID (";
if (entry_b.id) {
str_stream << "0x" << std::hex << entry_b.id.value();
@@ -243,13 +245,13 @@ static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
if (type_b_iter == pkg_b.types.end()) {
// Type A contains a type that type B does not have.
std::stringstream str_stream;
- str_stream << "missing " << pkg_a.name << ":" << type_a_iter->type;
+ str_stream << "missing " << pkg_a.name << ":" << type_a_iter->named_type;
EmitDiffLine(apk_a->GetSource(), str_stream.str());
diff = true;
} else if (type_a_iter == pkg_a.types.end()) {
// Type B contains a type that type A does not have.
std::stringstream str_stream;
- str_stream << "new type " << pkg_b.name << ":" << type_b_iter->type;
+ str_stream << "new type " << pkg_b.name << ":" << type_b_iter->named_type;
EmitDiffLine(apk_b->GetSource(), str_stream.str());
diff = true;
} else {
@@ -257,7 +259,7 @@ static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
const auto& type_b = *type_b_iter;
if (type_a.visibility_level != type_b.visibility_level) {
std::stringstream str_stream;
- str_stream << pkg_a.name << ":" << type_a.type << " has different visibility (";
+ str_stream << pkg_a.name << ":" << type_a.named_type << " has different visibility (";
if (type_b.visibility_level == Visibility::Level::kPublic) {
str_stream << "PUBLIC";
} else {
@@ -274,7 +276,7 @@ static bool EmitResourcePackageDiff(IAaptContext* context, LoadedApk* apk_a,
diff = true;
} else if (IsIdDiff(type_a.visibility_level, type_a.id, type_b.visibility_level, type_b.id)) {
std::stringstream str_stream;
- str_stream << pkg_a.name << ":" << type_a.type << " has different public ID (";
+ str_stream << pkg_a.name << ":" << type_a.named_type << " has different public ID (";
if (type_b.id) {
str_stream << "0x" << std::hex << type_b.id.value();
} else {
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index 790f2b34c58b..bd74cc7be350 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -556,7 +556,7 @@ bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archiv
file_op.config = config_value->config;
file_op.file_to_copy = file;
- if (type->type != ResourceType::kRaw &&
+ if (type->named_type.type != ResourceType::kRaw &&
(file_ref->type == ResourceFile::Type::kBinaryXml ||
file_ref->type == ResourceFile::Type::kProtoXml)) {
std::unique_ptr<io::IData> data = file->OpenAsData();
@@ -596,7 +596,8 @@ bool ResourceFileFlattener::Flatten(ResourceTable* table, IArchiveWriter* archiv
file_op.xml_to_flatten->file.config = config_value->config;
file_op.xml_to_flatten->file.source = file_ref->GetSource();
- file_op.xml_to_flatten->file.name = ResourceName(pkg->name, type->type, entry->name);
+ file_op.xml_to_flatten->file.name =
+ ResourceName(pkg->name, type->named_type, entry->name);
}
// NOTE(adamlesinski): Explicitly construct a StringPiece here, or
@@ -1009,7 +1010,7 @@ class Linker {
// We have a package that is not related to the one we're building!
for (const auto& type : package->types) {
for (const auto& entry : type->entries) {
- ResourceNameRef res_name(package->name, type->type, entry->name);
+ ResourceNameRef res_name(package->name, type->named_type, entry->name);
for (const auto& config_value : entry->values) {
// Special case the occurrence of an ID that is being generated
@@ -1046,7 +1047,7 @@ class Linker {
for (const auto& type : package->types) {
for (const auto& entry : type->entries) {
if (entry->id) {
- ResourceNameRef res_name(package->name, type->type, entry->name);
+ ResourceNameRef res_name(package->name, type->named_type, entry->name);
context_->GetDiagnostics()->Error(DiagMessage() << "resource " << res_name << " has ID "
<< entry->id.value() << " assigned");
return false;
@@ -1057,6 +1058,83 @@ class Linker {
return true;
}
+ bool VerifyLocaleFormat(xml::XmlResource* manifest, IDiagnostics* diag) {
+ // Skip it if the Manifest doesn't declare the localeConfig attribute within the <application>
+ // element.
+ const xml::Element* application = manifest->root->FindChild("", "application");
+ if (!application) {
+ return true;
+ }
+ const xml::Attribute* localeConfig =
+ application->FindAttribute(xml::kSchemaAndroid, "localeConfig");
+ if (!localeConfig) {
+ return true;
+ }
+
+ if (localeConfig->compiled_value) {
+ const auto localeconfig_reference = ValueCast<Reference>(localeConfig->compiled_value.get());
+ const auto localeconfig_entry =
+ ResolveTableEntry(context_, &final_table_, localeconfig_reference);
+ if (!localeconfig_entry) {
+ return true;
+ }
+
+ for (const auto& value : localeconfig_entry->values) {
+ // Load an XML file which is linked from the localeConfig attribute.
+ const std::string& path = value->value->GetSource().path;
+ std::unique_ptr<xml::XmlResource> localeConfig_xml = LoadXml(path, diag);
+ if (!localeConfig_xml) {
+ diag->Error(DiagMessage(path) << "can't load the XML");
+ return false;
+ }
+
+ xml::Element* localeConfig_el = xml::FindRootElement(localeConfig_xml->root.get());
+ if (!localeConfig_el) {
+ diag->Error(DiagMessage(path) << "no root tag defined");
+ return false;
+ }
+ if (localeConfig_el->name != "locale-config") {
+ diag->Error(DiagMessage(path) << "invalid element name: " << localeConfig_el->name
+ << ", expected: locale-config");
+ return false;
+ }
+
+ for (const xml::Element* child_el : localeConfig_el->GetChildElements()) {
+ if (child_el->name == "locale") {
+ if (const xml::Attribute* locale_name_attr =
+ child_el->FindAttribute(xml::kSchemaAndroid, "name")) {
+ const std::string& locale_name = locale_name_attr->value;
+ const std::string valid_name = ConvertToBCP47Tag(locale_name);
+
+ // Start to verify the locale format
+ ConfigDescription config;
+ if (!ConfigDescription::Parse(valid_name, &config)) {
+ diag->Error(DiagMessage(path) << "invalid configuration: " << locale_name);
+ return false;
+ }
+ } else {
+ diag->Error(DiagMessage(path) << "the attribute android:name is not found");
+ return false;
+ }
+ } else {
+ diag->Error(DiagMessage(path)
+ << "invalid element name: " << child_el->name << ", expected: locale");
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+
+ std::string ConvertToBCP47Tag(const std::string& locale) {
+ std::string bcp47tag = "b+";
+ bcp47tag += locale;
+ std::replace(bcp47tag.begin(), bcp47tag.end(), '-', '+');
+
+ return bcp47tag;
+ }
+
std::unique_ptr<IArchiveWriter> MakeArchiveWriter(const StringPiece& out) {
if (options_.output_to_directory) {
return CreateDirectoryArchiveWriter(context_->GetDiagnostics(), out);
@@ -1939,7 +2017,7 @@ class Linker {
for (auto& package : final_table_.packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
- ResourceName name(package->name, type->type, entry->name);
+ ResourceName name(package->name, type->named_type, entry->name);
// The IDs are guaranteed to exist.
options_.stable_id_map[std::move(name)] = entry->id.value();
}
@@ -2180,6 +2258,10 @@ class Linker {
return 1;
}
+ if (!VerifyLocaleFormat(manifest_xml.get(), context_->GetDiagnostics())) {
+ return 1;
+ };
+
if (!WriteApk(archive_writer.get(), &proguard_keep_set, manifest_xml.get(), &final_table_)) {
return 1;
}
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 430c184ef87d..7b1236ab4a5e 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -22,6 +22,7 @@
#include "LoadedApk.h"
#include "test/Test.h"
+using android::ConfigDescription;
using testing::Eq;
using testing::HasSubstr;
using testing::IsNull;
@@ -783,4 +784,51 @@ TEST_F(LinkTest, MacroSubstitution) {
EXPECT_THAT(xml_attrs[1].value, Eq("Hello World!"));
}
+TEST_F(LinkTest, ParseLocaleConfig) {
+ StdErrDiagnostics diag;
+ const std::string xml_values =
+ R"(<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
+ <locale android:name="pt"/>
+ <locale android:name="chr"/>
+ <locale android:name="chr-US"/>
+ <locale android:name="zh-Hant"/>
+ <locale android:name="es-419"/>
+ <locale android:name="en-US"/>
+ <locale android:name="zh-Hans-SG"/>
+ </locale-config>)";
+
+ const std::string res = GetTestPath("test-res");
+ ASSERT_TRUE(CompileFile(GetTestPath("res/xml/locale_config.xml"), xml_values, res, &diag));
+
+ const std::string out_apk = GetTestPath("out.apk");
+ auto link_args = LinkCommandBuilder(this)
+ .SetManifestFile(ManifestBuilder(this).SetPackageName("com.test").Build())
+ .AddCompiledResDir(res, &diag)
+ .AddFlag("--no-auto-version")
+ .Build(out_apk);
+ ASSERT_TRUE(Link(link_args, &diag));
+
+ std::unique_ptr<LoadedApk> apk = LoadedApk::LoadApkFromPath(out_apk, &diag);
+ ASSERT_THAT(apk, Ne(nullptr));
+
+ auto xml = apk->LoadXml("res/xml/locale_config.xml", &diag);
+ ASSERT_THAT(xml, NotNull());
+ EXPECT_THAT(xml->root->name, Eq("locale-config"));
+ ASSERT_THAT(xml->root->children.size(), Eq(7));
+ for (auto& node : xml->root->children) {
+ const xml::Element* child_el = xml::NodeCast<xml::Element>(node.get());
+ ASSERT_THAT(child_el, NotNull());
+ EXPECT_THAT(child_el->name, Eq("locale"));
+
+ auto& xml_attrs = child_el->attributes;
+ for (auto& attr : xml_attrs) {
+ std::string locale = "b+";
+ locale += attr.value;
+ std::replace(locale.begin(), locale.end(), '-', '+');
+ ConfigDescription config;
+ ASSERT_TRUE(ConfigDescription::Parse(locale, &config));
+ }
+ }
+}
+
} // namespace aapt
diff --git a/tools/aapt2/cmd/Optimize.cpp b/tools/aapt2/cmd/Optimize.cpp
index caa3e60d6af1..e1370fd10ef3 100644
--- a/tools/aapt2/cmd/Optimize.cpp
+++ b/tools/aapt2/cmd/Optimize.cpp
@@ -254,7 +254,7 @@ class Optimizer {
}
if (file_ref->file == nullptr) {
- ResourceNameRef name(pkg->name, type->type, entry->name);
+ ResourceNameRef name(pkg->name, type->named_type, entry->name);
context_->GetDiagnostics()->Warn(DiagMessage(file_ref->GetSource())
<< "file for resource " << name << " with config '"
<< config_value->config << "' not found");
diff --git a/tools/aapt2/compile/IdAssigner.cpp b/tools/aapt2/compile/IdAssigner.cpp
index fa816be43be3..29f9a08f9a10 100644
--- a/tools/aapt2/compile/IdAssigner.cpp
+++ b/tools/aapt2/compile/IdAssigner.cpp
@@ -128,7 +128,7 @@ bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) {
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
- const ResourceName name(package->name, type->type, entry->name);
+ const ResourceName name(package->name, type->named_type, entry->name);
if (entry->id && !assigned_ids.ReserveId(name, entry->id.value(), entry->visibility,
context->GetDiagnostics())) {
return false;
@@ -175,7 +175,7 @@ bool IdAssigner::Consume(IAaptContext* context, ResourceTable* table) {
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
- const ResourceName name(package->name, type->type, entry->name);
+ const ResourceName name(package->name, type->named_type, entry->name);
if (entry->id) {
continue;
}
diff --git a/tools/aapt2/compile/IdAssigner_test.cpp b/tools/aapt2/compile/IdAssigner_test.cpp
index d3575716ae4f..8911dad39470 100644
--- a/tools/aapt2/compile/IdAssigner_test.cpp
+++ b/tools/aapt2/compile/IdAssigner_test.cpp
@@ -191,12 +191,12 @@ TEST_F(IdAssignerTests, ExaustEntryIdsLastIdIsPublic) {
for (auto& entry : type->entries) {
if (!entry->id) {
return ::testing::AssertionFailure()
- << "resource " << ResourceNameRef(package->name, type->type, entry->name)
+ << "resource " << ResourceNameRef(package->name, type->named_type, entry->name)
<< " has no ID";
}
if (!seen_ids.insert(entry->id.value()).second) {
return ::testing::AssertionFailure()
- << "resource " << ResourceNameRef(package->name, type->type, entry->name)
+ << "resource " << ResourceNameRef(package->name, type->named_type, entry->name)
<< " has a non-unique ID" << std::hex << entry->id.value() << std::dec;
}
}
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index c65c55024bab..eea7efc449b9 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -18,19 +18,19 @@
#include <algorithm>
#include <map>
+#include <optional>
#include <string>
-#include "android-base/logging.h"
-#include "android-base/macros.h"
-#include "android-base/stringprintf.h"
-#include "androidfw/ResourceTypes.h"
-#include "androidfw/TypeWrappers.h"
-
#include "ResourceTable.h"
#include "ResourceUtils.h"
#include "ResourceValues.h"
#include "Source.h"
#include "ValueVisitor.h"
+#include "android-base/logging.h"
+#include "android-base/macros.h"
+#include "android-base/stringprintf.h"
+#include "androidfw/ResourceTypes.h"
+#include "androidfw/TypeWrappers.h"
#include "format/binary/ResChunkPullParser.h"
#include "util/Util.h"
@@ -364,7 +364,7 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
config.copyFromDtoH(type->config);
const std::string type_str = util::GetString(type_pool_, type->id - 1);
- const ResourceType* parsed_type = ParseResourceType(type_str);
+ std::optional<ResourceNamedTypeRef> parsed_type = ParseResourceNamedType(type_str);
if (!parsed_type) {
diag_->Warn(DiagMessage(source_)
<< "invalid type name '" << type_str << "' for type with ID " << type->id);
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index a9192e889c17..b42e7d0c34cd 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -360,7 +360,7 @@ class PackageFlattener {
if (!FlattenValue(&flat_entry, &values_buffer)) {
diag_->Error(DiagMessage()
<< "failed to flatten resource '"
- << ResourceNameRef(package_.name, type.type, flat_entry.entry->name)
+ << ResourceNameRef(package_.name, type.named_type, flat_entry.entry->name)
<< "' for configuration '" << config << "'");
return false;
}
@@ -447,7 +447,7 @@ class PackageFlattener {
ResourceId id = android::make_resid(package_.id.value(), type.id.value(), entry.id.value());
CHECK(seen_ids.find(id) == seen_ids.end())
<< "multiple overlayable definitions found for resource "
- << ResourceName(package_.name, type.type, entry.name).to_string();
+ << ResourceName(package_.name, type.named_type, entry.name).to_string();
seen_ids.insert(id);
// Find the overlayable chunk with the specified name
@@ -592,7 +592,8 @@ class PackageFlattener {
bool FlattenTypes(BigBuffer* buffer) {
size_t expected_type_id = 1;
for (const ResourceTableTypeView& type : package_.types) {
- if (type.type == ResourceType::kStyleable || type.type == ResourceType::kMacro) {
+ if (type.named_type.type == ResourceType::kStyleable ||
+ type.named_type.type == ResourceType::kMacro) {
// Styleables and macros are not real resource types.
continue;
}
@@ -606,7 +607,7 @@ class PackageFlattener {
expected_type_id++;
}
expected_type_id++;
- type_pool_.MakeRef(to_string(type.type));
+ type_pool_.MakeRef(type.named_type.to_string());
if (!FlattenTypeSpec(type, type.entries, buffer)) {
return false;
@@ -634,7 +635,7 @@ class PackageFlattener {
}
uint32_t local_key_index;
- ResourceName resource_name({}, type.type, entry.name);
+ ResourceName resource_name({}, type.named_type, entry.name);
if (!collapse_key_stringpool_ ||
name_collapse_exemptions_.find(resource_name) != name_collapse_exemptions_.end()) {
local_key_index = (uint32_t)key_pool_.MakeRef(entry.name).index();
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index cd1c0af702cf..c73bbb51f639 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -837,4 +837,45 @@ TEST_F(TableFlattenerTest, FlattenOverlayableNoPolicyFails) {
ASSERT_FALSE(Flatten(context_.get(), {}, table.get(), &output_table));
}
+TEST_F(TableFlattenerTest, FlattenCustomResourceTypes) {
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .AddSimple("com.app.test:id/one", ResourceId(0x7f010000))
+ .AddSimple("com.app.test:id.2/two", ResourceId(0x7f020000))
+ .AddValue("com.app.test:integer/one", ResourceId(0x7f030000),
+ util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 10u))
+ .AddValue("com.app.test:integer.1/one", ResourceId(0x7f040000),
+ util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 1u))
+ .AddValue("com.app.test:integer.1/one", test::ParseConfigOrDie("v1"),
+ ResourceId(0x7f040000),
+ util::make_unique<BinaryPrimitive>(uint8_t(Res_value::TYPE_INT_DEC), 2u))
+ .AddString("com.app.test:layout.custom/bar", ResourceId(0x7f050000), "res/layout/bar.xml")
+ .Build();
+
+ ResTable res_table;
+ ASSERT_TRUE(Flatten(context_.get(), {}, table.get(), &res_table));
+
+ EXPECT_TRUE(Exists(&res_table, "com.app.test:id/one", ResourceId(0x7f010000), {},
+ Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+
+ EXPECT_TRUE(Exists(&res_table, "com.app.test:id.2/two", ResourceId(0x7f020000), {},
+ Res_value::TYPE_INT_BOOLEAN, 0u, 0u));
+
+ EXPECT_TRUE(Exists(&res_table, "com.app.test:integer/one", ResourceId(0x7f030000), {},
+ Res_value::TYPE_INT_DEC, 10u, 0u));
+
+ EXPECT_TRUE(Exists(&res_table, "com.app.test:integer.1/one", ResourceId(0x7f040000), {},
+ Res_value::TYPE_INT_DEC, 1u, ResTable_config::CONFIG_VERSION));
+
+ EXPECT_TRUE(Exists(&res_table, "com.app.test:integer.1/one", ResourceId(0x7f040000),
+ test::ParseConfigOrDie("v1"), Res_value::TYPE_INT_DEC, 2u,
+ ResTable_config::CONFIG_VERSION));
+
+ std::u16string bar_path = u"res/layout/bar.xml";
+ auto idx = res_table.getTableStringBlock(0)->indexOfString(bar_path.data(), bar_path.size());
+ ASSERT_TRUE(idx.has_value());
+ EXPECT_TRUE(Exists(&res_table, "com.app.test:layout.custom/bar", ResourceId(0x7f050000), {},
+ Res_value::TYPE_STRING, (uint32_t)*idx, 0u));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index 236c38167545..82c7248f4b88 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -429,8 +429,8 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr
ResourceTablePackage* pkg = out_table->FindOrCreatePackage(pb_package.package_name());
for (const pb::Type& pb_type : pb_package.type()) {
- const ResourceType* res_type = ParseResourceType(pb_type.name());
- if (res_type == nullptr) {
+ auto res_type = ParseResourceNamedType(pb_type.name());
+ if (!res_type) {
std::ostringstream error;
error << "unknown type '" << pb_type.name() << "'";
*out_error = error.str();
@@ -515,7 +515,7 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr
ResourceId resid(pb_package.package_id().id(), pb_type.type_id().id(),
pb_entry.entry_id().id());
if (resid.is_valid()) {
- id_index[resid] = ResourceNameRef(pkg->name, type->type, entry->name);
+ id_index[resid] = ResourceNameRef(pkg->name, type->named_type, entry->name);
}
for (const pb::ConfigValue& pb_config_value : pb_entry.config_value()) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index f3b7f758e170..bb8ea0ce4f29 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -358,7 +358,7 @@ void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table
if (type.id) {
pb_type->mutable_type_id()->set_id(type.id.value());
}
- pb_type->set_name(to_string(type.type).to_string());
+ pb_type->set_name(type.named_type.to_string());
// hardcoded string uses characters which make it an invalid resource name
static const char* obfuscated_resource_name = "0_resource_name_obfuscated";
@@ -367,7 +367,7 @@ void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table
if (entry.id) {
pb_entry->mutable_entry_id()->set_id(entry.id.value());
}
- ResourceName resource_name({}, type.type, entry.name);
+ ResourceName resource_name({}, type.named_type, entry.name);
if (options.collapse_key_stringpool &&
options.name_collapse_exemptions.find(resource_name) ==
options.name_collapse_exemptions.end()) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index d1d72e012b31..0247021f1f8a 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -951,4 +951,76 @@ TEST(ProtoSerializeTest, StagedId) {
EXPECT_THAT(result.value().entry->staged_id.value().id, Eq(ResourceId(0x01ff0001)));
}
+TEST(ProtoSerializeTest, CustomResourceTypes) {
+ const uint32_t id_one_id = 0x7f020000;
+ const uint32_t id_2_two_id = 0x7f030000;
+ const uint32_t integer_three_id = 0x7f030000;
+ const uint32_t integer_1_four_id = 0x7f030000;
+ const uint32_t layout_bar_id = 0x7f050000;
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .AddSimple("com.app.test:id/one", ResourceId(id_one_id))
+ .AddSimple("com.app.test:id.2/two", ResourceId(id_2_two_id))
+ .AddValue(
+ "com.app.test:integer/one", ResourceId(integer_three_id),
+ util::make_unique<BinaryPrimitive>(uint8_t(android::Res_value::TYPE_INT_DEC), 10u))
+ .AddValue(
+ "com.app.test:integer.1/one", ResourceId(integer_1_four_id),
+ util::make_unique<BinaryPrimitive>(uint8_t(android::Res_value::TYPE_INT_DEC), 1u))
+ .AddValue(
+ "com.app.test:integer.1/one", test::ParseConfigOrDie("v1"),
+ ResourceId(integer_1_four_id),
+ util::make_unique<BinaryPrimitive>(uint8_t(android::Res_value::TYPE_INT_DEC), 2u))
+ .AddFileReference("com.app.test:layout.custom/bar", ResourceId(layout_bar_id),
+ "res/layout/bar.xml")
+ .Build();
+
+ test::TestFile file_a("res/layout/bar.xml");
+ MockFileCollection files;
+ EXPECT_CALL(files, FindFile(Eq("res/layout/bar.xml"))).WillRepeatedly(::testing::Return(&file_a));
+
+ ResourceTable new_table;
+ pb::ResourceTable pb_table;
+ std::string error;
+ SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
+ DeserializeTableFromPb(pb_table, &files, &new_table, &error);
+ ASSERT_THAT(error, IsEmpty());
+
+ auto bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(
+ &new_table, "com.app.test:integer.1/one", ConfigDescription::DefaultConfig(), "");
+ ASSERT_THAT(bp, NotNull());
+ EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
+ EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("1")->value.data));
+
+ bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "com.app.test:integer.1/one",
+ test::ParseConfigOrDie("v1"), "");
+ ASSERT_THAT(bp, NotNull());
+ EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
+ EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("2")->value.data));
+
+ bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "com.app.test:integer/one",
+ ConfigDescription::DefaultConfig(), "");
+ ASSERT_THAT(bp, NotNull());
+ EXPECT_THAT(bp->value.dataType, Eq(android::Res_value::TYPE_INT_DEC));
+ EXPECT_THAT(bp->value.data, Eq(ResourceUtils::TryParseInt("10")->value.data));
+
+ bp = test::GetValueForConfigAndProduct<BinaryPrimitive>(&new_table, "com.app.test:integer/one",
+ test::ParseConfigOrDie("v1"), "");
+ ASSERT_THAT(bp, IsNull());
+
+ auto id = test::GetValueForConfigAndProduct<Id>(&new_table, "com.app.test:id/one",
+ ConfigDescription::DefaultConfig(), "");
+ ASSERT_THAT(id, NotNull());
+
+ id = test::GetValueForConfigAndProduct<Id>(&new_table, "com.app.test:id.2/two",
+ ConfigDescription::DefaultConfig(), "");
+ ASSERT_THAT(id, NotNull());
+
+ auto custom_layout = test::GetValueForConfigAndProduct<FileReference>(
+ &new_table, "com.app.test:layout.custom/bar", ConfigDescription::DefaultConfig(), "");
+ ASSERT_THAT(custom_layout, NotNull());
+ EXPECT_THAT(*(custom_layout->path), Eq("res/layout/bar.xml"));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index a963d9893f2f..a25ca22c288d 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -548,10 +548,11 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate
}
// We need to make sure we hide the fact that we are generating kAttrPrivate attributes.
- const ResourceNameRef resource_name(
- package_name_to_generate,
- type.type == ResourceType::kAttrPrivate ? ResourceType::kAttr : type.type,
- unmangled_name.value());
+ const auto target_type = type.named_type.type == ResourceType::kAttrPrivate
+ ? ResourceNamedTypeWithDefaultName(ResourceType::kAttr)
+ : type.named_type;
+ const ResourceNameRef resource_name(package_name_to_generate, target_type,
+ unmangled_name.value());
// Check to see if the unmangled name is a valid Java name (not a keyword).
if (!IsValidSymbol(unmangled_name.value())) {
@@ -616,7 +617,8 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
for (const auto& package : table_->packages) {
for (const auto& type : package->types) {
- if (type->type == ResourceType::kAttrPrivate || type->type == ResourceType::kMacro) {
+ if (type->named_type.type == ResourceType::kAttrPrivate ||
+ type->named_type.type == ResourceType::kMacro) {
// We generate kAttrPrivate as part of the kAttr type, so skip them here.
// Macros are not actual resources, so skip them as well.
continue;
@@ -628,7 +630,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
std::unique_ptr<ClassDefinition> class_def;
if (out != nullptr) {
class_def = util::make_unique<ClassDefinition>(
- to_string(type->type), ClassQualifier::kStatic, force_creation_if_empty);
+ to_string(type->named_type.type), ClassQualifier::kStatic, force_creation_if_empty);
}
if (!ProcessType(package_name_to_generate, *package, *type, class_def.get(),
@@ -636,9 +638,10 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
return false;
}
- if (type->type == ResourceType::kAttr) {
+ if (type->named_type.type == ResourceType::kAttr) {
// Also include private attributes in this same class.
- if (const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate)) {
+ if (const ResourceTableType* priv_type =
+ package->FindTypeWithDefaultName(ResourceType::kAttrPrivate)) {
if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(),
rewrite_method.get(), r_txt_printer.get())) {
return false;
@@ -646,7 +649,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
}
}
- if (out != nullptr && type->type == ResourceType::kStyleable && is_public) {
+ if (out != nullptr && type->named_type.type == ResourceType::kStyleable && is_public) {
// When generating a public R class, we don't want Styleable to be part
// of the API. It is only emitted for documentation purposes.
class_def->GetCommentBuilder()->AppendComment("@doconly");
diff --git a/tools/aapt2/java/ProguardRules.cpp b/tools/aapt2/java/ProguardRules.cpp
index e53e22070b62..80a46d553960 100644
--- a/tools/aapt2/java/ProguardRules.cpp
+++ b/tools/aapt2/java/ProguardRules.cpp
@@ -517,7 +517,7 @@ bool CollectResourceReferences(aapt::IAaptContext* context, ResourceTable* table
for (auto& type : pkg->types) {
for (auto& entry : type->entries) {
for (auto& config_value : entry->values) {
- ResourceName from(pkg->name, type->type, entry->name);
+ ResourceName from(pkg->name, type->named_type, entry->name);
ReferenceVisitor visitor(context, from, keep_set);
config_value->value->Accept(&visitor);
}
diff --git a/tools/aapt2/link/AutoVersioner.cpp b/tools/aapt2/link/AutoVersioner.cpp
index 328ac97090a8..3dbd7e613a3e 100644
--- a/tools/aapt2/link/AutoVersioner.cpp
+++ b/tools/aapt2/link/AutoVersioner.cpp
@@ -75,7 +75,7 @@ bool AutoVersioner::Consume(IAaptContext* context, ResourceTable* table) {
CloningValueTransformer cloner(&table->string_pool);
for (auto& package : table->packages) {
for (auto& type : package->types) {
- if (type->type != ResourceType::kStyle) {
+ if (type->named_type.type != ResourceType::kStyle) {
continue;
}
diff --git a/tools/aapt2/link/NoDefaultResourceRemover.cpp b/tools/aapt2/link/NoDefaultResourceRemover.cpp
index 05990de6a9b3..ab3c04e59741 100644
--- a/tools/aapt2/link/NoDefaultResourceRemover.cpp
+++ b/tools/aapt2/link/NoDefaultResourceRemover.cpp
@@ -76,7 +76,7 @@ bool NoDefaultResourceRemover::Consume(IAaptContext* context, ResourceTable* tab
});
for (auto iter = remove_iter; iter != end_iter; ++iter) {
- const ResourceName name(pkg->name, type->type, (*iter)->name);
+ const ResourceName name(pkg->name, type->named_type, (*iter)->name);
IDiagnostics* diag = context->GetDiagnostics();
diag->Warn(DiagMessage() << "removing resource " << name
<< " without required default value");
diff --git a/tools/aapt2/link/PrivateAttributeMover.cpp b/tools/aapt2/link/PrivateAttributeMover.cpp
index 675b02a7e161..8c6c743dfff0 100644
--- a/tools/aapt2/link/PrivateAttributeMover.cpp
+++ b/tools/aapt2/link/PrivateAttributeMover.cpp
@@ -57,7 +57,7 @@ OutputIterator move_if(InputContainer& input_container, OutputIterator result, P
bool PrivateAttributeMover::Consume(IAaptContext* context, ResourceTable* table) {
for (auto& package : table->packages) {
- ResourceTableType* type = package->FindType(ResourceType::kAttr);
+ ResourceTableType* type = package->FindTypeWithDefaultName(ResourceType::kAttr);
if (!type) {
continue;
}
@@ -80,7 +80,8 @@ bool PrivateAttributeMover::Consume(IAaptContext* context, ResourceTable* table)
continue;
}
- ResourceTableType* priv_attr_type = package->FindOrCreateType(ResourceType::kAttrPrivate);
+ auto attr_private_type = ResourceNamedTypeWithDefaultName(ResourceType::kAttrPrivate);
+ ResourceTableType* priv_attr_type = package->FindOrCreateType(attr_private_type);
CHECK(priv_attr_type->entries.empty());
priv_attr_type->entries = std::move(private_attr_entries);
}
diff --git a/tools/aapt2/link/PrivateAttributeMover_test.cpp b/tools/aapt2/link/PrivateAttributeMover_test.cpp
index 168234b36e4a..32335b7f5a9f 100644
--- a/tools/aapt2/link/PrivateAttributeMover_test.cpp
+++ b/tools/aapt2/link/PrivateAttributeMover_test.cpp
@@ -41,13 +41,13 @@ TEST(PrivateAttributeMoverTest, MovePrivateAttributes) {
ResourceTablePackage* package = table->FindPackage("android");
ASSERT_NE(package, nullptr);
- ResourceTableType* type = package->FindType(ResourceType::kAttr);
+ ResourceTableType* type = package->FindTypeWithDefaultName(ResourceType::kAttr);
ASSERT_NE(type, nullptr);
ASSERT_EQ(type->entries.size(), 2u);
EXPECT_NE(type->FindEntry("publicA"), nullptr);
EXPECT_NE(type->FindEntry("publicB"), nullptr);
- type = package->FindType(ResourceType::kAttrPrivate);
+ type = package->FindTypeWithDefaultName(ResourceType::kAttrPrivate);
ASSERT_NE(type, nullptr);
ASSERT_EQ(type->entries.size(), 2u);
EXPECT_NE(type->FindEntry("privateA"), nullptr);
@@ -68,11 +68,11 @@ TEST(PrivateAttributeMoverTest, LeavePrivateAttributesWhenNoPublicAttributesDefi
ResourceTablePackage* package = table->FindPackage("android");
ASSERT_NE(package, nullptr);
- ResourceTableType* type = package->FindType(ResourceType::kAttr);
+ ResourceTableType* type = package->FindTypeWithDefaultName(ResourceType::kAttr);
ASSERT_NE(type, nullptr);
ASSERT_EQ(type->entries.size(), 2u);
- type = package->FindType(ResourceType::kAttrPrivate);
+ type = package->FindTypeWithDefaultName(ResourceType::kAttrPrivate);
ASSERT_EQ(type, nullptr);
}
@@ -87,12 +87,12 @@ TEST(PrivateAttributeMoverTest, DoNotCreatePrivateAttrsIfNoneExist) {
ResourceTablePackage* package = table->FindPackage("android");
ASSERT_NE(nullptr, package);
- ASSERT_EQ(nullptr, package->FindType(ResourceType::kAttrPrivate));
+ ASSERT_EQ(nullptr, package->FindTypeWithDefaultName(ResourceType::kAttrPrivate));
PrivateAttributeMover mover;
ASSERT_TRUE(mover.Consume(context.get(), table.get()));
- ASSERT_EQ(nullptr, package->FindType(ResourceType::kAttrPrivate));
+ ASSERT_EQ(nullptr, package->FindTypeWithDefaultName(ResourceType::kAttrPrivate));
}
} // namespace aapt
diff --git a/tools/aapt2/link/ProductFilter.cpp b/tools/aapt2/link/ProductFilter.cpp
index 793740af3021..0c54a739d347 100644
--- a/tools/aapt2/link/ProductFilter.cpp
+++ b/tools/aapt2/link/ProductFilter.cpp
@@ -98,7 +98,7 @@ bool ProductFilter::Consume(IAaptContext* context, ResourceTable* table) {
// End of the array, or we saw a different config,
// so this must be the end of a range of products.
// Select the product to keep from the set of products defined.
- ResourceNameRef name(pkg->name, type->type, entry->name);
+ ResourceNameRef name(pkg->name, type->named_type, entry->name);
auto value_to_keep = SelectProductToKeep(
name, start_range_iter, iter, context->GetDiagnostics());
if (value_to_keep == iter) {
diff --git a/tools/aapt2/link/ReferenceLinker.cpp b/tools/aapt2/link/ReferenceLinker.cpp
index 5372cf243951..d1fbffa1debd 100644
--- a/tools/aapt2/link/ReferenceLinker.cpp
+++ b/tools/aapt2/link/ReferenceLinker.cpp
@@ -468,7 +468,7 @@ bool ReferenceLinker::Consume(IAaptContext* context, ResourceTable* table) {
for (auto& type : package->types) {
for (auto& entry : type->entries) {
// First, unmangle the name if necessary.
- ResourceName name(package->name, type->type, entry->name);
+ ResourceName name(package->name, type->named_type, entry->name);
NameMangler::Unmangle(&name.entry, &name.package);
// Symbol state information may be lost if there is no value for the resource.
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index d78f0ac17f67..caaaba63931f 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -235,7 +235,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTablePackage* src_package,
bool error = false;
for (auto& src_type : src_package->types) {
- ResourceTableType* dst_type = main_package_->FindOrCreateType(src_type->type);
+ ResourceTableType* dst_type = main_package_->FindOrCreateType(src_type->named_type);
if (!MergeType(context_, src, dst_type, src_type.get())) {
error = true;
continue;
@@ -254,7 +254,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTablePackage* src_package,
dst_entry = dst_type->FindEntry(entry_name);
}
- const ResourceNameRef res_name(src_package->name, src_type->type, src_entry->name);
+ const ResourceNameRef res_name(src_package->name, src_type->named_type, src_entry->name);
if (!dst_entry) {
context_->GetDiagnostics()->Error(DiagMessage(src)
@@ -349,7 +349,7 @@ bool TableMerger::MergeFile(const ResourceFile& file_desc, bool overlay, io::IFi
file_ref->file = file;
ResourceTablePackage* pkg = table.FindOrCreatePackage(file_desc.name.package);
- pkg->FindOrCreateType(file_desc.name.type.type)
+ pkg->FindOrCreateType(file_desc.name.type)
->FindOrCreateEntry(file_desc.name.entry)
->FindOrCreateValue(file_desc.config, {})
->value = std::move(file_ref);
diff --git a/tools/aapt2/optimize/ResourceFilter.cpp b/tools/aapt2/optimize/ResourceFilter.cpp
index 08c045bf68f7..db84b66ecd2d 100644
--- a/tools/aapt2/optimize/ResourceFilter.cpp
+++ b/tools/aapt2/optimize/ResourceFilter.cpp
@@ -28,7 +28,7 @@ bool ResourceFilter::Consume(IAaptContext* context, ResourceTable* table) {
for (auto& package : table->packages) {
for (auto& type : package->types) {
for (auto it = type->entries.begin(); it != type->entries.end(); ) {
- ResourceName resource = ResourceName({}, type->type, (*it)->name);
+ ResourceName resource = ResourceName({}, type->named_type, (*it)->name);
if (exclude_list_.find(resource) != exclude_list_.end()) {
it = type->entries.erase(it);
} else {
diff --git a/tools/aapt2/split/TableSplitter.cpp b/tools/aapt2/split/TableSplitter.cpp
index 116b2ab9aa98..85d150f16b26 100644
--- a/tools/aapt2/split/TableSplitter.cpp
+++ b/tools/aapt2/split/TableSplitter.cpp
@@ -189,7 +189,7 @@ void TableSplitter::SplitTable(ResourceTable* original_table) {
}
for (auto& type : pkg->types) {
- if (type->type == ResourceType::kMipmap) {
+ if (type->named_type.type == ResourceType::kMipmap) {
// Always keep mipmaps.
continue;
}
@@ -241,7 +241,7 @@ void TableSplitter::SplitTable(ResourceTable* original_table) {
// Create the same resource structure in the split. We do this lazily because we might
// not have actual values for each type/entry.
ResourceTablePackage* split_pkg = split_table->FindPackage(pkg->name);
- ResourceTableType* split_type = split_pkg->FindOrCreateType(type->type);
+ ResourceTableType* split_type = split_pkg->FindOrCreateType(type->named_type);
split_type->visibility_level = type->visibility_level;
ResourceEntry* split_entry = split_type->FindOrCreateEntry(entry->name);
diff --git a/tools/lint/README.md b/tools/lint/README.md
index b534b62cb395..c674d36431b7 100644
--- a/tools/lint/README.md
+++ b/tools/lint/README.md
@@ -78,6 +78,7 @@ adding `cmd.Flag("--nowarn")` and running lint again.
## Documentation
- [Android Lint Docs](https://googlesamples.github.io/android-custom-lint-rules/)
+- [Lint Check Unit Testing](https://googlesamples.github.io/android-custom-lint-rules/api-guide/unit-testing.md.html)
- [Android Lint source files](https://source.corp.google.com/studio-main/tools/base/lint/libs/lint-api/src/main/java/com/android/tools/lint/)
- [PSI source files](https://github.com/JetBrains/intellij-community/tree/master/java/java-psi-api/src/com/intellij/psi)
- [UAST source files](https://upsource.jetbrains.com/idea-ce/structure/idea-ce-7b9b8cc138bbd90aec26433f82cd2c6838694003/uast/uast-common/src/org/jetbrains/uast)
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index a6fd9bba6192..859961a2a079 100644
--- a/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -19,6 +19,7 @@ package com.google.android.lint
import com.android.tools.lint.client.api.IssueRegistry
import com.android.tools.lint.client.api.Vendor
import com.android.tools.lint.detector.api.CURRENT_API
+import com.google.android.lint.parcel.SaferParcelChecker
import com.google.auto.service.AutoService
@AutoService(IssueRegistry::class)
@@ -33,7 +34,8 @@ class AndroidFrameworkIssueRegistry : IssueRegistry() {
CallingIdentityTokenDetector.ISSUE_CLEAR_IDENTITY_CALL_NOT_FOLLOWED_BY_TRY_FINALLY,
CallingSettingsNonUserGetterMethodsDetector.ISSUE_NON_USER_GETTER_CALLED,
EnforcePermissionDetector.ISSUE_MISSING_ENFORCE_PERMISSION,
- EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION
+ EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION,
+ SaferParcelChecker.ISSUE_UNSAFE_API_USAGE,
)
override val api: Int
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
new file mode 100644
index 000000000000..cc2ab19c97f1
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/CallMigrators.kt
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.google.android.lint.parcel
+
+import com.android.tools.lint.detector.api.JavaContext
+import com.android.tools.lint.detector.api.LintFix
+import com.android.tools.lint.detector.api.Location
+import com.intellij.psi.PsiCallExpression
+import com.intellij.psi.PsiClassType
+import com.intellij.psi.PsiIntersectionType
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiType
+import com.intellij.psi.PsiTypeParameter
+import com.intellij.psi.PsiWildcardType
+import org.jetbrains.kotlin.utils.addToStdlib.cast
+import org.jetbrains.uast.UCallExpression
+import org.jetbrains.uast.UExpression
+import org.jetbrains.uast.UVariable
+
+/**
+ * Subclass this class and override {@link #getBoundingClass} to report an unsafe Parcel API issue
+ * with a fix that migrates towards the new safer API by appending an argument in the form of
+ * {@code com.package.ItemType.class} coming from the result of the overridden method.
+ */
+abstract class CallMigrator(
+ val method: Method,
+ private val rejects: Set<String> = emptySet(),
+) {
+ open fun report(context: JavaContext, call: UCallExpression, method: PsiMethod) {
+ val location = context.getLocation(call)
+ val itemType = getBoundingClass(context, call, method)
+ val fix = (itemType as? PsiClassType)?.let { type ->
+ getParcelFix(location, this.method.name, getArgumentSuffix(type))
+ }
+ val message = "Unsafe `Parcel.${this.method.name}()` API usage"
+ context.report(SaferParcelChecker.ISSUE_UNSAFE_API_USAGE, call, location, message, fix)
+ }
+
+ protected open fun getArgumentSuffix(type: PsiClassType) =
+ ", ${type.rawType().canonicalText}.class"
+
+ protected open fun getBoundingClass(
+ context: JavaContext,
+ call: UCallExpression,
+ method: PsiMethod,
+ ): PsiType? = null
+
+ protected fun getItemType(type: PsiType, container: String): PsiClassType? {
+ val supers = getParentTypes(type).mapNotNull { it as? PsiClassType }
+ val containerType = supers.firstOrNull { it.rawType().canonicalText == container }
+ ?: return null
+ val itemType = containerType.parameters.getOrNull(0) ?: return null
+ // TODO: Expand to other types, see PsiTypeVisitor
+ return when (itemType) {
+ is PsiClassType -> itemType
+ is PsiWildcardType -> itemType.bound as PsiClassType
+ else -> null
+ }
+ }
+
+ /**
+ * Tries to obtain the type expected by the "receiving" end given a certain {@link UExpression}.
+ *
+ * This could be an assignment, an argument passed to a method call, to a constructor call, a
+ * type cast, etc. If no receiving end is found, the type of the UExpression itself is returned.
+ */
+ protected fun getReceivingType(expression: UExpression): PsiType? {
+ val parent = expression.uastParent
+ val type = when (parent) {
+ is UCallExpression -> {
+ val i = parent.valueArguments.indexOf(expression)
+ val psiCall = parent.sourcePsi as? PsiCallExpression ?: return null
+ val typeSubstitutor = psiCall.resolveMethodGenerics().substitutor
+ val method = psiCall.resolveMethod()!!
+ method.getSignature(typeSubstitutor).parameterTypes[i]
+ }
+ is UVariable -> parent.type
+ is UExpression -> parent.getExpressionType()
+ else -> null
+ }
+ return filter(type ?: expression.getExpressionType())
+ }
+
+ private fun filter(type: PsiType?): PsiType? {
+ // It's important that PsiIntersectionType case is above the one that check the type in
+ // rejects, because for intersect types, the canonicalText is one of the terms.
+ if (type is PsiIntersectionType) {
+ return type.conjuncts.mapNotNull(this::filter).firstOrNull()
+ }
+ if (type == null || type.canonicalText in rejects) {
+ return null
+ }
+ if (type is PsiClassType && type.resolve() is PsiTypeParameter) {
+ return null
+ }
+ return type
+ }
+
+ private fun getParentTypes(type: PsiType): Set<PsiType> =
+ type.superTypes.flatMap(::getParentTypes).toSet() + type
+
+ protected fun getParcelFix(location: Location, method: String, arguments: String) =
+ LintFix
+ .create()
+ .name("Migrate to safer Parcel.$method() API")
+ .replace()
+ .range(location)
+ .pattern("$method\\s*\\(((?:.|\\n)*)\\)")
+ .with("\\k<1>$arguments")
+ .autoFix()
+ .build()
+}
+
+/**
+ * This class derives the type to be appended by inferring the generic type of the {@code container}
+ * type (eg. "java.util.List") of the {@code argument}-th argument.
+ */
+class ContainerArgumentMigrator(
+ method: Method,
+ private val argument: Int,
+ private val container: String,
+ rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+ override fun getBoundingClass(
+ context: JavaContext, call: UCallExpression, method: PsiMethod
+ ): PsiType? {
+ val firstParamType = call.valueArguments[argument].getExpressionType() ?: return null
+ return getItemType(firstParamType, container)!!
+ }
+
+ /**
+ * We need to insert a casting construct in the class parameter. For example:
+ * (Class<Foo<Bar>>) (Class<?>) Foo.class.
+ * This is needed for when the arguments of the conflict (eg. when there is List<Foo<Bar>> and
+ * class type is Class<Foo?).
+ */
+ override fun getArgumentSuffix(type: PsiClassType): String {
+ if (type.parameters.isNotEmpty()) {
+ val rawType = type.rawType()
+ return ", (Class<${type.canonicalText}>) (Class<?>) ${rawType.canonicalText}.class"
+ }
+ return super.getArgumentSuffix(type)
+ }
+}
+
+/**
+ * This class derives the type to be appended by inferring the generic type of the {@code container}
+ * type (eg. "java.util.List") of the return type of the method.
+ */
+class ContainerReturnMigrator(
+ method: Method,
+ private val container: String,
+ rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+ override fun getBoundingClass(
+ context: JavaContext, call: UCallExpression, method: PsiMethod
+ ): PsiType? {
+ val type = getReceivingType(call.uastParent as UExpression) ?: return null
+ return getItemType(type, container)
+ }
+}
+
+/**
+ * This class derives the type to be appended by inferring the expected type for the method result.
+ */
+class ReturnMigrator(
+ method: Method,
+ rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+ override fun getBoundingClass(
+ context: JavaContext, call: UCallExpression, method: PsiMethod
+ ): PsiType? {
+ return getReceivingType(call.uastParent as UExpression)
+ }
+}
+
+/**
+ * This class appends the class loader and the class object by deriving the type from the method
+ * result.
+ */
+class ReturnMigratorWithClassLoader(
+ method: Method,
+ rejects: Set<String> = emptySet(),
+) : CallMigrator(method, rejects) {
+ override fun getBoundingClass(
+ context: JavaContext, call: UCallExpression, method: PsiMethod
+ ): PsiType? {
+ return getReceivingType(call.uastParent as UExpression)
+ }
+
+ override fun getArgumentSuffix(type: PsiClassType): String =
+ "${type.rawType().canonicalText}.class.getClassLoader(), " +
+ "${type.rawType().canonicalText}.class"
+
+} \ No newline at end of file
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt
new file mode 100644
index 000000000000..c032fa29f254
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/Method.kt
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.google.android.lint.parcel
+
+data class Method(
+ val params: List<String>,
+ val clazz: String,
+ val name: String,
+ val parameters: List<String>
+) {
+ constructor(
+ clazz: String,
+ name: String,
+ parameters: List<String>
+ ) : this(
+ listOf(), clazz, name, parameters
+ )
+
+ val signature: String
+ get() {
+ val prefix = if (params.isEmpty()) "" else "${params.joinToString(", ", "<", ">")} "
+ return "$prefix$clazz.$name(${parameters.joinToString()})"
+ }
+} \ No newline at end of file
diff --git a/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
new file mode 100644
index 000000000000..89dbcaeac3a7
--- /dev/null
+++ b/tools/lint/checks/src/main/java/com/google/android/lint/parcel/SaferParcelChecker.kt
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.google.android.lint.parcel
+
+import com.android.tools.lint.detector.api.*
+import com.intellij.psi.PsiMethod
+import com.intellij.psi.PsiSubstitutor
+import com.intellij.psi.PsiType
+import com.intellij.psi.PsiTypeParameter
+import org.jetbrains.uast.UCallExpression
+import java.util.*
+
+class SaferParcelChecker : Detector(), SourceCodeScanner {
+ override fun getApplicableMethodNames(): List<String> =
+ MIGRATORS
+ .map(CallMigrator::method)
+ .map(Method::name)
+
+ override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
+ if (!isAtLeastT(context)) return
+ val signature = getSignature(method)
+ val migrator = MIGRATORS.firstOrNull { it.method.signature == signature } ?: return
+ migrator.report(context, node, method)
+ }
+
+ private fun getSignature(method: PsiMethod): String {
+ val name = UastLintUtils.getQualifiedName(method)
+ val signature = method.getSignature(PsiSubstitutor.EMPTY)
+ val parameters =
+ signature.parameterTypes.joinToString(transform = PsiType::getCanonicalText)
+ val types = signature.typeParameters.map(PsiTypeParameter::getName)
+ val prefix = if (types.isEmpty()) "" else types.joinToString(", ", "<", ">") + " "
+ return "$prefix$name($parameters)"
+ }
+
+ /** Taken from androidx-main:core/core/src/main/java/androidx/core/os/BuildCompat.java */
+ private fun isAtLeastT(context: Context): Boolean {
+ val project = if (context.isGlobalAnalysis()) context.mainProject else context.project
+ return project.isAndroidProject
+ && project.minSdkVersion.featureLevel >= 32
+ && isAtLeastPreReleaseCodename("Tiramisu", project.minSdkVersion.codename)
+ }
+
+ /** Taken from androidx-main:core/core/src/main/java/androidx/core/os/BuildCompat.java */
+ private fun isAtLeastPreReleaseCodename(min: String, actual: String): Boolean {
+ if (actual == "REL") return false
+ return actual.uppercase(Locale.ROOT) >= min.uppercase(Locale.ROOT)
+ }
+
+ companion object {
+ @JvmField
+ val ISSUE_UNSAFE_API_USAGE: Issue = Issue.create(
+ id = "UnsafeParcelApi",
+ briefDescription = "Use of unsafe Parcel API",
+ explanation = """
+ You are using a deprecated Parcel API that doesn't accept the expected class as\
+ a parameter. This means that unexpected classes could be instantiated and\
+ unexpected code executed.
+
+ Please migrate to the safer alternative that takes an extra Class<T> parameter.
+ """,
+ category = Category.SECURITY,
+ priority = 8,
+ severity = Severity.WARNING,
+
+ implementation = Implementation(
+ SaferParcelChecker::class.java,
+ Scope.JAVA_FILE_SCOPE
+ )
+ )
+
+ private val METHOD_READ_SERIALIZABLE = Method("android.os.Parcel", "readSerializable", listOf())
+ private val METHOD_READ_ARRAY_LIST = Method("android.os.Parcel", "readArrayList", listOf("java.lang.ClassLoader"))
+ private val METHOD_READ_LIST = Method("android.os.Parcel", "readList", listOf("java.util.List", "java.lang.ClassLoader"))
+ private val METHOD_READ_PARCELABLE = Method(listOf("T"), "android.os.Parcel", "readParcelable", listOf("java.lang.ClassLoader"))
+ private val METHOD_READ_PARCELABLE_LIST = Method(listOf("T"), "android.os.Parcel", "readParcelableList", listOf("java.util.List<T>", "java.lang.ClassLoader"))
+ private val METHOD_READ_SPARSE_ARRAY = Method(listOf("T"), "android.os.Parcel", "readSparseArray", listOf("java.lang.ClassLoader"))
+
+ // TODO: Write migrators for methods below
+ private val METHOD_READ_ARRAY = Method("android.os.Parcel", "readArray", listOf("java.lang.ClassLoader"))
+ private val METHOD_READ_PARCELABLE_ARRAY = Method("android.os.Parcel", "readParcelableArray", listOf("java.lang.ClassLoader"))
+ private val METHOD_READ_PARCELABLE_CREATOR = Method("android.os.Parcel", "readParcelableCreator", listOf("java.lang.ClassLoader"))
+
+ private val MIGRATORS = listOf(
+ ReturnMigrator(METHOD_READ_PARCELABLE, setOf("android.os.Parcelable")),
+ ContainerArgumentMigrator(METHOD_READ_LIST, 0, "java.util.List"),
+ ContainerReturnMigrator(METHOD_READ_ARRAY_LIST, "java.util.Collection"),
+ ContainerReturnMigrator(METHOD_READ_SPARSE_ARRAY, "android.util.SparseArray"),
+ ContainerArgumentMigrator(METHOD_READ_PARCELABLE_LIST, 0, "java.util.List"),
+ ReturnMigratorWithClassLoader(METHOD_READ_SERIALIZABLE),
+ )
+ }
+} \ No newline at end of file
diff --git a/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt b/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
new file mode 100644
index 000000000000..05c7850c44c2
--- /dev/null
+++ b/tools/lint/checks/src/test/java/com/google/android/lint/parcel/SaferParcelCheckerTest.kt
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT 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.google.android.lint.parcel
+
+import com.android.tools.lint.checks.infrastructure.LintDetectorTest
+import com.android.tools.lint.checks.infrastructure.TestLintTask
+import com.android.tools.lint.checks.infrastructure.TestMode
+import com.android.tools.lint.detector.api.Detector
+import com.android.tools.lint.detector.api.Issue
+
+@Suppress("UnstableApiUsage")
+class SaferParcelCheckerTest : LintDetectorTest() {
+ override fun getDetector(): Detector = SaferParcelChecker()
+
+ override fun getIssues(): List<Issue> = listOf(
+ SaferParcelChecker.ISSUE_UNSAFE_API_USAGE
+ )
+
+ override fun lint(): TestLintTask =
+ super.lint()
+ .allowMissingSdk(true)
+ // We don't do partial analysis in the platform
+ .skipTestModes(TestMode.PARTIAL)
+
+ fun testDetectUnsafeReadSerializable() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.os.Parcel;
+ import java.io.Serializable;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ Serializable ans = p.readSerializable();
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .expectIdenticalTestModeOutput(false)
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:7: Warning: Unsafe Parcel.readSerializable() \
+ API usage [UnsafeParcelApi]
+ Serializable ans = p.readSerializable();
+ ~~~~~~~~~~~~~~~~~~~~
+ 0 errors, 1 warnings
+ """.addLineContinuation()
+ )
+ }
+
+ fun testDoesNotDetectSafeReadSerializable() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.os.Parcel;
+ import java.io.Serializable;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ String ans = p.readSerializable(null, String.class);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect("No warnings.")
+ }
+
+ fun testDetectUnsafeReadArrayList() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.os.Parcel;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ ArrayList ans = p.readArrayList(null);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:6: Warning: Unsafe Parcel.readArrayList() API \
+ usage [UnsafeParcelApi]
+ ArrayList ans = p.readArrayList(null);
+ ~~~~~~~~~~~~~~~~~~~~~
+ 0 errors, 1 warnings
+ """.addLineContinuation()
+ )
+ }
+
+ fun testDoesNotDetectSafeReadArrayList() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ ArrayList<Intent> ans = p.readArrayList(null, Intent.class);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect("No warnings.")
+ }
+
+ fun testDetectUnsafeReadList() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+ import java.util.List;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ List<Intent> list = new ArrayList<Intent>();
+ p.readList(list, null);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:9: Warning: Unsafe Parcel.readList() API usage \
+ [UnsafeParcelApi]
+ p.readList(list, null);
+ ~~~~~~~~~~~~~~~~~~~~~~
+ 0 errors, 1 warnings
+ """.addLineContinuation()
+ )
+ }
+
+ fun testDoesNotDetectSafeReadList() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+ import java.util.List;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ List<Intent> list = new ArrayList<Intent>();
+ p.readList(list, null, Intent.class);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect("No warnings.")
+ }
+
+ fun testDetectUnsafeReadParcelable() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ Intent ans = p.readParcelable(null);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:7: Warning: Unsafe Parcel.readParcelable() API \
+ usage [UnsafeParcelApi]
+ Intent ans = p.readParcelable(null);
+ ~~~~~~~~~~~~~~~~~~~~~~
+ 0 errors, 1 warnings
+ """.addLineContinuation()
+ )
+ }
+
+ fun testDoesNotDetectSafeReadParcelable() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ Intent ans = p.readParcelable(null, Intent.class);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect("No warnings.")
+ }
+
+ fun testDetectUnsafeReadParcelableList() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+ import java.util.List;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ List<Intent> list = new ArrayList<Intent>();
+ List<Intent> ans = p.readParcelableList(list, null);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:9: Warning: Unsafe Parcel.readParcelableList() \
+ API usage [UnsafeParcelApi]
+ List<Intent> ans = p.readParcelableList(list, null);
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ 0 errors, 1 warnings
+ """.addLineContinuation()
+ )
+ }
+
+ fun testDoesNotDetectSafeReadParcelableList() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+ import java.util.List;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ List<Intent> list = new ArrayList<Intent>();
+ List<Intent> ans =
+ p.readParcelableList(list, null, Intent.class);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect("No warnings.")
+ }
+
+ fun testDetectUnsafeReadSparseArray() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+ import android.util.SparseArray;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ SparseArray<Intent> ans = p.readSparseArray(null);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect(
+ """
+ src/test/pkg/TestClass.java:8: Warning: Unsafe Parcel.readSparseArray() API\
+ usage [UnsafeParcelApi]
+ SparseArray<Intent> ans = p.readSparseArray(null);
+ ~~~~~~~~~~~~~~~~~~~~~~~
+ 0 errors, 1 warnings
+ """.addLineContinuation()
+ )
+ }
+
+ fun testDoesNotDetectSafeReadSparseArray() {
+ lint()
+ .files(
+ java(
+ """
+ package test.pkg;
+ import android.content.Intent;
+ import android.os.Parcel;
+ import android.util.SparseArray;
+
+ public class TestClass {
+ private TestClass(Parcel p) {
+ SparseArray<Intent> ans =
+ p.readSparseArray(null, Intent.class);
+ }
+ }
+ """
+ ).indented(),
+ *includes
+ )
+ .run()
+ .expect("No warnings.")
+ }
+
+ /** Stubs for classes used for testing */
+
+
+ private val includes =
+ arrayOf(
+ manifest().minSdk("Tiramisu"),
+ java(
+ """
+ package android.os;
+ import java.util.ArrayList;
+ import java.util.List;
+ import java.util.Map;
+ import java.util.HashMap;
+
+ public final class Parcel {
+ // Deprecateds
+ public Object[] readArray(ClassLoader loader) { return null; }
+ public ArrayList readArrayList(ClassLoader loader) { return null; }
+ public HashMap readHashMap(ClassLoader loader) { return null; }
+ public void readList(List outVal, ClassLoader loader) {}
+ public void readMap(Map outVal, ClassLoader loader) {}
+ public <T extends Parcelable> T readParcelable(ClassLoader loader) { return null; }
+ public Parcelable[] readParcelableArray(ClassLoader loader) { return null; }
+ public Parcelable.Creator<?> readParcelableCreator(ClassLoader loader) { return null; }
+ public <T extends Parcelable> List<T> readParcelableList(List<T> list, ClassLoader cl) { return null; }
+ public Serializable readSerializable() { return null; }
+ public <T> SparseArray<T> readSparseArray(ClassLoader loader) { return null; }
+
+ // Replacements
+ public <T> T[] readArray(ClassLoader loader, Class<T> clazz) { return null; }
+ public <T> ArrayList<T> readArrayList(ClassLoader loader, Class<? extends T> clazz) { return null; }
+ public <K, V> HashMap<K,V> readHashMap(ClassLoader loader, Class<? extends K> clazzKey, Class<? extends V> clazzValue) { return null; }
+ public <T> void readList(List<? super T> outVal, ClassLoader loader, Class<T> clazz) {}
+ public <K, V> void readMap(Map<? super K, ? super V> outVal, ClassLoader loader, Class<K> clazzKey, Class<V> clazzValue) {}
+ public <T> T readParcelable(ClassLoader loader, Class<T> clazz) { return null; }
+ public <T> T[] readParcelableArray(ClassLoader loader, Class<T> clazz) { return null; }
+ public <T> Parcelable.Creator<T> readParcelableCreator(ClassLoader loader, Class<T> clazz) { return null; }
+ public <T> List<T> readParcelableList(List<T> list, ClassLoader cl, Class<T> clazz) { return null; }
+ public <T> T readSerializable(ClassLoader loader, Class<T> clazz) { return null; }
+ public <T> SparseArray<T> readSparseArray(ClassLoader loader, Class<? extends T> clazz) { return null; }
+ }
+ """
+ ).indented(),
+ java(
+ """
+ package android.os;
+ public interface Parcelable {}
+ """
+ ).indented(),
+ java(
+ """
+ package android.content;
+ public class Intent implements Parcelable, Cloneable {}
+ """
+ ).indented(),
+ java(
+ """
+ package android.util;
+ public class SparseArray<E> implements Cloneable {}
+ """
+ ).indented(),
+ )
+
+ // Substitutes "backslash + new line" with an empty string to imitate line continuation
+ private fun String.addLineContinuation(): String = this.trimIndent().replace("\\\n", "")
+}
diff --git a/tools/preload-check/device/src/com/android/preload/check/Util.java b/tools/preload-check/device/src/com/android/preload/check/Util.java
index fccea0a0c107..f521c95839f1 100644
--- a/tools/preload-check/device/src/com/android/preload/check/Util.java
+++ b/tools/preload-check/device/src/com/android/preload/check/Util.java
@@ -25,8 +25,8 @@ import java.io.FileOutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
+import java.util.ArrayList;
import java.util.Collection;
-import java.util.LinkedList;
import java.util.List;
public class Util {
@@ -48,7 +48,7 @@ public class Util {
Class<?> vmClassLoaderClass = Class.forName("java.lang.VMClassLoader");
Method getResources = vmClassLoaderClass.getDeclaredMethod("getResources", String.class);
getResources.setAccessible(true);
- LinkedList<DexFile> res = new LinkedList<>();
+ ArrayList<DexFile> res = new ArrayList<>();
for (int i = 1;; i++) {
try {
String name = "classes" + (i > 1 ? String.valueOf(i) : "") + ".dex";