summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp6
-rw-r--r--api/current.txt276
-rw-r--r--api/removed.txt26
-rw-r--r--api/system-current.txt195
-rw-r--r--api/system-removed.txt11
-rw-r--r--api/test-current.txt48
-rw-r--r--cmds/statsd/Android.bp1
-rw-r--r--cmds/statsd/src/StatsService.cpp14
-rw-r--r--cmds/statsd/src/atoms.proto46
-rw-r--r--cmds/statsd/src/logd/LogEvent.cpp3
-rw-r--r--cmds/statsd/src/logd/LogEvent.h2
-rw-r--r--cmds/statsd/src/statsd_config.proto6
-rw-r--r--cmds/statsd/src/storage/StorageManager.cpp55
-rw-r--r--cmds/statsd/src/storage/StorageManager.h3
-rw-r--r--cmds/statsd/src/subscriber/IncidentdReporter.cpp4
-rw-r--r--cmds/statsd/tests/external/IncidentReportArgs_test.cpp72
-rw-r--r--cmds/statsd/tests/storage/StorageManager_test.cpp78
-rw-r--r--config/hiddenapi-greylist.txt138
-rw-r--r--core/java/android/accounts/IAccountAuthenticator.aidl8
-rw-r--r--core/java/android/accounts/IAccountAuthenticatorResponse.aidl3
-rw-r--r--core/java/android/accounts/IAccountManagerResponse.aidl2
-rw-r--r--core/java/android/app/ActionBar.java4
-rw-r--r--core/java/android/app/Activity.java20
-rw-r--r--core/java/android/app/ActivityManagerInternal.java4
-rw-r--r--core/java/android/app/ActivityThread.java25
-rw-r--r--core/java/android/app/AutomaticZenRule.java14
-rw-r--r--core/java/android/app/ContextImpl.java1
-rw-r--r--core/java/android/app/DownloadManager.java1
-rw-r--r--core/java/android/app/IActivityManager.aidl92
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl10
-rw-r--r--core/java/android/app/IAlarmManager.aidl3
-rw-r--r--core/java/android/app/IAppTask.aidl1
-rw-r--r--core/java/android/app/IApplicationThread.aidl5
-rw-r--r--core/java/android/app/IAssistDataReceiver.aidl2
-rw-r--r--core/java/android/app/IInstrumentationWatcher.aidl1
-rw-r--r--core/java/android/app/INotificationManager.aidl9
-rw-r--r--core/java/android/app/ISearchManager.aidl1
-rw-r--r--core/java/android/app/IServiceConnection.aidl1
-rw-r--r--core/java/android/app/IStopUserCallback.aidl1
-rw-r--r--core/java/android/app/ITaskStackListener.aidl12
-rw-r--r--core/java/android/app/ITransientNotification.aidl1
-rw-r--r--core/java/android/app/IWallpaperManager.aidl6
-rw-r--r--core/java/android/app/KeyguardManager.java2
-rw-r--r--core/java/android/app/Notification.java7
-rw-r--r--core/java/android/app/TEST_MAPPING8
-rw-r--r--core/java/android/app/TaskStackListener.java7
-rw-r--r--core/java/android/app/WallpaperInfo.java6
-rw-r--r--core/java/android/app/ZygotePreload.java6
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java46
-rw-r--r--core/java/android/app/role/RoleManager.java1
-rw-r--r--core/java/android/content/AutofillOptions.java45
-rw-r--r--core/java/android/content/ContentResolver.java6
-rw-r--r--core/java/android/content/Context.java9
-rw-r--r--core/java/android/content/Intent.java1
-rw-r--r--core/java/android/content/LocusId.java4
-rw-r--r--core/java/android/content/pm/PackageParser.java33
-rw-r--r--core/java/android/content/pm/PermissionGroupInfo.java53
-rw-r--r--core/java/android/hardware/biometrics/BiometricConstants.java2
-rw-r--r--core/java/android/hardware/biometrics/BiometricFaceConstants.java2
-rw-r--r--core/java/android/hardware/biometrics/BiometricFingerprintConstants.java2
-rw-r--r--core/java/android/hardware/biometrics/BiometricPrompt.java10
-rw-r--r--core/java/android/os/IncidentReportArgs.java12
-rw-r--r--core/java/android/os/UserHandle.java11
-rw-r--r--core/java/android/os/UserManager.java6
-rw-r--r--core/java/android/os/VibrationEffect.java2
-rw-r--r--core/java/android/provider/DocumentsContract.java6
-rw-r--r--core/java/android/provider/DocumentsProvider.java13
-rw-r--r--core/java/android/provider/MediaStore.java2
-rw-r--r--core/java/android/provider/Settings.java36
-rw-r--r--core/java/android/service/carrier/CarrierIdentifier.java3
-rw-r--r--core/java/android/service/contentsuggestions/ContentSuggestionsService.java4
-rw-r--r--core/java/android/service/notification/NotificationAssistantService.java7
-rw-r--r--core/java/android/service/notification/ZenPolicy.java53
-rw-r--r--core/java/android/service/textclassifier/IConversationActionsCallback.aidl28
-rw-r--r--core/java/android/service/textclassifier/ITextClassificationCallback.aidl28
-rw-r--r--core/java/android/service/textclassifier/ITextClassifierCallback.aidl (renamed from core/java/android/service/textclassifier/ITextSelectionCallback.aidl)7
-rw-r--r--core/java/android/service/textclassifier/ITextClassifierService.aidl16
-rw-r--r--core/java/android/service/textclassifier/ITextLanguageCallback.aidl28
-rw-r--r--core/java/android/service/textclassifier/ITextLinksCallback.aidl28
-rw-r--r--core/java/android/service/textclassifier/TextClassifierService.java235
-rw-r--r--core/java/android/util/FeatureFlagUtils.java5
-rw-r--r--core/java/android/util/apk/ApkSignatureVerifier.java9
-rw-r--r--core/java/android/view/SurfaceControl.java27
-rw-r--r--core/java/android/view/View.java3
-rw-r--r--core/java/android/view/ViewGroup.java12
-rw-r--r--core/java/android/view/WindowInsets.java77
-rw-r--r--core/java/android/view/WindowManager.java13
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureManager.java9
-rw-r--r--core/java/android/view/contentcapture/ContentCaptureSession.java4
-rw-r--r--core/java/android/view/inspector/InspectableProperty.java13
-rw-r--r--core/java/android/view/inspector/PropertyMapper.java10
-rw-r--r--core/java/android/view/inspector/PropertyReader.java16
-rw-r--r--core/java/android/view/textclassifier/SystemTextClassifier.java106
-rw-r--r--core/java/android/webkit/WebViewDelegate.java13
-rw-r--r--core/java/android/widget/AbsoluteLayout.java3
-rw-r--r--core/java/android/widget/FrameLayout.java3
-rw-r--r--core/java/android/widget/LinearLayout.java4
-rw-r--r--core/java/android/widget/Magnifier.java2
-rw-r--r--core/java/android/widget/RelativeLayout.java1
-rw-r--r--core/java/android/widget/ScrollView.java2
-rw-r--r--core/java/android/widget/TableRow.java3
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java6
-rw-r--r--core/java/com/android/internal/infra/WhitelistHelper.java163
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java10
-rw-r--r--core/java/com/android/internal/widget/ViewPager.java4
-rw-r--r--core/jni/android/graphics/AnimatedImageDrawable.cpp23
-rw-r--r--core/jni/android_view_SurfaceControl.cpp9
-rw-r--r--core/proto/android/app/settings_enums.proto11
-rw-r--r--core/res/AndroidManifest.xml13
-rwxr-xr-xcore/res/res/values-mcc311-mnc480/config.xml15
-rw-r--r--core/res/res/values/attrs_manifest.xml2
-rw-r--r--core/res/res/values/config.xml17
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/symbols.xml4
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java1
-rw-r--r--core/tests/coretests/src/com/android/internal/infra/WhitelistHelperTest.java138
-rw-r--r--core/xsd/Android.bp6
-rw-r--r--core/xsd/permission.xsd166
-rw-r--r--core/xsd/schema/README.md1
-rw-r--r--core/xsd/schema/current.txt242
-rw-r--r--core/xsd/schema/last_current.txt0
-rw-r--r--core/xsd/schema/last_removed.txt0
-rw-r--r--core/xsd/schema/removed.txt1
-rw-r--r--graphics/java/android/graphics/Bitmap.java5
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java10
-rw-r--r--graphics/java/android/graphics/ImageDecoder.java37
-rw-r--r--graphics/java/android/graphics/RecordingCanvas.java4
-rw-r--r--graphics/java/android/graphics/RenderNode.java10
-rw-r--r--graphics/java/android/graphics/drawable/AnimatedImageDrawable.java12
-rw-r--r--graphics/java/android/graphics/drawable/GradientDrawable.java28
-rw-r--r--graphics/java/android/graphics/drawable/StateListDrawable.java6
-rw-r--r--keystore/java/android/security/keystore/DeviceIdAttestationException.java5
-rw-r--r--libs/incident/include/android/os/IncidentReportArgs.h6
-rw-r--r--libs/incident/src/IncidentReportArgs.cpp25
-rw-r--r--location/java/android/location/GpsStatus.java3
-rw-r--r--location/java/android/location/Location.java46
-rw-r--r--location/java/android/location/LocationManager.java376
-rw-r--r--location/java/android/location/LocationRequest.java40
-rw-r--r--media/apex/java/android/media/MediaItem2.java2
-rw-r--r--media/java/android/media/AudioAttributes.java33
-rw-r--r--media/java/android/media/AudioPlaybackCaptureConfiguration.java12
-rw-r--r--media/java/android/media/AudioRecord.java4
-rw-r--r--media/java/android/media/ExifInterface.java2
-rw-r--r--media/java/android/media/HwAudioSource.java9
-rw-r--r--packages/CaptivePortalLogin/Android.bp1
-rw-r--r--packages/CaptivePortalLogin/AndroidManifest.xml2
-rw-r--r--packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java11
-rw-r--r--packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java50
-rw-r--r--packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java42
-rw-r--r--packages/NetworkStack/Android.bp1
-rw-r--r--packages/NetworkStack/AndroidManifest.xml2
-rw-r--r--packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java8
-rw-r--r--packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java4
-rw-r--r--packages/NetworkStackPermissionStub/Android.bp1
-rw-r--r--packages/NetworkStackPermissionStub/AndroidManifest.xml2
-rw-r--r--packages/SettingsLib/res/values/strings.xml2
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java4
-rw-r--r--packages/SystemUI/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java86
-rw-r--r--packages/SystemUI/res-keyguard/layout/type_clock.xml4
-rw-r--r--packages/SystemUI/res/drawable/global_action_panel_scrim.xml26
-rw-r--r--packages/SystemUI/res/drawable/qs_detail_background.xml18
-rw-r--r--packages/SystemUI/res/layout-land/global_actions_grid.xml13
-rw-r--r--packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml15
-rw-r--r--packages/SystemUI/res/layout/global_actions_grid.xml12
-rw-r--r--packages/SystemUI/res/layout/notification_info.xml14
-rw-r--r--packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl61
-rw-r--r--packages/SystemUI/res/values/dimens.xml3
-rw-r--r--packages/SystemUI/res/values/donottranslate.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/MultiListLayout.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/ScreenDecorations.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java47
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java146
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt55
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/Estimate.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/Estimate.kt3
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/power/PowerUI.java263
-rw-r--r--packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java4
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java653
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java16
-rw-r--r--proto/src/metrics_constants/metrics_constants.proto9
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java43
-rw-r--r--services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java53
-rw-r--r--services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java8
-rw-r--r--services/core/java/com/android/server/LocationManagerService.java2
-rw-r--r--services/core/java/com/android/server/PackageWatchdog.java133
-rw-r--r--services/core/java/com/android/server/RescueParty.java22
-rw-r--r--services/core/java/com/android/server/TelephonyRegistry.java7
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerConstants.java28
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java28
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java32
-rw-r--r--services/core/java/com/android/server/am/BroadcastDispatcher.java8
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java5
-rw-r--r--services/core/java/com/android/server/am/ProcessList.java20
-rw-r--r--services/core/java/com/android/server/am/SettingsToPropertiesMapper.java3
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java2
-rw-r--r--services/core/java/com/android/server/appop/TEST_MAPPING8
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java11
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java3
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java2
-rw-r--r--services/core/java/com/android/server/notification/ManagedServices.java15
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java190
-rw-r--r--services/core/java/com/android/server/notification/NotificationShellCmd.java25
-rw-r--r--services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java2
-rw-r--r--services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java158
-rw-r--r--services/core/java/com/android/server/signedconfig/TEST_MAPPING7
-rw-r--r--services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java16
-rw-r--r--services/core/java/com/android/server/utils/FlagNamespaceUtils.java30
-rw-r--r--services/core/java/com/android/server/wallpaper/WallpaperManagerService.java76
-rw-r--r--services/core/java/com/android/server/wm/ActivityDisplay.java29
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java107
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java27
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java6
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java42
-rw-r--r--services/core/java/com/android/server/wm/Letterbox.java1
-rw-r--r--services/core/java/com/android/server/wm/TaskChangeNotificationController.java20
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java16
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java9
-rw-r--r--services/core/java/com/android/server/wm/WindowSurfaceController.java22
-rw-r--r--services/core/java/com/android/server/wm/WindowTracing.java19
-rw-r--r--services/core/jni/com_android_server_location_GnssLocationProvider.cpp16
-rw-r--r--services/core/xsd/Android.bp6
-rw-r--r--services/core/xsd/default-permissions.xsd40
-rw-r--r--services/core/xsd/schema/README.md1
-rw-r--r--services/core/xsd/schema/current.txt37
-rw-r--r--services/core/xsd/schema/last_current.txt0
-rw-r--r--services/core/xsd/schema/last_removed.txt0
-rw-r--r--services/core/xsd/schema/removed.txt1
-rw-r--r--services/java/com/android/server/SystemServer.java13
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java46
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java4
-rw-r--r--services/tests/uiservicestests/Android.bp1
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java18
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java119
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java49
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java20
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java41
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java12
-rw-r--r--telephony/java/android/provider/Telephony.java46
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationState.java219
-rw-r--r--telephony/java/android/telephony/NetworkService.java59
-rw-r--r--telephony/java/android/telephony/NetworkServiceCallback.java4
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java24
-rw-r--r--telephony/java/android/telephony/RadioAccessFamily.java5
-rw-r--r--telephony/java/android/telephony/ServiceState.java4
-rw-r--r--telephony/java/android/telephony/SubscriptionManager.java9
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java41
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java80
-rw-r--r--telephony/java/android/telephony/data/DataCallResponse.java4
-rw-r--r--telephony/java/android/telephony/data/DataProfile.java5
-rw-r--r--telephony/java/android/telephony/data/DataService.java77
-rw-r--r--telephony/java/android/telephony/data/DataServiceCallback.java15
-rw-r--r--telephony/java/android/telephony/ims/ImsException.java3
-rw-r--r--telephony/java/android/telephony/ims/ImsExternalCallState.java12
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java13
-rw-r--r--telephony/java/android/telephony/ims/ProvisioningManager.java9
-rwxr-xr-xtelephony/java/com/android/internal/telephony/IOns.aidl8
-rw-r--r--tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java81
-rw-r--r--tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java77
-rw-r--r--tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java12
-rw-r--r--tools/apilint/apilint.py183
-rw-r--r--tools/apilint/apilint_test.py4
-rw-r--r--tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java5
-rw-r--r--tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java96
-rw-r--r--tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java2
-rw-r--r--tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java1
-rw-r--r--tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt7
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java37
-rw-r--r--wifi/java/android/net/wifi/p2p/WifiP2pManager.java2
287 files changed, 6011 insertions, 2521 deletions
diff --git a/Android.bp b/Android.bp
index c97ee3da36e4..9077344adf21 100644
--- a/Android.bp
+++ b/Android.bp
@@ -352,12 +352,8 @@ java_defaults {
"core/java/android/service/chooser/IChooserTargetResult.aidl",
"core/java/android/service/resolver/IResolverRankerService.aidl",
"core/java/android/service/resolver/IResolverRankerResult.aidl",
- "core/java/android/service/textclassifier/IConversationActionsCallback.aidl",
- "core/java/android/service/textclassifier/ITextClassificationCallback.aidl",
+ "core/java/android/service/textclassifier/ITextClassifierCallback.aidl",
"core/java/android/service/textclassifier/ITextClassifierService.aidl",
- "core/java/android/service/textclassifier/ITextLanguageCallback.aidl",
- "core/java/android/service/textclassifier/ITextLinksCallback.aidl",
- "core/java/android/service/textclassifier/ITextSelectionCallback.aidl",
"core/java/android/service/attention/IAttentionService.aidl",
"core/java/android/service/attention/IAttentionCallback.aidl",
"core/java/android/view/accessibility/IAccessibilityInteractionConnection.aidl",
diff --git a/api/current.txt b/api/current.txt
index d8ec7780230a..cfad766c02be 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -768,6 +768,7 @@ package android {
field public static final int indicatorRight = 16843022; // 0x101010e
field public static final int indicatorStart = 16843729; // 0x10103d1
field public static final int inflatedId = 16842995; // 0x10100f3
+ field public static final int inheritShowWhenLocked = 16844194; // 0x10105a2
field public static final int initOrder = 16842778; // 0x101001a
field public static final int initialKeyguardLayout = 16843714; // 0x10103c2
field public static final int initialLayout = 16843345; // 0x1010251
@@ -3850,6 +3851,7 @@ package android.app {
method public final void setFeatureDrawableUri(int, android.net.Uri);
method public void setFinishOnTouchOutside(boolean);
method public void setImmersive(boolean);
+ method public void setInheritShowWhenLocked(boolean);
method public void setIntent(android.content.Intent);
method public final void setMediaController(android.media.session.MediaController);
method public void setPictureInPictureParams(@NonNull android.app.PictureInPictureParams);
@@ -4447,7 +4449,7 @@ package android.app {
public final class AutomaticZenRule implements android.os.Parcelable {
ctor @Deprecated public AutomaticZenRule(String, android.content.ComponentName, android.net.Uri, int, boolean);
- ctor public AutomaticZenRule(String, android.content.ComponentName, android.content.ComponentName, android.net.Uri, android.service.notification.ZenPolicy, int, boolean);
+ ctor public AutomaticZenRule(@NonNull String, @Nullable android.content.ComponentName, @Nullable android.content.ComponentName, @NonNull android.net.Uri, @Nullable android.service.notification.ZenPolicy, int, boolean);
ctor public AutomaticZenRule(android.os.Parcel);
method public int describeContents();
method public android.net.Uri getConditionId();
@@ -5421,14 +5423,14 @@ package android.app {
ctor @Deprecated public Notification.Action.Builder(int, CharSequence, android.app.PendingIntent);
ctor public Notification.Action.Builder(android.graphics.drawable.Icon, CharSequence, android.app.PendingIntent);
ctor public Notification.Action.Builder(android.app.Notification.Action);
- method public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
- method public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
- method public android.app.Notification.Action build();
- method public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender);
+ method @NonNull public android.app.Notification.Action.Builder addExtras(android.os.Bundle);
+ method @NonNull public android.app.Notification.Action.Builder addRemoteInput(android.app.RemoteInput);
+ method @NonNull public android.app.Notification.Action build();
+ method @NonNull public android.app.Notification.Action.Builder extend(android.app.Notification.Action.Extender);
method public android.os.Bundle getExtras();
- method public android.app.Notification.Action.Builder setAllowGeneratedReplies(boolean);
- method public android.app.Notification.Action.Builder setContextual(boolean);
- method public android.app.Notification.Action.Builder setSemanticAction(int);
+ method @NonNull public android.app.Notification.Action.Builder setAllowGeneratedReplies(boolean);
+ method @NonNull public android.app.Notification.Action.Builder setContextual(boolean);
+ method @NonNull public android.app.Notification.Action.Builder setSemanticAction(int);
}
public static interface Notification.Action.Extender {
@@ -6419,7 +6421,7 @@ package android.app {
method public android.content.pm.ServiceInfo getServiceInfo();
method public String getServiceName();
method public String getSettingsActivity();
- method public android.net.Uri getSettingsSliceUri();
+ method @Nullable public android.net.Uri getSettingsSliceUri();
method public boolean getShowMetadataInPreview();
method public CharSequence loadAuthor(android.content.pm.PackageManager) throws android.content.res.Resources.NotFoundException;
method public CharSequence loadContextDescription(android.content.pm.PackageManager) throws android.content.res.Resources.NotFoundException;
@@ -6490,7 +6492,7 @@ package android.app {
}
public interface ZygotePreload {
- method public void doPreload(android.content.pm.ApplicationInfo);
+ method public void doPreload(@NonNull android.content.pm.ApplicationInfo);
}
}
@@ -9558,8 +9560,8 @@ package android.content {
method public final void unregisterContentObserver(@NonNull android.database.ContentObserver);
method public final int update(@RequiresPermission.Write @NonNull android.net.Uri, @Nullable android.content.ContentValues, @Nullable String, @Nullable String[]);
method public static void validateSyncExtrasBundle(android.os.Bundle);
- method public static android.content.ContentResolver wrap(@NonNull android.content.ContentProvider);
- method public static android.content.ContentResolver wrap(@NonNull android.content.ContentProviderClient);
+ method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProvider);
+ method @NonNull public static android.content.ContentResolver wrap(@NonNull android.content.ContentProviderClient);
field public static final String ANY_CURSOR_ITEM_TYPE = "vnd.android.cursor.item/*";
field public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir";
field public static final String CURSOR_ITEM_BASE_TYPE = "vnd.android.cursor.item";
@@ -11825,15 +11827,15 @@ package android.content.pm {
}
public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
- ctor public PermissionGroupInfo();
- ctor public PermissionGroupInfo(android.content.pm.PermissionGroupInfo);
+ ctor @Deprecated public PermissionGroupInfo();
+ ctor @Deprecated public PermissionGroupInfo(@NonNull android.content.pm.PermissionGroupInfo);
method public int describeContents();
- method public CharSequence loadDescription(android.content.pm.PackageManager);
+ method @Nullable public CharSequence loadDescription(@NonNull android.content.pm.PackageManager);
field @NonNull public static final android.os.Parcelable.Creator<android.content.pm.PermissionGroupInfo> CREATOR;
field public static final int FLAG_PERSONAL_INFO = 1; // 0x1
- field public int descriptionRes;
+ field @StringRes public int descriptionRes;
field public int flags;
- field public CharSequence nonLocalizedDescription;
+ field @Nullable public CharSequence nonLocalizedDescription;
field public int priority;
}
@@ -14113,14 +14115,14 @@ package android.graphics {
public class HardwareRenderer {
ctor public HardwareRenderer();
method public void clearContent();
- method public android.graphics.HardwareRenderer.FrameRenderRequest createRenderRequest();
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest createRenderRequest();
method public void destroy();
method public boolean isOpaque();
method public void notifyFramePending();
method public void setContentRoot(@Nullable android.graphics.RenderNode);
method public void setLightSourceAlpha(@FloatRange(from=0.0f, to=1.0f) float, @FloatRange(from=0.0f, to=1.0f) float);
method public void setLightSourceGeometry(float, float, float, float);
- method public void setName(String);
+ method public void setName(@NonNull String);
method public void setOpaque(boolean);
method public void setStopped(boolean);
method public void setSurface(@Nullable android.view.Surface);
@@ -14132,9 +14134,9 @@ package android.graphics {
}
public final class HardwareRenderer.FrameRenderRequest {
- method public android.graphics.HardwareRenderer.FrameRenderRequest setFrameCommitCallback(@NonNull java.util.concurrent.Executor, @NonNull Runnable);
- method public android.graphics.HardwareRenderer.FrameRenderRequest setVsyncTime(long);
- method public android.graphics.HardwareRenderer.FrameRenderRequest setWaitForPresent(boolean);
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest setFrameCommitCallback(@NonNull java.util.concurrent.Executor, @NonNull Runnable);
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest setVsyncTime(long);
+ method @NonNull public android.graphics.HardwareRenderer.FrameRenderRequest setWaitForPresent(boolean);
method public int syncAndDraw();
}
@@ -14953,8 +14955,8 @@ package android.graphics {
public final class RenderNode {
ctor public RenderNode(@Nullable String);
- method public android.graphics.RecordingCanvas beginRecording(int, int);
- method public android.graphics.RecordingCanvas beginRecording();
+ method @NonNull public android.graphics.RecordingCanvas beginRecording(int, int);
+ method @NonNull public android.graphics.RecordingCanvas beginRecording();
method public long computeApproximateMemoryUsage();
method public void discardDisplayList();
method public void endRecording();
@@ -15007,7 +15009,7 @@ package android.graphics {
method public boolean setPivotX(float);
method public boolean setPivotY(float);
method public boolean setPosition(int, int, int, int);
- method public boolean setPosition(android.graphics.Rect);
+ method public boolean setPosition(@NonNull android.graphics.Rect);
method public boolean setProjectBackwards(boolean);
method public boolean setProjectionReceiver(boolean);
method public boolean setRotationX(float);
@@ -15446,38 +15448,38 @@ package android.graphics.drawable {
method public float getGradientCenterY();
method public float getGradientRadius();
method public int getGradientType();
- method public int getInnerRadius();
+ method @Px public int getInnerRadius();
method public float getInnerRadiusRatio();
method public int getOpacity();
method public android.graphics.drawable.GradientDrawable.Orientation getOrientation();
method public int getShape();
- method public int getThickness();
+ method @Px public int getThickness();
method public float getThicknessRatio();
method public boolean getUseLevel();
method public void setAlpha(int);
method public void setColor(@ColorInt int);
method public void setColor(@Nullable android.content.res.ColorStateList);
method public void setColorFilter(@Nullable android.graphics.ColorFilter);
- method public void setColors(@ColorInt int[]);
- method public void setColors(@ColorInt int[], @Nullable float[]);
+ method public void setColors(@Nullable @ColorInt int[]);
+ method public void setColors(@Nullable @ColorInt int[], @Nullable float[]);
method public void setCornerRadii(@Nullable float[]);
method public void setCornerRadius(float);
method public void setDither(boolean);
method public void setGradientCenter(float, float);
method public void setGradientRadius(float);
method public void setGradientType(int);
- method public void setInnerRadius(int);
- method public void setInnerRadiusRatio(float);
+ method public void setInnerRadius(@Px int);
+ method public void setInnerRadiusRatio(@FloatRange(from=0.0f, fromInclusive=false) float);
method public void setOrientation(android.graphics.drawable.GradientDrawable.Orientation);
- method public void setPadding(int, int, int, int);
+ method public void setPadding(@Px int, @Px int, @Px int, @Px int);
method public void setShape(int);
method public void setSize(int, int);
method public void setStroke(int, @ColorInt int);
method public void setStroke(int, android.content.res.ColorStateList);
method public void setStroke(int, @ColorInt int, float, float);
method public void setStroke(int, android.content.res.ColorStateList, float, float);
- method public void setThickness(int);
- method public void setThicknessRatio(float);
+ method public void setThickness(@Px int);
+ method public void setThicknessRatio(@FloatRange(from=0.0f, fromInclusive=false) float);
method public void setUseLevel(boolean);
field public static final int LINE = 2; // 0x2
field public static final int LINEAR_GRADIENT = 0; // 0x0
@@ -15690,10 +15692,10 @@ package android.graphics.drawable {
public class StateListDrawable extends android.graphics.drawable.DrawableContainer {
ctor public StateListDrawable();
method public void addState(int[], android.graphics.drawable.Drawable);
- method public int findStateDrawableIndex(int[]);
+ method public int findStateDrawableIndex(@NonNull int[]);
method public int getStateCount();
- method public android.graphics.drawable.Drawable getStateDrawable(int);
- method public int[] getStateSet(int);
+ method @Nullable public android.graphics.drawable.Drawable getStateDrawable(int);
+ method @NonNull public int[] getStateSet(int);
}
public class TransitionDrawable extends android.graphics.drawable.LayerDrawable implements android.graphics.drawable.Drawable.Callback {
@@ -16562,10 +16564,10 @@ package android.hardware.biometrics {
public static class BiometricPrompt.Builder {
ctor public BiometricPrompt.Builder(android.content.Context);
method @NonNull public android.hardware.biometrics.BiometricPrompt build();
- method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setAllowDeviceCredential(boolean);
+ method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setConfirmationRequired(boolean);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDescription(@NonNull CharSequence);
+ method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setDeviceCredentialAllowed(boolean);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setNegativeButton(@NonNull CharSequence, @NonNull java.util.concurrent.Executor, @NonNull android.content.DialogInterface.OnClickListener);
- method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setRequireConfirmation(boolean);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setSubtitle(@NonNull CharSequence);
method @NonNull public android.hardware.biometrics.BiometricPrompt.Builder setTitle(@NonNull CharSequence);
}
@@ -22826,24 +22828,6 @@ package android.location {
method @Deprecated public boolean usedInFix();
}
- @Deprecated public final class GpsStatus {
- method @Deprecated public int getMaxSatellites();
- method @Deprecated public Iterable<android.location.GpsSatellite> getSatellites();
- method @Deprecated public int getTimeToFirstFix();
- field @Deprecated public static final int GPS_EVENT_FIRST_FIX = 3; // 0x3
- field @Deprecated public static final int GPS_EVENT_SATELLITE_STATUS = 4; // 0x4
- field @Deprecated public static final int GPS_EVENT_STARTED = 1; // 0x1
- field @Deprecated public static final int GPS_EVENT_STOPPED = 2; // 0x2
- }
-
- @Deprecated public static interface GpsStatus.Listener {
- method @Deprecated public void onGpsStatusChanged(int);
- }
-
- @Deprecated public static interface GpsStatus.NmeaListener {
- method @Deprecated public void onNmeaReceived(long, String);
- }
-
public class Location implements android.os.Parcelable {
ctor public Location(String);
ctor public Location(android.location.Location);
@@ -22859,6 +22843,7 @@ package android.location {
method public float getBearing();
method public float getBearingAccuracyDegrees();
method public long getElapsedRealtimeNanos();
+ method public long getElapsedRealtimeUncertaintyNanos();
method public android.os.Bundle getExtras();
method public double getLatitude();
method public double getLongitude();
@@ -22871,6 +22856,7 @@ package android.location {
method public boolean hasAltitude();
method public boolean hasBearing();
method public boolean hasBearingAccuracy();
+ method public boolean hasElapsedRealtimeUncertaintyNanos();
method public boolean hasSpeed();
method public boolean hasSpeedAccuracy();
method public boolean hasVerticalAccuracy();
@@ -22886,6 +22872,7 @@ package android.location {
method public void setBearing(float);
method public void setBearingAccuracyDegrees(float);
method public void setElapsedRealtimeNanos(long);
+ method public void setElapsedRealtimeUncertaintyNanos(long);
method public void setExtras(android.os.Bundle);
method public void setLatitude(double);
method public void setLongitude(double);
@@ -22909,55 +22896,50 @@ package android.location {
}
public class LocationManager {
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.OnNmeaMessageListener);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.OnNmeaMessageListener, android.os.Handler);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void addProximityAlert(double, double, float, long, android.app.PendingIntent);
- method public void addTestProvider(String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
- method @Deprecated public void clearTestProviderEnabled(String);
- method @Deprecated public void clearTestProviderLocation(String);
- method @Deprecated public void clearTestProviderStatus(String);
- method public java.util.List<java.lang.String> getAllProviders();
- method public String getBestProvider(android.location.Criteria, boolean);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull android.location.OnNmeaMessageListener);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(@NonNull android.location.OnNmeaMessageListener, @Nullable android.os.Handler);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void addProximityAlert(double, double, float, long, @NonNull android.app.PendingIntent);
+ method public void addTestProvider(@NonNull String, boolean, boolean, boolean, boolean, boolean, boolean, boolean, int, int);
+ method @Deprecated public void clearTestProviderEnabled(@NonNull String);
+ method @Deprecated public void clearTestProviderLocation(@NonNull String);
+ method @Deprecated public void clearTestProviderStatus(@NonNull String);
+ method @NonNull public java.util.List<java.lang.String> getAllProviders();
+ method @Nullable public String getBestProvider(@NonNull android.location.Criteria, boolean);
method @Nullable public String getGnssHardwareModelName();
method public int getGnssYearOfHardware();
- method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(android.location.GpsStatus);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public android.location.Location getLastKnownLocation(String);
- method public android.location.LocationProvider getProvider(String);
- method public java.util.List<java.lang.String> getProviders(boolean);
- method public java.util.List<java.lang.String> getProviders(android.location.Criteria, boolean);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) @Nullable public android.location.Location getLastKnownLocation(@NonNull String);
+ method @Nullable public android.location.LocationProvider getProvider(@NonNull String);
+ method @NonNull public java.util.List<java.lang.String> getProviders(boolean);
+ method @NonNull public java.util.List<java.lang.String> getProviders(@NonNull android.location.Criteria, boolean);
method public boolean isLocationEnabled();
- method public boolean isProviderEnabled(String);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback, android.os.Handler);
- method public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback, android.os.Handler);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback);
- method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(android.location.GnssStatus.Callback, android.os.Handler);
- method @Deprecated public void removeGpsStatusListener(android.location.GpsStatus.Listener);
- method @Deprecated public void removeNmeaListener(android.location.GpsStatus.NmeaListener);
- method public void removeNmeaListener(android.location.OnNmeaMessageListener);
- method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeProximityAlert(android.app.PendingIntent);
- method public void removeTestProvider(String);
- method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeUpdates(android.location.LocationListener);
- method public void removeUpdates(android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(String, long, float, android.location.LocationListener);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(String, long, float, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, android.location.Criteria, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(String, long, float, android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, android.location.Criteria, android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(String, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(android.location.Criteria, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(String, android.app.PendingIntent);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(android.location.Criteria, android.app.PendingIntent);
- method public boolean sendExtraCommand(String, String, android.os.Bundle);
- method public void setTestProviderEnabled(String, boolean);
- method public void setTestProviderLocation(String, android.location.Location);
- method @Deprecated public void setTestProviderStatus(String, int, android.os.Bundle, long);
- method public void unregisterGnssMeasurementsCallback(android.location.GnssMeasurementsEvent.Callback);
- method public void unregisterGnssNavigationMessageCallback(android.location.GnssNavigationMessage.Callback);
- method public void unregisterGnssStatusCallback(android.location.GnssStatus.Callback);
+ method public boolean isProviderEnabled(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback, @Nullable android.os.Handler);
+ method public boolean registerGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback, @Nullable android.os.Handler);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(@NonNull android.location.GnssStatus.Callback);
+ method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean registerGnssStatusCallback(@NonNull android.location.GnssStatus.Callback, @Nullable android.os.Handler);
+ method public void removeNmeaListener(@NonNull android.location.OnNmeaMessageListener);
+ method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeProximityAlert(@NonNull android.app.PendingIntent);
+ method public void removeTestProvider(@NonNull String);
+ method @RequiresPermission(anyOf={"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"}, apis="..22") public void removeUpdates(@NonNull android.location.LocationListener);
+ method public void removeUpdates(@NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.location.LocationListener);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull String, long, float, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(long, float, @NonNull android.location.Criteria, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull String, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestSingleUpdate(@NonNull android.location.Criteria, @NonNull android.app.PendingIntent);
+ method public boolean sendExtraCommand(@NonNull String, @NonNull String, @Nullable android.os.Bundle);
+ method public void setTestProviderEnabled(@NonNull String, boolean);
+ method public void setTestProviderLocation(@NonNull String, @NonNull android.location.Location);
+ method @Deprecated public void setTestProviderStatus(@NonNull String, int, @Nullable android.os.Bundle, long);
+ method public void unregisterGnssMeasurementsCallback(@NonNull android.location.GnssMeasurementsEvent.Callback);
+ method public void unregisterGnssNavigationMessageCallback(@NonNull android.location.GnssNavigationMessage.Callback);
+ method public void unregisterGnssStatusCallback(@NonNull android.location.GnssStatus.Callback);
field public static final String GPS_PROVIDER = "gps";
field public static final String KEY_LOCATION_CHANGED = "location";
field public static final String KEY_PROVIDER_ENABLED = "providerEnabled";
@@ -23016,6 +22998,7 @@ package android.media {
}
public final class AudioAttributes implements android.os.Parcelable {
+ method public boolean areHapticChannelsMuted();
method public int describeContents();
method public int getContentType();
method public int getFlags();
@@ -23053,10 +23036,11 @@ package android.media {
ctor public AudioAttributes.Builder();
ctor public AudioAttributes.Builder(android.media.AudioAttributes);
method public android.media.AudioAttributes build();
- method public android.media.AudioAttributes.Builder setAllowCapture(boolean);
+ method @NonNull public android.media.AudioAttributes.Builder setAllowCapture(boolean);
method public android.media.AudioAttributes.Builder setContentType(int);
method public android.media.AudioAttributes.Builder setFlags(int);
method public android.media.AudioAttributes.Builder setLegacyStreamType(int);
+ method public android.media.AudioAttributes.Builder setMuteHapticChannels(boolean);
method public android.media.AudioAttributes.Builder setUsage(int);
}
@@ -23392,11 +23376,11 @@ package android.media {
public static final class AudioPlaybackCaptureConfiguration.Builder {
ctor public AudioPlaybackCaptureConfiguration.Builder(@NonNull android.media.projection.MediaProjection);
- method public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUid(int);
- method public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(@NonNull android.media.AudioAttributes);
- method public android.media.AudioPlaybackCaptureConfiguration build();
- method public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUid(int);
- method public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(@NonNull android.media.AudioAttributes);
+ method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUid(int);
+ method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder addMatchingUsage(@NonNull android.media.AudioAttributes);
+ method @NonNull public android.media.AudioPlaybackCaptureConfiguration build();
+ method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUid(int);
+ method @NonNull public android.media.AudioPlaybackCaptureConfiguration.Builder excludeUsage(@NonNull android.media.AudioAttributes);
}
public final class AudioPlaybackConfiguration implements android.os.Parcelable {
@@ -23497,7 +23481,7 @@ package android.media {
ctor public AudioRecord.Builder();
method public android.media.AudioRecord build() throws java.lang.UnsupportedOperationException;
method public android.media.AudioRecord.Builder setAudioFormat(@NonNull android.media.AudioFormat) throws java.lang.IllegalArgumentException;
- method public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration);
+ method @NonNull public android.media.AudioRecord.Builder setAudioPlaybackCaptureConfig(@NonNull android.media.AudioPlaybackCaptureConfiguration);
method public android.media.AudioRecord.Builder setAudioSource(int) throws java.lang.IllegalArgumentException;
method public android.media.AudioRecord.Builder setBufferSizeInBytes(int) throws java.lang.IllegalArgumentException;
}
@@ -23805,7 +23789,7 @@ package android.media {
method public android.graphics.Bitmap getThumbnailBitmap();
method public byte[] getThumbnailBytes();
method @Nullable public long[] getThumbnailRange();
- method public boolean hasAttribute(String);
+ method public boolean hasAttribute(@NonNull String);
method public boolean hasThumbnail();
method public boolean isThumbnailCompressed();
method public void saveAttributes() throws java.io.IOException;
@@ -25137,7 +25121,7 @@ package android.media {
field public static final long POSITION_UNKNOWN = 576460752303423487L; // 0x7ffffffffffffffL
}
- public static class MediaItem2.Builder {
+ public static final class MediaItem2.Builder {
ctor public MediaItem2.Builder();
method @NonNull public android.media.MediaItem2 build();
method @NonNull public android.media.MediaItem2.Builder setEndPosition(long);
@@ -30553,7 +30537,7 @@ package android.net.wifi.p2p {
}
public static interface WifiP2pManager.DeviceInfoListener {
- method public void onDeviceInfoAvailable(android.net.wifi.p2p.WifiP2pDevice);
+ method public void onDeviceInfoAvailable(@Nullable android.net.wifi.p2p.WifiP2pDevice);
}
public static interface WifiP2pManager.DiscoveryStateListener {
@@ -35523,7 +35507,7 @@ package android.os {
public abstract class VibrationEffect implements android.os.Parcelable {
method public static android.os.VibrationEffect createOneShot(long, int);
- method public static android.os.VibrationEffect createPredefined(int);
+ method @NonNull public static android.os.VibrationEffect createPredefined(int);
method public static android.os.VibrationEffect createWaveform(long[], int);
method public static android.os.VibrationEffect createWaveform(long[], int[], int);
method public int describeContents();
@@ -38327,10 +38311,10 @@ package android.provider {
method public android.database.Cursor queryChildDocuments(String, @Nullable String[], @Nullable android.os.Bundle) throws java.io.FileNotFoundException;
method public abstract android.database.Cursor queryDocument(String, String[]) throws java.io.FileNotFoundException;
method public android.database.Cursor queryRecentDocuments(String, String[]) throws java.io.FileNotFoundException;
- method public android.database.Cursor queryRecentDocuments(String, String[], @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;
+ method @Nullable public android.database.Cursor queryRecentDocuments(@NonNull String, @Nullable String[], @Nullable android.os.Bundle, @Nullable android.os.CancellationSignal) throws java.io.FileNotFoundException;
method public abstract android.database.Cursor queryRoots(String[]) throws java.io.FileNotFoundException;
method public android.database.Cursor querySearchDocuments(String, String, String[]) throws java.io.FileNotFoundException;
- method public android.database.Cursor querySearchDocuments(@NonNull String, @Nullable String[], @NonNull android.os.Bundle) throws java.io.FileNotFoundException;
+ method @Nullable public android.database.Cursor querySearchDocuments(@NonNull String, @Nullable String[], @NonNull android.os.Bundle) throws java.io.FileNotFoundException;
method public void removeDocument(String, String) throws java.io.FileNotFoundException;
method public String renameDocument(String, String) throws java.io.FileNotFoundException;
method public final void revokeDocumentPermission(String);
@@ -38428,7 +38412,7 @@ package android.provider {
field public static final String ACTION_REVIEW_SECURE = "android.provider.action.REVIEW_SECURE";
field public static final String ACTION_VIDEO_CAPTURE = "android.media.action.VIDEO_CAPTURE";
field public static final String AUTHORITY = "media";
- field public static final android.net.Uri AUTHORITY_URI;
+ field @NonNull public static final android.net.Uri AUTHORITY_URI;
field public static final String EXTRA_BRIGHTNESS = "android.provider.extra.BRIGHTNESS";
field public static final String EXTRA_DURATION_LIMIT = "android.intent.extra.durationLimit";
field public static final String EXTRA_FINISH_ON_COMPLETION = "android.intent.extra.finishOnCompletion";
@@ -41387,7 +41371,7 @@ package android.service.carrier {
public class CarrierIdentifier implements android.os.Parcelable {
ctor public CarrierIdentifier(String, String, @Nullable String, @Nullable String, @Nullable String, @Nullable String);
- ctor public CarrierIdentifier(String, String, @Nullable String, @Nullable String, @Nullable String, @Nullable String, int, int);
+ ctor public CarrierIdentifier(@NonNull String, @NonNull String, @Nullable String, @Nullable String, @Nullable String, @Nullable String, int, int);
ctor public CarrierIdentifier(byte[], @Nullable String, @Nullable String);
method public int describeContents();
method public int getCarrierId();
@@ -41867,28 +41851,28 @@ package android.service.notification {
field public static final int STATE_UNSET = 0; // 0x0
}
- public static class ZenPolicy.Builder {
+ public static final class ZenPolicy.Builder {
ctor public ZenPolicy.Builder();
- method public android.service.notification.ZenPolicy.Builder allowAlarms(boolean);
- method public android.service.notification.ZenPolicy.Builder allowAllSounds();
- method public android.service.notification.ZenPolicy.Builder allowCalls(int);
- method public android.service.notification.ZenPolicy.Builder allowEvents(boolean);
- method public android.service.notification.ZenPolicy.Builder allowMedia(boolean);
- method public android.service.notification.ZenPolicy.Builder allowMessages(int);
- method public android.service.notification.ZenPolicy.Builder allowReminders(boolean);
- method public android.service.notification.ZenPolicy.Builder allowRepeatCallers(boolean);
- method public android.service.notification.ZenPolicy.Builder allowSystem(boolean);
- method public android.service.notification.ZenPolicy build();
- method public android.service.notification.ZenPolicy.Builder disallowAllSounds();
- method public android.service.notification.ZenPolicy.Builder hideAllVisualEffects();
- method public android.service.notification.ZenPolicy.Builder showAllVisualEffects();
- method public android.service.notification.ZenPolicy.Builder showBadges(boolean);
- method public android.service.notification.ZenPolicy.Builder showFullScreenIntent(boolean);
- method public android.service.notification.ZenPolicy.Builder showInAmbientDisplay(boolean);
- method public android.service.notification.ZenPolicy.Builder showInNotificationList(boolean);
- method public android.service.notification.ZenPolicy.Builder showLights(boolean);
- method public android.service.notification.ZenPolicy.Builder showPeeking(boolean);
- method public android.service.notification.ZenPolicy.Builder showStatusBarIcons(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowAlarms(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowAllSounds();
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowCalls(int);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowEvents(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowMedia(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowMessages(int);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowReminders(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowRepeatCallers(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder allowSystem(boolean);
+ method @NonNull public android.service.notification.ZenPolicy build();
+ method @NonNull public android.service.notification.ZenPolicy.Builder disallowAllSounds();
+ method @NonNull public android.service.notification.ZenPolicy.Builder hideAllVisualEffects();
+ method @NonNull public android.service.notification.ZenPolicy.Builder showAllVisualEffects();
+ method @NonNull public android.service.notification.ZenPolicy.Builder showBadges(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder showFullScreenIntent(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder showInAmbientDisplay(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder showInNotificationList(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder showLights(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder showPeeking(boolean);
+ method @NonNull public android.service.notification.ZenPolicy.Builder showStatusBarIcons(boolean);
}
}
@@ -44781,6 +44765,7 @@ package android.telephony {
public class PhoneStateListener {
ctor public PhoneStateListener();
ctor public PhoneStateListener(@NonNull java.util.concurrent.Executor);
+ method public void onActiveDataSubscriptionIdChanged(int);
method public void onCallForwardingIndicatorChanged(boolean);
method public void onCallStateChanged(int, String);
method public void onCellInfoChanged(java.util.List<android.telephony.CellInfo>);
@@ -44793,6 +44778,7 @@ package android.telephony {
method @Deprecated public void onSignalStrengthChanged(int);
method public void onSignalStrengthsChanged(android.telephony.SignalStrength);
method public void onUserMobileDataStateChanged(boolean);
+ field public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 4194304; // 0x400000
field public static final int LISTEN_CALL_FORWARDING_INDICATOR = 8; // 0x8
field public static final int LISTEN_CALL_STATE = 32; // 0x20
field public static final int LISTEN_CELL_INFO = 1024; // 0x400
@@ -44821,7 +44807,7 @@ package android.telephony {
public class ServiceState implements android.os.Parcelable {
ctor public ServiceState();
ctor public ServiceState(android.telephony.ServiceState);
- ctor public ServiceState(android.os.Parcel);
+ ctor @Deprecated public ServiceState(android.os.Parcel);
method protected void copyFrom(android.telephony.ServiceState);
method public int describeContents();
method public int getCdmaNetworkId();
@@ -45214,7 +45200,7 @@ package android.telephony {
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setNetworkSelectionModeManual(String, boolean);
method public boolean setOperatorBrandOverride(String);
method public boolean setPreferredNetworkTypeToGlobal();
- method public boolean setPreferredOpportunisticDataSubscription(int);
+ method public void setPreferredOpportunisticDataSubscription(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
method public void setVisualVoicemailSmsFilterSettings(android.telephony.VisualVoicemailSmsFilterSettings);
method public boolean setVoiceMailNumber(String, String);
method @Deprecated public void setVoicemailRingtoneUri(android.telecom.PhoneAccountHandle, android.net.Uri);
@@ -51972,6 +51958,7 @@ package android.view {
method public int getStableInsetRight();
method public int getStableInsetTop();
method @NonNull public android.graphics.Insets getStableInsets();
+ method @NonNull public android.graphics.Insets getSystemGestureInsets();
method public int getSystemWindowInsetBottom();
method public int getSystemWindowInsetLeft();
method public int getSystemWindowInsetRight();
@@ -51993,6 +51980,7 @@ package android.view {
method @NonNull public android.view.WindowInsets build();
method @NonNull public android.view.WindowInsets.Builder setDisplayCutout(@Nullable android.view.DisplayCutout);
method @NonNull public android.view.WindowInsets.Builder setStableInsets(@NonNull android.graphics.Insets);
+ method @NonNull public android.view.WindowInsets.Builder setSystemGestureInsets(@NonNull android.graphics.Insets);
method @NonNull public android.view.WindowInsets.Builder setSystemWindowInsets(@NonNull android.graphics.Insets);
}
@@ -53557,6 +53545,7 @@ package android.view.inspector {
method public int mapIntFlag(@NonNull String, @AttrRes int, @NonNull android.view.inspector.IntFlagMapping);
method public int mapLong(@NonNull String, @AttrRes int);
method public int mapObject(@NonNull String, @AttrRes int);
+ method public int mapResourceId(@NonNull String, @AttrRes int);
method public int mapShort(@NonNull String, @AttrRes int);
}
@@ -53579,6 +53568,7 @@ package android.view.inspector {
method public void readIntFlag(int, int);
method public void readLong(int, long);
method public void readObject(int, @Nullable Object);
+ method public void readResourceId(int, @AnyRes int);
method public void readShort(int, short);
}
@@ -56237,7 +56227,7 @@ package android.widget {
field public static final int SOURCE_BOUND_MAX_VISIBLE = 1; // 0x1
}
- public static class Magnifier.Builder {
+ public static final class Magnifier.Builder {
ctor public Magnifier.Builder(@NonNull android.view.View);
method @NonNull public android.widget.Magnifier build();
method @NonNull public android.widget.Magnifier.Builder setClippingEnabled(boolean);
@@ -56786,7 +56776,7 @@ package android.widget {
method public boolean isFillViewport();
method public boolean isSmoothScrollingEnabled();
method public boolean pageScroll(int);
- method public void scrollToDescendant(android.view.View);
+ method public void scrollToDescendant(@NonNull android.view.View);
method public void setBottomEdgeEffectColor(@ColorInt int);
method public void setEdgeEffectColor(@ColorInt int);
method public void setFillViewport(boolean);
diff --git a/api/removed.txt b/api/removed.txt
index fdfaf91096a0..7a06803053e8 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -282,12 +282,38 @@ package android.hardware {
package android.location {
+ @Deprecated public final class GpsStatus {
+ method public int getMaxSatellites();
+ method public Iterable<android.location.GpsSatellite> getSatellites();
+ method public int getTimeToFirstFix();
+ field public static final int GPS_EVENT_FIRST_FIX = 3; // 0x3
+ field public static final int GPS_EVENT_SATELLITE_STATUS = 4; // 0x4
+ field public static final int GPS_EVENT_STARTED = 1; // 0x1
+ field public static final int GPS_EVENT_STOPPED = 2; // 0x2
+ }
+
+ @Deprecated public static interface GpsStatus.Listener {
+ method public void onGpsStatusChanged(int);
+ }
+
+ @Deprecated public static interface GpsStatus.NmeaListener {
+ method public void onNmeaReceived(long, String);
+ }
+
public class Location implements android.os.Parcelable {
method @Deprecated public void removeBearingAccuracy();
method @Deprecated public void removeSpeedAccuracy();
method @Deprecated public void removeVerticalAccuracy();
}
+ public class LocationManager {
+ method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addGpsStatusListener(android.location.GpsStatus.Listener);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public boolean addNmeaListener(android.location.GpsStatus.NmeaListener);
+ method @Deprecated @Nullable @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public android.location.GpsStatus getGpsStatus(@Nullable android.location.GpsStatus);
+ method @Deprecated public void removeGpsStatusListener(android.location.GpsStatus.Listener);
+ method @Deprecated public void removeNmeaListener(android.location.GpsStatus.NmeaListener);
+ }
+
}
package android.media {
diff --git a/api/system-current.txt b/api/system-current.txt
index 752640bb8d02..8016304b6dfb 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -25,6 +25,7 @@ package android {
field public static final String BIND_AUGMENTED_AUTOFILL_SERVICE = "android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE";
field @Deprecated public static final String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final String BIND_CONTENT_CAPTURE_SERVICE = "android.permission.BIND_CONTENT_CAPTURE_SERVICE";
+ field public static final String BIND_CONTENT_SUGGESTIONS_SERVICE = "android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE";
field public static final String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
field public static final String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
field public static final String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
@@ -163,6 +164,7 @@ package android {
field public static final String RESET_PASSWORD = "android.permission.RESET_PASSWORD";
field public static final String RESTRICTED_VR_ACCESS = "android.permission.RESTRICTED_VR_ACCESS";
field public static final String RETRIEVE_WINDOW_CONTENT = "android.permission.RETRIEVE_WINDOW_CONTENT";
+ field public static final String REVIEW_ACCESSIBILITY_SERVICES = "android.permission.REVIEW_ACCESSIBILITY_SERVICES";
field public static final String REVOKE_RUNTIME_PERMISSIONS = "android.permission.REVOKE_RUNTIME_PERMISSIONS";
field public static final String SCORE_NETWORKS = "android.permission.SCORE_NETWORKS";
field public static final String SEND_DEVICE_CUSTOMIZATION_READY = "android.permission.SEND_DEVICE_CUSTOMIZATION_READY";
@@ -209,7 +211,6 @@ package android {
public static final class R.attr {
field public static final int allowClearUserDataOnFailedRestore = 16844198; // 0x10105a6
- field public static final int inheritShowWhenLocked = 16844194; // 0x10105a2
field public static final int isVrOnly = 16844152; // 0x1010578
field public static final int requiredSystemPropertyName = 16844133; // 0x1010565
field public static final int requiredSystemPropertyValue = 16844134; // 0x1010566
@@ -279,7 +280,6 @@ package android.app {
method public boolean convertToTranslucent(android.app.Activity.TranslucentConversionListener, android.app.ActivityOptions);
method @Deprecated public boolean isBackgroundVisibleBehind();
method @Deprecated public void onBackgroundVisibleBehindChanged(boolean);
- method public void setInheritShowWhenLocked(boolean);
}
public static interface Activity.TranslucentConversionListener {
@@ -1413,7 +1413,7 @@ package android.content {
field public static final String ACTION_PRE_BOOT_COMPLETED = "android.intent.action.PRE_BOOT_COMPLETED";
field public static final String ACTION_QUERY_PACKAGE_RESTART = "android.intent.action.QUERY_PACKAGE_RESTART";
field public static final String ACTION_RESOLVE_INSTANT_APP_PACKAGE = "android.intent.action.RESOLVE_INSTANT_APP_PACKAGE";
- field public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES = "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES";
+ field @RequiresPermission(android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES) public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES = "android.intent.action.REVIEW_ACCESSIBILITY_SERVICES";
field @RequiresPermission(android.Manifest.permission.GRANT_RUNTIME_PERMISSIONS) public static final String ACTION_REVIEW_APP_PERMISSION_USAGE = "android.intent.action.REVIEW_APP_PERMISSION_USAGE";
field public static final String ACTION_REVIEW_PERMISSIONS = "android.intent.action.REVIEW_PERMISSIONS";
field public static final String ACTION_REVIEW_PERMISSION_USAGE = "android.intent.action.REVIEW_PERMISSION_USAGE";
@@ -1707,9 +1707,9 @@ package android.content.pm {
}
public class PermissionGroupInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
- field @StringRes public int backgroundRequestDetailResourceId;
- field @StringRes public int backgroundRequestResourceId;
- field @StringRes public int requestDetailResourceId;
+ field @StringRes public final int backgroundRequestDetailResourceId;
+ field @StringRes public final int backgroundRequestResourceId;
+ field @StringRes public final int requestDetailResourceId;
field @StringRes public int requestRes;
}
@@ -3365,57 +3365,53 @@ package android.location {
}
public class LocationManager {
- method @Deprecated public boolean addGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
- method @Deprecated public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void flushGnssBatch();
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public int getGnssBatchSize();
method public int getGnssCapabilities();
method @Nullable public String getLocationControllerExtraPackage();
method @RequiresPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) public void injectGnssMeasurementCorrections(@NonNull android.location.GnssMeasurementCorrections);
method public boolean isLocationControllerExtraPackageEnabled();
- method public boolean isLocationEnabledForUser(android.os.UserHandle);
- method public boolean isProviderEnabledForUser(String, android.os.UserHandle);
- method public boolean isProviderPackage(String);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, android.location.BatchedLocationCallback, android.os.Handler);
- method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
- method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(String);
+ method public boolean isLocationEnabledForUser(@NonNull android.os.UserHandle);
+ method public boolean isProviderEnabledForUser(@NonNull String, @NonNull android.os.UserHandle);
+ method public boolean isProviderPackage(@NonNull String);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean registerGnssBatchedLocationCallback(long, boolean, @NonNull android.location.BatchedLocationCallback, @Nullable android.os.Handler);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackage(@NonNull String);
method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public void setLocationControllerExtraPackageEnabled(boolean);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, android.os.UserHandle);
- method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(String, boolean, android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(android.location.BatchedLocationCallback);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
+ method @Deprecated @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean setProviderEnabledForUser(@NonNull String, boolean, @NonNull android.os.UserHandle);
+ method @RequiresPermission(android.Manifest.permission.LOCATION_HARDWARE) public boolean unregisterGnssBatchedLocationCallback(@NonNull android.location.BatchedLocationCallback);
}
public final class LocationRequest implements android.os.Parcelable {
- method public static android.location.LocationRequest create();
- method public static android.location.LocationRequest createFromDeprecatedCriteria(android.location.Criteria, long, float, boolean);
- method public static android.location.LocationRequest createFromDeprecatedProvider(String, long, float, boolean);
+ method @NonNull public static android.location.LocationRequest create();
+ method @NonNull public static android.location.LocationRequest createFromDeprecatedCriteria(@NonNull android.location.Criteria, long, float, boolean);
+ method @NonNull public static android.location.LocationRequest createFromDeprecatedProvider(@NonNull String, long, float, boolean);
method public int describeContents();
method public long getExpireAt();
method public long getFastestInterval();
method public boolean getHideFromAppOps();
method public long getInterval();
method public int getNumUpdates();
- method public String getProvider();
+ method @NonNull public String getProvider();
method public int getQuality();
method public float getSmallestDisplacement();
- method public android.os.WorkSource getWorkSource();
+ method @Nullable public android.os.WorkSource getWorkSource();
method public boolean isLocationSettingsIgnored();
method public boolean isLowPowerMode();
- method public android.location.LocationRequest setExpireAt(long);
- method public android.location.LocationRequest setExpireIn(long);
- method public android.location.LocationRequest setFastestInterval(long);
+ method @NonNull public android.location.LocationRequest setExpireAt(long);
+ method @NonNull public android.location.LocationRequest setExpireIn(long);
+ method @NonNull public android.location.LocationRequest setFastestInterval(long);
method public void setHideFromAppOps(boolean);
- method public android.location.LocationRequest setInterval(long);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest setLocationSettingsIgnored(boolean);
- method public android.location.LocationRequest setLowPowerMode(boolean);
- method public android.location.LocationRequest setNumUpdates(int);
- method public android.location.LocationRequest setProvider(String);
- method public android.location.LocationRequest setQuality(int);
- method public android.location.LocationRequest setSmallestDisplacement(float);
- method public void setWorkSource(android.os.WorkSource);
+ method @NonNull public android.location.LocationRequest setInterval(long);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @NonNull public android.location.LocationRequest setLocationSettingsIgnored(boolean);
+ method @NonNull public android.location.LocationRequest setLowPowerMode(boolean);
+ method @NonNull public android.location.LocationRequest setNumUpdates(int);
+ method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
+ method @NonNull public android.location.LocationRequest setQuality(int);
+ method @NonNull public android.location.LocationRequest setSmallestDisplacement(float);
+ method public void setWorkSource(@Nullable android.os.WorkSource);
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACCURACY_BLOCK = 102; // 0x66
field public static final int ACCURACY_CITY = 104; // 0x68
@@ -3537,6 +3533,7 @@ package android.media {
}
public class HwAudioSource {
+ method public boolean isPlaying();
method public void start();
method public void stop();
}
@@ -4755,7 +4752,7 @@ package android.net.wifi {
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsConfiguratorInitiator(@NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startEasyConnectAsEnrolleeInitiator(@NonNull String, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.EasyConnectStatusCallback);
method @RequiresPermission(android.Manifest.permission.UPDATE_DEVICE_STATS) public boolean startScan(android.os.WorkSource);
- method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(android.net.wifi.hotspot2.OsuProvider, android.net.wifi.hotspot2.ProvisioningCallback, @Nullable android.os.Handler);
+ method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void startSubscriptionProvisioning(@NonNull android.net.wifi.hotspot2.OsuProvider, @NonNull java.util.concurrent.Executor, @NonNull android.net.wifi.hotspot2.ProvisioningCallback);
method @RequiresPermission(anyOf={"android.permission.NETWORK_SETTINGS", android.Manifest.permission.NETWORK_SETUP_WIZARD}) public void stopEasyConnectSession();
method @RequiresPermission("android.permission.WIFI_UPDATE_USABILITY_STATS_SCORE") public void updateWifiUsabilityScore(int, int, int);
field public static final int CHANGE_REASON_ADDED = 0; // 0x0
@@ -5591,9 +5588,9 @@ package android.os {
method public boolean isSystem();
method public static int myUserId();
method public static android.os.UserHandle of(int);
- field public static final android.os.UserHandle ALL;
- field public static final android.os.UserHandle CURRENT;
- field public static final android.os.UserHandle SYSTEM;
+ field @NonNull public static final android.os.UserHandle ALL;
+ field @NonNull public static final android.os.UserHandle CURRENT;
+ field @NonNull public static final android.os.UserHandle SYSTEM;
}
public class UserManager {
@@ -5604,7 +5601,7 @@ package android.os {
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.PersistableBundle getSeedAccountOptions();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public String getSeedAccountType();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public long[] getSerialNumbersOfUsers(boolean);
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.graphics.Bitmap getUserIcon();
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.graphics.Bitmap getUserIcon();
method @Deprecated @android.os.UserManager.UserRestrictionSource @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public int getUserRestrictionSource(String, android.os.UserHandle);
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public java.util.List<android.os.UserManager.EnforcingUser> getUserRestrictionSources(String, android.os.UserHandle);
method public boolean hasRestrictedProfiles();
@@ -5615,8 +5612,8 @@ package android.os {
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isPrimaryUser();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean isRestrictedProfile();
method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public boolean removeUser(android.os.UserHandle);
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(android.graphics.Bitmap);
- method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(String);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserIcon(@NonNull android.graphics.Bitmap);
+ method @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public void setUserName(@Nullable String);
field public static final String ACTION_USER_RESTRICTIONS_CHANGED = "android.os.action.USER_RESTRICTIONS_CHANGED";
field @Deprecated public static final String DISALLOW_OEM_UNLOCK = "no_oem_unlock";
field public static final String DISALLOW_RUN_IN_BACKGROUND = "no_run_in_background";
@@ -5926,8 +5923,8 @@ package android.provider {
}
public final class DocumentsContract {
- method public static boolean isManageMode(android.net.Uri);
- method public static android.net.Uri setManageMode(android.net.Uri);
+ method public static boolean isManageMode(@NonNull android.net.Uri);
+ method @NonNull public static android.net.Uri setManageMode(@NonNull android.net.Uri);
field public static final String ACTION_DOCUMENT_ROOT_SETTINGS = "android.provider.action.DOCUMENT_ROOT_SETTINGS";
field public static final String ACTION_MANAGE_DOCUMENT = "android.provider.action.MANAGE_DOCUMENT";
field public static final String EXTRA_SHOW_ADVANCED = "android.provider.extra.SHOW_ADVANCED";
@@ -6079,6 +6076,7 @@ package android.provider {
field public static final String CARRIER_APP_WHITELIST = "carrier_app_whitelist";
field public static final String DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = "data_stall_consecutive_dns_timeout_threshold";
field public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
+ field public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; // 0x1
field public static final String DATA_STALL_MIN_EVALUATE_INTERVAL = "data_stall_min_evaluate_interval";
field public static final String DATA_STALL_VALID_DNS_TIME_THRESHOLD = "data_stall_valid_dns_time_threshold";
field public static final String DEFAULT_SM_DP_PLUS = "default_sm_dp_plus";
@@ -6187,8 +6185,8 @@ package android.security.keystore {
}
public class DeviceIdAttestationException extends java.lang.Exception {
- ctor public DeviceIdAttestationException(String);
- ctor public DeviceIdAttestationException(String, Throwable);
+ ctor public DeviceIdAttestationException(@Nullable String);
+ ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
}
}
@@ -6763,15 +6761,15 @@ package android.service.textclassifier {
method public static android.view.textclassifier.TextClassifier getDefaultTextClassifierImplementation(@NonNull android.content.Context);
method @Deprecated public final android.view.textclassifier.TextClassifier getLocalTextClassifier();
method @Nullable public final android.os.IBinder onBind(android.content.Intent);
- method public abstract void onClassifyText(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassification.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextClassification>);
- method public void onCreateTextClassificationSession(@NonNull android.view.textclassifier.TextClassificationContext, @NonNull android.view.textclassifier.TextClassificationSessionId);
- method public void onDestroyTextClassificationSession(@NonNull android.view.textclassifier.TextClassificationSessionId);
- method public void onDetectLanguage(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextLanguage.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextLanguage>);
- method public abstract void onGenerateLinks(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextLinks.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextLinks>);
- method @Deprecated public void onSelectionEvent(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.SelectionEvent);
- method public void onSuggestConversationActions(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.ConversationActions.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.ConversationActions>);
- method public abstract void onSuggestSelection(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextSelection.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextSelection>);
- method public void onTextClassifierEvent(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassifierEvent);
+ method @MainThread public abstract void onClassifyText(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassification.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextClassification>);
+ method @MainThread public void onCreateTextClassificationSession(@NonNull android.view.textclassifier.TextClassificationContext, @NonNull android.view.textclassifier.TextClassificationSessionId);
+ method @MainThread public void onDestroyTextClassificationSession(@NonNull android.view.textclassifier.TextClassificationSessionId);
+ method @MainThread public void onDetectLanguage(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextLanguage.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextLanguage>);
+ method @MainThread public abstract void onGenerateLinks(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextLinks.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextLinks>);
+ method @Deprecated @MainThread public void onSelectionEvent(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.SelectionEvent);
+ method @MainThread public void onSuggestConversationActions(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.ConversationActions.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.ConversationActions>);
+ method @MainThread public abstract void onSuggestSelection(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextSelection.Request, @NonNull android.os.CancellationSignal, @NonNull android.service.textclassifier.TextClassifierService.Callback<android.view.textclassifier.TextSelection>);
+ method @MainThread public void onTextClassifierEvent(@Nullable android.view.textclassifier.TextClassificationSessionId, @NonNull android.view.textclassifier.TextClassifierEvent);
field public static final String SERVICE_INTERFACE = "android.service.textclassifier.TextClassifierService";
}
@@ -7616,12 +7614,11 @@ package android.telephony {
}
public class NetworkRegistrationState implements android.os.Parcelable {
- ctor public NetworkRegistrationState(int, int, int, int, int, boolean, int[], @Nullable android.telephony.CellIdentity);
- ctor protected NetworkRegistrationState(android.os.Parcel);
+ ctor public NetworkRegistrationState(int, int, int, int, int, boolean, @NonNull int[], @Nullable android.telephony.CellIdentity);
method public int describeContents();
method public int getAccessNetworkTechnology();
- method public int[] getAvailableServices();
- method public android.telephony.CellIdentity getCellIdentity();
+ method @NonNull public int[] getAvailableServices();
+ method @Nullable public android.telephony.CellIdentity getCellIdentity();
method @Nullable public android.telephony.DataSpecificRegistrationStates getDataSpecificStates();
method public int getDomain();
method public int getRegState();
@@ -7647,9 +7644,25 @@ package android.telephony {
field public static final int SERVICE_TYPE_VOICE = 1; // 0x1
}
+ public static class NetworkRegistrationState.Builder {
+ ctor public NetworkRegistrationState.Builder();
+ method @NonNull public android.telephony.NetworkRegistrationState build();
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setAccessNetworkTechnology(int);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setAvailableServices(@NonNull int[]);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setCellIdentity(@Nullable android.telephony.CellIdentity);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setDomain(int);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setEmergencyOnly(boolean);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setNrStatus(int);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setRegState(int);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setRejectCause(int);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setRoamingType(int);
+ method @NonNull public android.telephony.NetworkRegistrationState.Builder setTransportType(int);
+ }
+
public abstract class NetworkService extends android.app.Service {
ctor public NetworkService();
- method protected abstract android.telephony.NetworkService.NetworkServiceProvider createNetworkServiceProvider(int);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method @Nullable public abstract android.telephony.NetworkService.NetworkServiceProvider onCreateNetworkServiceProvider(int);
field public static final String NETWORK_SERVICE_INTERFACE = "android.telephony.NetworkService";
}
@@ -7657,12 +7670,12 @@ package android.telephony {
ctor public NetworkService.NetworkServiceProvider(int);
method public abstract void close();
method public void getNetworkRegistrationState(int, @NonNull android.telephony.NetworkServiceCallback);
- method public final int getSlotId();
+ method public final int getSlotIndex();
method public final void notifyNetworkRegistrationStateChanged();
}
public class NetworkServiceCallback {
- method public void onGetNetworkRegistrationStateComplete(int, android.telephony.NetworkRegistrationState);
+ method public void onGetNetworkRegistrationStateComplete(int, @Nullable android.telephony.NetworkRegistrationState);
field public static final int RESULT_ERROR_BUSY = 3; // 0x3
field public static final int RESULT_ERROR_FAILED = 5; // 0x5
field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
@@ -7884,7 +7897,7 @@ package android.telephony {
method public void requestEmbeddedSubscriptionInfoListRefresh(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultDataSubId(int);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setDefaultSmsSubId(int);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @NonNull java.util.concurrent.Executor, java.util.function.Consumer<java.lang.Integer>);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setPreferredDataSubscriptionId(int, boolean, @Nullable java.util.concurrent.Executor, @Nullable java.util.function.Consumer<java.lang.Integer>);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public boolean setSubscriptionEnabled(int, boolean);
field @NonNull public static final android.net.Uri ADVANCED_CALLING_ENABLED_CONTENT_URI;
field public static final int PROFILE_CLASS_DEFAULT = -1; // 0xffffffff
@@ -8094,7 +8107,6 @@ package android.telephony.data {
public final class DataCallResponse implements android.os.Parcelable {
ctor public DataCallResponse(int, int, int, int, int, @Nullable String, @Nullable java.util.List<android.net.LinkAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.net.InetAddress>, @Nullable java.util.List<java.lang.String>, int);
- ctor public DataCallResponse(android.os.Parcel);
method public int describeContents();
method public int getActive();
method @NonNull public java.util.List<android.net.LinkAddress> getAddresses();
@@ -8112,19 +8124,19 @@ package android.telephony.data {
}
public final class DataProfile implements android.os.Parcelable {
- method public String getApn();
+ method @NonNull public String getApn();
method public int getAuthType();
method public int getBearerBitmap();
method public int getMaxConns();
method public int getMaxConnsTime();
method public int getMtu();
- method public String getPassword();
+ method @Nullable public String getPassword();
method public int getProfileId();
method public int getProtocol();
method public int getRoamingProtocol();
method public int getSupportedApnTypesBitmap();
method public int getType();
- method public String getUserName();
+ method @Nullable public String getUserName();
method public int getWaitTime();
method public boolean isEnabled();
method public boolean isPersistent();
@@ -8136,7 +8148,8 @@ package android.telephony.data {
public abstract class DataService extends android.app.Service {
ctor public DataService();
- method public abstract android.telephony.data.DataService.DataServiceProvider createDataServiceProvider(int);
+ method public android.os.IBinder onBind(android.content.Intent);
+ method @Nullable public abstract android.telephony.data.DataService.DataServiceProvider onCreateDataServiceProvider(int);
field public static final String DATA_SERVICE_INTERFACE = "android.telephony.data.DataService";
field public static final int REQUEST_REASON_HANDOVER = 3; // 0x3
field public static final int REQUEST_REASON_NORMAL = 1; // 0x1
@@ -8148,7 +8161,7 @@ package android.telephony.data {
method public abstract void close();
method public void deactivateDataCall(int, int, @Nullable android.telephony.data.DataServiceCallback);
method public void getDataCallList(@NonNull android.telephony.data.DataServiceCallback);
- method public final int getSlotId();
+ method public final int getSlotIndex();
method public final void notifyDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
method public void setDataProfile(@NonNull java.util.List<android.telephony.data.DataProfile>, boolean, @Nullable android.telephony.data.DataServiceCallback);
method public void setInitialAttachApn(@NonNull android.telephony.data.DataProfile, boolean, @Nullable android.telephony.data.DataServiceCallback);
@@ -8156,12 +8169,12 @@ package android.telephony.data {
}
public class DataServiceCallback {
- method public void onDataCallListChanged(java.util.List<android.telephony.data.DataCallResponse>);
+ method public void onDataCallListChanged(@NonNull java.util.List<android.telephony.data.DataCallResponse>);
method public void onDeactivateDataCallComplete(int);
- method public void onGetDataCallListComplete(int, java.util.List<android.telephony.data.DataCallResponse>);
+ method public void onGetDataCallListComplete(int, @NonNull java.util.List<android.telephony.data.DataCallResponse>);
method public void onSetDataProfileComplete(int);
method public void onSetInitialAttachApnComplete(int);
- method public void onSetupDataCallComplete(int, android.telephony.data.DataCallResponse);
+ method public void onSetupDataCallComplete(int, @Nullable android.telephony.data.DataCallResponse);
field public static final int RESULT_ERROR_BUSY = 3; // 0x3
field public static final int RESULT_ERROR_ILLEGAL_STATE = 4; // 0x4
field public static final int RESULT_ERROR_INVALID_ARG = 2; // 0x2
@@ -8493,7 +8506,7 @@ package android.telephony.ims {
public class ImsException extends java.lang.Exception {
ctor public ImsException(@Nullable String);
ctor public ImsException(@Nullable String, int);
- ctor public ImsException(@Nullable String, int, Throwable);
+ ctor public ImsException(@Nullable String, int, @Nullable Throwable);
method public int getCode();
field public static final int CODE_ERROR_SERVICE_UNAVAILABLE = 1; // 0x1
field public static final int CODE_ERROR_UNSPECIFIED = 0; // 0x0
@@ -8501,13 +8514,13 @@ package android.telephony.ims {
}
public final class ImsExternalCallState implements android.os.Parcelable {
- ctor public ImsExternalCallState(String, android.net.Uri, android.net.Uri, boolean, int, int, boolean);
+ ctor public ImsExternalCallState(@NonNull String, @NonNull android.net.Uri, @Nullable android.net.Uri, boolean, int, int, boolean);
method public int describeContents();
- method public android.net.Uri getAddress();
+ method @NonNull public android.net.Uri getAddress();
method public int getCallId();
method public int getCallState();
method public int getCallType();
- method public android.net.Uri getLocalAddress();
+ method @Nullable public android.net.Uri getLocalAddress();
method public boolean isCallHeld();
method public boolean isCallPullable();
method public void writeToParcel(android.os.Parcel, int);
@@ -8517,7 +8530,7 @@ package android.telephony.ims {
}
public class ImsMmTelManager {
- method public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
+ method @NonNull public static android.telephony.ims.ImsMmTelManager createForSubscriptionId(int);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getVoWiFiRoamingModeSetting();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isAdvancedCallingSettingEnabled();
@@ -8526,7 +8539,7 @@ package android.telephony.ims {
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiRoamingSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVoWiFiSettingEnabled();
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean isVtSettingEnabled();
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerImsRegistrationCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.RegistrationCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerMmTelCapabilityCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ImsMmTelManager.CapabilityCallback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setAdvancedCallingSettingEnabled(boolean);
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setRttCapabilitySetting(boolean);
@@ -8545,15 +8558,15 @@ package android.telephony.ims {
public static class ImsMmTelManager.CapabilityCallback {
ctor public ImsMmTelManager.CapabilityCallback();
- method public void onCapabilitiesStatusChanged(android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
+ method public void onCapabilitiesStatusChanged(@NonNull android.telephony.ims.feature.MmTelFeature.MmTelCapabilities);
}
public static class ImsMmTelManager.RegistrationCallback {
ctor public ImsMmTelManager.RegistrationCallback();
method public void onRegistered(int);
method public void onRegistering(int);
- method public void onTechnologyChangeFailed(int, android.telephony.ims.ImsReasonInfo);
- method public void onUnregistered(android.telephony.ims.ImsReasonInfo);
+ method public void onTechnologyChangeFailed(int, @Nullable android.telephony.ims.ImsReasonInfo);
+ method public void onUnregistered(@Nullable android.telephony.ims.ImsReasonInfo);
}
public final class ImsReasonInfo implements android.os.Parcelable {
@@ -8962,14 +8975,14 @@ package android.telephony.ims {
}
public class ProvisioningManager {
- method public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
+ method @NonNull public static android.telephony.ims.ProvisioningManager createForSubscriptionId(int);
method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public int getProvisioningIntValue(int);
method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public boolean getProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int);
- method @WorkerThread @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public String getProvisioningStringValue(int);
- method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) @WorkerThread public String getProvisioningStringValue(int);
+ method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void registerProvisioningChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.telephony.ims.ProvisioningManager.Callback) throws android.telephony.ims.ImsException;
method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningIntValue(int, int);
method @WorkerThread @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) public void setProvisioningStatusForCapability(@android.telephony.ims.feature.MmTelFeature.MmTelCapabilities.MmTelCapability int, int, boolean);
- method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, String);
+ method @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE) @WorkerThread public int setProvisioningStringValue(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE) public void unregisterProvisioningChangedCallback(@NonNull android.telephony.ims.ProvisioningManager.Callback);
field public static final int KEY_VOICE_OVER_WIFI_MODE_OVERRIDE = 27; // 0x1b
field public static final int KEY_VOICE_OVER_WIFI_ROAMING_ENABLED_OVERRIDE = 26; // 0x1a
@@ -9635,16 +9648,16 @@ package android.webkit {
public final class WebViewDelegate {
method public void addWebViewAssetPath(android.content.Context);
- method public void callDrawGlFunction(android.graphics.Canvas, long);
- method public void callDrawGlFunction(@NonNull android.graphics.Canvas, long, @Nullable Runnable);
- method public boolean canInvokeDrawGlFunctor(android.view.View);
- method public void detachDrawGlFunctor(android.view.View, long);
+ method @Deprecated public void callDrawGlFunction(android.graphics.Canvas, long);
+ method @Deprecated public void callDrawGlFunction(@NonNull android.graphics.Canvas, long, @Nullable Runnable);
+ method @Deprecated public boolean canInvokeDrawGlFunctor(android.view.View);
+ method @Deprecated public void detachDrawGlFunctor(android.view.View, long);
method public void drawWebViewFunctor(@NonNull android.graphics.Canvas, int);
method public android.app.Application getApplication();
method public String getDataDirectorySuffix();
method public String getErrorString(android.content.Context, int);
method public int getPackageId(android.content.res.Resources, String);
- method public void invokeDrawGlFunctor(android.view.View, long, boolean);
+ method @Deprecated public void invokeDrawGlFunctor(android.view.View, long, boolean);
method public boolean isMultiProcessEnabled();
method public boolean isTraceTagEnabled();
method public void setOnTraceEnabledChangeListener(android.webkit.WebViewDelegate.OnTraceEnabledChangeListener);
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 22a3fb39d2f6..7e044698c72c 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -60,6 +60,17 @@ package android.content {
}
+package android.location {
+
+ public class LocationManager {
+ method @Deprecated public boolean addGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
+ method @Deprecated public boolean addGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
+ method @Deprecated public void removeGpsMeasurementListener(android.location.GpsMeasurementsEvent.Listener);
+ method @Deprecated public void removeGpsNavigationMessageListener(android.location.GpsNavigationMessageEvent.Listener);
+ }
+
+}
+
package android.media.tv {
public final class TvInputManager {
diff --git a/api/test-current.txt b/api/test-current.txt
index 684524e8987b..707df9a89eec 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -41,7 +41,6 @@ package android.app {
public class Activity extends android.view.ContextThemeWrapper implements android.content.ComponentCallbacks2 android.view.KeyEvent.Callback android.view.LayoutInflater.Factory2 android.view.View.OnCreateContextMenuListener android.view.Window.Callback {
method public void onMovedToDisplay(int, android.content.res.Configuration);
- method public void setInheritShowWhenLocked(boolean);
}
public class ActivityManager {
@@ -523,6 +522,7 @@ package android.app.role {
method @RequiresPermission("android.permission.MANAGE_ROLE_HOLDERS") public void removeRoleHolderAsUser(@NonNull String, @NonNull String, int, @NonNull android.os.UserHandle, @NonNull java.util.concurrent.Executor, @NonNull android.app.role.RoleManagerCallback);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public boolean removeRoleHolderFromController(@NonNull String, @NonNull String);
method @RequiresPermission("com.android.permissioncontroller.permission.MANAGE_ROLES_FROM_CONTROLLER") public void setRoleNamesFromController(@NonNull java.util.List<java.lang.String>);
+ field public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1; // 0x1
}
public interface RoleManagerCallback {
@@ -563,11 +563,13 @@ package android.content {
ctor public AutofillOptions(int, boolean);
method public int describeContents();
method public static android.content.AutofillOptions forWhitelistingItself();
+ method public boolean isAugmentedAutofillEnabled(@NonNull android.content.Context);
method public void writeToParcel(android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.content.AutofillOptions> CREATOR;
- field public boolean augmentedEnabled;
+ field public boolean augmentedAutofillEnabled;
field public final boolean compatModeEnabled;
field public final int loggingLevel;
+ field @Nullable public android.util.ArraySet<android.content.ComponentName> whitelistedActivitiesForAugmentedAutofill;
}
public final class ContentCaptureOptions implements android.os.Parcelable {
@@ -936,16 +938,16 @@ package android.location {
}
public class LocationManager {
- method public String[] getBackgroundThrottlingWhitelist();
- method public String[] getIgnoreSettingsWhitelist();
+ method @NonNull public String[] getBackgroundThrottlingWhitelist();
+ method @NonNull public String[] getIgnoreSettingsWhitelist();
method @NonNull public java.util.List<android.location.LocationRequest> getTestProviderCurrentRequests(String);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.location.LocationListener, android.os.Looper);
- method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(android.location.LocationRequest, android.app.PendingIntent);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, android.os.UserHandle);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.location.LocationListener, @Nullable android.os.Looper);
+ method @RequiresPermission(anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}) public void requestLocationUpdates(@NonNull android.location.LocationRequest, @NonNull android.app.PendingIntent);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setLocationEnabledForUser(boolean, @NonNull android.os.UserHandle);
}
public final class LocationRequest implements android.os.Parcelable {
- method public static android.location.LocationRequest create();
+ method @NonNull public static android.location.LocationRequest create();
method public int describeContents();
method public long getExpireAt();
method public long getFastestInterval();
@@ -953,14 +955,14 @@ package android.location {
method public int getNumUpdates();
method public int getQuality();
method public boolean isLocationSettingsIgnored();
- method public android.location.LocationRequest setExpireAt(long);
- method public android.location.LocationRequest setExpireIn(long);
- method public android.location.LocationRequest setFastestInterval(long);
- method public android.location.LocationRequest setInterval(long);
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.location.LocationRequest setLocationSettingsIgnored(boolean);
- method public android.location.LocationRequest setNumUpdates(int);
- method public android.location.LocationRequest setProvider(String);
- method public android.location.LocationRequest setQuality(int);
+ method @NonNull public android.location.LocationRequest setExpireAt(long);
+ method @NonNull public android.location.LocationRequest setExpireIn(long);
+ method @NonNull public android.location.LocationRequest setFastestInterval(long);
+ method @NonNull public android.location.LocationRequest setInterval(long);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) @NonNull public android.location.LocationRequest setLocationSettingsIgnored(boolean);
+ method @NonNull public android.location.LocationRequest setNumUpdates(int);
+ method @NonNull public android.location.LocationRequest setProvider(@NonNull String);
+ method @NonNull public android.location.LocationRequest setQuality(int);
method public void writeToParcel(android.os.Parcel, int);
field public static final int ACCURACY_BLOCK = 102; // 0x66
field public static final int ACCURACY_CITY = 104; // 0x68
@@ -1752,9 +1754,9 @@ package android.os {
method public static int getAppId(int);
method public int getIdentifier();
method public static boolean isApp(int);
- field public static final android.os.UserHandle ALL;
- field public static final android.os.UserHandle CURRENT;
- field public static final android.os.UserHandle SYSTEM;
+ field @NonNull public static final android.os.UserHandle ALL;
+ field @NonNull public static final android.os.UserHandle CURRENT;
+ field @NonNull public static final android.os.UserHandle SYSTEM;
}
public class UserManager {
@@ -2031,6 +2033,7 @@ package android.provider {
field public static final String CAPTIVE_PORTAL_USE_HTTPS = "captive_portal_use_https";
field public static final String DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD = "data_stall_consecutive_dns_timeout_threshold";
field public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
+ field public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; // 0x1
field public static final String DATA_STALL_MIN_EVALUATE_INTERVAL = "data_stall_min_evaluate_interval";
field public static final String DATA_STALL_VALID_DNS_TIME_THRESHOLD = "data_stall_valid_dns_time_threshold";
field public static final String DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD = "dynamic_power_savings_disable_threshold";
@@ -2099,8 +2102,8 @@ package android.security.keystore {
}
public class DeviceIdAttestationException extends java.lang.Exception {
- ctor public DeviceIdAttestationException(String);
- ctor public DeviceIdAttestationException(String, Throwable);
+ ctor public DeviceIdAttestationException(@Nullable String);
+ ctor public DeviceIdAttestationException(@Nullable String, @Nullable Throwable);
}
public static final class KeyGenParameterSpec.Builder {
@@ -2845,7 +2848,7 @@ package android.view {
field public static final int ACCESSIBILITY_TITLE_CHANGED = 33554432; // 0x2000000
field public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 64; // 0x40
field public CharSequence accessibilityTitle;
- field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=0x1, equals=0x1, name="FAKE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x2, equals=0x2, name="FORCE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x4, equals=0x4, name="WANTS_OFFSET_NOTIFICATIONS"), @android.view.ViewDebug.FlagToString(mask=0x10, equals=0x10, name="SHOW_FOR_ALL_USERS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, equals=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, name="NO_MOVE_ANIMATION"), @android.view.ViewDebug.FlagToString(mask=0x80, equals=0x80, name="COMPATIBLE_WINDOW"), @android.view.ViewDebug.FlagToString(mask=0x100, equals=0x100, name="SYSTEM_ERROR"), @android.view.ViewDebug.FlagToString(mask=0x200, equals=0x200, name="INHERIT_TRANSLUCENT_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x400, equals=0x400, name="KEYGUARD"), @android.view.ViewDebug.FlagToString(mask=0x800, equals=0x800, name="DISABLE_WALLPAPER_TOUCH_EVENTS"), @android.view.ViewDebug.FlagToString(mask=0x1000, equals=0x1000, name="FORCE_STATUS_BAR_VISIBLE_TRANSPARENT"), @android.view.ViewDebug.FlagToString(mask=0x2000, equals=0x2000, name="PRESERVE_GEOMETRY"), @android.view.ViewDebug.FlagToString(mask=0x4000, equals=0x4000, name="FORCE_DECOR_VIEW_VISIBILITY"), @android.view.ViewDebug.FlagToString(mask=0x8000, equals=0x8000, name="WILL_NOT_REPLACE_ON_RELAUNCH"), @android.view.ViewDebug.FlagToString(mask=0x10000, equals=0x10000, name="LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"), @android.view.ViewDebug.FlagToString(mask=0x20000, equals=0x20000, name="FORCE_DRAW_STATUS_BAR_BACKGROUND"), @android.view.ViewDebug.FlagToString(mask=0x40000, equals=0x40000, name="SUSTAINED_PERFORMANCE_MODE"), @android.view.ViewDebug.FlagToString(mask=0x80000, equals=0x80000, name="HIDE_NON_SYSTEM_OVERLAY_WINDOWS"), @android.view.ViewDebug.FlagToString(mask=0x100000, equals=0x100000, name="IS_ROUNDED_CORNERS_OVERLAY"), @android.view.ViewDebug.FlagToString(mask=0x400000, equals=0x400000, name="IS_SCREEN_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x800000, equals=0x800000, name="STATUS_FORCE_SHOW_NAVIGATION")}) public int privateFlags;
+ field @android.view.ViewDebug.ExportedProperty(flagMapping={@android.view.ViewDebug.FlagToString(mask=0x1, equals=0x1, name="FAKE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x2, equals=0x2, name="FORCE_HARDWARE_ACCELERATED"), @android.view.ViewDebug.FlagToString(mask=0x4, equals=0x4, name="WANTS_OFFSET_NOTIFICATIONS"), @android.view.ViewDebug.FlagToString(mask=0x10, equals=0x10, name="SHOW_FOR_ALL_USERS"), @android.view.ViewDebug.FlagToString(mask=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, equals=android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION, name="NO_MOVE_ANIMATION"), @android.view.ViewDebug.FlagToString(mask=0x80, equals=0x80, name="COMPATIBLE_WINDOW"), @android.view.ViewDebug.FlagToString(mask=0x100, equals=0x100, name="SYSTEM_ERROR"), @android.view.ViewDebug.FlagToString(mask=0x200, equals=0x200, name="INHERIT_TRANSLUCENT_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x400, equals=0x400, name="KEYGUARD"), @android.view.ViewDebug.FlagToString(mask=0x800, equals=0x800, name="DISABLE_WALLPAPER_TOUCH_EVENTS"), @android.view.ViewDebug.FlagToString(mask=0x1000, equals=0x1000, name="FORCE_STATUS_BAR_VISIBLE_TRANSPARENT"), @android.view.ViewDebug.FlagToString(mask=0x2000, equals=0x2000, name="PRESERVE_GEOMETRY"), @android.view.ViewDebug.FlagToString(mask=0x4000, equals=0x4000, name="FORCE_DECOR_VIEW_VISIBILITY"), @android.view.ViewDebug.FlagToString(mask=0x8000, equals=0x8000, name="WILL_NOT_REPLACE_ON_RELAUNCH"), @android.view.ViewDebug.FlagToString(mask=0x10000, equals=0x10000, name="LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"), @android.view.ViewDebug.FlagToString(mask=0x20000, equals=0x20000, name="FORCE_DRAW_STATUS_BAR_BACKGROUND"), @android.view.ViewDebug.FlagToString(mask=0x40000, equals=0x40000, name="SUSTAINED_PERFORMANCE_MODE"), @android.view.ViewDebug.FlagToString(mask=0x80000, equals=0x80000, name="HIDE_NON_SYSTEM_OVERLAY_WINDOWS"), @android.view.ViewDebug.FlagToString(mask=0x100000, equals=0x100000, name="IS_ROUNDED_CORNERS_OVERLAY"), @android.view.ViewDebug.FlagToString(mask=0x400000, equals=0x400000, name="IS_SCREEN_DECOR"), @android.view.ViewDebug.FlagToString(mask=0x800000, equals=0x800000, name="STATUS_FORCE_SHOW_NAVIGATION"), @android.view.ViewDebug.FlagToString(mask=0x1000000, equals=0x1000000, name="COLOR_SPACE_AGNOSTIC")}) public int privateFlags;
}
}
@@ -3060,6 +3063,7 @@ package android.view.inspector {
enum_constant public static final android.view.inspector.InspectableProperty.ValueType INT_ENUM;
enum_constant public static final android.view.inspector.InspectableProperty.ValueType INT_FLAG;
enum_constant public static final android.view.inspector.InspectableProperty.ValueType NONE;
+ enum_constant public static final android.view.inspector.InspectableProperty.ValueType RESOURCE_ID;
}
}
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index da720021512d..7298da6f6835 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -219,6 +219,7 @@ cc_test {
"tests/anomaly/AnomalyTracker_test.cpp",
"tests/ConfigManager_test.cpp",
"tests/external/puller_util_test.cpp",
+ "tests/external/IncidentReportArgs_test.cpp",
"tests/external/StatsPuller_test.cpp",
"tests/indexed_priority_queue_test.cpp",
"tests/LogEntryMatcher_test.cpp",
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index 9ac888ba2eb5..1526d6609fa0 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -1210,20 +1210,22 @@ Status StatsService::sendBinaryPushStateChangedAtom(const android::String16& tra
(long long)expId);
}
- vector<uint8_t> buffer;
- buffer.resize(proto.size());
+ vector<uint8_t> experimentIdsProtoBuffer;
+ experimentIdsProtoBuffer.resize(proto.size());
size_t pos = 0;
auto iter = proto.data();
while (iter.readBuffer() != NULL) {
size_t toRead = iter.currentToRead();
- std::memcpy(&(buffer[pos]), iter.readBuffer(), toRead);
+ std::memcpy(&(experimentIdsProtoBuffer[pos]), iter.readBuffer(), toRead);
pos += toRead;
iter.rp()->move(toRead);
}
- LogEvent event(std::string(String8(trainName).string()), trainVersionCode, requiresStaging,
- rollbackEnabled, requiresLowLatencyMonitor, state, buffer, userId);
+
+ std::string trainNameUtf8 = std::string(String8(trainName).string());
+ LogEvent event(trainNameUtf8, trainVersionCode, requiresStaging, rollbackEnabled,
+ requiresLowLatencyMonitor, state, experimentIdsProtoBuffer, userId);
mProcessor->OnLogEvent(&event);
- StorageManager::writeTrainInfo(trainVersionCode, buffer);
+ StorageManager::writeTrainInfo(trainVersionCode, trainNameUtf8, state, experimentIdsProtoBuffer);
return Status::ok();
}
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index a983b2705d14..4e540b1c6fa9 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -1568,7 +1568,7 @@ message WatchdogRollbackOccurred {
ROLLBACK_INITIATE = 1;
ROLLBACK_SUCCESS = 2;
ROLLBACK_FAILURE = 3;
- ROLLBACK_ROOT_TRIGGERED = 4;
+ ROLLBACK_BOOT_TRIGGERED = 4;
}
optional RollbackType rollback_type = 1;
@@ -3005,6 +3005,9 @@ message LmkKillOccurred {
// The elapsed real time of start of the process.
optional int64 process_start_time_nanos = 9;
+
+ // Min oom adj score considered by lmkd.
+ optional int32 min_oom_score = 10;
}
/*
@@ -3240,8 +3243,18 @@ message BinaryPushStateChanged {
INSTALL_FAILURE = 6;
INSTALL_CANCELLED = 7;
INSTALLER_ROLLBACK_REQUESTED = 8;
- INSTALLER_ROLLBACK_SUCCESS = 9;
- INSTALLER_ROLLBACK_FAILURE = 10;
+ INSTALLER_ROLLBACK_INITIATED = 9;
+ INSTALLER_ROLLBACK_INITIATED_FAILURE = 10;
+ INSTALLER_ROLLBACK_STAGED = 11;
+ INSTALLER_ROLLBACK_STAGED_FAILURE = 12;
+ INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13;
+ INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14;
+ INSTALLER_ROLLBACK_SUCCESS = 15;
+ INSTALLER_ROLLBACK_FAILURE = 16;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_REMOVE_FROM_QUEUE = 17;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_INITIATED = 18;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_SUCCESS = 19;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_FAILURE = 20;
}
optional State state = 6;
// Possible experiment ids for monitoring this push.
@@ -5650,6 +5663,33 @@ message TrainInfo {
optional int64 train_version_code = 1;
optional TrainExperimentIds train_experiment_id = 2;
+
+ optional string train_name = 3;
+
+ enum Status {
+ UNKNOWN = 0;
+ INSTALL_REQUESTED = 1;
+ INSTALL_STARTED = 2;
+ INSTALL_STAGED_NOT_READY = 3;
+ INSTALL_STAGED_READY = 4;
+ INSTALL_SUCCESS = 5;
+ INSTALL_FAILURE = 6;
+ INSTALL_CANCELLED = 7;
+ INSTALLER_ROLLBACK_REQUESTED = 8;
+ INSTALLER_ROLLBACK_INITIATED = 9;
+ INSTALLER_ROLLBACK_INITIATED_FAILURE = 10;
+ INSTALLER_ROLLBACK_STAGED = 11;
+ INSTALLER_ROLLBACK_STAGED_FAILURE = 12;
+ INSTALLER_ROLLBACK_BOOT_TRIGGERED = 13;
+ INSTALLER_ROLLBACK_BOOT_TRIGGERED_FAILURE = 14;
+ INSTALLER_ROLLBACK_SUCCESS = 15;
+ INSTALLER_ROLLBACK_FAILURE = 16;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_REMOVE_FROM_QUEUE = 17;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_INITIATED = 18;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_SUCCESS = 19;
+ INSTALLER_ROLLBACK_CANCEL_STAGED_DELETE_SESSION_FAILURE = 20;
+ }
+ optional Status status = 4;
}
/**
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index 0430e4ec9a2d..d9f5415463e3 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -238,9 +238,12 @@ LogEvent::LogEvent(int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
mLogdTimestampNs = wallClockTimestampNs;
mElapsedTimestampNs = elapsedTimestampNs;
mTagId = android::util::TRAIN_INFO;
+
mValues.push_back(
FieldValue(Field(mTagId, getSimpleField(1)), Value(trainInfo.trainVersionCode)));
mValues.push_back(FieldValue(Field(mTagId, getSimpleField(2)), Value(trainInfo.experimentIds)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(3)), Value(trainInfo.trainName)));
+ mValues.push_back(FieldValue(Field(mTagId, getSimpleField(4)), Value(trainInfo.status)));
}
LogEvent::LogEvent(int32_t tagId, int64_t timestampNs) : LogEvent(tagId, timestampNs, 0) {}
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 2fde8b4c027d..753a9a500c57 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -58,6 +58,8 @@ struct AttributionNodeInternal {
struct InstallTrainInfo {
int64_t trainVersionCode;
+ std::string trainName;
+ int32_t status;
std::vector<uint8_t> experimentIds;
};
/**
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index 5c6d548ad13a..0e91f527083a 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -324,6 +324,12 @@ message IncidentdDetails {
EXPLICIT = 1;
}
optional Destination dest = 2;
+
+ // Package name of the incident report receiver.
+ optional string receiver_pkg = 3;
+
+ // Class name of the incident report receiver.
+ optional string receiver_cls = 4;
}
message PerfettoDetails {
diff --git a/cmds/statsd/src/storage/StorageManager.cpp b/cmds/statsd/src/storage/StorageManager.cpp
index 165e57c73743..5df8fb5c0e29 100644
--- a/cmds/statsd/src/storage/StorageManager.cpp
+++ b/cmds/statsd/src/storage/StorageManager.cpp
@@ -95,8 +95,8 @@ void StorageManager::writeFile(const char* file, const void* buffer, int numByte
close(fd);
}
-bool StorageManager::writeTrainInfo(int64_t trainVersionCode,
- const std::vector<uint8_t>& experimentIds) {
+bool StorageManager::writeTrainInfo(int64_t trainVersionCode, const std::string& trainName,
+ int32_t status, const std::vector<uint8_t>& experimentIds) {
std::lock_guard<std::mutex> lock(sTrainInfoMutex);
deleteAllFiles(TRAIN_INFO_DIR);
@@ -109,7 +109,34 @@ bool StorageManager::writeTrainInfo(int64_t trainVersionCode,
return false;
}
- size_t result = write(fd, experimentIds.data(), experimentIds.size());
+ size_t result;
+
+ // Write # of bytes in trainName to file
+ const size_t trainNameSize = trainName.size();
+ const size_t trainNameSizeByteCount = sizeof(trainNameSize);
+ result = write(fd, (uint8_t*)&trainNameSize, trainNameSizeByteCount);
+ if (result != trainNameSizeByteCount) {
+ VLOG("Failed to write %s", file_name.c_str());
+ return false;
+ }
+
+ // Write trainName to file
+ result = write(fd, trainName.c_str(), trainNameSize);
+ if (result != trainNameSize) {
+ VLOG("Failed to write %s", file_name.c_str());
+ return false;
+ }
+
+ // Write status to file
+ const size_t statusByteCount = sizeof(status);
+ result = write(fd, (uint8_t*)&status, statusByteCount);
+ if (result != statusByteCount) {
+ VLOG("Failed to write %s", file_name.c_str());
+ return false;
+ }
+
+ // Write experimentIds to file
+ result = write(fd, experimentIds.data(), experimentIds.size());
if (result == experimentIds.size()) {
VLOG("Successfully wrote %s", file_name.c_str());
} else {
@@ -150,7 +177,27 @@ bool StorageManager::readTrainInfo(InstallTrainInfo& trainInfo) {
string str;
if (android::base::ReadFdToString(fd, &str)) {
close(fd);
- std::copy(str.begin(), str.end(), std::back_inserter(trainInfo.experimentIds));
+
+ auto it = str.begin();
+
+ // Read # of bytes taken by trainName in the file
+ size_t trainNameSize;
+ const size_t trainNameSizeByteCount = sizeof(trainNameSize);
+ std::copy_n(it, trainNameSizeByteCount, &trainNameSize);
+ it += trainNameSizeByteCount;
+
+ // Read trainName
+ std::copy_n(it, trainNameSize, std::back_inserter(trainInfo.trainName));
+ it += trainNameSize;
+
+ // Read status
+ const size_t statusByteCount = sizeof(trainInfo.status);
+ std::copy_n(it, statusByteCount, &trainInfo.status);
+ it += statusByteCount;
+
+ // Read experimentIds
+ std::copy(it, str.end(), std::back_inserter(trainInfo.experimentIds));
+
VLOG("Read train info file successful: %s", fullPath.c_str());
return true;
}
diff --git a/cmds/statsd/src/storage/StorageManager.h b/cmds/statsd/src/storage/StorageManager.h
index d6df8674e59b..88280cf218b3 100644
--- a/cmds/statsd/src/storage/StorageManager.h
+++ b/cmds/statsd/src/storage/StorageManager.h
@@ -44,7 +44,8 @@ public:
/**
* Writes train info.
*/
- static bool writeTrainInfo(int64_t trainVersionCode, const std::vector<uint8_t>& experimentIds);
+ static bool writeTrainInfo(int64_t trainVersionCode, const std::string& trainName,
+ int32_t status, const std::vector<uint8_t>& experimentIds);
/**
* Reads train info.
diff --git a/cmds/statsd/src/subscriber/IncidentdReporter.cpp b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
index 0ed2d75802da..7c2d2420528c 100644
--- a/cmds/statsd/src/subscriber/IncidentdReporter.cpp
+++ b/cmds/statsd/src/subscriber/IncidentdReporter.cpp
@@ -162,6 +162,10 @@ bool GenerateIncidentReport(const IncidentdDetails& config, int64_t rule_id, int
}
incidentReport.setDest(dest);
+ incidentReport.setReceiverPkg(config.receiver_pkg());
+
+ incidentReport.setReceiverCls(config.receiver_cls());
+
sp<IIncidentManager> service = interface_cast<IIncidentManager>(
defaultServiceManager()->getService(android::String16("incident")));
if (service == nullptr) {
diff --git a/cmds/statsd/tests/external/IncidentReportArgs_test.cpp b/cmds/statsd/tests/external/IncidentReportArgs_test.cpp
new file mode 100644
index 000000000000..c170b12dc242
--- /dev/null
+++ b/cmds/statsd/tests/external/IncidentReportArgs_test.cpp
@@ -0,0 +1,72 @@
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <android/os/IncidentReportArgs.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+namespace os {
+namespace statsd {
+
+TEST(IncidentReportArgsTest, testSerialization) {
+ IncidentReportArgs args;
+ args.setAll(0);
+ args.addSection(1000);
+ args.addSection(1001);
+
+ vector<uint8_t> header1;
+ header1.push_back(0x1);
+ header1.push_back(0x2);
+ vector<uint8_t> header2;
+ header1.push_back(0x22);
+ header1.push_back(0x33);
+
+ args.addHeader(header1);
+ args.addHeader(header2);
+
+ args.setDest(1);
+
+ args.setReceiverPkg("com.android.os");
+ args.setReceiverCls("com.android.os.Receiver");
+
+ Parcel out;
+ status_t err = args.writeToParcel(&out);
+ EXPECT_EQ(NO_ERROR, err);
+
+ out.setDataPosition(0);
+
+ IncidentReportArgs args2;
+ err = args2.readFromParcel(&out);
+ EXPECT_EQ(NO_ERROR, err);
+
+ EXPECT_EQ(0, args2.all());
+ set<int> sections;
+ sections.insert(1000);
+ sections.insert(1001);
+ EXPECT_EQ(sections, args2.sections());
+ EXPECT_EQ(1, args2.dest());
+
+ EXPECT_EQ(String16("com.android.os"), args2.receiverPkg());
+ EXPECT_EQ(String16("com.android.os.Receiver"), args2.receiverCls());
+
+ vector<vector<uint8_t>> headers;
+ headers.push_back(header1);
+ headers.push_back(header2);
+ EXPECT_EQ(headers, args2.headers());
+}
+
+} // namespace statsd
+} // namespace os
+} // namespace android \ No newline at end of file
diff --git a/cmds/statsd/tests/storage/StorageManager_test.cpp b/cmds/statsd/tests/storage/StorageManager_test.cpp
index f66de0518f80..4564a5d058a3 100644
--- a/cmds/statsd/tests/storage/StorageManager_test.cpp
+++ b/cmds/statsd/tests/storage/StorageManager_test.cpp
@@ -32,16 +32,82 @@ using testing::Contains;
TEST(StorageManagerTest, TrainInfoReadWriteTest) {
InstallTrainInfo trainInfo;
trainInfo.trainVersionCode = 12345;
+ trainInfo.trainName = "This is a train name #)$(&&$";
+ trainInfo.status = 1;
const char* expIds = "test_ids";
trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
- StorageManager::writeTrainInfo(trainInfo.trainVersionCode, trainInfo.experimentIds);
+ bool result;
- InstallTrainInfo result;
- StorageManager::readTrainInfo(result);
- EXPECT_EQ(trainInfo.trainVersionCode, result.trainVersionCode);
- EXPECT_EQ(trainInfo.experimentIds.size(), result.experimentIds.size());
- EXPECT_EQ(trainInfo.experimentIds, result.experimentIds);
+ result = StorageManager::writeTrainInfo(trainInfo.trainVersionCode, trainInfo.trainName,
+ trainInfo.status, trainInfo.experimentIds);
+
+ EXPECT_TRUE(result);
+
+ InstallTrainInfo trainInfoResult;
+ result = StorageManager::readTrainInfo(trainInfoResult);
+ EXPECT_TRUE(result);
+
+ EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
+ EXPECT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
+ EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
+ EXPECT_EQ(trainInfo.status, trainInfoResult.status);
+ EXPECT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
+ EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
+}
+
+TEST(StorageManagerTest, TrainInfoReadWriteEmptyTrainNameTest) {
+ InstallTrainInfo trainInfo;
+ trainInfo.trainVersionCode = 12345;
+ trainInfo.trainName = "";
+ trainInfo.status = 1;
+ const char* expIds = "test_ids";
+ trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
+
+ bool result;
+
+ result = StorageManager::writeTrainInfo(trainInfo.trainVersionCode, trainInfo.trainName,
+ trainInfo.status, trainInfo.experimentIds);
+
+ EXPECT_TRUE(result);
+
+ InstallTrainInfo trainInfoResult;
+ result = StorageManager::readTrainInfo(trainInfoResult);
+ EXPECT_TRUE(result);
+
+ EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
+ EXPECT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
+ EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
+ EXPECT_EQ(trainInfo.status, trainInfoResult.status);
+ EXPECT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
+ EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
+}
+
+TEST(StorageManagerTest, TrainInfoReadWriteTrainNameSizeOneTest) {
+ InstallTrainInfo trainInfo;
+ trainInfo.trainVersionCode = 12345;
+ trainInfo.trainName = "{";
+ trainInfo.status = 1;
+ const char* expIds = "test_ids";
+ trainInfo.experimentIds.assign(expIds, expIds + strlen(expIds));
+
+ bool result;
+
+ result = StorageManager::writeTrainInfo(trainInfo.trainVersionCode, trainInfo.trainName,
+ trainInfo.status, trainInfo.experimentIds);
+
+ EXPECT_TRUE(result);
+
+ InstallTrainInfo trainInfoResult;
+ result = StorageManager::readTrainInfo(trainInfoResult);
+ EXPECT_TRUE(result);
+
+ EXPECT_EQ(trainInfo.trainVersionCode, trainInfoResult.trainVersionCode);
+ EXPECT_EQ(trainInfo.trainName.size(), trainInfoResult.trainName.size());
+ EXPECT_EQ(trainInfo.trainName, trainInfoResult.trainName);
+ EXPECT_EQ(trainInfo.status, trainInfoResult.status);
+ EXPECT_EQ(trainInfo.experimentIds.size(), trainInfoResult.experimentIds.size());
+ EXPECT_EQ(trainInfo.experimentIds, trainInfoResult.experimentIds);
}
} // namespace statsd
diff --git a/config/hiddenapi-greylist.txt b/config/hiddenapi-greylist.txt
index 9b0e6574e5c4..8ed07b1759c5 100644
--- a/config/hiddenapi-greylist.txt
+++ b/config/hiddenapi-greylist.txt
@@ -5,21 +5,10 @@ Landroid/accounts/IAccountAuthenticator$Stub$Proxy;-><init>(Landroid/os/IBinder;
Landroid/accounts/IAccountAuthenticator$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/accounts/IAccountAuthenticator$Stub;-><init>()V
Landroid/accounts/IAccountAuthenticator$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountAuthenticator;
-Landroid/accounts/IAccountAuthenticator;->addAccount(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Landroid/os/Bundle;)V
-Landroid/accounts/IAccountAuthenticator;->confirmCredentials(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Landroid/os/Bundle;)V
-Landroid/accounts/IAccountAuthenticator;->editProperties(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;)V
-Landroid/accounts/IAccountAuthenticator;->getAccountRemovalAllowed(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;)V
-Landroid/accounts/IAccountAuthenticator;->getAuthToken(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
-Landroid/accounts/IAccountAuthenticator;->getAuthTokenLabel(Landroid/accounts/IAccountAuthenticatorResponse;Ljava/lang/String;)V
-Landroid/accounts/IAccountAuthenticator;->hasFeatures(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;[Ljava/lang/String;)V
-Landroid/accounts/IAccountAuthenticator;->updateCredentials(Landroid/accounts/IAccountAuthenticatorResponse;Landroid/accounts/Account;Ljava/lang/String;Landroid/os/Bundle;)V
Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/accounts/IAccountAuthenticatorResponse$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/accounts/IAccountAuthenticatorResponse$Stub;-><init>()V
Landroid/accounts/IAccountAuthenticatorResponse$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountAuthenticatorResponse;
-Landroid/accounts/IAccountAuthenticatorResponse;->onError(ILjava/lang/String;)V
-Landroid/accounts/IAccountAuthenticatorResponse;->onRequestContinued()V
-Landroid/accounts/IAccountAuthenticatorResponse;->onResult(Landroid/os/Bundle;)V
Landroid/accounts/IAccountManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/accounts/IAccountManager$Stub;-><init>()V
Landroid/accounts/IAccountManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManager;
@@ -27,8 +16,6 @@ Landroid/accounts/IAccountManagerResponse$Stub$Proxy;-><init>(Landroid/os/IBinde
Landroid/accounts/IAccountManagerResponse$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/accounts/IAccountManagerResponse$Stub;-><init>()V
Landroid/accounts/IAccountManagerResponse$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accounts/IAccountManagerResponse;
-Landroid/accounts/IAccountManagerResponse;->onError(ILjava/lang/String;)V
-Landroid/accounts/IAccountManagerResponse;->onResult(Landroid/os/Bundle;)V
Landroid/app/ActivityManagerNative;-><init>()V
Landroid/app/ActivityThread$AppBindData;-><init>()V
Landroid/app/ActivityThread$CreateServiceData;-><init>()V
@@ -39,7 +26,6 @@ Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_removeActiveAdmin:I
Landroid/app/backup/IBackupManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/backup/IBackupManager;
Landroid/app/backup/IFullBackupRestoreObserver$Stub;-><init>()V
Landroid/app/backup/IRestoreObserver$Stub;-><init>()V
-Landroid/app/DownloadManager;->restartDownload([J)V
Landroid/app/IActivityController$Stub;-><init>()V
Landroid/app/IActivityManager$Stub$Proxy;->getConfiguration()Landroid/content/res/Configuration;
Landroid/app/IActivityManager$Stub$Proxy;->getLaunchedFromUid(Landroid/os/IBinder;)I
@@ -49,156 +35,33 @@ Landroid/app/IActivityManager$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/app/IActivityManager$Stub$Proxy;->setActivityController(Landroid/app/IActivityController;Z)V
Landroid/app/IActivityManager$Stub$Proxy;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V
Landroid/app/IActivityManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IActivityManager;
-Landroid/app/IActivityManager;->bindService(Landroid/app/IApplicationThread;Landroid/os/IBinder;Landroid/content/Intent;Ljava/lang/String;Landroid/app/IServiceConnection;ILjava/lang/String;I)I
-Landroid/app/IActivityManager;->broadcastIntent(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;Landroid/content/IIntentReceiver;ILjava/lang/String;Landroid/os/Bundle;[Ljava/lang/String;ILandroid/os/Bundle;ZZI)I
-Landroid/app/IActivityManager;->cancelRecentsAnimation(Z)V
-Landroid/app/IActivityManager;->cancelTaskWindowTransition(I)V
-Landroid/app/IActivityManager;->checkPermission(Ljava/lang/String;II)I
-Landroid/app/IActivityManager;->closeSystemDialogs(Ljava/lang/String;)V
-Landroid/app/IActivityManager;->finishActivity(Landroid/os/IBinder;ILandroid/content/Intent;I)Z
-Landroid/app/IActivityManager;->finishHeavyWeightApp()V
Landroid/app/IActivityManager;->finishReceiver(Landroid/os/IBinder;ILjava/lang/String;Landroid/os/Bundle;ZI)V
-Landroid/app/IActivityManager;->forceStopPackage(Ljava/lang/String;I)V
-Landroid/app/IActivityManager;->getAllStackInfos()Ljava/util/List;
-Landroid/app/IActivityManager;->getConfiguration()Landroid/content/res/Configuration;
-Landroid/app/IActivityManager;->getCurrentUser()Landroid/content/pm/UserInfo;
-Landroid/app/IActivityManager;->getFilteredTasks(III)Ljava/util/List;
-Landroid/app/IActivityManager;->getIntentForIntentSender(Landroid/content/IIntentSender;)Landroid/content/Intent;
-Landroid/app/IActivityManager;->getIntentSender(ILjava/lang/String;Landroid/os/IBinder;Ljava/lang/String;I[Landroid/content/Intent;[Ljava/lang/String;ILandroid/os/Bundle;I)Landroid/content/IIntentSender;
-Landroid/app/IActivityManager;->getLaunchedFromPackage(Landroid/os/IBinder;)Ljava/lang/String;
-Landroid/app/IActivityManager;->getLaunchedFromUid(Landroid/os/IBinder;)I
-Landroid/app/IActivityManager;->getLockTaskModeState()I
-Landroid/app/IActivityManager;->getMemoryInfo(Landroid/app/ActivityManager$MemoryInfo;)V
-Landroid/app/IActivityManager;->getPackageProcessState(Ljava/lang/String;Ljava/lang/String;)I
-Landroid/app/IActivityManager;->getProcessLimit()I
-Landroid/app/IActivityManager;->getProcessMemoryInfo([I)[Landroid/os/Debug$MemoryInfo;
-Landroid/app/IActivityManager;->getProcessPss([I)[J
-Landroid/app/IActivityManager;->getProviderMimeType(Landroid/net/Uri;I)Ljava/lang/String;
-Landroid/app/IActivityManager;->getRecentTasks(III)Landroid/content/pm/ParceledListSlice;
-Landroid/app/IActivityManager;->getRunningAppProcesses()Ljava/util/List;
-Landroid/app/IActivityManager;->getServices(II)Ljava/util/List;
-Landroid/app/IActivityManager;->getTaskBounds(I)Landroid/graphics/Rect;
-Landroid/app/IActivityManager;->getTaskForActivity(Landroid/os/IBinder;Z)I
-Landroid/app/IActivityManager;->getTaskSnapshot(IZ)Landroid/app/ActivityManager$TaskSnapshot;
-Landroid/app/IActivityManager;->handleApplicationStrictModeViolation(Landroid/os/IBinder;ILandroid/os/StrictMode$ViolationInfo;)V
-Landroid/app/IActivityManager;->hang(Landroid/os/IBinder;Z)V
-Landroid/app/IActivityManager;->isInLockTaskMode()Z
-Landroid/app/IActivityManager;->isIntentSenderAnActivity(Landroid/content/IIntentSender;)Z
-Landroid/app/IActivityManager;->isTopOfTask(Landroid/os/IBinder;)Z
-Landroid/app/IActivityManager;->isUserRunning(II)Z
-Landroid/app/IActivityManager;->killAllBackgroundProcesses()V
-Landroid/app/IActivityManager;->killBackgroundProcesses(Ljava/lang/String;I)V
-Landroid/app/IActivityManager;->moveActivityTaskToBack(Landroid/os/IBinder;Z)Z
-Landroid/app/IActivityManager;->moveTaskToFront(IILandroid/os/Bundle;)V
-Landroid/app/IActivityManager;->moveTaskToStack(IIZ)V
-Landroid/app/IActivityManager;->moveTopActivityToPinnedStack(ILandroid/graphics/Rect;)Z
-Landroid/app/IActivityManager;->positionTaskInStack(III)V
-Landroid/app/IActivityManager;->profileControl(Ljava/lang/String;IZLandroid/app/ProfilerInfo;I)Z
-Landroid/app/IActivityManager;->publishContentProviders(Landroid/app/IApplicationThread;Ljava/util/List;)V
-Landroid/app/IActivityManager;->registerProcessObserver(Landroid/app/IProcessObserver;)V
-Landroid/app/IActivityManager;->registerReceiver(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/IIntentReceiver;Landroid/content/IntentFilter;Ljava/lang/String;II)Landroid/content/Intent;
-Landroid/app/IActivityManager;->registerTaskStackListener(Landroid/app/ITaskStackListener;)V
-Landroid/app/IActivityManager;->registerUserSwitchObserver(Landroid/app/IUserSwitchObserver;Ljava/lang/String;)V
-Landroid/app/IActivityManager;->removeContentProviderExternal(Ljava/lang/String;Landroid/os/IBinder;)V
-Landroid/app/IActivityManager;->removeStack(I)V
-Landroid/app/IActivityManager;->removeTask(I)Z
-Landroid/app/IActivityManager;->requestBugReport(I)V
-Landroid/app/IActivityManager;->resizeDockedStack(Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;Landroid/graphics/Rect;)V
-Landroid/app/IActivityManager;->resizeStack(ILandroid/graphics/Rect;ZZZI)V
-Landroid/app/IActivityManager;->resizeTask(ILandroid/graphics/Rect;I)V
-Landroid/app/IActivityManager;->restart()V
-Landroid/app/IActivityManager;->resumeAppSwitches()V
-Landroid/app/IActivityManager;->sendIdleJobTrigger()V
Landroid/app/IActivityManager;->serviceDoneExecuting(Landroid/os/IBinder;III)V
-Landroid/app/IActivityManager;->setActivityController(Landroid/app/IActivityController;Z)V
-Landroid/app/IActivityManager;->setAlwaysFinish(Z)V
-Landroid/app/IActivityManager;->setDebugApp(Ljava/lang/String;ZZ)V
-Landroid/app/IActivityManager;->setDumpHeapDebugLimit(Ljava/lang/String;IJLjava/lang/String;)V
-Landroid/app/IActivityManager;->setPackageScreenCompatMode(Ljava/lang/String;I)V
-Landroid/app/IActivityManager;->setProcessImportant(Landroid/os/IBinder;IZLjava/lang/String;)V
-Landroid/app/IActivityManager;->setProcessLimit(I)V
-Landroid/app/IActivityManager;->setProcessMemoryTrimLevel(Ljava/lang/String;II)Z
-Landroid/app/IActivityManager;->setRequestedOrientation(Landroid/os/IBinder;I)V
-Landroid/app/IActivityManager;->setTaskResizeable(II)V
-Landroid/app/IActivityManager;->shutdown(I)Z
-Landroid/app/IActivityManager;->startActivity(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;)I
-Landroid/app/IActivityManager;->startActivityAsUser(Landroid/app/IApplicationThread;Ljava/lang/String;Landroid/content/Intent;Ljava/lang/String;Landroid/os/IBinder;Ljava/lang/String;IILandroid/app/ProfilerInfo;Landroid/os/Bundle;I)I
-Landroid/app/IActivityManager;->startActivityFromRecents(ILandroid/os/Bundle;)I
-Landroid/app/IActivityManager;->startBinderTracking()Z
-Landroid/app/IActivityManager;->startInstrumentation(Landroid/content/ComponentName;Ljava/lang/String;ILandroid/os/Bundle;Landroid/app/IInstrumentationWatcher;Landroid/app/IUiAutomationConnection;ILjava/lang/String;)Z
-Landroid/app/IActivityManager;->startRecentsActivity(Landroid/content/Intent;Landroid/app/IAssistDataReceiver;Landroid/view/IRecentsAnimationRunner;)V
-Landroid/app/IActivityManager;->startSystemLockTaskMode(I)V
-Landroid/app/IActivityManager;->startUserInBackground(I)Z
-Landroid/app/IActivityManager;->stopAppSwitches()V
-Landroid/app/IActivityManager;->stopBinderTrackingAndDump(Landroid/os/ParcelFileDescriptor;)Z
-Landroid/app/IActivityManager;->stopService(Landroid/app/IApplicationThread;Landroid/content/Intent;Ljava/lang/String;I)I
-Landroid/app/IActivityManager;->stopUser(IZLandroid/app/IStopUserCallback;)I
-Landroid/app/IActivityManager;->suppressResizeConfigChanges(Z)V
-Landroid/app/IActivityManager;->switchUser(I)Z
-Landroid/app/IActivityManager;->unbindService(Landroid/app/IServiceConnection;)Z
-Landroid/app/IActivityManager;->unhandledBack()V
-Landroid/app/IActivityManager;->unlockUser(I[B[BLandroid/os/IProgressListener;)Z
-Landroid/app/IActivityManager;->unregisterProcessObserver(Landroid/app/IProcessObserver;)V
-Landroid/app/IActivityManager;->unregisterReceiver(Landroid/content/IIntentReceiver;)V
-Landroid/app/IActivityManager;->unstableProviderDied(Landroid/os/IBinder;)V
-Landroid/app/IActivityManager;->updateConfiguration(Landroid/content/res/Configuration;)Z
-Landroid/app/IActivityManager;->updatePersistentConfiguration(Landroid/content/res/Configuration;)V
Landroid/app/IAlarmManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/IAlarmManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IAlarmManager;
Landroid/app/IAlarmManager$Stub;->TRANSACTION_remove:I
Landroid/app/IAlarmManager$Stub;->TRANSACTION_set:I
-Landroid/app/IAlarmManager;->getNextAlarmClock(I)Landroid/app/AlarmManager$AlarmClockInfo;
-Landroid/app/IAlarmManager;->set(Ljava/lang/String;IJJJILandroid/app/PendingIntent;Landroid/app/IAlarmListener;Ljava/lang/String;Landroid/os/WorkSource;Landroid/app/AlarmManager$AlarmClockInfo;)V
-Landroid/app/IAlarmManager;->setTime(J)Z
-Landroid/app/IApplicationThread;->scheduleBindService(Landroid/os/IBinder;Landroid/content/Intent;ZI)V
-Landroid/app/IApplicationThread;->scheduleCreateService(Landroid/os/IBinder;Landroid/content/pm/ServiceInfo;Landroid/content/res/CompatibilityInfo;I)V
-Landroid/app/IApplicationThread;->scheduleStopService(Landroid/os/IBinder;)V
-Landroid/app/IApplicationThread;->scheduleTrimMemory(I)V
-Landroid/app/IApplicationThread;->scheduleUnbindService(Landroid/os/IBinder;Landroid/content/Intent;)V
-Landroid/app/IAppTask;->getTaskInfo()Landroid/app/ActivityManager$RecentTaskInfo;
Landroid/app/IAssistDataReceiver$Stub;-><init>()V
-Landroid/app/IAssistDataReceiver;->onHandleAssistData(Landroid/os/Bundle;)V
-Landroid/app/IAssistDataReceiver;->onHandleAssistScreenshot(Landroid/graphics/Bitmap;)V
Landroid/app/IInstrumentationWatcher$Stub;-><init>()V
-Landroid/app/IInstrumentationWatcher;->instrumentationStatus(Landroid/content/ComponentName;ILandroid/os/Bundle;)V
Landroid/app/INotificationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/INotificationManager$Stub$Proxy;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z
Landroid/app/INotificationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/INotificationManager;
Landroid/app/INotificationManager$Stub;->TRANSACTION_enqueueNotificationWithTag:I
-Landroid/app/INotificationManager;->areNotificationsEnabledForPackage(Ljava/lang/String;I)Z
-Landroid/app/INotificationManager;->cancelAllNotifications(Ljava/lang/String;I)V
-Landroid/app/INotificationManager;->cancelNotificationWithTag(Ljava/lang/String;Ljava/lang/String;II)V
-Landroid/app/INotificationManager;->cancelToast(Ljava/lang/String;Landroid/app/ITransientNotification;)V
-Landroid/app/INotificationManager;->enqueueToast(Ljava/lang/String;Landroid/app/ITransientNotification;II)V
-Landroid/app/INotificationManager;->getActiveNotifications(Ljava/lang/String;)[Landroid/service/notification/StatusBarNotification;
-Landroid/app/INotificationManager;->getHistoricalNotifications(Ljava/lang/String;I)[Landroid/service/notification/StatusBarNotification;
-Landroid/app/INotificationManager;->getZenMode()I
-Landroid/app/INotificationManager;->getZenModeConfig()Landroid/service/notification/ZenModeConfig;
Landroid/app/IProcessObserver$Stub;-><init>()V
Landroid/app/ISearchManager$Stub$Proxy;->getGlobalSearchActivity()Landroid/content/ComponentName;
Landroid/app/ISearchManager$Stub$Proxy;->getWebSearchActivity()Landroid/content/ComponentName;
Landroid/app/ISearchManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/ISearchManager;
-Landroid/app/ISearchManager;->getGlobalSearchActivity()Landroid/content/ComponentName;
Landroid/app/IServiceConnection$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/IServiceConnection$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/app/IServiceConnection$Stub;-><init>()V
Landroid/app/IServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IServiceConnection;
-Landroid/app/IServiceConnection;->connected(Landroid/content/ComponentName;Landroid/os/IBinder;Z)V
Landroid/app/IStopUserCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/IStopUserCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/app/IStopUserCallback$Stub;-><init>()V
-Landroid/app/IStopUserCallback;->userStopped(I)V
Landroid/app/ITransientNotification$Stub;-><init>()V
-Landroid/app/ITransientNotification;->show(Landroid/os/IBinder;)V
Landroid/app/IUiModeManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/IUserSwitchObserver$Stub;-><init>()V
Landroid/app/IWallpaperManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/IWallpaperManager;
-Landroid/app/IWallpaperManager;->getHeightHint(I)I
-Landroid/app/IWallpaperManager;->getWallpaper(Ljava/lang/String;Landroid/app/IWallpaperManagerCallback;ILandroid/os/Bundle;I)Landroid/os/ParcelFileDescriptor;
-Landroid/app/IWallpaperManager;->getWallpaperInfo(I)Landroid/app/WallpaperInfo;
-Landroid/app/IWallpaperManager;->getWidthHint(I)I
-Landroid/app/IWallpaperManager;->hasNamedWallpaper(Ljava/lang/String;)Z
-Landroid/app/IWallpaperManager;->setWallpaperComponent(Landroid/content/ComponentName;)V
Landroid/app/IWallpaperManagerCallback$Stub;-><init>()V
Landroid/app/job/IJobCallback$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/app/job/IJobCallback$Stub$Proxy;->mRemote:Landroid/os/IBinder;
@@ -212,7 +75,6 @@ Landroid/app/job/IJobService$Stub;-><init>()V
Landroid/app/job/IJobService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/job/IJobService;
Landroid/app/PackageDeleteObserver;-><init>()V
Landroid/app/PackageInstallObserver;-><init>()V
-Landroid/app/ReceiverRestrictedContext;-><init>(Landroid/content/Context;)V
Landroid/app/ResourcesManager$ActivityResources;-><init>()V
Landroid/app/ResourcesManager;-><init>()V
Landroid/app/TaskStackListener;-><init>()V
diff --git a/core/java/android/accounts/IAccountAuthenticator.aidl b/core/java/android/accounts/IAccountAuthenticator.aidl
index 8b98ca28ca81..701cecf38f32 100644
--- a/core/java/android/accounts/IAccountAuthenticator.aidl
+++ b/core/java/android/accounts/IAccountAuthenticator.aidl
@@ -28,47 +28,55 @@ oneway interface IAccountAuthenticator {
/**
* prompts the user for account information and adds the result to the IAccountManager
*/
+ @UnsupportedAppUsage
void addAccount(in IAccountAuthenticatorResponse response, String accountType,
String authTokenType, in String[] requiredFeatures, in Bundle options);
/**
* prompts the user for the credentials of the account
*/
+ @UnsupportedAppUsage
void confirmCredentials(in IAccountAuthenticatorResponse response, in Account account,
in Bundle options);
/**
* gets the password by either prompting the user or querying the IAccountManager
*/
+ @UnsupportedAppUsage
void getAuthToken(in IAccountAuthenticatorResponse response, in Account account,
String authTokenType, in Bundle options);
/**
* Gets the user-visible label of the given authtoken type.
*/
+ @UnsupportedAppUsage
void getAuthTokenLabel(in IAccountAuthenticatorResponse response, String authTokenType);
/**
* prompts the user for a new password and writes it to the IAccountManager
*/
+ @UnsupportedAppUsage
void updateCredentials(in IAccountAuthenticatorResponse response, in Account account,
String authTokenType, in Bundle options);
/**
* launches an activity that lets the user edit and set the properties for an authenticator
*/
+ @UnsupportedAppUsage
void editProperties(in IAccountAuthenticatorResponse response, String accountType);
/**
* returns a Bundle where the boolean value BOOLEAN_RESULT_KEY is set if the account has the
* specified features
*/
+ @UnsupportedAppUsage
void hasFeatures(in IAccountAuthenticatorResponse response, in Account account,
in String[] features);
/**
* Gets whether or not the account is allowed to be removed.
*/
+ @UnsupportedAppUsage
void getAccountRemovalAllowed(in IAccountAuthenticatorResponse response, in Account account);
/**
diff --git a/core/java/android/accounts/IAccountAuthenticatorResponse.aidl b/core/java/android/accounts/IAccountAuthenticatorResponse.aidl
index 0c75e507f1e8..fbc8e5dcf3db 100644
--- a/core/java/android/accounts/IAccountAuthenticatorResponse.aidl
+++ b/core/java/android/accounts/IAccountAuthenticatorResponse.aidl
@@ -22,7 +22,10 @@ import android.os.Bundle;
* @hide
*/
oneway interface IAccountAuthenticatorResponse {
+ @UnsupportedAppUsage
void onResult(in Bundle value);
+ @UnsupportedAppUsage
void onRequestContinued();
+ @UnsupportedAppUsage
void onError(int errorCode, String errorMessage);
}
diff --git a/core/java/android/accounts/IAccountManagerResponse.aidl b/core/java/android/accounts/IAccountManagerResponse.aidl
index ca1203d1a058..11d0c023350a 100644
--- a/core/java/android/accounts/IAccountManagerResponse.aidl
+++ b/core/java/android/accounts/IAccountManagerResponse.aidl
@@ -22,6 +22,8 @@ import android.os.Bundle;
* @hide
*/
oneway interface IAccountManagerResponse {
+ @UnsupportedAppUsage
void onResult(in Bundle value);
+ @UnsupportedAppUsage
void onError(int errorCode, String errorMessage);
}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 831cac261d34..e57327991a82 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -36,6 +36,7 @@ import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
import android.view.Window;
+import android.view.inspector.InspectableProperty;
import android.widget.SpinnerAdapter;
import java.lang.annotation.Retention;
@@ -1374,6 +1375,9 @@ public abstract class ActionBar {
@ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
@ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
})
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity = Gravity.NO_GRAVITY;
public LayoutParams(@NonNull Context c, AttributeSet attrs) {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 68b2de425b72..56bf8fa8ffce 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -127,6 +127,7 @@ import android.view.autofill.AutofillPopupWindow;
import android.view.autofill.IAutofillWindowPresenter;
import android.view.contentcapture.ContentCaptureContext;
import android.view.contentcapture.ContentCaptureManager;
+import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -717,7 +718,7 @@ public class Activity extends ContextThemeWrapper
Window.Callback, KeyEvent.Callback,
OnCreateContextMenuListener, ComponentCallbacks2,
Window.OnWindowDismissedCallback, WindowControllerCallback,
- AutofillManager.AutofillClient {
+ AutofillManager.AutofillClient, ContentCaptureManager.ContentCaptureClient {
private static final String TAG = "Activity";
private static final boolean DEBUG_LIFECYCLE = false;
@@ -1119,6 +1120,12 @@ public class Activity extends ContextThemeWrapper
return this;
}
+ /** @hide */
+ @Override
+ public final ContentCaptureClient getContentCaptureClient() {
+ return this;
+ }
+
/**
* Register an {@link Application.ActivityLifecycleCallbacks} instance that receives
* lifecycle callbacks for only this Activity.
@@ -6464,6 +6471,12 @@ public class Activity extends ContextThemeWrapper
return getComponentName();
}
+ /** @hide */
+ @Override
+ public final ComponentName contentCaptureClientGetComponentName() {
+ return getComponentName();
+ }
+
/**
* Retrieve a {@link SharedPreferences} object for accessing preferences
* that are private to this activity. This simply calls the underlying
@@ -8366,11 +8379,8 @@ public class Activity extends ContextThemeWrapper
* screen when this activity has another activity behind it with
* the showWhenLock attribute set; {@code false} otherwise.
* @see #setShowWhenLocked(boolean)
- * See android.R.attr#inheritShowWhenLocked
- * @hide
+ * @see android.R.attr#inheritShowWhenLocked
*/
- @SystemApi
- @TestApi
public void setInheritShowWhenLocked(boolean inheritShowWhenLocked) {
try {
ActivityTaskManager.getService().setInheritShowWhenLocked(
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 7d828d87e278..664f0a37a459 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -196,6 +196,9 @@ public abstract class ActivityManagerInternal {
/** Kill the processes in the list due to their tasks been removed. */
public abstract void killProcessesForRemovedTask(ArrayList<Object> procsToKill);
+ /** Kill the process immediately. */
+ public abstract void killProcess(String processName, int uid, String reason);
+
/**
* Returns {@code true} if {@code uid} is running an activity from {@code packageName}.
*/
@@ -276,6 +279,7 @@ public abstract class ActivityManagerInternal {
public abstract boolean isActivityStartsLoggingEnabled();
/** Returns true if the background activity starts is enabled. */
public abstract boolean isBackgroundActivityStartsEnabled();
+ public abstract boolean isPackageNameWhitelistedForBgActivityStarts(String packageName);
public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);
/** Input dispatch timeout to a window, start the ANR process. */
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index b654258e6dcb..08239a1e7ed9 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -332,7 +332,6 @@ public final class ActivityThread extends ClientTransactionHandler {
String[] mInstrumentedSplitAppDirs = null;
String mInstrumentedLibDir = null;
boolean mSystemThread = false;
- boolean mJitEnabled = false;
boolean mSomeActivitiesChanged = false;
boolean mUpdatingSystemConfig = false;
/* package */ boolean mHiddenApiWarningShown = false;
@@ -1696,7 +1695,6 @@ public final class ActivityThread extends ClientTransactionHandler {
public static final int SUICIDE = 130;
@UnsupportedAppUsage
public static final int REMOVE_PROVIDER = 131;
- public static final int ENABLE_JIT = 132;
public static final int DISPATCH_PACKAGE_BROADCAST = 133;
@UnsupportedAppUsage
public static final int SCHEDULE_CRASH = 134;
@@ -1746,7 +1744,6 @@ public final class ActivityThread extends ClientTransactionHandler {
case DESTROY_BACKUP_AGENT: return "DESTROY_BACKUP_AGENT";
case SUICIDE: return "SUICIDE";
case REMOVE_PROVIDER: return "REMOVE_PROVIDER";
- case ENABLE_JIT: return "ENABLE_JIT";
case DISPATCH_PACKAGE_BROADCAST: return "DISPATCH_PACKAGE_BROADCAST";
case SCHEDULE_CRASH: return "SCHEDULE_CRASH";
case DUMP_HEAP: return "DUMP_HEAP";
@@ -1858,9 +1855,6 @@ public final class ActivityThread extends ClientTransactionHandler {
completeRemoveProvider((ProviderRefCount)msg.obj);
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
- case ENABLE_JIT:
- ensureJitEnabled();
- break;
case DISPATCH_PACKAGE_BROADCAST:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastPackage");
handleDispatchPackageBroadcast(msg.arg1, (String[])msg.obj);
@@ -1996,7 +1990,6 @@ public final class ActivityThread extends ClientTransactionHandler {
if (stopProfiling) {
mProfiler.stopProfiling();
}
- ensureJitEnabled();
return false;
}
}
@@ -2330,13 +2323,6 @@ public final class ActivityThread extends ClientTransactionHandler {
}
}
- void ensureJitEnabled() {
- if (!mJitEnabled) {
- mJitEnabled = true;
- dalvik.system.VMRuntime.getRuntime().startJitCompilation();
- }
- }
-
@UnsupportedAppUsage
void scheduleGcIdler() {
if (!mGcIdlerScheduled) {
@@ -3782,7 +3768,6 @@ public final class ActivityThread extends ClientTransactionHandler {
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
- ensureJitEnabled();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
@@ -3896,7 +3881,6 @@ public final class ActivityThread extends ClientTransactionHandler {
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
- ensureJitEnabled();
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
@@ -6177,9 +6161,6 @@ public final class ActivityThread extends ClientTransactionHandler {
if (!data.restrictedBackupMode) {
if (!ArrayUtils.isEmpty(data.providers)) {
installContentProviders(app, data.providers);
- // For process that contains content providers, we want to
- // ensure that the JIT is enabled "at some point".
- mH.sendEmptyMessageDelayed(H.ENABLE_JIT, 10*1000);
}
}
@@ -6812,12 +6793,6 @@ public final class ActivityThread extends ClientTransactionHandler {
sCurrentActivityThread = this;
mSystemThread = system;
if (!system) {
- ViewRootImpl.addFirstDrawHandler(new Runnable() {
- @Override
- public void run() {
- ensureJitEnabled();
- }
- });
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
UserHandle.myUserId());
RuntimeInit.setApplicationObject(mAppThread.asBinder());
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index 4a826d1faf90..010a900b9d96 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -16,18 +16,15 @@
package android.app;
-import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY;
-
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.app.NotificationManager.InterruptionFilter;
import android.content.ComponentName;
-import android.content.Intent;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
-import android.service.notification.ZenPolicy;
import android.service.notification.Condition;
-
-import com.android.internal.util.Preconditions;
+import android.service.notification.ZenPolicy;
import java.util.Objects;
@@ -92,8 +89,9 @@ public final class AutomaticZenRule implements Parcelable {
* action ({@link Condition#STATE_TRUE}).
* @param enabled Whether the rule is enabled.
*/
- public AutomaticZenRule(String name, ComponentName owner, ComponentName configurationActivity,
- Uri conditionId, ZenPolicy policy, int interruptionFilter, boolean enabled) {
+ public AutomaticZenRule(@NonNull String name, @Nullable ComponentName owner,
+ @Nullable ComponentName configurationActivity, @NonNull Uri conditionId,
+ @Nullable ZenPolicy policy, int interruptionFilter, boolean enabled) {
this.name = name;
this.owner = owner;
this.configurationActivity = configurationActivity;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index b607f9adebbe..daf2366c7621 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -102,6 +102,7 @@ import java.util.Objects;
import java.util.concurrent.Executor;
class ReceiverRestrictedContext extends ContextWrapper {
+ @UnsupportedAppUsage
ReceiverRestrictedContext(Context base) {
super(base);
}
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index e20c4901ea0d..7ae88fd0dbb3 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -1158,6 +1158,7 @@ public class DownloadManager {
* @param ids the IDs of the downloads
* @hide
*/
+ @UnsupportedAppUsage
public void restartDownload(long... ids) {
Cursor cursor = query(new Query().setFilterById(ids));
try {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 5cbb59976c5a..16fe7dba0fbe 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -102,15 +102,21 @@ interface IActivityManager {
// Special low-level communication with activity manager.
void handleApplicationCrash(in IBinder app,
in ApplicationErrorReport.ParcelableCrashInfo crashInfo);
+ @UnsupportedAppUsage
int startActivity(in IApplicationThread caller, in String callingPackage, in Intent intent,
in String resolvedType, in IBinder resultTo, in String resultWho, int requestCode,
int flags, in ProfilerInfo profilerInfo, in Bundle options);
+ @UnsupportedAppUsage
void unhandledBack();
+ @UnsupportedAppUsage
boolean finishActivity(in IBinder token, int code, in Intent data, int finishTask);
+ @UnsupportedAppUsage
Intent registerReceiver(in IApplicationThread caller, in String callerPackage,
in IIntentReceiver receiver, in IntentFilter filter,
in String requiredPermission, int userId, int flags);
+ @UnsupportedAppUsage
void unregisterReceiver(in IIntentReceiver receiver);
+ @UnsupportedAppUsage
int broadcastIntent(in IApplicationThread caller, in Intent intent,
in String resolvedType, in IIntentReceiver resultTo, int resultCode,
in String resultData, in Bundle map, in String[] requiredPermissions,
@@ -120,21 +126,27 @@ interface IActivityManager {
boolean abortBroadcast, int flags);
void attachApplication(in IApplicationThread app, long startSeq);
List<ActivityManager.RunningTaskInfo> getTasks(int maxNum);
+ @UnsupportedAppUsage
List<ActivityManager.RunningTaskInfo> getFilteredTasks(int maxNum, int ignoreActivityType,
int ignoreWindowingMode);
+ @UnsupportedAppUsage
void moveTaskToFront(int task, int flags, in Bundle options);
+ @UnsupportedAppUsage
int getTaskForActivity(in IBinder token, in boolean onlyRoot);
ContentProviderHolder getContentProvider(in IApplicationThread caller, in String callingPackage,
in String name, int userId, boolean stable);
+ @UnsupportedAppUsage
void publishContentProviders(in IApplicationThread caller,
in List<ContentProviderHolder> providers);
boolean refContentProvider(in IBinder connection, int stableDelta, int unstableDelta);
PendingIntent getRunningServiceControlPanel(in ComponentName service);
ComponentName startService(in IApplicationThread caller, in Intent service,
in String resolvedType, boolean requireForeground, in String callingPackage, int userId);
+ @UnsupportedAppUsage
int stopService(in IApplicationThread caller, in Intent service,
in String resolvedType, int userId);
// Currently keeping old bindService because it is on the greylist
+ @UnsupportedAppUsage
int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
in String resolvedType, in IServiceConnection connection, int flags,
in String callingPackage, int userId);
@@ -142,11 +154,15 @@ interface IActivityManager {
in String resolvedType, in IServiceConnection connection, int flags,
in String instanceName, in String callingPackage, int userId);
void updateServiceGroup(in IServiceConnection connection, int group, int importance);
+ @UnsupportedAppUsage
boolean unbindService(in IServiceConnection connection);
void publishService(in IBinder token, in Intent intent, in IBinder service);
+ @UnsupportedAppUsage
void setDebugApp(in String packageName, boolean waitForDebugger, boolean persistent);
void setAgentApp(in String packageName, @nullable String agent);
+ @UnsupportedAppUsage
void setAlwaysFinish(boolean enabled);
+ @UnsupportedAppUsage
boolean startInstrumentation(in ComponentName className, in String profileFile,
int flags, in Bundle arguments, in IInstrumentationWatcher watcher,
in IUiAutomationConnection connection, int userId,
@@ -159,6 +175,7 @@ interface IActivityManager {
* system. Corresponds to the configuration of the default display.
* @throws RemoteException
*/
+ @UnsupportedAppUsage
Configuration getConfiguration();
/**
* Updates global configuration and applies changes to the entire system.
@@ -167,10 +184,14 @@ interface IActivityManager {
* @throws RemoteException
* @return Returns true if the configuration was updated.
*/
+ @UnsupportedAppUsage
boolean updateConfiguration(in Configuration values);
boolean stopServiceToken(in ComponentName className, in IBinder token, int startId);
+ @UnsupportedAppUsage
void setProcessLimit(int max);
+ @UnsupportedAppUsage
int getProcessLimit();
+ @UnsupportedAppUsage
int checkPermission(in String permission, int pid, int uid);
int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
in IBinder callerToken);
@@ -178,6 +199,7 @@ interface IActivityManager {
int mode, int userId);
void revokeUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
int mode, int userId);
+ @UnsupportedAppUsage
void setActivityController(in IActivityController watcher, boolean imAMonkey);
void showWaitingForDebugger(in IApplicationThread who, boolean waiting);
/*
@@ -186,8 +208,10 @@ interface IActivityManager {
*/
void signalPersistentProcesses(int signal);
+ @UnsupportedAppUsage
ParceledListSlice getRecentTasks(int maxNum, int flags, int userId);
oneway void serviceDoneExecuting(in IBinder token, int type, int startId, int res);
+ @UnsupportedAppUsage
IIntentSender getIntentSender(int type, in String packageName, in IBinder token,
in String resultWho, int requestCode, in Intent[] intents, in String[] resolvedTypes,
int flags, in Bundle options, int userId);
@@ -199,28 +223,39 @@ interface IActivityManager {
void noteWakeupAlarm(in IIntentSender sender, in WorkSource workSource, int sourceUid,
in String sourcePkg, in String tag);
void removeContentProvider(in IBinder connection, boolean stable);
+ @UnsupportedAppUsage
void setRequestedOrientation(in IBinder token, int requestedOrientation);
void unbindFinished(in IBinder token, in Intent service, boolean doRebind);
+ @UnsupportedAppUsage
void setProcessImportant(in IBinder token, int pid, boolean isForeground, String reason);
void setServiceForeground(in ComponentName className, in IBinder token,
int id, in Notification notification, int flags, int foregroundServiceType);
int getForegroundServiceType(in ComponentName className, in IBinder token);
+ @UnsupportedAppUsage
boolean moveActivityTaskToBack(in IBinder token, boolean nonRoot);
+ @UnsupportedAppUsage
void getMemoryInfo(out ActivityManager.MemoryInfo outInfo);
List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState();
boolean clearApplicationUserData(in String packageName, boolean keepState,
in IPackageDataObserver observer, int userId);
+ @UnsupportedAppUsage
void forceStopPackage(in String packageName, int userId);
boolean killPids(in int[] pids, in String reason, boolean secure);
+ @UnsupportedAppUsage
List<ActivityManager.RunningServiceInfo> getServices(int maxNum, int flags);
// Retrieve running application processes in the system
+ @UnsupportedAppUsage
List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses();
IBinder peekService(in Intent service, in String resolvedType, in String callingPackage);
// Turn on/off profiling in a particular process.
+ @UnsupportedAppUsage
boolean profileControl(in String process, int userId, boolean start,
in ProfilerInfo profilerInfo, int profileType);
+ @UnsupportedAppUsage
boolean shutdown(int timeout);
+ @UnsupportedAppUsage
void stopAppSwitches();
+ @UnsupportedAppUsage
void resumeAppSwitches();
boolean bindBackupAgent(in String packageName, int backupRestoreMode, int targetUserId);
void backupAgentCreated(in String packageName, in IBinder agent, int userId);
@@ -230,60 +265,83 @@ interface IActivityManager {
boolean requireFull, in String name, in String callerPackage);
void addPackageDependency(in String packageName);
void killApplication(in String pkg, int appId, int userId, in String reason);
+ @UnsupportedAppUsage
void closeSystemDialogs(in String reason);
+ @UnsupportedAppUsage
Debug.MemoryInfo[] getProcessMemoryInfo(in int[] pids);
void killApplicationProcess(in String processName, int uid);
// Special low-level communication with activity manager.
boolean handleApplicationWtf(in IBinder app, in String tag, boolean system,
in ApplicationErrorReport.ParcelableCrashInfo crashInfo);
+ @UnsupportedAppUsage
void killBackgroundProcesses(in String packageName, int userId);
boolean isUserAMonkey();
// Retrieve info of applications installed on external media that are currently
// running.
List<ApplicationInfo> getRunningExternalApplications();
+ @UnsupportedAppUsage
void finishHeavyWeightApp();
// A StrictMode violation to be handled.
+ @UnsupportedAppUsage
void handleApplicationStrictModeViolation(in IBinder app, int penaltyMask,
in StrictMode.ViolationInfo crashInfo);
boolean isTopActivityImmersive();
void crashApplication(int uid, int initialPid, in String packageName, int userId, in String message);
+ @UnsupportedAppUsage
String getProviderMimeType(in Uri uri, int userId);
// Cause the specified process to dump the specified heap.
boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo,
boolean runGc, in String path, in ParcelFileDescriptor fd,
in RemoteCallback finishCallback);
+ @UnsupportedAppUsage
boolean isUserRunning(int userid, int flags);
+ @UnsupportedAppUsage
void setPackageScreenCompatMode(in String packageName, int mode);
+ @UnsupportedAppUsage
boolean switchUser(int userid);
+ @UnsupportedAppUsage
boolean removeTask(int taskId);
+ @UnsupportedAppUsage
void registerProcessObserver(in IProcessObserver observer);
+ @UnsupportedAppUsage
void unregisterProcessObserver(in IProcessObserver observer);
boolean isIntentSenderTargetedToPackage(in IIntentSender sender);
+ @UnsupportedAppUsage
void updatePersistentConfiguration(in Configuration values);
+ @UnsupportedAppUsage
long[] getProcessPss(in int[] pids);
void showBootMessage(in CharSequence msg, boolean always);
+ @UnsupportedAppUsage
void killAllBackgroundProcesses();
ContentProviderHolder getContentProviderExternal(in String name, int userId,
in IBinder token, String tag);
/** @deprecated - Use {@link #removeContentProviderExternalAsUser} which takes a user ID. */
+ @UnsupportedAppUsage
void removeContentProviderExternal(in String name, in IBinder token);
void removeContentProviderExternalAsUser(in String name, in IBinder token, int userId);
// Get memory information about the calling process.
void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo);
boolean killProcessesBelowForeground(in String reason);
+ @UnsupportedAppUsage
UserInfo getCurrentUser();
// This is not public because you need to be very careful in how you
// manage your activity to make sure it is always the uid you expect.
+ @UnsupportedAppUsage
int getLaunchedFromUid(in IBinder activityToken);
+ @UnsupportedAppUsage
void unstableProviderDied(in IBinder connection);
+ @UnsupportedAppUsage
boolean isIntentSenderAnActivity(in IIntentSender sender);
boolean isIntentSenderAForegroundService(in IIntentSender sender);
boolean isIntentSenderABroadcast(in IIntentSender sender);
+ @UnsupportedAppUsage
int startActivityAsUser(in IApplicationThread caller, in String callingPackage,
in Intent intent, in String resolvedType, in IBinder resultTo, in String resultWho,
int requestCode, int flags, in ProfilerInfo profilerInfo,
in Bundle options, int userId);
+ @UnsupportedAppUsage
int stopUser(int userid, boolean force, in IStopUserCallback callback);
+ @UnsupportedAppUsage
void registerUserSwitchObserver(in IUserSwitchObserver observer, in String name);
void unregisterUserSwitchObserver(in IUserSwitchObserver observer);
int[] getRunningUserIds();
@@ -291,6 +349,7 @@ interface IActivityManager {
// Deprecated - This method is only used by a few internal components and it will soon be
// replaced by a proper bug report API (which will be restricted to a few, pre-defined apps).
// No new code should be calling it.
+ @UnsupportedAppUsage
void requestBugReport(int bugreportType);
/**
@@ -319,15 +378,20 @@ interface IActivityManager {
*/
void requestWifiBugReport(in String shareTitle, in String shareDescription);
+ @UnsupportedAppUsage
Intent getIntentForIntentSender(in IIntentSender sender);
// This is not public because you need to be very careful in how you
// manage your activity to make sure it is always the uid you expect.
+ @UnsupportedAppUsage
String getLaunchedFromPackage(in IBinder activityToken);
void killUid(int appId, int userId, in String reason);
void setUserIsMonkey(boolean monkey);
+ @UnsupportedAppUsage
void hang(in IBinder who, boolean allowRestart);
+ @UnsupportedAppUsage
List<ActivityManager.StackInfo> getAllStackInfos();
+ @UnsupportedAppUsage
void moveTaskToStack(int taskId, int stackId, boolean toTop);
/**
* Resizes the input stack id to the given bounds.
@@ -343,60 +407,83 @@ interface IActivityManager {
* default animation duration should be used.
* @throws RemoteException
*/
+ @UnsupportedAppUsage
void resizeStack(int stackId, in Rect bounds, boolean allowResizeInDockedMode,
boolean preserveWindows, boolean animate, int animationDuration);
void setFocusedStack(int stackId);
ActivityManager.StackInfo getFocusedStackInfo();
+ @UnsupportedAppUsage
void restart();
void performIdleMaintenance();
void appNotRespondingViaProvider(in IBinder connection);
+ @UnsupportedAppUsage
Rect getTaskBounds(int taskId);
+ @UnsupportedAppUsage
boolean setProcessMemoryTrimLevel(in String process, int uid, int level);
// Start of L transactions
String getTagForIntentSender(in IIntentSender sender, in String prefix);
+ @UnsupportedAppUsage
boolean startUserInBackground(int userid);
+ @UnsupportedAppUsage
boolean isInLockTaskMode();
+ @UnsupportedAppUsage
void startRecentsActivity(in Intent intent, in IAssistDataReceiver assistDataReceiver,
in IRecentsAnimationRunner recentsAnimationRunner);
+ @UnsupportedAppUsage
void cancelRecentsAnimation(boolean restoreHomeStackPosition);
+ @UnsupportedAppUsage
int startActivityFromRecents(int taskId, in Bundle options);
+ @UnsupportedAppUsage
void startSystemLockTaskMode(int taskId);
+ @UnsupportedAppUsage
boolean isTopOfTask(in IBinder token);
void bootAnimationComplete();
int checkPermissionWithToken(in String permission, int pid, int uid,
in IBinder callerToken);
+ @UnsupportedAppUsage
void registerTaskStackListener(in ITaskStackListener listener);
void unregisterTaskStackListener(in ITaskStackListener listener);
void notifyCleartextNetwork(int uid, in byte[] firstPacket);
+ @UnsupportedAppUsage
void setTaskResizeable(int taskId, int resizeableMode);
+ @UnsupportedAppUsage
void resizeTask(int taskId, in Rect bounds, int resizeMode);
+ @UnsupportedAppUsage
int getLockTaskModeState();
+ @UnsupportedAppUsage
void setDumpHeapDebugLimit(in String processName, int uid, long maxMemSize,
in String reportPackage);
void dumpHeapFinished(in String path);
void updateLockTaskPackages(int userId, in String[] packages);
void noteAlarmStart(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
+ @UnsupportedAppUsage
int getPackageProcessState(in String packageName, in String callingPackage);
void updateDeviceOwner(in String packageName);
// Start of N transactions
// Start Binder transaction tracking for all applications.
+ @UnsupportedAppUsage
boolean startBinderTracking();
// Stop Binder transaction tracking for all applications and dump trace data to the given file
// descriptor.
+ @UnsupportedAppUsage
boolean stopBinderTrackingAndDump(in ParcelFileDescriptor fd);
/**
* Try to place task to provided position. The final position might be different depending on
* current user and stacks state. The task will be moved to target stack if it's currently in
* different stack.
*/
+ @UnsupportedAppUsage
void positionTaskInStack(int taskId, int stackId, int position);
+ @UnsupportedAppUsage
void suppressResizeConfigChanges(boolean suppress);
+ @UnsupportedAppUsage
boolean moveTopActivityToPinnedStack(int stackId, in Rect bounds);
boolean isAppStartModeDisabled(int uid, in String packageName);
+ @UnsupportedAppUsage
boolean unlockUser(int userid, in byte[] token, in byte[] secret,
in IProgressListener listener);
void killPackageDependents(in String packageName, int userId);
@@ -419,15 +506,18 @@ interface IActivityManager {
* stacks.
* @throws RemoteException
*/
+ @UnsupportedAppUsage
void resizeDockedStack(in Rect dockedBounds, in Rect tempDockedTaskBounds,
in Rect tempDockedTaskInsetBounds,
in Rect tempOtherTaskBounds, in Rect tempOtherTaskInsetBounds);
+ @UnsupportedAppUsage
void removeStack(int stackId);
void makePackageIdle(String packageName, int userId);
int getMemoryTrimLevel();
boolean isVrModePackageEnabled(in ComponentName packageName);
void notifyLockedProfile(int userId);
void startConfirmDeviceCredentialIntent(in Intent intent, in Bundle options);
+ @UnsupportedAppUsage
void sendIdleJobTrigger();
int sendIntentSender(in IIntentSender target, in IBinder whitelistToken, int code,
in Intent intent, in String resolvedType, in IIntentReceiver finishedReceiver,
@@ -449,6 +539,7 @@ interface IActivityManager {
// Start of O transactions
int restartUserInBackground(int userId);
/** Cancels the window transitions for the given task. */
+ @UnsupportedAppUsage
void cancelTaskWindowTransition(int taskId);
/**
* @param taskId the id of the task to retrieve the sAutoapshots for
@@ -456,6 +547,7 @@ interface IActivityManager {
* a reduced resolution of it, which is much faster
* @return a graphic buffer representing a screenshot of a task
*/
+ @UnsupportedAppUsage
ActivityManager.TaskSnapshot getTaskSnapshot(int taskId, boolean reducedResolution);
void scheduleApplicationInfoChanged(in List<String> packageNames, int userId);
void setPersistentVrThread(int tid);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index b16188f1a0e3..a6b76cb0db60 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -473,4 +473,14 @@ interface IActivityTaskManager {
* contain one task.
*/
void setDisplayToSingleTaskInstance(int displayId);
+
+ /**
+ * Restarts the activity by killing its process if it is visible. If the activity is not
+ * visible, the activity will not be restarted immediately and just keep the activity record in
+ * the stack. It also resets the current override configuration so the activity will use the
+ * configuration according to the latest state.
+ *
+ * @param activityToken The token of the target activity to restart.
+ */
+ void restartActivityProcessIfVisible(in IBinder activityToken);
}
diff --git a/core/java/android/app/IAlarmManager.aidl b/core/java/android/app/IAlarmManager.aidl
index ded4c4954956..6f624ee672e6 100644
--- a/core/java/android/app/IAlarmManager.aidl
+++ b/core/java/android/app/IAlarmManager.aidl
@@ -29,13 +29,16 @@ import android.os.WorkSource;
*/
interface IAlarmManager {
/** windowLength == 0 means exact; windowLength < 0 means the let the OS decide */
+ @UnsupportedAppUsage
void set(String callingPackage, int type, long triggerAtTime, long windowLength,
long interval, int flags, in PendingIntent operation, in IAlarmListener listener,
String listenerTag, in WorkSource workSource, in AlarmManager.AlarmClockInfo alarmClock);
+ @UnsupportedAppUsage
boolean setTime(long millis);
void setTimeZone(String zone);
void remove(in PendingIntent operation, in IAlarmListener listener);
long getNextWakeFromIdleTime();
+ @UnsupportedAppUsage
AlarmManager.AlarmClockInfo getNextAlarmClock(int userId);
long currentNetworkTimeMillis();
}
diff --git a/core/java/android/app/IAppTask.aidl b/core/java/android/app/IAppTask.aidl
index 37fead9e1d7a..61f6264408f8 100644
--- a/core/java/android/app/IAppTask.aidl
+++ b/core/java/android/app/IAppTask.aidl
@@ -23,6 +23,7 @@ import android.os.Bundle;
/** @hide */
interface IAppTask {
void finishAndRemoveTask();
+ @UnsupportedAppUsage
ActivityManager.RecentTaskInfo getTaskInfo();
void moveToFront();
int startActivity(IBinder whoThread, String callingPackage,
diff --git a/core/java/android/app/IApplicationThread.aidl b/core/java/android/app/IApplicationThread.aidl
index b8af8989170e..3a09c4cdfdeb 100644
--- a/core/java/android/app/IApplicationThread.aidl
+++ b/core/java/android/app/IApplicationThread.aidl
@@ -60,8 +60,10 @@ oneway interface IApplicationThread {
in CompatibilityInfo compatInfo,
int resultCode, in String data, in Bundle extras, boolean sync,
int sendingUser, int processState);
+ @UnsupportedAppUsage
void scheduleCreateService(IBinder token, in ServiceInfo info,
in CompatibilityInfo compatInfo, int processState);
+ @UnsupportedAppUsage
void scheduleStopService(IBinder token);
void bindApplication(in String packageName, in ApplicationInfo info,
in List<ProviderInfo> providers, in ComponentName testName,
@@ -77,8 +79,10 @@ oneway interface IApplicationThread {
void scheduleServiceArgs(IBinder token, in ParceledListSlice args);
void updateTimeZone();
void processInBackground();
+ @UnsupportedAppUsage
void scheduleBindService(IBinder token,
in Intent intent, boolean rebind, int processState);
+ @UnsupportedAppUsage
void scheduleUnbindService(IBinder token,
in Intent intent);
void dumpService(in ParcelFileDescriptor fd, IBinder servicetoken,
@@ -106,6 +110,7 @@ oneway interface IApplicationThread {
void updateHttpProxy();
void setCoreSettings(in Bundle coreSettings);
void updatePackageCompatibilityInfo(in String pkg, in CompatibilityInfo info);
+ @UnsupportedAppUsage
void scheduleTrimMemory(int level);
void dumpMemInfo(in ParcelFileDescriptor fd, in Debug.MemoryInfo mem, boolean checkin,
boolean dumpInfo, boolean dumpDalvik, boolean dumpSummaryOnly, boolean dumpUnreachable,
diff --git a/core/java/android/app/IAssistDataReceiver.aidl b/core/java/android/app/IAssistDataReceiver.aidl
index 2d5daf97a1c4..0d69838e4329 100644
--- a/core/java/android/app/IAssistDataReceiver.aidl
+++ b/core/java/android/app/IAssistDataReceiver.aidl
@@ -21,6 +21,8 @@ import android.os.Bundle;
/** @hide */
oneway interface IAssistDataReceiver {
+ @UnsupportedAppUsage
void onHandleAssistData(in Bundle resultData);
+ @UnsupportedAppUsage
void onHandleAssistScreenshot(in Bitmap screenshot);
}
diff --git a/core/java/android/app/IInstrumentationWatcher.aidl b/core/java/android/app/IInstrumentationWatcher.aidl
index 6c8c4d6e03ef..df42decd8c90 100644
--- a/core/java/android/app/IInstrumentationWatcher.aidl
+++ b/core/java/android/app/IInstrumentationWatcher.aidl
@@ -23,6 +23,7 @@ import android.os.Bundle;
/** @hide */
interface IInstrumentationWatcher
{
+ @UnsupportedAppUsage
void instrumentationStatus(in ComponentName name, int resultCode,
in Bundle results);
void instrumentationFinished(in ComponentName name, int resultCode,
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index df04a6b4d134..e1da08bb2e1a 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -40,15 +40,19 @@ import android.service.notification.ZenModeConfig;
/** {@hide} */
interface INotificationManager
{
+ @UnsupportedAppUsage
void cancelAllNotifications(String pkg, int userId);
void clearData(String pkg, int uid, boolean fromApp);
+ @UnsupportedAppUsage
void enqueueToast(String pkg, ITransientNotification callback, int duration, int displayId);
+ @UnsupportedAppUsage
void cancelToast(String pkg, ITransientNotification callback);
void finishToken(String pkg, ITransientNotification callback);
void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
in Notification notification, int userId);
+ @UnsupportedAppUsage
void cancelNotificationWithTag(String pkg, String tag, int id, int userId);
void setShowBadge(String pkg, int uid, boolean showBadge);
@@ -61,6 +65,7 @@ interface INotificationManager
*/
void setNotificationsEnabledWithImportanceLockForPackage(String pkg, int uid, boolean enabled);
+ @UnsupportedAppUsage
boolean areNotificationsEnabledForPackage(String pkg, int uid);
boolean areNotificationsEnabled(String pkg);
int getPackageImportance(String pkg);
@@ -102,7 +107,9 @@ interface INotificationManager
// TODO: Remove this when callers have been migrated to the equivalent
// INotificationListener method.
+ @UnsupportedAppUsage
StatusBarNotification[] getActiveNotifications(String callingPkg);
+ @UnsupportedAppUsage
StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count);
void registerListener(in INotificationListener listener, in ComponentName component, int userid);
@@ -157,7 +164,9 @@ interface INotificationManager
ComponentName getAllowedNotificationAssistantForUser(int userId);
ComponentName getAllowedNotificationAssistant();
+ @UnsupportedAppUsage
int getZenMode();
+ @UnsupportedAppUsage
ZenModeConfig getZenModeConfig();
NotificationManager.Policy getConsolidatedNotificationPolicy();
oneway void setZenMode(int mode, in Uri conditionId, String reason);
diff --git a/core/java/android/app/ISearchManager.aidl b/core/java/android/app/ISearchManager.aidl
index 0d09e4a92d7b..53f1a46c1b8b 100644
--- a/core/java/android/app/ISearchManager.aidl
+++ b/core/java/android/app/ISearchManager.aidl
@@ -28,6 +28,7 @@ interface ISearchManager {
SearchableInfo getSearchableInfo(in ComponentName launchActivity);
List<SearchableInfo> getSearchablesInGlobalSearch();
List<ResolveInfo> getGlobalSearchActivities();
+ @UnsupportedAppUsage
ComponentName getGlobalSearchActivity();
ComponentName getWebSearchActivity();
void launchAssist(in Bundle args);
diff --git a/core/java/android/app/IServiceConnection.aidl b/core/java/android/app/IServiceConnection.aidl
index 97042aa2919f..0115bcfa4d19 100644
--- a/core/java/android/app/IServiceConnection.aidl
+++ b/core/java/android/app/IServiceConnection.aidl
@@ -21,6 +21,7 @@ import android.content.ComponentName;
/** @hide */
oneway interface IServiceConnection {
+ @UnsupportedAppUsage
void connected(in ComponentName name, IBinder service, boolean dead);
}
diff --git a/core/java/android/app/IStopUserCallback.aidl b/core/java/android/app/IStopUserCallback.aidl
index 19ac1d5d4ecd..d3c2ff776128 100644
--- a/core/java/android/app/IStopUserCallback.aidl
+++ b/core/java/android/app/IStopUserCallback.aidl
@@ -22,6 +22,7 @@ package android.app;
*/
interface IStopUserCallback
{
+ @UnsupportedAppUsage
void userStopped(int userId);
void userStopAborted(int userId);
}
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 8c85ad134e53..841ff6a3f12e 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -149,4 +149,16 @@ oneway interface ITaskStackListener {
* Called when a task snapshot got updated.
*/
void onTaskSnapshotChanged(int taskId, in ActivityManager.TaskSnapshot snapshot);
+
+ /**
+ * Called when the resumed activity is in size compatibility mode and its override configuration
+ * is different from the current one of system.
+ *
+ * @param displayId Id of the display where the activity resides.
+ * @param activityToken Token of the size compatibility mode activity. It will be null when
+ * switching to a activity that is not in size compatibility mode or the
+ * configuration of the activity.
+ * @see com.android.server.wm.AppWindowToken#inSizeCompatMode
+ */
+ void onSizeCompatModeActivityChanged(int displayId, in IBinder activityToken);
}
diff --git a/core/java/android/app/ITransientNotification.aidl b/core/java/android/app/ITransientNotification.aidl
index d5b3ed0a44d8..09a3ba045fc2 100644
--- a/core/java/android/app/ITransientNotification.aidl
+++ b/core/java/android/app/ITransientNotification.aidl
@@ -19,6 +19,7 @@ package android.app;
/** @hide */
oneway interface ITransientNotification {
+ @UnsupportedAppUsage
void show(IBinder windowToken);
void hide();
}
diff --git a/core/java/android/app/IWallpaperManager.aidl b/core/java/android/app/IWallpaperManager.aidl
index 666f7218a4f2..7f5350ddd4e0 100644
--- a/core/java/android/app/IWallpaperManager.aidl
+++ b/core/java/android/app/IWallpaperManager.aidl
@@ -55,11 +55,13 @@ interface IWallpaperManager {
/**
* Set the live wallpaper. This only affects the system wallpaper.
*/
+ @UnsupportedAppUsage
void setWallpaperComponent(in ComponentName name);
/**
* Get the wallpaper for a given user.
*/
+ @UnsupportedAppUsage
ParcelFileDescriptor getWallpaper(String callingPkg, IWallpaperManagerCallback cb, int which,
out Bundle outParams, int userId);
@@ -73,6 +75,7 @@ interface IWallpaperManager {
* information about that wallpaper. Otherwise, if it is a static image,
* simply return null.
*/
+ @UnsupportedAppUsage
WallpaperInfo getWallpaperInfo(int userId);
/**
@@ -83,6 +86,7 @@ interface IWallpaperManager {
/**
* Return whether the current system wallpaper has the given name.
*/
+ @UnsupportedAppUsage
boolean hasNamedWallpaper(String name);
/**
@@ -94,11 +98,13 @@ interface IWallpaperManager {
/**
* Returns the desired minimum width for the wallpaper in a particular display.
*/
+ @UnsupportedAppUsage
int getWidthHint(int displayId);
/**
* Returns the desired minimum height for the wallpaper in a particular display.
*/
+ @UnsupportedAppUsage
int getHeightHint(int displayId);
/**
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index 17f645dfbf23..3ecb5870416f 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -125,7 +125,7 @@ public class KeyguardManager {
public static final int RESULT_ALTERNATE = 1;
/**
- * @deprecated see {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)}
+ * @deprecated see {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)}
*
* Get an intent to prompt the user to confirm credentials (pin, pattern, password or biometrics
* if enrolled) for the current user of the device. The caller is expected to launch this
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e0cf56184081..f690f5d4a88e 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -1629,6 +1629,7 @@ public class Notification implements Parcelable
*
* @see Notification.Action#extras
*/
+ @NonNull
public Builder addExtras(Bundle extras) {
if (extras != null) {
mExtras.putAll(extras);
@@ -1652,6 +1653,7 @@ public class Notification implements Parcelable
* @param remoteInput a {@link RemoteInput} to add to the action
* @return this object for method chaining
*/
+ @NonNull
public Builder addRemoteInput(RemoteInput remoteInput) {
if (mRemoteInputs == null) {
mRemoteInputs = new ArrayList<RemoteInput>();
@@ -1669,6 +1671,7 @@ public class Notification implements Parcelable
* @return this object for method chaining
* The default value is {@code true}
*/
+ @NonNull
public Builder setAllowGeneratedReplies(boolean allowGeneratedReplies) {
mAllowGeneratedReplies = allowGeneratedReplies;
return this;
@@ -1682,6 +1685,7 @@ public class Notification implements Parcelable
* {@code SEMANTIC_ACTION_} prefixes
* @return this object for method chaining
*/
+ @NonNull
public Builder setSemanticAction(@SemanticAction int semanticAction) {
mSemanticAction = semanticAction;
return this;
@@ -1692,6 +1696,7 @@ public class Notification implements Parcelable
* dependent on the notification message body. An example of a contextual action could
* be an action opening a map application with an address shown in the notification.
*/
+ @NonNull
public Builder setContextual(boolean isContextual) {
mIsContextual = isContextual;
return this;
@@ -1701,6 +1706,7 @@ public class Notification implements Parcelable
* Apply an extender to this action builder. Extenders may be used to add
* metadata or change options on this builder.
*/
+ @NonNull
public Builder extend(Extender extender) {
extender.extend(this);
return this;
@@ -1728,6 +1734,7 @@ public class Notification implements Parcelable
* object.
* @return the built action
*/
+ @NonNull
public Action build() {
checkContextualActionNullFields();
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index ad614b1047ed..14c58e744dac 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -23,13 +23,7 @@
"name": "FrameworksServicesTests",
"options": [
{
- "include-filter": "com.android.server.appop.AppOpsUpgradeTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsServiceTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsActiveWatcherTest"
+ "include-filter": "com.android.server.appop"
}
]
}
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 47ad6d737430..97b9176d4a86 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -19,6 +19,7 @@ package android.app;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityManager.TaskSnapshot;
import android.content.ComponentName;
+import android.os.IBinder;
import android.os.RemoteException;
/**
@@ -155,4 +156,10 @@ public abstract class TaskStackListener extends ITaskStackListener.Stub {
@UnsupportedAppUsage
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) throws RemoteException {
}
+
+ @Override
+ @UnsupportedAppUsage
+ public void onSizeCompatModeActivityChanged(int displayId, IBinder activityToken)
+ throws RemoteException {
+ }
}
diff --git a/core/java/android/app/WallpaperInfo.java b/core/java/android/app/WallpaperInfo.java
index c2be4b04e43d..e9b01750b3b1 100644
--- a/core/java/android/app/WallpaperInfo.java
+++ b/core/java/android/app/WallpaperInfo.java
@@ -16,6 +16,7 @@
package android.app;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.slice.Slice;
import android.content.ComponentName;
@@ -354,12 +355,17 @@ public final class WallpaperInfo implements Parcelable {
/**
* Returns an URI that provides a settings {@link Slice} for this wallpaper.
+ * The wallpaper should implement a SliceProvider associated with this URI.
+ * The system will display the Slice in the customization section while previewing the live
+ * wallpaper. Because this URI is accessible to other apps, it is recommended to protect it
+ * with the android.permission.BIND_WALLPAPER permission.
*
* <p>{@code null} will be returned if there is no settings Slice URI associated
* with the wallpaper.
*
* @return The URI.
*/
+ @Nullable
public Uri getSettingsSliceUri() {
if (mSettingsSliceUri == null) {
return null;
diff --git a/core/java/android/app/ZygotePreload.java b/core/java/android/app/ZygotePreload.java
index a295af352c0a..eaaeb5458642 100644
--- a/core/java/android/app/ZygotePreload.java
+++ b/core/java/android/app/ZygotePreload.java
@@ -15,6 +15,7 @@
*/
package android.app;
+import android.annotation.NonNull;
import android.content.pm.ApplicationInfo;
/**
@@ -27,8 +28,7 @@ import android.content.pm.ApplicationInfo;
* {@link android.R.styleable#AndroidManifestService_useAppZygote android:useAppZygote} attribute
* of the &lt;service&gt; tag set to <code>true</code>.
*
- * Note that this implementations of this class must provide a default constructor with no
- * arguments.
+ * Note that implementations of this class must provide a default constructor with no arguments.
*/
public interface ZygotePreload {
/**
@@ -38,5 +38,5 @@ public interface ZygotePreload {
*
* @param appInfo The ApplicationInfo object belonging to the application
*/
- void doPreload(ApplicationInfo appInfo);
+ void doPreload(@NonNull ApplicationInfo appInfo);
}
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index efbd09844977..095d0147afd4 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -10632,18 +10632,18 @@ public class DevicePolicyManager {
}
/**
- * Whitelists a set of packages that are allowed to access cross-profile calendar APIs.
+ * Allows a set of packages to access cross-profile calendar APIs.
*
* <p>Called by a profile owner of a managed profile.
*
- * <p>Calling with a null value for the set disables the restriction so that all packages
- * are allowed to access cross-profile calendar APIs. Calling with an empty set disallows
- * all packages from accessing cross-profile calendar APIs. If this method isn't called,
- * no package will be allowed to access cross-profile calendar APIs by default.
+ * <p>Calling with a {@code null} value for the set disables the restriction so that all
+ * packages are allowed to access cross-profile calendar APIs. Calling with an empty set
+ * disallows all packages from accessing cross-profile calendar APIs. If this method isn't
+ * called, no package is allowed to access cross-profile calendar APIs by default.
*
- * @param admin which {@link DeviceAdminReceiver} this request is associated with.
- * @param packageNames set of packages to be whitelisted.
- * @throws SecurityException if {@code admin} is not a profile owner.
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with
+ * @param packageNames set of packages to be whitelisted
+ * @throws SecurityException if {@code admin} is not a profile owner
*
* @see #getCrossProfileCalendarPackages(ComponentName)
*/
@@ -10661,15 +10661,15 @@ public class DevicePolicyManager {
}
/**
- * Gets a set of package names that are whitelisted to access cross-profile calendar APIs.
+ * Gets a set of package names that are allowed to access cross-profile calendar APIs.
*
* <p>Called by a profile owner of a managed profile.
*
- * @param admin which {@link DeviceAdminReceiver} this request is associated with.
- * @return the set of names of packages that were previously whitelisted via
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with
+ * @return the set of names of packages that were previously allowed via
* {@link #setCrossProfileCalendarPackages(ComponentName, Set)}, or an
- * empty set if none have been whitelisted.
- * @throws SecurityException if {@code admin} is not a profile owner.
+ * empty set if none have been allowed
+ * @throws SecurityException if {@code admin} is not a profile owner
*
* @see #setCrossProfileCalendarPackages(ComponentName, Set)
*/
@@ -10699,8 +10699,8 @@ public class DevicePolicyManager {
* that user, and get a {@link DevicePolicyManager} from this context.
*
* @param packageName the name of the package
- * @return {@code true} if the package is allowed to access cross-profile calendar APIs.
- * {@code false} otherwise.
+ * @return {@code true} if the package is allowed to access cross-profile calendar APIs,
+ * {@code false} otherwise
*
* @see #setCrossProfileCalendarPackages(ComponentName, Set)
* @see #getCrossProfileCalendarPackages(ComponentName)
@@ -10720,15 +10720,15 @@ public class DevicePolicyManager {
}
/**
- * Gets a set of package names that are whitelisted to access cross-profile calendar APIs.
+ * Gets a set of package names that are allowed to access cross-profile calendar APIs.
*
* <p>To query for a specific user, use
* {@link Context#createPackageContextAsUser(String, int, UserHandle)} to create a context for
* that user, and get a {@link DevicePolicyManager} from this context.
*
- * @return the set of names of packages that were previously whitelisted via
+ * @return the set of names of packages that were previously allowed via
* {@link #setCrossProfileCalendarPackages(ComponentName, Set)}, or an
- * empty set if none have been whitelisted.
+ * empty set if none have been allowed
*
* @see #setCrossProfileCalendarPackages(ComponentName, Set)
* @see #getCrossProfileCalendarPackages(ComponentName)
@@ -10820,12 +10820,12 @@ public class DevicePolicyManager {
/**
* Starts an activity to view calendar events in the managed profile.
*
- * @param eventId the id of the event to be viewed.
- * @param start the start time of the event.
- * @param end the end time of the event.
- * @param allDay if the event is an all-day event.
+ * @param eventId the id of the event to be viewed
+ * @param start the start time of the event
+ * @param end the end time of the event
+ * @param allDay if the event is an all-day event
* @param flags flags to be set for the intent
- * @return {@code true} if the activity is started successfully. {@code false} otherwise.
+ * @return {@code true} if the activity is started successfully, {@code false} otherwise
*
* @see CalendarContract#startViewCalendarEventInManagedProfile(Context, String, long, long,
* long, boolean, int)
diff --git a/core/java/android/app/role/RoleManager.java b/core/java/android/app/role/RoleManager.java
index c665cb238028..f91d8780084f 100644
--- a/core/java/android/app/role/RoleManager.java
+++ b/core/java/android/app/role/RoleManager.java
@@ -187,6 +187,7 @@ public final class RoleManager {
* @hide
*/
@SystemApi
+ @TestApi
public static final int MANAGE_HOLDERS_FLAG_DONT_KILL_APP = 1;
/**
diff --git a/core/java/android/content/AutofillOptions.java b/core/java/android/content/AutofillOptions.java
index 0d25f4d5fe24..f59bc9891c86 100644
--- a/core/java/android/content/AutofillOptions.java
+++ b/core/java/android/content/AutofillOptions.java
@@ -16,12 +16,15 @@
package android.content;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.TestApi;
import android.app.ActivityThread;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArraySet;
import android.util.Log;
import android.view.autofill.AutofillManager;
+import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import java.io.PrintWriter;
@@ -51,8 +54,13 @@ public final class AutofillOptions implements Parcelable {
/**
* Whether package is whitelisted for augmented autofill.
*/
- public boolean augmentedEnabled;
- // TODO(b/123100824): add (optional) list of activities
+ public boolean augmentedAutofillEnabled;
+
+ /**
+ * List of whitelisted activities.
+ */
+ @Nullable
+ public ArraySet<ComponentName> whitelistedActivitiesForAugmentedAutofill;
public AutofillOptions(int loggingLevel, boolean compatModeEnabled) {
this.loggingLevel = loggingLevel;
@@ -60,6 +68,20 @@ public final class AutofillOptions implements Parcelable {
}
/**
+ * Returns whether activity is whitelisted for augmented autofill.
+ */
+ public boolean isAugmentedAutofillEnabled(@NonNull Context context) {
+ if (!augmentedAutofillEnabled) return false;
+
+ final ContentCaptureClient contentCaptureClient = context.getContentCaptureClient();
+ if (contentCaptureClient == null) return false;
+
+ final ComponentName component = contentCaptureClient.contentCaptureClientGetComponentName();
+ return whitelistedActivitiesForAugmentedAutofill == null
+ || whitelistedActivitiesForAugmentedAutofill.contains(component);
+ }
+
+ /**
* @hide
*/
@TestApi
@@ -78,7 +100,7 @@ public final class AutofillOptions implements Parcelable {
final AutofillOptions options = new AutofillOptions(
AutofillManager.FLAG_ADD_CLIENT_VERBOSE, /* compatModeAllowed= */ true);
- options.augmentedEnabled = true;
+ options.augmentedAutofillEnabled = true;
// Always log, as it's used by test only
Log.i(TAG, "forWhitelistingItself(" + packageName + "): " + options);
@@ -87,15 +109,19 @@ public final class AutofillOptions implements Parcelable {
@Override
public String toString() {
- return "AutofillOptions [loggingLevel=" + loggingLevel + ", compatMode="
- + compatModeEnabled + ", augmentedEnabled=" + augmentedEnabled + "]";
+ return "AutofillOptions [loggingLevel=" + loggingLevel + ", compatMode=" + compatModeEnabled
+ + ", augmentedAutofillEnabled=" + augmentedAutofillEnabled + "]";
}
/** @hide */
public void dumpShort(@NonNull PrintWriter pw) {
pw.print("logLvl="); pw.print(loggingLevel);
pw.print(", compatMode="); pw.print(compatModeEnabled);
- pw.print(", augmented="); pw.print(augmentedEnabled);
+ pw.print(", augmented="); pw.print(augmentedAutofillEnabled);
+ if (whitelistedActivitiesForAugmentedAutofill != null) {
+ pw.print(", whitelistedActivitiesForAugmentedAutofill=");
+ pw.print(whitelistedActivitiesForAugmentedAutofill);
+ }
}
@Override
@@ -107,7 +133,8 @@ public final class AutofillOptions implements Parcelable {
public void writeToParcel(Parcel parcel, int flags) {
parcel.writeInt(loggingLevel);
parcel.writeBoolean(compatModeEnabled);
- parcel.writeBoolean(augmentedEnabled);
+ parcel.writeBoolean(augmentedAutofillEnabled);
+ parcel.writeArraySet(whitelistedActivitiesForAugmentedAutofill);
}
public static final @android.annotation.NonNull Parcelable.Creator<AutofillOptions> CREATOR =
@@ -118,7 +145,9 @@ public final class AutofillOptions implements Parcelable {
final int loggingLevel = parcel.readInt();
final boolean compatMode = parcel.readBoolean();
final AutofillOptions options = new AutofillOptions(loggingLevel, compatMode);
- options.augmentedEnabled = parcel.readBoolean();
+ options.augmentedAutofillEnabled = parcel.readBoolean();
+ options.whitelistedActivitiesForAugmentedAutofill =
+ (ArraySet<ComponentName>) parcel.readArraySet(null);
return options;
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 1e4b1e7b45c6..fa85f0ae1670 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -623,7 +623,7 @@ public abstract class ContentResolver implements ContentInterface {
}
/** {@hide} */
- public static ContentResolver wrap(@NonNull ContentInterface wrapped) {
+ public static @NonNull ContentResolver wrap(@NonNull ContentInterface wrapped) {
Preconditions.checkNotNull(wrapped);
return new ContentResolver(null, wrapped) {
@@ -654,7 +654,7 @@ public abstract class ContentResolver implements ContentInterface {
* Create a {@link ContentResolver} instance that redirects all its methods
* to the given {@link ContentProvider}.
*/
- public static ContentResolver wrap(@NonNull ContentProvider wrapped) {
+ public static @NonNull ContentResolver wrap(@NonNull ContentProvider wrapped) {
return wrap((ContentInterface) wrapped);
}
@@ -662,7 +662,7 @@ public abstract class ContentResolver implements ContentInterface {
* Create a {@link ContentResolver} instance that redirects all its methods
* to the given {@link ContentProviderClient}.
*/
- public static ContentResolver wrap(@NonNull ContentProviderClient wrapped) {
+ public static @NonNull ContentResolver wrap(@NonNull ContentProviderClient wrapped) {
return wrap((ContentInterface) wrapped);
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index beb1fb68d218..4199528893e6 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -69,6 +69,7 @@ import android.view.View;
import android.view.ViewDebug;
import android.view.WindowManager;
import android.view.autofill.AutofillManager.AutofillClient;
+import android.view.contentcapture.ContentCaptureManager.ContentCaptureClient;
import android.view.textclassifier.TextClassificationManager;
import java.io.File;
@@ -5343,6 +5344,14 @@ public abstract class Context {
/**
* @hide
*/
+ @Nullable
+ public ContentCaptureClient getContentCaptureClient() {
+ return null;
+ }
+
+ /**
+ * @hide
+ */
public final boolean isAutofillCompatibilityEnabled() {
final AutofillOptions options = getAutofillOptions();
return options != null && options.compatModeEnabled;
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index d3b8e29d7399..0715572c03c0 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -2124,6 +2124,7 @@ public class Intent implements Parcelable, Cloneable {
* @hide
*/
@SystemApi
+ @RequiresPermission(android.Manifest.permission.REVIEW_ACCESSIBILITY_SERVICES)
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_REVIEW_ACCESSIBILITY_SERVICES =
"android.intent.action.REVIEW_ACCESSIBILITY_SERVICES";
diff --git a/core/java/android/content/LocusId.java b/core/java/android/content/LocusId.java
index 3d1ddc3ca77b..c67ff7caaf64 100644
--- a/core/java/android/content/LocusId.java
+++ b/core/java/android/content/LocusId.java
@@ -37,9 +37,11 @@ public final class LocusId implements Parcelable {
/**
* Default constructor.
+ *
+ * @throws IllegalArgumentException if {@code id} is empty or {@code null}.
*/
public LocusId(@NonNull String id) {
- mId = Preconditions.checkNotNull(id);
+ mId = Preconditions.checkStringNotEmpty(id, "id cannot be empty");
}
/**
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index a006f2374393..e516ed646f9a 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -45,6 +45,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.StringRes;
import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.app.ActivityTaskManager;
@@ -3260,10 +3261,21 @@ public class PackageParser {
private boolean parsePermissionGroup(Package owner, int flags, Resources res,
XmlResourceParser parser, String[] outError)
throws XmlPullParserException, IOException {
- PermissionGroup perm = new PermissionGroup(owner);
-
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestPermissionGroup);
+
+ int requestDetailResourceId = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_requestDetail, 0);
+ int backgroundRequestResourceId = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_backgroundRequest,
+ 0);
+ int backgroundRequestDetailResourceId = sa.getResourceId(
+ com.android.internal.R.styleable
+ .AndroidManifestPermissionGroup_backgroundRequestDetail, 0);
+
+ PermissionGroup perm = new PermissionGroup(owner, requestDetailResourceId,
+ backgroundRequestResourceId, backgroundRequestDetailResourceId);
+
if (!parsePackageItemInfo(owner, perm.info, outError,
"<permission-group>", sa, true /*nameRequired*/,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
@@ -3282,14 +3294,6 @@ public class PackageParser {
0);
perm.info.requestRes = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestPermissionGroup_request, 0);
- perm.info.requestDetailResourceId = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_requestDetail, 0);
- perm.info.backgroundRequestResourceId = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestPermissionGroup_backgroundRequest,
- 0);
- perm.info.backgroundRequestDetailResourceId = sa.getResourceId(
- com.android.internal.R.styleable
- .AndroidManifestPermissionGroup_backgroundRequestDetail, 0);
perm.info.flags = sa.getInt(
com.android.internal.R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags, 0);
perm.info.priority = sa.getInt(
@@ -7676,9 +7680,12 @@ public class PackageParser {
@UnsupportedAppUsage
public final PermissionGroupInfo info;
- public PermissionGroup(Package _owner) {
- super(_owner);
- info = new PermissionGroupInfo();
+ public PermissionGroup(Package owner, @StringRes int requestDetailResourceId,
+ @StringRes int backgroundRequestResourceId,
+ @StringRes int backgroundRequestDetailResourceId) {
+ super(owner);
+ info = new PermissionGroupInfo(requestDetailResourceId, backgroundRequestResourceId,
+ backgroundRequestDetailResourceId);
}
public PermissionGroup(Package _owner, PermissionGroupInfo _info) {
diff --git a/core/java/android/content/pm/PermissionGroupInfo.java b/core/java/android/content/pm/PermissionGroupInfo.java
index 3a87eca67ec9..e65e742cb6ec 100644
--- a/core/java/android/content/pm/PermissionGroupInfo.java
+++ b/core/java/android/content/pm/PermissionGroupInfo.java
@@ -16,12 +16,20 @@
package android.content.pm;
+import static android.content.res.Resources.ID_NULL;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.StringRes;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Information you can retrieve about a particular security permission
* group known to the system. This corresponds to information collected from the
@@ -33,7 +41,7 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
* permission's description. From the "description" attribute or,
* if not set, 0.
*/
- public int descriptionRes;
+ public @StringRes int descriptionRes;
/**
* A string resource identifier (in the package's resources) used to request the permissions.
@@ -54,7 +62,7 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
* @hide
*/
@SystemApi
- public @StringRes int requestDetailResourceId;
+ public final @StringRes int requestDetailResourceId;
/**
* A string resource identifier (in the package's resources) used when requesting background
@@ -66,7 +74,7 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
* @hide
*/
@SystemApi
- public @StringRes int backgroundRequestResourceId;
+ public final @StringRes int backgroundRequestResourceId;
/**
* A string resource identifier (in the package's resources) used as subtitle when requesting
@@ -78,7 +86,7 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
* @hide
*/
@SystemApi
- public @StringRes int backgroundRequestDetailResourceId;
+ public final @StringRes int backgroundRequestDetailResourceId;
/**
* The description string provided in the AndroidManifest file, if any. You
@@ -86,7 +94,7 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
* is in a resource. You probably want
* {@link PermissionInfo#loadDescription} instead.
*/
- public CharSequence nonLocalizedDescription;
+ public @Nullable CharSequence nonLocalizedDescription;
/**
* Flag for {@link #flags}, corresponding to <code>personalInfo</code>
@@ -94,21 +102,48 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
*/
public static final int FLAG_PERSONAL_INFO = 1<<0;
+ /** @hide */
+ @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+ FLAG_PERSONAL_INFO,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Flags {}
+
/**
* Additional flags about this group as given by
* {@link android.R.attr#permissionGroupFlags}.
*/
- public int flags;
+ public @Flags int flags;
/**
* Prioritization of this group, for visually sorting with other groups.
*/
public int priority;
+ /**
+ * @hide
+ */
+ public PermissionGroupInfo(@StringRes int requestDetailResourceId,
+ @StringRes int backgroundRequestResourceId,
+ @StringRes int backgroundRequestDetailResourceId) {
+ this.requestDetailResourceId = requestDetailResourceId;
+ this.backgroundRequestResourceId = backgroundRequestResourceId;
+ this.backgroundRequestDetailResourceId = backgroundRequestDetailResourceId;
+ }
+
+ /**
+ * @deprecated Should only be created by the system.
+ */
+ @Deprecated
public PermissionGroupInfo() {
+ this(ID_NULL, ID_NULL, ID_NULL);
}
- public PermissionGroupInfo(PermissionGroupInfo orig) {
+ /**
+ * @deprecated Should only be created by the system.
+ */
+ @Deprecated
+ public PermissionGroupInfo(@NonNull PermissionGroupInfo orig) {
super(orig);
descriptionRes = orig.descriptionRes;
requestRes = orig.requestRes;
@@ -131,7 +166,7 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
* @return Returns a CharSequence containing the permission's description.
* If there is no description, null is returned.
*/
- public CharSequence loadDescription(PackageManager pm) {
+ public @Nullable CharSequence loadDescription(@NonNull PackageManager pm) {
if (nonLocalizedDescription != null) {
return nonLocalizedDescription;
}
@@ -166,7 +201,7 @@ public class PermissionGroupInfo extends PackageItemInfo implements Parcelable {
dest.writeInt(priority);
}
- public static final @android.annotation.NonNull Creator<PermissionGroupInfo> CREATOR =
+ public static final @NonNull Creator<PermissionGroupInfo> CREATOR =
new Creator<PermissionGroupInfo>() {
public PermissionGroupInfo createFromParcel(Parcel source) {
return new PermissionGroupInfo(source);
diff --git a/core/java/android/hardware/biometrics/BiometricConstants.java b/core/java/android/hardware/biometrics/BiometricConstants.java
index 1cb7eb0d1256..27c04b407315 100644
--- a/core/java/android/hardware/biometrics/BiometricConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricConstants.java
@@ -128,7 +128,7 @@ public interface BiometricConstants {
/**
* The device does not have pin, pattern, or password set up. See
- * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and
+ * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
* {@link KeyguardManager#isDeviceSecure()}
*/
int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
diff --git a/core/java/android/hardware/biometrics/BiometricFaceConstants.java b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
index 459ec62d4135..3602a3379e0e 100644
--- a/core/java/android/hardware/biometrics/BiometricFaceConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFaceConstants.java
@@ -136,7 +136,7 @@ public interface BiometricFaceConstants {
/**
* The device does not have pin, pattern, or password set up. See
- * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and
+ * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
* {@link KeyguardManager#isDeviceSecure()}
*/
public static final int BIOMETRIC_ERROR_NO_DEVICE_CREDENTIAL = 14;
diff --git a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
index 6cbab471ce23..b025508fc70e 100644
--- a/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
+++ b/core/java/android/hardware/biometrics/BiometricFingerprintConstants.java
@@ -121,7 +121,7 @@ public interface BiometricFingerprintConstants {
/**
* The device does not have pin, pattern, or password set up. See
- * {@link BiometricPrompt.Builder#setAllowDeviceCredential(boolean)} and
+ * {@link BiometricPrompt.Builder#setDeviceCredentialAllowed(boolean)} and
* {@link KeyguardManager#isDeviceSecure()}
* @hide
*/
diff --git a/core/java/android/hardware/biometrics/BiometricPrompt.java b/core/java/android/hardware/biometrics/BiometricPrompt.java
index c64e48f44fd9..e751b2c77dbb 100644
--- a/core/java/android/hardware/biometrics/BiometricPrompt.java
+++ b/core/java/android/hardware/biometrics/BiometricPrompt.java
@@ -204,7 +204,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* "Cancel" button, but may be also used to show an alternative method for authentication,
* such as screen that asks for a backup password.
*
- * Note that this should not be set if {@link #setAllowDeviceCredential(boolean)
+ * Note that this should not be set if {@link #setDeviceCredentialAllowed(boolean)}(boolean)
* is set to true.
*
* @param text
@@ -245,7 +245,7 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
*
* @param requireConfirmation
*/
- @NonNull public Builder setRequireConfirmation(boolean requireConfirmation) {
+ @NonNull public Builder setConfirmationRequired(boolean requireConfirmation) {
mBundle.putBoolean(KEY_REQUIRE_CONFIRMATION, requireConfirmation);
return this;
}
@@ -261,12 +261,12 @@ public class BiometricPrompt implements BiometricAuthenticator, BiometricConstan
* Note that {@link #setNegativeButton(CharSequence, Executor,
* DialogInterface.OnClickListener)} should not be set if this is set to true.
*
- * @param enable When true, the prompt will fall back to ask for the user's device
+ * @param allowed When true, the prompt will fall back to ask for the user's device
* credentials (PIN, pattern, or password).
* @return
*/
- @NonNull public Builder setAllowDeviceCredential(boolean enable) {
- mBundle.putBoolean(KEY_ALLOW_DEVICE_CREDENTIAL, enable);
+ @NonNull public Builder setDeviceCredentialAllowed(boolean allowed) {
+ mBundle.putBoolean(KEY_ALLOW_DEVICE_CREDENTIAL, allowed);
return this;
}
diff --git a/core/java/android/os/IncidentReportArgs.java b/core/java/android/os/IncidentReportArgs.java
index 1bdfd945c5b0..a1f2430f4ee3 100644
--- a/core/java/android/os/IncidentReportArgs.java
+++ b/core/java/android/os/IncidentReportArgs.java
@@ -36,6 +36,8 @@ public final class IncidentReportArgs implements Parcelable {
private final ArrayList<byte[]> mHeaders = new ArrayList<byte[]>();
private boolean mAll;
private int mPrivacyPolicy;
+ private String mReceiverPkg;
+ private String mReceiverCls;
/**
* Construct an incident report args with no fields.
@@ -73,6 +75,10 @@ public final class IncidentReportArgs implements Parcelable {
}
out.writeInt(mPrivacyPolicy);
+
+ out.writeString(mReceiverPkg);
+
+ out.writeString(mReceiverCls);
}
public void readFromParcel(Parcel in) {
@@ -91,6 +97,10 @@ public final class IncidentReportArgs implements Parcelable {
}
mPrivacyPolicy = in.readInt();
+
+ mReceiverPkg = in.readString();
+
+ mReceiverCls = in.readString();
}
public static final @android.annotation.NonNull Parcelable.Creator<IncidentReportArgs> CREATOR
@@ -126,6 +136,8 @@ public final class IncidentReportArgs implements Parcelable {
sb.append(mHeaders.size());
sb.append(" headers), ");
sb.append("privacy: ").append(mPrivacyPolicy);
+ sb.append("receiver pkg: ").append(mReceiverPkg);
+ sb.append("receiver cls: ").append(mReceiverCls);
return sb.toString();
}
diff --git a/core/java/android/os/UserHandle.java b/core/java/android/os/UserHandle.java
index 82d1b1a5a631..286185b8bda5 100644
--- a/core/java/android/os/UserHandle.java
+++ b/core/java/android/os/UserHandle.java
@@ -17,6 +17,7 @@
package android.os;
import android.annotation.AppIdInt;
+import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.annotation.TestApi;
import android.annotation.UserIdInt;
@@ -40,7 +41,7 @@ public final class UserHandle implements Parcelable {
/** @hide A user handle to indicate all users on the device */
@SystemApi
@TestApi
- public static final UserHandle ALL = new UserHandle(USER_ALL);
+ public static final @NonNull UserHandle ALL = new UserHandle(USER_ALL);
/** @hide A user id to indicate the currently active user */
public static final @UserIdInt int USER_CURRENT = -2;
@@ -48,7 +49,7 @@ public final class UserHandle implements Parcelable {
/** @hide A user handle to indicate the current user of the device */
@SystemApi
@TestApi
- public static final UserHandle CURRENT = new UserHandle(USER_CURRENT);
+ public static final @NonNull UserHandle CURRENT = new UserHandle(USER_CURRENT);
/** @hide A user id to indicate that we would like to send to the current
* user, but if this is calling from a user process then we will send it
@@ -58,7 +59,7 @@ public final class UserHandle implements Parcelable {
/** @hide A user handle to indicate that we would like to send to the current
* user, but if this is calling from a user process then we will send it
* to the caller's user instead of failing with a security exception */
- public static final UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);
+ public static final @NonNull UserHandle CURRENT_OR_SELF = new UserHandle(USER_CURRENT_OR_SELF);
/** @hide An undefined user id */
public static final @UserIdInt int USER_NULL = -10000;
@@ -77,7 +78,7 @@ public final class UserHandle implements Parcelable {
* check the target user's flag {@link android.content.pm.UserInfo#isAdmin}.
*/
@Deprecated
- public static final UserHandle OWNER = new UserHandle(USER_OWNER);
+ public static final @NonNull UserHandle OWNER = new UserHandle(USER_OWNER);
/** @hide A user id constant to indicate the "system" user of the device */
public static final @UserIdInt int USER_SYSTEM = 0;
@@ -88,7 +89,7 @@ public final class UserHandle implements Parcelable {
/** @hide A user handle to indicate the "system" user of the device */
@SystemApi
@TestApi
- public static final UserHandle SYSTEM = new UserHandle(USER_SYSTEM);
+ public static final @NonNull UserHandle SYSTEM = new UserHandle(USER_SYSTEM);
/**
* @hide Enable multi-user related side effects. Set this to false if
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 7f73dab82d88..42633778a321 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -2705,7 +2705,7 @@ public class UserManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public void setUserName(String name) {
+ public void setUserName(@Nullable String name) {
setUserName(getUserHandle(), name);
}
@@ -2732,7 +2732,7 @@ public class UserManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public void setUserIcon(Bitmap icon) {
+ public void setUserIcon(@NonNull Bitmap icon) {
setUserIcon(getUserHandle(), icon);
}
@@ -2772,7 +2772,7 @@ public class UserManager {
*/
@SystemApi
@RequiresPermission(android.Manifest.permission.MANAGE_USERS)
- public Bitmap getUserIcon() {
+ public @Nullable Bitmap getUserIcon() {
return getUserIcon(getUserHandle());
}
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 44add87da609..c74cbff567c5 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -17,6 +17,7 @@
package android.os;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.TestApi;
import android.content.ContentResolver;
@@ -240,6 +241,7 @@ public abstract class VibrationEffect implements Parcelable {
*
* @return The desired effect.
*/
+ @NonNull
public static VibrationEffect createPredefined(@EffectType int effectId) {
return get(effectId, true);
}
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index 49567b29f710..4632b7553ca0 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -1252,7 +1252,8 @@ public final class DocumentsContract {
* {@hide}
*/
@SystemApi
- public static Uri setManageMode(Uri uri) {
+ public static @NonNull Uri setManageMode(@NonNull Uri uri) {
+ Preconditions.checkNotNull(uri, "uri can not be null");
return uri.buildUpon().appendQueryParameter(PARAM_MANAGE, "true").build();
}
@@ -1262,7 +1263,8 @@ public final class DocumentsContract {
* {@hide}
*/
@SystemApi
- public static boolean isManageMode(Uri uri) {
+ public static boolean isManageMode(@NonNull Uri uri) {
+ Preconditions.checkNotNull(uri, "uri can not be null");
return uri.getBooleanQueryParameter(PARAM_MANAGE, false);
}
diff --git a/core/java/android/provider/DocumentsProvider.java b/core/java/android/provider/DocumentsProvider.java
index 9b9e2dee8f9b..cb794ad023e3 100644
--- a/core/java/android/provider/DocumentsProvider.java
+++ b/core/java/android/provider/DocumentsProvider.java
@@ -487,10 +487,12 @@ public abstract class DocumentsProvider extends ContentProvider {
* @see DocumentsContract#EXTRA_LOADING
*/
@SuppressWarnings("unused")
+ @Nullable
public Cursor queryRecentDocuments(
- String rootId, String[] projection, @Nullable Bundle queryArgs,
- @Nullable CancellationSignal signal)
- throws FileNotFoundException {
+ @NonNull String rootId, @Nullable String[] projection, @Nullable Bundle queryArgs,
+ @Nullable CancellationSignal signal) throws FileNotFoundException {
+ Preconditions.checkNotNull(rootId, "rootId can not be null");
+
Cursor c = queryRecentDocuments(rootId, projection);
Bundle extras = new Bundle();
c.setExtras(extras);
@@ -697,8 +699,9 @@ public abstract class DocumentsProvider extends ContentProvider {
* @see DocumentsContract#EXTRA_ERROR
*/
@SuppressWarnings("unused")
- public Cursor querySearchDocuments(@NonNull String rootId, @Nullable String[] projection,
- @NonNull Bundle queryArgs) throws FileNotFoundException {
+ @Nullable
+ public Cursor querySearchDocuments(@NonNull String rootId,
+ @Nullable String[] projection, @NonNull Bundle queryArgs) throws FileNotFoundException {
Preconditions.checkNotNull(rootId, "rootId can not be null");
Preconditions.checkNotNull(queryArgs, "queryArgs can not be null");
return querySearchDocuments(rootId, DocumentsContract.getSearchDocumentsQuery(queryArgs),
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 917b5c2615db..14863338f182 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -98,7 +98,7 @@ public final class MediaStore {
/** The authority for the media provider */
public static final String AUTHORITY = "media";
/** A content:// style uri to the authority for the media provider */
- public static final Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
+ public static final @NonNull Uri AUTHORITY_URI = Uri.parse("content://" + AUTHORITY);
/**
* Volume name used for content on "internal" storage of device. This
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 45219d6f2e33..6c2a2a55a42c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -8017,9 +8017,9 @@ public final class Settings {
/**
* Whether or not face unlock always requires user confirmation, meaning {@link
- * android.hardware.biometrics.BiometricPrompt.Builder#setRequireConfirmation(boolean)}
+ * android.hardware.biometrics.BiometricPrompt.Builder#setConfirmationRequired(boolean)}
* is always 'true'. This overrides the behavior that apps choose in the
- * setRequireConfirmation API.
+ * setConfirmationRequired API.
* @hide
*/
public static final String FACE_UNLOCK_ALWAYS_REQUIRE_CONFIRMATION =
@@ -10684,7 +10684,7 @@ public final class Settings {
/**
* Setting to enable the Wi-Fi link probing.
- * Disabled by default, and setting it to 1 will enable it.
+ * Enabled by default, and setting it to 0 will disable it.
* The value is boolean (0 or 1).
* @hide
*/
@@ -11137,8 +11137,9 @@ public final class Settings {
/**
* The threshold value for the number of consecutive dns timeout events received to be a
- * signal of data stall. Set the value to 0 or less than 0 to disable. Note that the value
- * should be larger than 0 if the DNS data stall detection is enabled.
+ * signal of data stall. The number of consecutive timeouts needs to be {@code >=} this
+ * threshold to be considered a data stall. Set the value to {@code <= 0} to disable. Note
+ * that the value should be {@code > 0} if the DNS data stall detection is enabled.
*
* @hide
*/
@@ -11169,9 +11170,12 @@ public final class Settings {
"data_stall_valid_dns_time_threshold";
/**
- * Which data stall detection signal to use. Possible values are a union of the powers of 2
- * of DATA_STALL_EVALUATION_TYPE_*.
+ * Which data stall detection signal to use. This is a bitmask constructed by bitwise-or-ing
+ * (i.e. {@code |}) the DATA_STALL_EVALUATION_TYPE_* values.
*
+ * Type: int
+ * Valid values:
+ * {@link #DATA_STALL_EVALUATION_TYPE_DNS} : Use dns as a signal.
* @hide
*/
@SystemApi
@@ -11179,6 +11183,15 @@ public final class Settings {
public static final String DATA_STALL_EVALUATION_TYPE = "data_stall_evaluation_type";
/**
+ * Use dns timeout counts to detect data stall.
+ *
+ * @hide
+ */
+ @SystemApi
+ @TestApi
+ public static final int DATA_STALL_EVALUATION_TYPE_DNS = 1;
+
+ /**
* Whether to try cellular data recovery when a bad network is reported.
*
* @hide
@@ -11453,6 +11466,15 @@ public final class Settings {
"background_activity_starts_enabled";
/**
+ * The packages temporarily whitelisted to be able so start activities from background.
+ * The list of packages is {@code ":"} colon delimited.
+ *
+ * @hide
+ */
+ public static final String BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST =
+ "background_activity_starts_package_names_whitelist";
+
+ /**
* @hide
* @see com.android.server.appbinding.AppBindingConstants
*/
diff --git a/core/java/android/service/carrier/CarrierIdentifier.java b/core/java/android/service/carrier/CarrierIdentifier.java
index 3a57e3ad4239..3b7392fcb052 100644
--- a/core/java/android/service/carrier/CarrierIdentifier.java
+++ b/core/java/android/service/carrier/CarrierIdentifier.java
@@ -16,6 +16,7 @@
package android.service.carrier;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -74,7 +75,7 @@ public class CarrierIdentifier implements Parcelable {
* @param preciseCarrierId precise carrier identifier
* {@link TelephonyManager#getSimPreciseCarrierId()}
*/
- public CarrierIdentifier(String mcc, String mnc, @Nullable String spn,
+ public CarrierIdentifier(@NonNull String mcc, @NonNull String mnc, @Nullable String spn,
@Nullable String imsi, @Nullable String gid1, @Nullable String gid2,
int carrierid, int preciseCarrierId) {
mMcc = mcc;
diff --git a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
index 40333bf7709e..28143003fcc4 100644
--- a/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
+++ b/core/java/android/service/contentsuggestions/ContentSuggestionsService.java
@@ -52,6 +52,10 @@ public abstract class ContentSuggestionsService extends Service {
/**
* The action for the intent used to define the content suggestions service.
+ *
+ * <p>To be supported, the service must also require the
+ * * {@link android.Manifest.permission#BIND_CONTENT_SUGGESTIONS_SERVICE} permission so
+ * * that other applications can not abuse it.
*/
public static final String SERVICE_INTERFACE =
"android.service.contentsuggestions.ContentSuggestionsService";
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index 56d22d097a5c..ceb21e7d418a 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -68,7 +68,14 @@ public abstract class NotificationAssistantService extends NotificationListenerS
@Retention(SOURCE)
@IntDef({SOURCE_FROM_APP, SOURCE_FROM_ASSISTANT})
public @interface Source {}
+
+ /**
+ * To indicate an adjustment is from an app.
+ */
public static final int SOURCE_FROM_APP = 0;
+ /**
+ * To indicate an adjustment is from a {@link NotificationAssistantService}.
+ */
public static final int SOURCE_FROM_ASSISTANT = 1;
/**
diff --git a/core/java/android/service/notification/ZenPolicy.java b/core/java/android/service/notification/ZenPolicy.java
index 74e6c6e29e00..96949985cb84 100644
--- a/core/java/android/service/notification/ZenPolicy.java
+++ b/core/java/android/service/notification/ZenPolicy.java
@@ -17,6 +17,7 @@
package android.service.notification;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.app.Notification;
import android.app.NotificationChannel;
import android.os.Parcel;
@@ -357,7 +358,7 @@ public final class ZenPolicy implements Parcelable {
* Provides a convenient way to set the various fields of a {@link ZenPolicy}. If a field
* is not set, it is (@link STATE_UNSET} and will not change the current set policy.
*/
- public static class Builder {
+ public static final class Builder {
private ZenPolicy mZenPolicy;
public Builder() {
@@ -378,14 +379,14 @@ public final class ZenPolicy implements Parcelable {
/**
* Builds the current ZenPolicy.
*/
- public ZenPolicy build() {
+ public @NonNull ZenPolicy build() {
return mZenPolicy.copy();
}
/**
* Allows all notifications to bypass DND and unmutes all streams.
*/
- public Builder allowAllSounds() {
+ public @NonNull Builder allowAllSounds() {
for (int i = 0; i < mZenPolicy.mPriorityCategories.size(); i++) {
mZenPolicy.mPriorityCategories.set(i, STATE_ALLOW);
}
@@ -401,7 +402,7 @@ public final class ZenPolicy implements Parcelable {
* {@link NotificationChannel#canBypassDnd can bypass DND}. If no channels can bypass DND,
* the ringer stream is also muted.
*/
- public Builder disallowAllSounds() {
+ public @NonNull Builder disallowAllSounds() {
for (int i = 0; i < mZenPolicy.mPriorityCategories.size(); i++) {
mZenPolicy.mPriorityCategories.set(i, STATE_DISALLOW);
}
@@ -413,7 +414,7 @@ public final class ZenPolicy implements Parcelable {
/**
* Allows notifications intercepted by DND to show on all surfaces when DND is active.
*/
- public Builder showAllVisualEffects() {
+ public @NonNull Builder showAllVisualEffects() {
for (int i = 0; i < mZenPolicy.mVisualEffects.size(); i++) {
mZenPolicy.mVisualEffects.set(i, STATE_ALLOW);
}
@@ -423,7 +424,7 @@ public final class ZenPolicy implements Parcelable {
/**
* Disallows notifications intercepted by DND from showing when DND is active.
*/
- public Builder hideAllVisualEffects() {
+ public @NonNull Builder hideAllVisualEffects() {
for (int i = 0; i < mZenPolicy.mVisualEffects.size(); i++) {
mZenPolicy.mVisualEffects.set(i, STATE_DISALLOW);
}
@@ -435,7 +436,7 @@ public final class ZenPolicy implements Parcelable {
* unset categories will default to the current applied policy.
* @hide
*/
- public Builder unsetPriorityCategory(@PriorityCategory int category) {
+ public @NonNull Builder unsetPriorityCategory(@PriorityCategory int category) {
mZenPolicy.mPriorityCategories.set(category, STATE_UNSET);
if (category == PRIORITY_CATEGORY_MESSAGES) {
@@ -452,7 +453,7 @@ public final class ZenPolicy implements Parcelable {
* unset effects will default to the current applied policy.
* @hide
*/
- public Builder unsetVisualEffect(@VisualEffect int effect) {
+ public @NonNull Builder unsetVisualEffect(@VisualEffect int effect) {
mZenPolicy.mVisualEffects.set(effect, STATE_UNSET);
return this;
}
@@ -461,7 +462,7 @@ public final class ZenPolicy implements Parcelable {
* Whether to allow notifications with category {@link Notification#CATEGORY_REMINDER}
* to play sounds and visually appear or to intercept them when DND is active.
*/
- public Builder allowReminders(boolean allow) {
+ public @NonNull Builder allowReminders(boolean allow) {
mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_REMINDERS,
allow ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -471,7 +472,7 @@ public final class ZenPolicy implements Parcelable {
* Whether to allow notifications with category {@link Notification#CATEGORY_EVENT}
* to play sounds and visually appear or to intercept them when DND is active.
*/
- public Builder allowEvents(boolean allow) {
+ public @NonNull Builder allowEvents(boolean allow) {
mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_EVENTS,
allow ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -483,7 +484,7 @@ public final class ZenPolicy implements Parcelable {
* them when DND is active.
* @param audienceType message senders that are allowed to bypass DND
*/
- public Builder allowMessages(@PeopleType int audienceType) {
+ public @NonNull Builder allowMessages(@PeopleType int audienceType) {
if (audienceType == STATE_UNSET) {
return unsetPriorityCategory(PRIORITY_CATEGORY_MESSAGES);
}
@@ -507,7 +508,7 @@ public final class ZenPolicy implements Parcelable {
* them when DND is active.
* @param audienceType callers that are allowed to bypass DND
*/
- public Builder allowCalls(@PeopleType int audienceType) {
+ public @NonNull Builder allowCalls(@PeopleType int audienceType) {
if (audienceType == STATE_UNSET) {
return unsetPriorityCategory(PRIORITY_CATEGORY_CALLS);
}
@@ -530,7 +531,7 @@ public final class ZenPolicy implements Parcelable {
* {@link Notification#CATEGORY_CALL} that have recently called
* to play sounds and visually appear.
*/
- public Builder allowRepeatCallers(boolean allow) {
+ public @NonNull Builder allowRepeatCallers(boolean allow) {
mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_REPEAT_CALLERS,
allow ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -542,7 +543,7 @@ public final class ZenPolicy implements Parcelable {
* to play sounds and visually appear or to intercept them when DND is active.
* Disallowing alarms will mute the alarm stream when DND is active.
*/
- public Builder allowAlarms(boolean allow) {
+ public @NonNull Builder allowAlarms(boolean allow) {
mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_ALARMS,
allow ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -553,7 +554,7 @@ public final class ZenPolicy implements Parcelable {
* appear or to intercept them when DND is active.
* Disallowing media will mute the media stream when DND is active.
*/
- public Builder allowMedia(boolean allow) {
+ public @NonNull Builder allowMedia(boolean allow) {
mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_MEDIA,
allow ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -563,7 +564,7 @@ public final class ZenPolicy implements Parcelable {
* Whether to allow system sounds to play when DND is active.
* Disallowing system sounds will mute the system stream when DND is active.
*/
- public Builder allowSystem(boolean allow) {
+ public @NonNull Builder allowSystem(boolean allow) {
mZenPolicy.mPriorityCategories.set(PRIORITY_CATEGORY_SYSTEM,
allow ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -573,7 +574,7 @@ public final class ZenPolicy implements Parcelable {
* Whether to allow {@link PriorityCategory} sounds to play when DND is active.
* @hide
*/
- public Builder allowCategory(@PriorityCategory int category, boolean allow) {
+ public @NonNull Builder allowCategory(@PriorityCategory int category, boolean allow) {
switch (category) {
case PRIORITY_CATEGORY_ALARMS:
allowAlarms(allow);
@@ -601,7 +602,7 @@ public final class ZenPolicy implements Parcelable {
* Whether {@link Notification#fullScreenIntent full screen intents} that are intercepted
* by DND are shown.
*/
- public Builder showFullScreenIntent(boolean show) {
+ public @NonNull Builder showFullScreenIntent(boolean show) {
mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_FULL_SCREEN_INTENT,
show ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -611,7 +612,7 @@ public final class ZenPolicy implements Parcelable {
* Whether {@link NotificationChannel#shouldShowLights() notification lights} from
* notifications intercepted by DND are blocked.
*/
- public Builder showLights(boolean show) {
+ public @NonNull Builder showLights(boolean show) {
mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_LIGHTS,
show ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -620,7 +621,7 @@ public final class ZenPolicy implements Parcelable {
/**
* Whether notifications intercepted by DND are prevented from peeking.
*/
- public Builder showPeeking(boolean show) {
+ public @NonNull Builder showPeeking(boolean show) {
mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_PEEK,
show ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -630,7 +631,7 @@ public final class ZenPolicy implements Parcelable {
* Whether notifications intercepted by DND are prevented from appearing in the status bar
* on devices that support status bars.
*/
- public Builder showStatusBarIcons(boolean show) {
+ public @NonNull Builder showStatusBarIcons(boolean show) {
mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_STATUS_BAR,
show ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -640,7 +641,7 @@ public final class ZenPolicy implements Parcelable {
* Whether {@link NotificationChannel#canShowBadge() badges} from
* notifications intercepted by DND are allowed on devices that support badging.
*/
- public Builder showBadges(boolean show) {
+ public @NonNull Builder showBadges(boolean show) {
mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_BADGE,
show ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -650,7 +651,7 @@ public final class ZenPolicy implements Parcelable {
* Whether notification intercepted by DND are prevented from appearing on ambient displays
* on devices that support ambient display.
*/
- public Builder showInAmbientDisplay(boolean show) {
+ public @NonNull Builder showInAmbientDisplay(boolean show) {
mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_AMBIENT,
show ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -661,7 +662,7 @@ public final class ZenPolicy implements Parcelable {
* list views like the notification shade or lockscreen on devices that support those
* views.
*/
- public Builder showInNotificationList(boolean show) {
+ public @NonNull Builder showInNotificationList(boolean show) {
mZenPolicy.mVisualEffects.set(VISUAL_EFFECT_NOTIFICATION_LIST,
show ? STATE_ALLOW : STATE_DISALLOW);
return this;
@@ -672,7 +673,7 @@ public final class ZenPolicy implements Parcelable {
* {@link VisualEffect}
* @hide
*/
- public Builder showVisualEffect(@VisualEffect int effect, boolean show) {
+ public @NonNull Builder showVisualEffect(@VisualEffect int effect, boolean show) {
switch (effect) {
case VISUAL_EFFECT_FULL_SCREEN_INTENT:
showFullScreenIntent(show);
@@ -1001,7 +1002,7 @@ public final class ZenPolicy implements Parcelable {
* Makes deep copy of this ZenPolicy.
* @hide
*/
- public ZenPolicy copy() {
+ public @NonNull ZenPolicy copy() {
final Parcel parcel = Parcel.obtain();
try {
writeToParcel(parcel, 0);
diff --git a/core/java/android/service/textclassifier/IConversationActionsCallback.aidl b/core/java/android/service/textclassifier/IConversationActionsCallback.aidl
deleted file mode 100644
index c35d4246e924..000000000000
--- a/core/java/android/service/textclassifier/IConversationActionsCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.textclassifier;
-
-import android.view.textclassifier.ConversationActions;
-
-/**
- * Callback for a ConversationActions request.
- * @hide
- */
-oneway interface IConversationActionsCallback {
- void onSuccess(in ConversationActions conversationActions);
- void onFailure();
-} \ No newline at end of file
diff --git a/core/java/android/service/textclassifier/ITextClassificationCallback.aidl b/core/java/android/service/textclassifier/ITextClassificationCallback.aidl
deleted file mode 100644
index 10bfe6324509..000000000000
--- a/core/java/android/service/textclassifier/ITextClassificationCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.textclassifier;
-
-import android.view.textclassifier.TextClassification;
-
-/**
- * Callback for a TextClassification request.
- * @hide
- */
-oneway interface ITextClassificationCallback {
- void onSuccess(in TextClassification classification);
- void onFailure();
-}
diff --git a/core/java/android/service/textclassifier/ITextSelectionCallback.aidl b/core/java/android/service/textclassifier/ITextClassifierCallback.aidl
index 1b4c4d10d427..2926734086a5 100644
--- a/core/java/android/service/textclassifier/ITextSelectionCallback.aidl
+++ b/core/java/android/service/textclassifier/ITextClassifierCallback.aidl
@@ -16,13 +16,14 @@
package android.service.textclassifier;
+import android.os.Bundle;
import android.view.textclassifier.TextSelection;
/**
- * Callback for a TextSelection request.
+ * Callback for all requests from SystemTextClassifier.
* @hide
*/
-oneway interface ITextSelectionCallback {
- void onSuccess(in TextSelection selection);
+oneway interface ITextClassifierCallback {
+ void onSuccess(in Bundle result);
void onFailure();
} \ No newline at end of file
diff --git a/core/java/android/service/textclassifier/ITextClassifierService.aidl b/core/java/android/service/textclassifier/ITextClassifierService.aidl
index 794179415fc0..2f8d67b6ccee 100644
--- a/core/java/android/service/textclassifier/ITextClassifierService.aidl
+++ b/core/java/android/service/textclassifier/ITextClassifierService.aidl
@@ -16,11 +16,7 @@
package android.service.textclassifier;
-import android.service.textclassifier.IConversationActionsCallback;
-import android.service.textclassifier.ITextClassificationCallback;
-import android.service.textclassifier.ITextLanguageCallback;
-import android.service.textclassifier.ITextLinksCallback;
-import android.service.textclassifier.ITextSelectionCallback;
+import android.service.textclassifier.ITextClassifierCallback;
import android.view.textclassifier.ConversationActions;
import android.view.textclassifier.SelectionEvent;
import android.view.textclassifier.TextClassification;
@@ -41,17 +37,17 @@ oneway interface ITextClassifierService {
void onSuggestSelection(
in TextClassificationSessionId sessionId,
in TextSelection.Request request,
- in ITextSelectionCallback callback);
+ in ITextClassifierCallback callback);
void onClassifyText(
in TextClassificationSessionId sessionId,
in TextClassification.Request request,
- in ITextClassificationCallback callback);
+ in ITextClassifierCallback callback);
void onGenerateLinks(
in TextClassificationSessionId sessionId,
in TextLinks.Request request,
- in ITextLinksCallback callback);
+ in ITextClassifierCallback callback);
// TODO: Remove
void onSelectionEvent(
@@ -72,10 +68,10 @@ oneway interface ITextClassifierService {
void onDetectLanguage(
in TextClassificationSessionId sessionId,
in TextLanguage.Request request,
- in ITextLanguageCallback callback);
+ in ITextClassifierCallback callback);
void onSuggestConversationActions(
in TextClassificationSessionId sessionId,
in ConversationActions.Request request,
- in IConversationActionsCallback callback);
+ in ITextClassifierCallback callback);
}
diff --git a/core/java/android/service/textclassifier/ITextLanguageCallback.aidl b/core/java/android/service/textclassifier/ITextLanguageCallback.aidl
deleted file mode 100644
index 263d99afca5c..000000000000
--- a/core/java/android/service/textclassifier/ITextLanguageCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.textclassifier;
-
-import android.view.textclassifier.TextLanguage;
-
-/**
- * Callback for a TextLanguage request.
- * @hide
- */
-oneway interface ITextLanguageCallback {
- void onSuccess(in TextLanguage textLanguage);
- void onFailure();
-} \ No newline at end of file
diff --git a/core/java/android/service/textclassifier/ITextLinksCallback.aidl b/core/java/android/service/textclassifier/ITextLinksCallback.aidl
deleted file mode 100644
index a9e0dde56773..000000000000
--- a/core/java/android/service/textclassifier/ITextLinksCallback.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.textclassifier;
-
-import android.view.textclassifier.TextLinks;
-
-/**
- * Callback for a TextLinks request.
- * @hide
- */
-oneway interface ITextLinksCallback {
- void onSuccess(in TextLinks links);
- void onFailure();
-} \ No newline at end of file
diff --git a/core/java/android/service/textclassifier/TextClassifierService.java b/core/java/android/service/textclassifier/TextClassifierService.java
index 235b8e8c9176..4088ce8ea4b0 100644
--- a/core/java/android/service/textclassifier/TextClassifierService.java
+++ b/core/java/android/service/textclassifier/TextClassifierService.java
@@ -17,6 +17,7 @@
package android.service.textclassifier;
import android.Manifest;
+import android.annotation.MainThread;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -27,8 +28,12 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.text.TextUtils;
import android.util.Slog;
@@ -46,6 +51,10 @@ import android.view.textclassifier.TextSelection;
import com.android.internal.util.Preconditions;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
/**
* Abstract base class for the TextClassifier service.
*
@@ -68,6 +77,11 @@ import com.android.internal.util.Preconditions;
* </intent-filter>
* </service>}</pre>
*
+ * <p>From {@link android.os.Build.VERSION_CODES#Q} onward, all callbacks are called on the main
+ * thread. Prior to Q, there is no guarantee on what thread the callback will happen. You should
+ * make sure the callbacks are executed in your desired thread by using a executor, a handler or
+ * something else along the line.
+ *
* @see TextClassifier
* @hide
*/
@@ -85,201 +99,102 @@ public abstract class TextClassifierService extends Service {
public static final String SERVICE_INTERFACE =
"android.service.textclassifier.TextClassifierService";
+ /** @hide **/
+ private static final String KEY_RESULT = "key_result";
+
+ private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper(), null, true);
+ private final ExecutorService mSingleThreadExecutor = Executors.newSingleThreadExecutor();
+
private final ITextClassifierService.Stub mBinder = new ITextClassifierService.Stub() {
// TODO(b/72533911): Implement cancellation signal
@NonNull private final CancellationSignal mCancellationSignal = new CancellationSignal();
- /** {@inheritDoc} */
@Override
public void onSuggestSelection(
TextClassificationSessionId sessionId,
- TextSelection.Request request, ITextSelectionCallback callback) {
+ TextSelection.Request request, ITextClassifierCallback callback) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
- TextClassifierService.this.onSuggestSelection(
- sessionId, request, mCancellationSignal,
- new Callback<TextSelection>() {
- @Override
- public void onSuccess(TextSelection result) {
- try {
- callback.onSuccess(result);
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
-
- @Override
- public void onFailure(CharSequence error) {
- try {
- if (callback.asBinder().isBinderAlive()) {
- callback.onFailure();
- }
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
- });
+ mMainThreadHandler.post(() -> TextClassifierService.this.onSuggestSelection(
+ sessionId, request, mCancellationSignal, new ProxyCallback<>(callback)));
+
}
- /** {@inheritDoc} */
@Override
public void onClassifyText(
TextClassificationSessionId sessionId,
- TextClassification.Request request, ITextClassificationCallback callback) {
+ TextClassification.Request request, ITextClassifierCallback callback) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
- TextClassifierService.this.onClassifyText(
- sessionId, request, mCancellationSignal,
- new Callback<TextClassification>() {
- @Override
- public void onSuccess(TextClassification result) {
- try {
- callback.onSuccess(result);
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
-
- @Override
- public void onFailure(CharSequence error) {
- try {
- callback.onFailure();
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
- });
+ mMainThreadHandler.post(() -> TextClassifierService.this.onClassifyText(
+ sessionId, request, mCancellationSignal, new ProxyCallback<>(callback)));
}
- /** {@inheritDoc} */
@Override
public void onGenerateLinks(
TextClassificationSessionId sessionId,
- TextLinks.Request request, ITextLinksCallback callback) {
+ TextLinks.Request request, ITextClassifierCallback callback) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
- TextClassifierService.this.onGenerateLinks(
- sessionId, request,
- mCancellationSignal,
- new Callback<TextLinks>() {
- @Override
- public void onSuccess(TextLinks result) {
- try {
- callback.onSuccess(result);
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
-
- @Override
- public void onFailure(CharSequence error) {
- try {
- callback.onFailure();
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
- });
+ mMainThreadHandler.post(() -> TextClassifierService.this.onGenerateLinks(
+ sessionId, request, mCancellationSignal, new ProxyCallback<>(callback)));
}
- /** {@inheritDoc} */
@Override
public void onSelectionEvent(
TextClassificationSessionId sessionId,
SelectionEvent event) {
Preconditions.checkNotNull(event);
- TextClassifierService.this.onSelectionEvent(sessionId, event);
+ mMainThreadHandler.post(
+ () -> TextClassifierService.this.onSelectionEvent(sessionId, event));
}
- /** {@inheritDoc} */
@Override
public void onTextClassifierEvent(
TextClassificationSessionId sessionId,
TextClassifierEvent event) {
Preconditions.checkNotNull(event);
- TextClassifierService.this.onTextClassifierEvent(sessionId, event);
+ mMainThreadHandler.post(
+ () -> TextClassifierService.this.onTextClassifierEvent(sessionId, event));
}
- /** {@inheritDoc} */
@Override
public void onDetectLanguage(
TextClassificationSessionId sessionId,
TextLanguage.Request request,
- ITextLanguageCallback callback) {
+ ITextClassifierCallback callback) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
- TextClassifierService.this.onDetectLanguage(
- sessionId,
- request,
- mCancellationSignal,
- new Callback<TextLanguage>() {
- @Override
- public void onSuccess(TextLanguage result) {
- try {
- callback.onSuccess(result);
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
-
- @Override
- public void onFailure(CharSequence error) {
- try {
- callback.onFailure();
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- };
- });
+ mMainThreadHandler.post(() -> TextClassifierService.this.onDetectLanguage(
+ sessionId, request, mCancellationSignal, new ProxyCallback<>(callback)));
}
- /** {@inheritDoc} */
@Override
public void onSuggestConversationActions(
TextClassificationSessionId sessionId,
ConversationActions.Request request,
- IConversationActionsCallback callback) {
+ ITextClassifierCallback callback) {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
- TextClassifierService.this.onSuggestConversationActions(
- sessionId,
- request,
- mCancellationSignal,
- new Callback<ConversationActions>() {
- @Override
- public void onSuccess(ConversationActions result) {
- try {
- callback.onSuccess(result);
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
-
- @Override
- public void onFailure(CharSequence error) {
- try {
- callback.onFailure();
- } catch (RemoteException e) {
- Slog.d(LOG_TAG, "Error calling callback");
- }
- }
- });
+ mMainThreadHandler.post(() -> TextClassifierService.this.onSuggestConversationActions(
+ sessionId, request, mCancellationSignal, new ProxyCallback<>(callback)));
}
- /** {@inheritDoc} */
@Override
public void onCreateTextClassificationSession(
TextClassificationContext context, TextClassificationSessionId sessionId) {
Preconditions.checkNotNull(context);
Preconditions.checkNotNull(sessionId);
- TextClassifierService.this.onCreateTextClassificationSession(context, sessionId);
+ mMainThreadHandler.post(
+ () -> TextClassifierService.this.onCreateTextClassificationSession(
+ context, sessionId));
}
- /** {@inheritDoc} */
@Override
public void onDestroyTextClassificationSession(TextClassificationSessionId sessionId) {
- TextClassifierService.this.onDestroyTextClassificationSession(sessionId);
+ mMainThreadHandler.post(
+ () -> TextClassifierService.this.onDestroyTextClassificationSession(sessionId));
}
};
@@ -301,6 +216,7 @@ public abstract class TextClassifierService extends Service {
* @param cancellationSignal object to watch for canceling the current operation
* @param callback the callback to return the result to
*/
+ @MainThread
public abstract void onSuggestSelection(
@Nullable TextClassificationSessionId sessionId,
@NonNull TextSelection.Request request,
@@ -316,6 +232,7 @@ public abstract class TextClassifierService extends Service {
* @param cancellationSignal object to watch for canceling the current operation
* @param callback the callback to return the result to
*/
+ @MainThread
public abstract void onClassifyText(
@Nullable TextClassificationSessionId sessionId,
@NonNull TextClassification.Request request,
@@ -331,6 +248,7 @@ public abstract class TextClassifierService extends Service {
* @param cancellationSignal object to watch for canceling the current operation
* @param callback the callback to return the result to
*/
+ @MainThread
public abstract void onGenerateLinks(
@Nullable TextClassificationSessionId sessionId,
@NonNull TextLinks.Request request,
@@ -345,12 +263,14 @@ public abstract class TextClassifierService extends Service {
* @param cancellationSignal object to watch for canceling the current operation
* @param callback the callback to return the result to
*/
+ @MainThread
public void onDetectLanguage(
@Nullable TextClassificationSessionId sessionId,
@NonNull TextLanguage.Request request,
@NonNull CancellationSignal cancellationSignal,
@NonNull Callback<TextLanguage> callback) {
- callback.onSuccess(getLocalTextClassifier().detectLanguage(request));
+ mSingleThreadExecutor.submit(() ->
+ callback.onSuccess(getLocalTextClassifier().detectLanguage(request)));
}
/**
@@ -361,12 +281,14 @@ public abstract class TextClassifierService extends Service {
* @param cancellationSignal object to watch for canceling the current operation
* @param callback the callback to return the result to
*/
+ @MainThread
public void onSuggestConversationActions(
@Nullable TextClassificationSessionId sessionId,
@NonNull ConversationActions.Request request,
@NonNull CancellationSignal cancellationSignal,
@NonNull Callback<ConversationActions> callback) {
- callback.onSuccess(getLocalTextClassifier().suggestConversationActions(request));
+ mSingleThreadExecutor.submit(() ->
+ callback.onSuccess(getLocalTextClassifier().suggestConversationActions(request)));
}
/**
@@ -383,6 +305,7 @@ public abstract class TextClassifierService extends Service {
* instead
*/
@Deprecated
+ @MainThread
public void onSelectionEvent(
@Nullable TextClassificationSessionId sessionId, @NonNull SelectionEvent event) {}
@@ -396,6 +319,7 @@ public abstract class TextClassifierService extends Service {
* @param sessionId the session id
* @param event the TextClassifier event
*/
+ @MainThread
public void onTextClassifierEvent(
@Nullable TextClassificationSessionId sessionId, @NonNull TextClassifierEvent event) {}
@@ -405,6 +329,7 @@ public abstract class TextClassifierService extends Service {
* @param context the text classification context
* @param sessionId the session's Id
*/
+ @MainThread
public void onCreateTextClassificationSession(
@NonNull TextClassificationContext context,
@NonNull TextClassificationSessionId sessionId) {}
@@ -414,6 +339,7 @@ public abstract class TextClassifierService extends Service {
*
* @param sessionId the id of the session to destroy
*/
+ @MainThread
public void onDestroyTextClassificationSession(
@NonNull TextClassificationSessionId sessionId) {}
@@ -441,6 +367,11 @@ public abstract class TextClassifierService extends Service {
return TextClassifier.NO_OP;
}
+ /** @hide **/
+ public static <T extends Parcelable> T getResponse(Bundle bundle) {
+ return bundle.getParcelable(KEY_RESULT);
+ }
+
/**
* Callbacks for TextClassifierService results.
*
@@ -494,4 +425,44 @@ public abstract class TextClassifierService extends Service {
si.permission));
return null;
}
+
+ /**
+ * Forwards the callback result to a wrapped binder callback.
+ */
+ private static final class ProxyCallback<T extends Parcelable> implements Callback<T> {
+ private WeakReference<ITextClassifierCallback> mTextClassifierCallback;
+
+ private ProxyCallback(ITextClassifierCallback textClassifierCallback) {
+ mTextClassifierCallback =
+ new WeakReference<>(Preconditions.checkNotNull(textClassifierCallback));
+ }
+
+ @Override
+ public void onSuccess(T result) {
+ ITextClassifierCallback callback = mTextClassifierCallback.get();
+ if (callback == null) {
+ return;
+ }
+ try {
+ Bundle bundle = new Bundle(1);
+ bundle.putParcelable(KEY_RESULT, result);
+ callback.onSuccess(bundle);
+ } catch (RemoteException e) {
+ Slog.d(LOG_TAG, "Error calling callback");
+ }
+ }
+
+ @Override
+ public void onFailure(CharSequence error) {
+ ITextClassifierCallback callback = mTextClassifierCallback.get();
+ if (callback == null) {
+ return;
+ }
+ try {
+ callback.onFailure();
+ } catch (RemoteException e) {
+ Slog.d(LOG_TAG, "Error calling callback");
+ }
+ }
+ }
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index fac699ece642..b99336bb0dbf 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -39,6 +39,8 @@ public class FeatureFlagUtils {
public static final String SAFETY_HUB = "settings_safety_hub";
public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
public static final String GLOBAL_ACTIONS_GRID_ENABLED = "settings_global_actions_grid_enabled";
+ public static final String GLOBAL_ACTIONS_PANEL_ENABLED =
+ "settings_global_actions_panel_enabled";
private static final Map<String, String> DEFAULT_FLAGS;
@@ -56,7 +58,8 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
DEFAULT_FLAGS.put(SAFETY_HUB, "false");
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
- DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "false");
+ DEFAULT_FLAGS.put(GLOBAL_ACTIONS_GRID_ENABLED, "true");
+ DEFAULT_FLAGS.put(GLOBAL_ACTIONS_PANEL_ENABLED, "true");
}
/**
diff --git a/core/java/android/util/apk/ApkSignatureVerifier.java b/core/java/android/util/apk/ApkSignatureVerifier.java
index ab67d372021b..71c8e98a0faa 100644
--- a/core/java/android/util/apk/ApkSignatureVerifier.java
+++ b/core/java/android/util/apk/ApkSignatureVerifier.java
@@ -393,15 +393,18 @@ public class ApkSignatureVerifier {
/**
* @return the verity root hash in the Signing Block.
*/
- public static byte[] getVerityRootHash(String apkPath)
- throws IOException, SignatureNotFoundException, SecurityException {
+ public static byte[] getVerityRootHash(String apkPath) throws IOException, SecurityException {
// first try v3
try {
return ApkSignatureSchemeV3Verifier.getVerityRootHash(apkPath);
} catch (SignatureNotFoundException e) {
// try older version
}
- return ApkSignatureSchemeV2Verifier.getVerityRootHash(apkPath);
+ try {
+ return ApkSignatureSchemeV2Verifier.getVerityRootHash(apkPath);
+ } catch (SignatureNotFoundException e) {
+ return null;
+ }
}
/**
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 54e70ea6bbcc..5e2aaae44cb1 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -117,6 +117,8 @@ public final class SurfaceControl implements Parcelable {
float dtdy, float dsdy);
private static native void nativeSetColorTransform(long transactionObj, long nativeObject,
float[] matrix, float[] translation);
+ private static native void nativeSetColorSpaceAgnostic(long transactionObj, long nativeObject,
+ boolean agnostic);
private static native void nativeSetGeometry(long transactionObj, long nativeObject,
Rect sourceCrop, Rect dest, long orientation);
private static native void nativeSetColor(long transactionObj, long nativeObject, float[] color);
@@ -1207,6 +1209,19 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * Sets the Surface to be color space agnostic. If a surface is color space agnostic,
+ * the color can be interpreted in any color space.
+ * @param agnostic A boolean to indicate whether the surface is color space agnostic
+ * @hide
+ */
+ public void setColorSpaceAgnostic(boolean agnostic) {
+ checkNotReleased();
+ synchronized (SurfaceControl.class) {
+ sGlobalTransaction.setColorSpaceAgnostic(this, agnostic);
+ }
+ }
+
+ /**
* Bounds the surface and its children to the bounds specified. Size of the surface will be
* ignored and only the crop and buffer size will be used to determine the bounds of the
* surface. If no crop is specified and the surface has no buffer, the surface bounds is only
@@ -2227,6 +2242,18 @@ public final class SurfaceControl implements Parcelable {
}
/**
+ * Sets the Surface to be color space agnostic. If a surface is color space agnostic,
+ * the color can be interpreted in any color space.
+ * @param agnostic A boolean to indicate whether the surface is color space agnostic
+ * @hide
+ */
+ public Transaction setColorSpaceAgnostic(SurfaceControl sc, boolean agnostic) {
+ sc.checkNotReleased();
+ nativeSetColorSpaceAgnostic(mNativeObject, sc.mNativeObject, agnostic);
+ return this;
+ }
+
+ /**
* @hide
*/
@UnsupportedAppUsage
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 874be814ed9a..287365f70344 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9530,8 +9530,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// View is not important for "regular" autofill, so we must check if Augmented Autofill
// is enabled for the activity
final AutofillOptions options = mContext.getAutofillOptions();
- if (options == null || !options.augmentedEnabled) {
- // TODO(b/123100824): should also check if activity is whitelisted
+ if (options == null || !options.isAugmentedAutofillEnabled(mContext)) {
return false;
}
final AutofillManager afm = getAutofillManager();
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index f2474a58b176..4dc20d4fad6d 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7845,6 +7845,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
@ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
})
+ @InspectableProperty(name = "layout_width", enumMapping = {
+ @InspectableProperty.EnumMap(name = "match_parent", value = MATCH_PARENT),
+ @InspectableProperty.EnumMap(name = "wrap_content", value = WRAP_CONTENT)
+ })
public int width;
/**
@@ -7856,6 +7860,10 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
@ViewDebug.IntToString(from = MATCH_PARENT, to = "MATCH_PARENT"),
@ViewDebug.IntToString(from = WRAP_CONTENT, to = "WRAP_CONTENT")
})
+ @InspectableProperty(name = "layout_height", enumMapping = {
+ @InspectableProperty.EnumMap(name = "match_parent", value = MATCH_PARENT),
+ @InspectableProperty.EnumMap(name = "wrap_content", value = WRAP_CONTENT)
+ })
public int height;
/**
@@ -8028,6 +8036,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginLeft")
public int leftMargin;
/**
@@ -8036,6 +8045,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginTop")
public int topMargin;
/**
@@ -8044,6 +8054,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginRight")
public int rightMargin;
/**
@@ -8052,6 +8063,7 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
* to this field.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_marginBottom")
public int bottomMargin;
/**
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 135a8912fc60..f3bbca3500c7 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -22,6 +22,7 @@ import static android.view.WindowInsets.Type.IME;
import static android.view.WindowInsets.Type.LAST;
import static android.view.WindowInsets.Type.SIDE_BARS;
import static android.view.WindowInsets.Type.SIZE;
+import static android.view.WindowInsets.Type.SYSTEM_GESTURES;
import static android.view.WindowInsets.Type.TOP_BAR;
import static android.view.WindowInsets.Type.all;
import static android.view.WindowInsets.Type.compatSystemInsets;
@@ -35,7 +36,6 @@ import android.annotation.UnsupportedAppUsage;
import android.graphics.Insets;
import android.graphics.Rect;
import android.util.SparseArray;
-import android.view.InsetsState.InternalInsetType;
import android.view.WindowInsets.Type.InsetType;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethod;
@@ -229,6 +229,7 @@ public final class WindowInsets {
static void assignCompatInsets(Insets[] typeInsetMap, Rect insets) {
typeInsetMap[indexOf(TOP_BAR)] = Insets.of(0, insets.top, 0, 0);
typeInsetMap[indexOf(SIDE_BARS)] = Insets.of(insets.left, 0, insets.right, insets.bottom);
+ typeInsetMap[indexOf(SYSTEM_GESTURES)] = Insets.of(insets);
}
private static boolean[] createCompatVisibilityMap(@Nullable Insets[] typeInsetMap) {
@@ -630,6 +631,28 @@ public final class WindowInsets {
}
/**
+ * Returns the system gesture insets.
+ *
+ * <p>The system gesture insets represent the area of a window where system gestures have
+ * priority and may consume some or all touch input, e.g. due to the a system bar
+ * occupying it, or it being reserved for touch-only gestures.
+ *
+ * <p>Simple taps are guaranteed to reach the window even within the system gesture insets,
+ * as long as they are outside the {@link #getSystemWindowInsets() system window insets}.
+ *
+ * <p>When {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} is requested, an inset will be returned
+ * even when the system gestures are inactive due to
+ * {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} or
+ * {@link View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}.
+ *
+ * <p>This inset does not affect the result of {@link #isConsumed()} and cannot be consumed.
+ */
+ @NonNull
+ public Insets getSystemGestureInsets() {
+ return getInsets(mTypeInsetsMap, SYSTEM_GESTURES);
+ }
+
+ /**
* Returns a copy of this WindowInsets with the stable insets fully consumed.
*
* @return A modified copy of this WindowInsets
@@ -853,6 +876,22 @@ public final class WindowInsets {
}
/**
+ * Sets system gesture insets in pixels.
+ *
+ * <p>The system gesture insets represent the area of a window where system gestures have
+ * priority and may consume some or all touch input, e.g. due to the a system bar
+ * occupying it, or it being reserved for touch-only gestures.
+ *
+ * @see #getSystemGestureInsets()
+ * @return itself
+ */
+ @NonNull
+ public Builder setSystemGestureInsets(@NonNull Insets insets) {
+ WindowInsets.setInsets(mTypeInsetsMap, SYSTEM_GESTURES, insets);
+ return this;
+ }
+
+ /**
* Sets the insets of a specific window type in pixels.
*
* <p>The insets represents the area of a a window that is partially or fully obscured by
@@ -1005,8 +1044,10 @@ public final class WindowInsets {
static final int IME = 0x2;
static final int SIDE_BARS = 0x4;
- static final int LAST = 0x8;
- static final int SIZE = 4;
+ static final int SYSTEM_GESTURES = 0x8;
+
+ static final int LAST = 0x10;
+ static final int SIZE = 5;
static final int WINDOW_DECOR = LAST;
static int indexOf(@InsetType int type) {
@@ -1017,8 +1058,10 @@ public final class WindowInsets {
return 1;
case SIDE_BARS:
return 2;
- case WINDOW_DECOR:
+ case SYSTEM_GESTURES:
return 3;
+ case WINDOW_DECOR:
+ return 4;
default:
throw new IllegalArgumentException("type needs to be >= FIRST and <= LAST,"
+ " type=" + type);
@@ -1030,7 +1073,7 @@ public final class WindowInsets {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
- @IntDef(flag = true, value = { TOP_BAR, IME, SIDE_BARS, WINDOW_DECOR })
+ @IntDef(flag = true, value = { TOP_BAR, IME, SIDE_BARS, WINDOW_DECOR, SYSTEM_GESTURES })
public @interface InsetType {
}
@@ -1064,6 +1107,27 @@ public final class WindowInsets {
}
/**
+ * Returns an inset type representing the system gesture insets.
+ *
+ * <p>The system gesture insets represent the area of a window where system gestures have
+ * priority and may consume some or all touch input, e.g. due to the a system bar
+ * occupying it, or it being reserved for touch-only gestures.
+ *
+ * <p>Simple taps are guaranteed to reach the window even within the system gesture insets,
+ * as long as they are outside the {@link #getSystemWindowInsets() system window insets}.
+ *
+ * <p>When {@link View#SYSTEM_UI_FLAG_LAYOUT_STABLE} is requested, an inset will be returned
+ * even when the system gestures are inactive due to
+ * {@link View#SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN} or
+ * {@link View#SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION}.
+ *
+ * @see #getSystemGestureInsets()
+ */
+ public static @InsetType int systemGestures() {
+ return SYSTEM_GESTURES;
+ }
+
+ /**
* @return All system bars. Includes {@link #topBar()} as well as {@link #sideBars()}, but
* not {@link #ime()}.
*/
@@ -1082,6 +1146,9 @@ public final class WindowInsets {
/**
* @return All inset types combined.
+ *
+ * TODO: Figure out if this makes sense at all, mixing e.g {@link #systemGestures()} and
+ * {@link #ime()} does not seem very useful.
*/
public static @InsetType int all() {
return 0xFFFFFFFF;
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 86b735046b2b..bd38327d2c93 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -1793,6 +1793,13 @@ public interface WindowManager extends ViewManager {
public static final int PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION = 0x00800000;
/**
+ * Flag to indicate that the window is color space agnostic, and the color can be
+ * interpreted to any color space.
+ * @hide
+ */
+ public static final int PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC = 0x01000000;
+
+ /**
* An internal annotation for flags that can be specified to {@link #softInputMode}.
*
* @hide
@@ -1892,7 +1899,11 @@ public interface WindowManager extends ViewManager {
@ViewDebug.FlagToString(
mask = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
equals = PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION,
- name = "STATUS_FORCE_SHOW_NAVIGATION")
+ name = "STATUS_FORCE_SHOW_NAVIGATION"),
+ @ViewDebug.FlagToString(
+ mask = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
+ equals = PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC,
+ name = "COLOR_SPACE_AGNOSTIC")
})
@TestApi
public int privateFlags;
diff --git a/core/java/android/view/contentcapture/ContentCaptureManager.java b/core/java/android/view/contentcapture/ContentCaptureManager.java
index 885bd2a39580..a3e65496bcd0 100644
--- a/core/java/android/view/contentcapture/ContentCaptureManager.java
+++ b/core/java/android/view/contentcapture/ContentCaptureManager.java
@@ -193,6 +193,15 @@ public final class ContentCaptureManager {
private MainContentCaptureSession mMainSession;
/** @hide */
+ public interface ContentCaptureClient {
+ /**
+ * Gets the component name of the client.
+ */
+ @NonNull
+ ComponentName contentCaptureClientGetComponentName();
+ }
+
+ /** @hide */
public ContentCaptureManager(@NonNull Context context,
@NonNull IContentCaptureManager service, @NonNull ContentCaptureOptions options) {
mContext = Preconditions.checkNotNull(context, "context cannot be null");
diff --git a/core/java/android/view/contentcapture/ContentCaptureSession.java b/core/java/android/view/contentcapture/ContentCaptureSession.java
index 6bf1eba30f55..1f0971e7d6c5 100644
--- a/core/java/android/view/contentcapture/ContentCaptureSession.java
+++ b/core/java/android/view/contentcapture/ContentCaptureSession.java
@@ -121,11 +121,11 @@ public abstract class ContentCaptureSession implements AutoCloseable {
public static final int STATE_INTERNAL_ERROR = 0x100;
/**
- * Session is disabled because service didn't whitelist package.
+ * Session is disabled because service didn't whitelist package or activity.
*
* @hide
*/
- public static final int STATE_PACKAGE_NOT_WHITELISTED = 0x200;
+ public static final int STATE_NOT_WHITELISTED = 0x200;
private static final int INITIAL_CHILDREN_CAPACITY = 5;
diff --git a/core/java/android/view/inspector/InspectableProperty.java b/core/java/android/view/inspector/InspectableProperty.java
index 30938c152eca..97ede862bfaa 100644
--- a/core/java/android/view/inspector/InspectableProperty.java
+++ b/core/java/android/view/inspector/InspectableProperty.java
@@ -233,6 +233,17 @@ public @interface InspectableProperty {
* @hide
*/
@TestApi
- GRAVITY
+ GRAVITY,
+
+ /**
+ * Value is a resource ID
+ *
+ * This type is inferred from the presence of a resource ID annotation such as
+ * {@link android.annotation.AnyRes}.
+ *
+ * @hide
+ */
+ @TestApi
+ RESOURCE_ID
}
}
diff --git a/core/java/android/view/inspector/PropertyMapper.java b/core/java/android/view/inspector/PropertyMapper.java
index 00b18d172eed..54d99df843a1 100644
--- a/core/java/android/view/inspector/PropertyMapper.java
+++ b/core/java/android/view/inspector/PropertyMapper.java
@@ -157,6 +157,16 @@ public interface PropertyMapper {
@NonNull IntEnumMapping mapping);
/**
+ * Map a string name to an integer ID for an attribute that contains resource IDs.
+ *
+ * @param name The name of the property
+ * @param attributeId If the property is from an XML attribute, the resource ID of the property
+ * @return An integer ID for the property
+ * @throws PropertyConflictException If the property name is already mapped as another type.
+ */
+ int mapResourceId(@NonNull String name, @AttrRes int attributeId);
+
+ /**
* Map a string name to an integer ID for a flag set packed into an int property.
*
* @param name The name of the property
diff --git a/core/java/android/view/inspector/PropertyReader.java b/core/java/android/view/inspector/PropertyReader.java
index a8b7ecc3f57e..b5020ce6495f 100644
--- a/core/java/android/view/inspector/PropertyReader.java
+++ b/core/java/android/view/inspector/PropertyReader.java
@@ -16,6 +16,7 @@
package android.view.inspector;
+import android.annotation.AnyRes;
import android.annotation.ColorInt;
import android.annotation.ColorLong;
import android.annotation.NonNull;
@@ -150,7 +151,7 @@ public interface PropertyReader {
void readColor(int id, @Nullable Color value);
/**
- * Read {@link android.view.Gravity} packed into an primitive {int}.
+ * Read {@link android.view.Gravity} packed into an primitive {@code int}.
*
* @param id Identifier of the property from a {@link PropertyMapper}
* @param value Value of the property
@@ -159,7 +160,7 @@ public interface PropertyReader {
void readGravity(int id, int value);
/**
- * Read an enumeration packed into a primitive {int}.
+ * Read an enumeration packed into a primitive {@code int}.
*
* @param id Identifier of the property from a {@link PropertyMapper}
* @param value Value of the property
@@ -168,7 +169,7 @@ public interface PropertyReader {
void readIntEnum(int id, int value);
/**
- * Read a flag packed into a primitive {int}.
+ * Read a flag packed into a primitive {@code int}.
*
* @param id Identifier of the property from a {@link PropertyMapper}
* @param value Value of the property
@@ -177,6 +178,15 @@ public interface PropertyReader {
void readIntFlag(int id, int value);
/**
+ * Read an integer that contains a resource ID.
+ *
+ * @param id Identifier of the property from a {@link PropertyMapper}
+ * @param value Value of the property
+ * @throws PropertyTypeMismatchException If the property ID is not mapped as a resource ID.
+ */
+ void readResourceId(int id, @AnyRes int value);
+
+ /**
* Thrown if a client calls a typed read method for a property of a different type.
*/
class PropertyTypeMismatchException extends RuntimeException {
diff --git a/core/java/android/view/textclassifier/SystemTextClassifier.java b/core/java/android/view/textclassifier/SystemTextClassifier.java
index 8b370f543ccc..8f8766e3f783 100644
--- a/core/java/android/view/textclassifier/SystemTextClassifier.java
+++ b/core/java/android/view/textclassifier/SystemTextClassifier.java
@@ -20,15 +20,14 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.WorkerThread;
import android.content.Context;
+import android.os.Bundle;
import android.os.Looper;
+import android.os.Parcelable;
import android.os.RemoteException;
import android.os.ServiceManager;
-import android.service.textclassifier.IConversationActionsCallback;
-import android.service.textclassifier.ITextClassificationCallback;
+import android.service.textclassifier.ITextClassifierCallback;
import android.service.textclassifier.ITextClassifierService;
-import android.service.textclassifier.ITextLanguageCallback;
-import android.service.textclassifier.ITextLinksCallback;
-import android.service.textclassifier.ITextSelectionCallback;
+import android.service.textclassifier.TextClassifierService;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting.Visibility;
@@ -73,9 +72,10 @@ public final class SystemTextClassifier implements TextClassifier {
Utils.checkMainThread();
try {
request.setCallingPackageName(mPackageName);
- final TextSelectionCallback callback = new TextSelectionCallback();
+ final BlockingCallback<TextSelection> callback =
+ new BlockingCallback<>("textselection");
mManagerService.onSuggestSelection(mSessionId, request, callback);
- final TextSelection selection = callback.mReceiver.get();
+ final TextSelection selection = callback.get();
if (selection != null) {
return selection;
}
@@ -95,9 +95,10 @@ public final class SystemTextClassifier implements TextClassifier {
Utils.checkMainThread();
try {
request.setCallingPackageName(mPackageName);
- final TextClassificationCallback callback = new TextClassificationCallback();
+ final BlockingCallback<TextClassification> callback =
+ new BlockingCallback<>("textclassification");
mManagerService.onClassifyText(mSessionId, request, callback);
- final TextClassification classification = callback.mReceiver.get();
+ final TextClassification classification = callback.get();
if (classification != null) {
return classification;
}
@@ -122,9 +123,10 @@ public final class SystemTextClassifier implements TextClassifier {
try {
request.setCallingPackageName(mPackageName);
- final TextLinksCallback callback = new TextLinksCallback();
+ final BlockingCallback<TextLinks> callback =
+ new BlockingCallback<>("textlinks");
mManagerService.onGenerateLinks(mSessionId, request, callback);
- final TextLinks links = callback.mReceiver.get();
+ final TextLinks links = callback.get();
if (links != null) {
return links;
}
@@ -165,9 +167,10 @@ public final class SystemTextClassifier implements TextClassifier {
try {
request.setCallingPackageName(mPackageName);
- final TextLanguageCallback callback = new TextLanguageCallback();
+ final BlockingCallback<TextLanguage> callback =
+ new BlockingCallback<>("textlanguage");
mManagerService.onDetectLanguage(mSessionId, request, callback);
- final TextLanguage textLanguage = callback.mReceiver.get();
+ final TextLanguage textLanguage = callback.get();
if (textLanguage != null) {
return textLanguage;
}
@@ -184,9 +187,10 @@ public final class SystemTextClassifier implements TextClassifier {
try {
request.setCallingPackageName(mPackageName);
- final ConversationActionsCallback callback = new ConversationActionsCallback();
+ final BlockingCallback<ConversationActions> callback =
+ new BlockingCallback<>("conversation-actions");
mManagerService.onSuggestConversationActions(mSessionId, request, callback);
- final ConversationActions conversationActions = callback.mReceiver.get();
+ final ConversationActions conversationActions = callback.get();
if (conversationActions != null) {
return conversationActions;
}
@@ -245,82 +249,28 @@ public final class SystemTextClassifier implements TextClassifier {
}
}
- private static final class TextSelectionCallback extends ITextSelectionCallback.Stub {
+ private static final class BlockingCallback<T extends Parcelable>
+ extends ITextClassifierCallback.Stub {
+ private final ResponseReceiver<T> mReceiver;
- final ResponseReceiver<TextSelection> mReceiver = new ResponseReceiver<>("textselection");
-
- @Override
- public void onSuccess(TextSelection selection) {
- mReceiver.onSuccess(selection);
+ BlockingCallback(String name) {
+ mReceiver = new ResponseReceiver<>(name);
}
@Override
- public void onFailure() {
- mReceiver.onFailure();
- }
- }
-
- private static final class TextClassificationCallback extends ITextClassificationCallback.Stub {
-
- final ResponseReceiver<TextClassification> mReceiver =
- new ResponseReceiver<>("textclassification");
-
- @Override
- public void onSuccess(TextClassification classification) {
- mReceiver.onSuccess(classification);
+ public void onSuccess(Bundle result) {
+ mReceiver.onSuccess(TextClassifierService.getResponse(result));
}
@Override
public void onFailure() {
mReceiver.onFailure();
}
- }
- private static final class TextLinksCallback extends ITextLinksCallback.Stub {
-
- final ResponseReceiver<TextLinks> mReceiver = new ResponseReceiver<>("textlinks");
-
- @Override
- public void onSuccess(TextLinks links) {
- mReceiver.onSuccess(links);
- }
-
- @Override
- public void onFailure() {
- mReceiver.onFailure();
- }
- }
-
- private static final class TextLanguageCallback extends ITextLanguageCallback.Stub {
-
- final ResponseReceiver<TextLanguage> mReceiver = new ResponseReceiver<>("textlanguage");
-
- @Override
- public void onSuccess(TextLanguage textLanguage) {
- mReceiver.onSuccess(textLanguage);
- }
-
- @Override
- public void onFailure() {
- mReceiver.onFailure();
- }
- }
-
- private static final class ConversationActionsCallback
- extends IConversationActionsCallback.Stub {
-
- final ResponseReceiver<ConversationActions> mReceiver =
- new ResponseReceiver<>("conversationaction");
-
- @Override
- public void onSuccess(ConversationActions conversationActions) {
- mReceiver.onSuccess(conversationActions);
+ public T get() {
+ return mReceiver.get();
}
- @Override
- public void onFailure() {
- mReceiver.onFailure();
- }
}
private static final class ResponseReceiver<T> {
diff --git a/core/java/android/webkit/WebViewDelegate.java b/core/java/android/webkit/WebViewDelegate.java
index ef69b6333cce..3d3d94198448 100644
--- a/core/java/android/webkit/WebViewDelegate.java
+++ b/core/java/android/webkit/WebViewDelegate.java
@@ -79,7 +79,10 @@ public final class WebViewDelegate {
/**
* Returns {@code true} if the draw GL functor can be invoked (see {@link #invokeDrawGlFunctor})
* and {@code false} otherwise.
+ *
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public boolean canInvokeDrawGlFunctor(View containerView) {
return true;
}
@@ -90,7 +93,9 @@ public final class WebViewDelegate {
*
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void invokeDrawGlFunctor(View containerView, long nativeDrawGLFunctor,
boolean waitForCompletion) {
ViewRootImpl.invokeFunctor(nativeDrawGLFunctor, waitForCompletion);
@@ -105,7 +110,9 @@ public final class WebViewDelegate {
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
* @throws IllegalArgumentException if the canvas is not hardware accelerated
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void callDrawGlFunction(Canvas canvas, long nativeDrawGLFunctor) {
if (!(canvas instanceof RecordingCanvas)) {
// Canvas#isHardwareAccelerated() is only true for subclasses of HardwareCanvas.
@@ -126,7 +133,9 @@ public final class WebViewDelegate {
* @param releasedRunnable Called when this nativeDrawGLFunctor is no longer referenced by this
* canvas, so is safe to be destroyed.
* @throws IllegalArgumentException if the canvas is not hardware accelerated
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void callDrawGlFunction(@NonNull Canvas canvas, long nativeDrawGLFunctor,
@Nullable Runnable releasedRunnable) {
if (!(canvas instanceof RecordingCanvas)) {
@@ -139,7 +148,7 @@ public final class WebViewDelegate {
/**
* Call webview draw functor. See API in draw_fn.h.
- * @param canvas a hardware accelerated canvas (see {@link Canvas#isHardwareAccelerated()}).
+ * @param canvas a {@link RecordingCanvas}.
* @param functor created by AwDrawFn_CreateFunctor in draw_fn.h.
*/
public void drawWebViewFunctor(@NonNull Canvas canvas, int functor) {
@@ -156,7 +165,9 @@ public final class WebViewDelegate {
*
* @param nativeDrawGLFunctor the pointer to the native functor that implements
* system/core/include/utils/Functor.h
+ * @deprecated Use {@link #drawWebViewFunctor(Canvas, int)}
*/
+ @Deprecated
public void detachDrawGlFunctor(View containerView, long nativeDrawGLFunctor) {
ViewRootImpl viewRootImpl = containerView.getViewRootImpl();
if (nativeDrawGLFunctor != 0 && viewRootImpl != null) {
diff --git a/core/java/android/widget/AbsoluteLayout.java b/core/java/android/widget/AbsoluteLayout.java
index 4ce0d5d21fd6..e3499f9f961f 100644
--- a/core/java/android/widget/AbsoluteLayout.java
+++ b/core/java/android/widget/AbsoluteLayout.java
@@ -21,6 +21,7 @@ import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
+import android.view.inspector.InspectableProperty;
import android.widget.RemoteViews.RemoteView;
@@ -159,10 +160,12 @@ public class AbsoluteLayout extends ViewGroup {
/**
* The horizontal, or X, location of the child within the view group.
*/
+ @InspectableProperty(name = "layout_x")
public int x;
/**
* The vertical, or Y, location of the child within the view group.
*/
+ @InspectableProperty(name = "layout_y")
public int y;
/**
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 3570c79430a4..69da9112ca01 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -443,6 +443,9 @@ public class FrameLayout extends ViewGroup {
* @see android.view.Gravity
* @attr ref android.R.styleable#FrameLayout_Layout_layout_gravity
*/
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity = UNSPECIFIED_GRAVITY;
public LayoutParams(@NonNull Context c, @Nullable AttributeSet attrs) {
diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java
index e833df9d498a..bdde4352d69d 100644
--- a/core/java/android/widget/LinearLayout.java
+++ b/core/java/android/widget/LinearLayout.java
@@ -1987,6 +1987,7 @@ public class LinearLayout extends ViewGroup {
* will be pro-rated among all views whose weight is greater than 0.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_weight")
public float weight;
/**
@@ -2010,6 +2011,9 @@ public class LinearLayout extends ViewGroup {
@ViewDebug.IntToString(from = Gravity.CENTER, to = "CENTER"),
@ViewDebug.IntToString(from = Gravity.FILL, to = "FILL")
})
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity = -1;
/**
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index b7cdad2d5e51..50e883679eb9 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -1116,7 +1116,7 @@ public final class Magnifier {
/**
* Builder class for {@link Magnifier} objects.
*/
- public static class Builder {
+ public static final class Builder {
private @NonNull View mView;
private @Px @IntRange(from = 0) int mWidth;
private @Px @IntRange(from = 0) int mHeight;
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index 109c0a432c1b..8ee31e212cbf 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -1286,6 +1286,7 @@ public class RelativeLayout extends ViewGroup {
* the anchor's visibility is GONE.
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_alignWithParentIfMissing")
public boolean alignWithParent;
public LayoutParams(Context c, AttributeSet attrs) {
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 457be342473e..a3e89c85fcbc 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -1474,7 +1474,7 @@ public class ScrollView extends FrameLayout {
*
* @param child the View to scroll to
*/
- public void scrollToDescendant(View child) {
+ public void scrollToDescendant(@NonNull View child) {
if (!mIsLayoutDirty) {
child.getDrawingRect(mTempRect);
diff --git a/core/java/android/widget/TableRow.java b/core/java/android/widget/TableRow.java
index 22931fcb3e97..ac23093a0073 100644
--- a/core/java/android/widget/TableRow.java
+++ b/core/java/android/widget/TableRow.java
@@ -26,6 +26,7 @@ import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewHierarchyEncoder;
+import android.view.inspector.InspectableProperty;
/**
* <p>A layout that arranges its children horizontally. A TableRow should
@@ -398,12 +399,14 @@ public class TableRow extends LinearLayout {
* <p>The column index of the cell represented by the widget.</p>
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_column")
public int column;
/**
* <p>The number of columns the widgets spans over.</p>
*/
@ViewDebug.ExportedProperty(category = "layout")
+ @InspectableProperty(name = "layout_span")
public int span;
private static final int LOCATION = 0;
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index f3bf9130b163..fd74c0486bd7 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -81,6 +81,12 @@ public final class SystemUiDeviceConfigFlags {
*/
public static final String SSIN_MAX_NUM_ACTIONS = "ssin_max_num_actions";
+ /**
+ * The default component of
+ * {@link android.service.notification.NotificationAssistantService}.
+ */
+ public static final String NAS_DEFAULT_SERVICE = "nas_default_service";
+
// Flags related to media notifications
/**
diff --git a/core/java/com/android/internal/infra/WhitelistHelper.java b/core/java/com/android/internal/infra/WhitelistHelper.java
new file mode 100644
index 000000000000..eec82bc2403e
--- /dev/null
+++ b/core/java/com/android/internal/infra/WhitelistHelper.java
@@ -0,0 +1,163 @@
+/*
+ * 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.infra;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
+
+/**
+ * Helper class for keeping track of whitelisted packages/activities.
+ *
+ * @hide
+ */
+public final class WhitelistHelper {
+
+ private static final String TAG = "WhitelistHelper";
+
+ /**
+ * Map of whitelisted packages/activities. The whole package is whitelisted if its
+ * corresponding value is {@code null}.
+ */
+ @Nullable
+ private ArrayMap<String, ArraySet<ComponentName>> mWhitelistedPackages;
+
+ /**
+ * Sets the whitelist with the given packages and activities. The list is cleared if both
+ * packageNames and components are {@code null}.
+ *
+ * @param packageNames packages to be whitelisted.
+ * @param components activities to be whitelisted.
+ *
+ * @throws IllegalArgumentException if packages or components are empty.
+ */
+ public void setWhitelist(@Nullable ArraySet<String> packageNames,
+ @Nullable ArraySet<ComponentName> components) {
+ mWhitelistedPackages = null;
+ if (packageNames == null && components == null) return;
+
+ if ((packageNames != null && packageNames.isEmpty())
+ || (components != null && components.isEmpty())) {
+ throw new IllegalArgumentException("Packages or Components cannot be empty.");
+ }
+
+ mWhitelistedPackages = new ArrayMap<>();
+
+ if (packageNames != null) {
+ for (int i = 0; i < packageNames.size(); i++) {
+ mWhitelistedPackages.put(packageNames.valueAt(i), null);
+ }
+ }
+
+ if (components != null) {
+ for (int i = 0; i < components.size(); i++) {
+ final ComponentName component = components.valueAt(i);
+ if (component == null) {
+ Log.w(TAG, "setWhitelist(): component is null");
+ continue;
+ }
+
+ final String packageName = component.getPackageName();
+ ArraySet<ComponentName> set = mWhitelistedPackages.get(packageName);
+ if (set == null) {
+ set = new ArraySet<>();
+ mWhitelistedPackages.put(packageName, set);
+ }
+ set.add(component);
+ }
+ }
+ }
+
+ /**
+ * Returns {@code true} if the entire package is whitelisted.
+ */
+ public boolean isWhitelisted(@NonNull String packageName) {
+ Preconditions.checkNotNull(packageName);
+
+ if (mWhitelistedPackages == null) return false;
+
+ return mWhitelistedPackages.containsKey(packageName)
+ && mWhitelistedPackages.get(packageName) == null;
+ }
+
+ /**
+ * Returns {@code true} if the specified activity is whitelisted.
+ */
+ public boolean isWhitelisted(@NonNull ComponentName componentName) {
+ Preconditions.checkNotNull(componentName);
+
+ final String packageName = componentName.getPackageName();
+ final ArraySet<ComponentName> whitelistedComponents = getWhitelistedComponents(packageName);
+ if (whitelistedComponents != null) {
+ return whitelistedComponents.contains(componentName);
+ }
+
+ return isWhitelisted(packageName);
+ }
+
+ /**
+ * Returns a set of whitelisted components with the given package, or null if nothing is
+ * whitelisted.
+ */
+ @Nullable
+ public ArraySet<ComponentName> getWhitelistedComponents(@NonNull String packageName) {
+ Preconditions.checkNotNull(packageName);
+
+ return mWhitelistedPackages == null ? null : mWhitelistedPackages.get(packageName);
+ }
+
+ @Override
+ public String toString() {
+ return "WhitelistHelper[" + mWhitelistedPackages + ']';
+ }
+
+ /**
+ * Dumps it!
+ */
+ public void dump(@NonNull String prefix, @NonNull String message, @NonNull PrintWriter pw) {
+ if (mWhitelistedPackages == null || mWhitelistedPackages.size() == 0) {
+ pw.print(prefix); pw.print(message); pw.println(": (no whitelisted packages)");
+ return;
+ }
+
+ final int size = mWhitelistedPackages.size();
+ pw.print(prefix); pw.print(message); pw.print(": "); pw.print(size);
+ pw.println(" packages");
+ for (int i = 0; i < mWhitelistedPackages.size(); i++) {
+ final String packageName = mWhitelistedPackages.keyAt(i);
+ final ArraySet<ComponentName> components = mWhitelistedPackages.valueAt(i);
+ pw.print(prefix); pw.print(i); pw.print("."); pw.print(packageName); pw.print(": ");
+ if (components == null) {
+ pw.println("(whole package)");
+ continue;
+ }
+
+ pw.print("["); pw.print(components.valueAt(0));
+ for (int j = 1; j < components.size(); j++) {
+ pw.print(", "); pw.print(components.valueAt(i));
+ }
+ pw.println("]");
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index a5e7202c0e50..5f2371961857 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -41,7 +41,6 @@ import android.system.OsConstants;
import android.system.StructCapUserData;
import android.system.StructCapUserHeader;
import android.text.Hyphenator;
-import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
@@ -85,8 +84,6 @@ public class ZygoteInit {
private static final String PROPERTY_DISABLE_OPENGL_PRELOADING = "ro.zygote.disable_gl_preload";
private static final String PROPERTY_GFX_DRIVER = "ro.gfx.driver.0";
- private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
- "persist.device_config.runtime_native.use_app_image_startup_cache";
private static final int LOG_BOOT_PROGRESS_PRELOAD_START = 3020;
private static final int LOG_BOOT_PROGRESS_PRELOAD_END = 3030;
@@ -708,13 +705,6 @@ public class ZygoteInit {
parsedArgs.mRuntimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
}
- String use_app_image_cache = SystemProperties.get(
- PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
- // Property defaults to true currently.
- if (!TextUtils.isEmpty(use_app_image_cache) && !use_app_image_cache.equals("false")) {
- parsedArgs.mRuntimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
- }
-
/* Request to fork the system server process */
pid = Zygote.forkSystemServer(
parsedArgs.mUid, parsedArgs.mGid,
diff --git a/core/java/com/android/internal/widget/ViewPager.java b/core/java/com/android/internal/widget/ViewPager.java
index 64bdc6e1eb37..f48b56d7af36 100644
--- a/core/java/com/android/internal/widget/ViewPager.java
+++ b/core/java/com/android/internal/widget/ViewPager.java
@@ -46,6 +46,7 @@ import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
import android.view.animation.Interpolator;
+import android.view.inspector.InspectableProperty;
import android.widget.EdgeEffect;
import android.widget.Scroller;
@@ -2779,6 +2780,9 @@ public class ViewPager extends ViewGroup {
* Where to position the view page within the overall ViewPager
* container; constants are defined in {@link android.view.Gravity}.
*/
+ @InspectableProperty(
+ name = "layout_gravity",
+ valueType = InspectableProperty.ValueType.GRAVITY)
public int gravity;
/**
diff --git a/core/jni/android/graphics/AnimatedImageDrawable.cpp b/core/jni/android/graphics/AnimatedImageDrawable.cpp
index 8dd5f5f0e561..12900261bddd 100644
--- a/core/jni/android/graphics/AnimatedImageDrawable.cpp
+++ b/core/jni/android/graphics/AnimatedImageDrawable.cpp
@@ -35,14 +35,14 @@ static jmethodID gAnimatedImageDrawable_onAnimationEndMethodID;
// Note: jpostProcess holds a handle to the ImageDecoder.
static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
jlong nativeImageDecoder, jobject jpostProcess,
- jint width, jint height, jobject jsubset) {
+ jint width, jint height, jlong colorSpaceHandle,
+ jboolean extended, jobject jsubset) {
if (nativeImageDecoder == 0) {
doThrowIOE(env, "Cannot create AnimatedImageDrawable from null!");
return 0;
}
auto* imageDecoder = reinterpret_cast<ImageDecoder*>(nativeImageDecoder);
- const SkISize scaledSize = SkISize::Make(width, height);
SkIRect subset;
if (jsubset) {
GraphicsJNI::jrect_to_irect(env, jsubset, &subset);
@@ -50,15 +50,8 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
subset = SkIRect::MakeWH(width, height);
}
- auto info = imageDecoder->mCodec->getInfo();
bool hasRestoreFrame = false;
- if (imageDecoder->mCodec->getEncodedFormat() == SkEncodedImageFormat::kWEBP) {
- if (width < info.width() && height < info.height()) {
- // WebP will scale its SkBitmap to the scaled size.
- // FIXME: b/73529447 GIF should do the same.
- info = info.makeWH(width, height);
- }
- } else {
+ if (imageDecoder->mCodec->getEncodedFormat() != SkEncodedImageFormat::kWEBP) {
const int frameCount = imageDecoder->mCodec->codec()->getFrameCount();
for (int i = 0; i < frameCount; ++i) {
SkCodec::FrameInfo frameInfo;
@@ -73,6 +66,12 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
}
}
+ auto info = imageDecoder->mCodec->getInfo().makeWH(width, height)
+ .makeColorSpace(GraphicsJNI::getNativeColorSpace(colorSpaceHandle));
+ if (extended) {
+ info = info.makeColorType(kRGBA_F16_SkColorType);
+ }
+
size_t bytesUsed = info.computeMinByteSize();
// SkAnimatedImage has one SkBitmap for decoding, plus an extra one if there is a
// kRestorePrevious frame. AnimatedImageDrawable has two SkPictures storing the current
@@ -96,7 +95,7 @@ static jlong AnimatedImageDrawable_nCreate(JNIEnv* env, jobject /*clazz*/,
sk_sp<SkAnimatedImage> animatedImg = SkAnimatedImage::Make(std::move(imageDecoder->mCodec),
- scaledSize, subset,
+ info, subset,
std::move(picture));
if (!animatedImg) {
doThrowIOE(env, "Failed to create drawable");
@@ -246,7 +245,7 @@ static void AnimatedImageDrawable_nSetMirrored(JNIEnv* env, jobject /*clazz*/, j
}
static const JNINativeMethod gAnimatedImageDrawableMethods[] = {
- { "nCreate", "(JLandroid/graphics/ImageDecoder;IILandroid/graphics/Rect;)J", (void*) AnimatedImageDrawable_nCreate },
+ { "nCreate", "(JLandroid/graphics/ImageDecoder;IIJZLandroid/graphics/Rect;)J",(void*) AnimatedImageDrawable_nCreate },
{ "nGetNativeFinalizer", "()J", (void*) AnimatedImageDrawable_nGetNativeFinalizer },
{ "nDraw", "(JJ)J", (void*) AnimatedImageDrawable_nDraw },
{ "nSetAlpha", "(JI)V", (void*) AnimatedImageDrawable_nSetAlpha },
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index af2bf2d40146..89d908b31aa0 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -463,6 +463,13 @@ static void nativeSetColorTransform(JNIEnv* env, jclass clazz, jlong transaction
transaction->setColorTransform(surfaceControl, matrix, translation);
}
+static void nativeSetColorSpaceAgnostic(JNIEnv* env, jclass clazz, jlong transactionObj,
+ jlong nativeObject, jboolean agnostic) {
+ auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj);
+ SurfaceControl* const surfaceControl = reinterpret_cast<SurfaceControl*>(nativeObject);
+ transaction->setColorSpaceAgnostic(surfaceControl, agnostic);
+}
+
static void nativeSetWindowCrop(JNIEnv* env, jclass clazz, jlong transactionObj,
jlong nativeObject,
jint l, jint t, jint r, jint b) {
@@ -1206,6 +1213,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
(void*)nativeSetMatrix },
{"nativeSetColorTransform", "(JJ[F[F)V",
(void*)nativeSetColorTransform },
+ {"nativeSetColorSpaceAgnostic", "(JJZ)V",
+ (void*)nativeSetColorSpaceAgnostic },
{"nativeSetFlags", "(JJII)V",
(void*)nativeSetFlags },
{"nativeSetWindowCrop", "(JJIIII)V",
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index 5064d23453a7..445075da7f90 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -616,7 +616,7 @@ enum Action {
// OS: Q
ACTION_PANEL_INTERACTION = 1658;
- // ACTION: Show Contextual homepage, log latency in loading cards
+ // ACTION: Show Contextual homepage. Log total loading latency.
ACTION_CONTEXTUAL_HOME_SHOW = 1662;
// ACTION: Contextual card displays
@@ -649,6 +649,15 @@ enum Action {
ACTION_ATCSCUC = 1680;
ACTION_ATCHNUC = 1681;
+
+ // ACTION: Individual contextual card loading time
+ ACTION_CONTEXTUAL_CARD_LOAD = 1684;
+
+ //ACTION: Contextual card loading timeout
+ ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685;
+
+ //ACTION: Log result for each card's eligibility check
+ ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686;
}
/**
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index ae3e714eb950..4c4393d4fd61 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3139,6 +3139,14 @@
<permission android:name="android.permission.BIND_CONTENT_CAPTURE_SERVICE"
android:protectionLevel="signature" />
+ <!-- Must be required by a android.service.contentsuggestions.ContentSuggestionsService,
+ to ensure that only the system can bind to it.
+ @SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
+ <p>Protection level: signature
+ -->
+ <permission android:name="android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- Must be required by a android.service.autofill.augmented.AugmentedAutofillService,
to ensure that only the system can bind to it.
@SystemApi @hide This is not a third-party API (intended for OEMs and system apps).
@@ -4455,6 +4463,11 @@
@hide -->
<permission android:name="android.permission.MANAGE_SENSOR_PRIVACY"
android:protectionLevel="signature" />
+ <!-- @SystemApi Permission that protects the {@link Intent#ACTION_REVIEW_ACCESSIBILITY_SERVICES}
+ intent.
+ @hide -->
+ <permission android:name="android.permission.REVIEW_ACCESSIBILITY_SERVICES"
+ android:protectionLevel="signature" />
<!-- @SystemApi Allows an activity to replace the app name and icon displayed in share targets
in the sharesheet for the Q-release and later.
diff --git a/core/res/res/values-mcc311-mnc480/config.xml b/core/res/res/values-mcc311-mnc480/config.xml
index cc7daa8efec6..db2f8d01f93a 100755
--- a/core/res/res/values-mcc311-mnc480/config.xml
+++ b/core/res/res/values-mcc311-mnc480/config.xml
@@ -19,21 +19,6 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- CDMA home system id for Verizon -->
- <string-array translatable="false" name="config_cdma_home_system">
- <item>64</item>
- <item>65</item>
- <item>66</item>
- <item>76</item>
- <item>77</item>
- <item>78</item>
- <item>79</item>
- <item>80</item>
- <item>81</item>
- <item>82</item>
- <item>83</item>
- </string-array>
-
<!-- Flag indicating whether the IMS service can be turned off. If false then
the service will not be turned-off completely (the ImsManager.turnOffIms() will
be disabled) but individual Features can be disabled using ImsConfig.setFeatureValue() -->
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 6b8e000777d8..fc7b4cf05b56 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -965,7 +965,7 @@
<p>The default value of this attribute is <code>false</code>. -->
<attr name="allowEmbedded" format="boolean" />
- <!-- @hide @SystemApi Specifies whether this {@link android.app.Activity} should be shown on
+ <!-- Specifies whether this {@link android.app.Activity} should be shown on
top of the lock screen whenever the lockscreen is up and this activity has another
activity behind it with the {@link android.R.attr#showWhenLocked} attribute set. That
is, this activity is only visible on the lock screen if there is another activity with
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 2f2fdca7f279..ccd35cd1b634 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -654,7 +654,7 @@
<bool translatable="false" name="config_wifi_framework_enable_associated_network_selection">true</bool>
<!-- Boolean indicating whether single radio chain scan results are to be used for network selection -->
- <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">false</bool>
+ <bool translatable="false" name="config_wifi_framework_use_single_radio_chain_scan_results_network_selection">true</bool>
<!-- Boolean indicating that wifi only link configuratios that have exact same credentials (i.e PSK) -->
<bool translatable="false" name="config_wifi_only_link_same_credential_configurations">true</bool>
@@ -706,6 +706,9 @@
<!-- Indicates that connected MAC randomization is supported on this device -->
<bool translatable="false" name="config_wifi_connected_mac_randomization_supported">false</bool>
+ <!-- Indicates that p2p MAC randomization is supported on this device -->
+ <bool translatable="false" name="config_wifi_p2p_mac_randomization_supported">false</bool>
+
<!-- Indicates that wifi link probing is supported on this device -->
<bool translatable="false" name="config_wifi_link_probing_supported">false</bool>
@@ -2917,14 +2920,6 @@
<bool name="config_networkSamplingWakesDevice">true</bool>
- <!-- Home (non-roaming) values for CDMA roaming indicator.
- Carriers can override this table by resource overlay. If not,
- the default values come from 3GPP2 C.R1001 table
- 8.1-1. Enhanced Roaming Indicator Number Assignments -->
- <string-array translatable="false" name="config_cdma_home_system">
- <item>1</item>
- </string-array>
-
<!--From SmsMessage-->
<!--Support decoding the user data payload as pack GSM 8-bit (a GSM alphabet
string that's stored in 8-bit unpacked format) characters.-->
@@ -3706,8 +3701,8 @@
<string translatable="false" name="config_batterySaverDeviceSpecificConfig"></string>
- <!-- Package name that should be granted Notification Assistant access -->
- <string name="config_defaultAssistantAccessPackage" translatable="false">android.ext.services</string>
+ <!-- Component name that should be granted Notification Assistant access -->
+ <string name="config_defaultAssistantAccessComponent" translatable="false">android.ext.services/android.ext.services.notification.Assistant</string>
<bool name="config_supportBluetoothPersistedState">true</bool>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 61d530027eaa..b48c6b04eb7e 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2934,7 +2934,6 @@
<public name="foregroundServiceType" />
<public name="hasFragileUserData" />
<public name="minAspectRatio" />
- <!-- @hide @SystemApi -->
<public name="inheritShowWhenLocked" />
<public name="zygotePreloadName" />
<public name="useEmbeddedDex" />
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d5444c0e760c..3d1baaebb305 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1939,6 +1939,7 @@
<java-symbol type="bool" name="config_wifi_convert_apband_5ghz_to_any" />
<java-symbol type="bool" name="config_wifi_local_only_hotspot_5ghz" />
<java-symbol type="bool" name="config_wifi_connected_mac_randomization_supported" />
+ <java-symbol type="bool" name="config_wifi_p2p_mac_randomization_supported" />
<java-symbol type="bool" name="config_wifi_link_probing_supported" />
<java-symbol type="bool" name="config_wifi_fast_bss_transition_enabled" />
<java-symbol type="bool" name="config_wimaxEnabled" />
@@ -2606,7 +2607,6 @@
<java-symbol type="attr" name="lightRadius" />
<java-symbol type="attr" name="ambientShadowAlpha" />
<java-symbol type="attr" name="spotShadowAlpha" />
- <java-symbol type="array" name="config_cdma_home_system" />
<java-symbol type="bool" name="config_sms_decode_gsm_8bit_data" />
<java-symbol type="dimen" name="text_size_small_material" />
<java-symbol type="attr" name="checkMarkGravity" />
@@ -3533,7 +3533,7 @@
<java-symbol type="string" name="harmful_app_warning_title" />
<java-symbol type="layout" name="harmful_app_warning_dialog" />
- <java-symbol type="string" name="config_defaultAssistantAccessPackage" />
+ <java-symbol type="string" name="config_defaultAssistantAccessComponent" />
<java-symbol type="bool" name="config_supportBluetoothPersistedState" />
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ebc6be72bea6..ad1403db242c 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -132,6 +132,7 @@ public class SettingsBackupTest {
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS,
Settings.Global.AUTOMATIC_POWER_SAVER_MODE,
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED,
+ Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST,
Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY,
Settings.Global.BROADCAST_BG_CONSTANTS,
Settings.Global.BROADCAST_FG_CONSTANTS,
diff --git a/core/tests/coretests/src/com/android/internal/infra/WhitelistHelperTest.java b/core/tests/coretests/src/com/android/internal/infra/WhitelistHelperTest.java
new file mode 100644
index 000000000000..ab6830b106d0
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/infra/WhitelistHelperTest.java
@@ -0,0 +1,138 @@
+/*
+ * 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.infra;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.testng.Assert.assertThrows;
+
+import android.content.ComponentName;
+import android.util.ArraySet;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.junit.MockitoJUnitRunner;
+
+/**
+ * Unit test for {@link WhitelistHelper}.
+ *
+ * <p>To run it:
+ * {@code atest FrameworksCoreTests:com.android.internal.infra.WhitelistHelperTest}
+ */
+
+@RunWith(MockitoJUnitRunner.class)
+public class WhitelistHelperTest {
+ private WhitelistHelper mWhitelistHelper = new WhitelistHelper();
+
+ private String mPackage1 = "com.example";
+ private String mPackage2 = "com.example2";
+
+ private ComponentName mComponent1 = new ComponentName(mPackage1, "class1");
+ private ComponentName mComponent2 = new ComponentName(mPackage1, "class2");
+ private ComponentName mComponentDifferentPkg = new ComponentName(mPackage2, "class3");
+
+ @Test
+ public void testSetWhitelist_emptyArguments() {
+ assertThrows(IllegalArgumentException.class,
+ () -> mWhitelistHelper.setWhitelist(new ArraySet<>(), null));
+ assertThrows(IllegalArgumentException.class,
+ () -> mWhitelistHelper.setWhitelist(null, new ArraySet<>()));
+ assertThrows(IllegalArgumentException.class,
+ () -> mWhitelistHelper.setWhitelist(new ArraySet<>(), new ArraySet<>()));
+ }
+
+ @Test
+ public void testWhitelistHelper_nullArguments() {
+ assertThrows(NullPointerException.class,
+ () -> mWhitelistHelper.isWhitelisted((String) null));
+ assertThrows(NullPointerException.class,
+ () -> mWhitelistHelper.isWhitelisted((ComponentName) null));
+ assertThrows(NullPointerException.class,
+ () -> mWhitelistHelper.getWhitelistedComponents(null));
+ }
+
+ @Test
+ public void testSetWhitelist_nullPackage() {
+ final ArraySet<String> packages = new ArraySet<>();
+ packages.add(null);
+ mWhitelistHelper.setWhitelist(packages, null);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+
+ @Test
+ public void testSetWhitelist_nullActivity() {
+ final ArraySet<ComponentName> components = new ArraySet<>();
+ components.add(null);
+ mWhitelistHelper.setWhitelist(null, components);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+
+ @Test
+ public void testSetWhitelist_replaceWhitelist() {
+ final ArraySet<ComponentName> components = new ArraySet<>();
+ components.add(mComponent1);
+ mWhitelistHelper.setWhitelist(null, components);
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+
+ final ArraySet<ComponentName> components2 = new ArraySet<>();
+ components2.add(mComponent2);
+ mWhitelistHelper.setWhitelist(null, components2);
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isTrue();
+ }
+
+ @Test
+ public void testIsWhitelisted_packageWhitelisted() {
+ final ArraySet<String> packages = new ArraySet<>();
+ packages.add(mPackage1);
+ mWhitelistHelper.setWhitelist(packages, null);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+
+ @Test
+ public void testIsWhitelisted_activityWhitelisted() {
+ final ArraySet<ComponentName> components = new ArraySet<>();
+ components.add(mComponent1);
+ mWhitelistHelper.setWhitelist(null, components);
+
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage1)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mPackage2)).isFalse();
+
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent1)).isTrue();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponent2)).isFalse();
+ assertThat(mWhitelistHelper.isWhitelisted(mComponentDifferentPkg)).isFalse();
+ }
+}
diff --git a/core/xsd/Android.bp b/core/xsd/Android.bp
new file mode 100644
index 000000000000..81669eb290db
--- /dev/null
+++ b/core/xsd/Android.bp
@@ -0,0 +1,6 @@
+xsd_config {
+ name: "permission",
+ srcs: ["permission.xsd"],
+ api_dir: "schema",
+ package_name: "com.android.xml.permission",
+}
diff --git a/core/xsd/permission.xsd b/core/xsd/permission.xsd
new file mode 100644
index 000000000000..d90863b2c716
--- /dev/null
+++ b/core/xsd/permission.xsd
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="permissions">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="group" type="group" maxOccurs="unbounded"/>
+ <xs:element name="permission" type="permission" maxOccurs="unbounded"/>
+ <xs:element name="assign-permission" type="assign-permission" maxOccurs="unbounded"/>
+ <xs:element name="split-permission" type="split-permission" maxOccurs="unbounded"/>
+ <xs:element name="library" type="library" maxOccurs="unbounded"/>
+ <xs:element name="feature" type="feature" maxOccurs="unbounded"/>
+ <xs:element name="unavailable-feature" type="unavailable-feature" maxOccurs="unbounded"/>
+ <xs:element name="allow-in-power-save-except-idle" type="allow-in-power-save-except-idle" maxOccurs="unbounded"/>
+ <xs:element name="allow-in-power-save" type="allow-in-power-save" maxOccurs="unbounded"/>
+ <xs:element name="allow-in-data-usage-save" type="allow-in-data-usage-save" maxOccurs="unbounded"/>
+ <xs:element name="allow-unthrottled-location" type="allow-unthrottled-location" maxOccurs="unbounded"/>
+ <xs:element name="allow-ignore-location-settings" type="allow-ignore-location-settings" maxOccurs="unbounded"/>
+ <xs:element name="allow-implicit-broadcast" type="allow-implicit-broadcast" maxOccurs="unbounded"/>
+ <xs:element name="app-link" type="app-link" maxOccurs="unbounded"/>
+ <xs:element name="system-user-whitelisted-app" type="system-user-whitelisted-app" maxOccurs="unbounded"/>
+ <xs:element name="system-user-blacklisted-app" type="system-user-blacklisted-app" maxOccurs="unbounded"/>
+ <xs:element name="default-enabled-vr-app" type="default-enabled-vr-app" maxOccurs="unbounded"/>
+ <xs:element name="backup-transport-whitelisted-service" type="backup-transport-whitelisted-service" maxOccurs="unbounded"/>
+ <xs:element name="disabled-until-used-preinstalled-carrier-associated-app" type="disabled-until-used-preinstalled-carrier-associated-app" maxOccurs="unbounded"/>
+ <xs:element name="disabled-until-used-preinstalled-carrier-app" type="disabled-until-used-preinstalled-carrier-app" maxOccurs="unbounded"/>
+ <xs:element name="privapp-permissions" type="privapp-permissions" maxOccurs="unbounded"/>
+ <xs:element name="oem-permissions" type="oem-permissions" maxOccurs="unbounded"/>
+ <xs:element name="hidden-api-whitelisted-app" type="hidden-api-whitelisted-app" maxOccurs="unbounded"/>
+ <xs:element name="allow-association" type="allow-association" maxOccurs="unbounded"/>
+ <xs:element name="bugreport-whitelisted" type="bugreport-whitelisted" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="group">
+ <xs:attribute name="gid" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="permission">
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="assign-permission">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="uid" type="xs:int"/>
+ </xs:complexType>
+ <xs:complexType name="split-permission">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="targetSdk" type="xs:int"/>
+ <xs:sequence>
+ <xs:element name="library" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="library">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="file" type="xs:string"/>
+ <xs:attribute name="dependency" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="feature">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="notLowRam" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="unavailable-feature">
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="allow-in-power-save-except-idle">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="allow-in-power-save">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="allow-in-data-usage-save">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="allow-unthrottled-location">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="allow-ignore-location-settings">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="allow-implicit-broadcast">
+ <xs:attribute name="action" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="app-link">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="system-user-whitelisted-app">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="system-user-blacklisted-app">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="default-enabled-vr-app">
+ <xs:attribute name="package" type="xs:string"/>
+ <xs:attribute name="class" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="backup-transport-whitelisted-service">
+ <xs:attribute name="service" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="disabled-until-used-preinstalled-carrier-associated-app">
+ <xs:attribute name="package" type="xs:string"/>
+ <xs:attribute name="carrierAppPackage" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="disabled-until-used-preinstalled-carrier-app">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="privapp-permissions">
+ <xs:attribute name="package" type="xs:string"/>
+ <xs:sequence>
+ <xs:element name="permission" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="deny-permission" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="oem-permissions">
+ <xs:attribute name="package" type="xs:string"/>
+ <xs:sequence>
+ <xs:element name="permission" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ <xs:element name="deny-permission" maxOccurs="unbounded">
+ <xs:complexType>
+ <xs:attribute name="name" type="xs:string"/>
+ </xs:complexType>
+ </xs:element>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:complexType name="hidden-api-whitelisted-app">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="allow-association">
+ <xs:attribute name="target" type="xs:string"/>
+ <xs:attribute name="allowed" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="bugreport-whitelisted">
+ <xs:attribute name="package" type="xs:string"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/core/xsd/schema/README.md b/core/xsd/schema/README.md
new file mode 100644
index 000000000000..f52d93d2b65a
--- /dev/null
+++ b/core/xsd/schema/README.md
@@ -0,0 +1 @@
+Please see the [README](https://android.googlesource.com/platform/system/tools/xsdc/+/refs/heads/master/README.md) for details regarding the Configfile as API.
diff --git a/core/xsd/schema/current.txt b/core/xsd/schema/current.txt
new file mode 100644
index 000000000000..82bb0feac089
--- /dev/null
+++ b/core/xsd/schema/current.txt
@@ -0,0 +1,242 @@
+// Signature format: 2.0
+package com.android.xml.permission {
+
+ public class AllowAssociation {
+ ctor public AllowAssociation();
+ method public String getAllowed();
+ method public String getTarget();
+ method public void setAllowed(String);
+ method public void setTarget(String);
+ }
+
+ public class AllowIgnoreLocationSettings {
+ ctor public AllowIgnoreLocationSettings();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class AllowImplicitBroadcast {
+ ctor public AllowImplicitBroadcast();
+ method public String getAction();
+ method public void setAction(String);
+ }
+
+ public class AllowInDataUsageSave {
+ ctor public AllowInDataUsageSave();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class AllowInPowerSave {
+ ctor public AllowInPowerSave();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class AllowInPowerSaveExceptIdle {
+ ctor public AllowInPowerSaveExceptIdle();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class AllowUnthrottledLocation {
+ ctor public AllowUnthrottledLocation();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class AppLink {
+ ctor public AppLink();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class AssignPermission {
+ ctor public AssignPermission();
+ method public String getName();
+ method public int getUid();
+ method public void setName(String);
+ method public void setUid(int);
+ }
+
+ public class BackupTransportWhitelistedService {
+ ctor public BackupTransportWhitelistedService();
+ method public String getService();
+ method public void setService(String);
+ }
+
+ public class BugreportWhitelisted {
+ ctor public BugreportWhitelisted();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class DefaultEnabledVrApp {
+ ctor public DefaultEnabledVrApp();
+ method public String get_class();
+ method public String get_package();
+ method public void set_class(String);
+ method public void set_package(String);
+ }
+
+ public class DisabledUntilUsedPreinstalledCarrierApp {
+ ctor public DisabledUntilUsedPreinstalledCarrierApp();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class DisabledUntilUsedPreinstalledCarrierAssociatedApp {
+ ctor public DisabledUntilUsedPreinstalledCarrierAssociatedApp();
+ method public String getCarrierAppPackage();
+ method public String get_package();
+ method public void setCarrierAppPackage(String);
+ method public void set_package(String);
+ }
+
+ public class Feature {
+ ctor public Feature();
+ method public String getName();
+ method public String getNotLowRam();
+ method public void setName(String);
+ method public void setNotLowRam(String);
+ }
+
+ public class Group {
+ ctor public Group();
+ method public int getGid();
+ method public void setGid(int);
+ }
+
+ public class HiddenApiWhitelistedApp {
+ ctor public HiddenApiWhitelistedApp();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class Library {
+ ctor public Library();
+ method public String getDependency();
+ method public String getFile();
+ method public String getName();
+ method public void setDependency(String);
+ method public void setFile(String);
+ method public void setName(String);
+ }
+
+ public class OemPermissions {
+ ctor public OemPermissions();
+ method public java.util.List<com.android.xml.permission.OemPermissions.DenyPermission> getDenyPermission();
+ method public java.util.List<com.android.xml.permission.OemPermissions.Permission> getPermission();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public static class OemPermissions.DenyPermission {
+ ctor public OemPermissions.DenyPermission();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public static class OemPermissions.Permission {
+ ctor public OemPermissions.Permission();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class Permission {
+ ctor public Permission();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class Permissions {
+ ctor public Permissions();
+ method public java.util.List<com.android.xml.permission.AllowAssociation> getAllowAssociation();
+ method public java.util.List<com.android.xml.permission.AllowIgnoreLocationSettings> getAllowIgnoreLocationSettings();
+ method public java.util.List<com.android.xml.permission.AllowImplicitBroadcast> getAllowImplicitBroadcast();
+ method public java.util.List<com.android.xml.permission.AllowInDataUsageSave> getAllowInDataUsageSave();
+ method public java.util.List<com.android.xml.permission.AllowInPowerSave> getAllowInPowerSave();
+ method public java.util.List<com.android.xml.permission.AllowInPowerSaveExceptIdle> getAllowInPowerSaveExceptIdle();
+ method public java.util.List<com.android.xml.permission.AllowUnthrottledLocation> getAllowUnthrottledLocation();
+ method public java.util.List<com.android.xml.permission.AppLink> getAppLink();
+ method public java.util.List<com.android.xml.permission.AssignPermission> getAssignPermission();
+ method public java.util.List<com.android.xml.permission.BackupTransportWhitelistedService> getBackupTransportWhitelistedService();
+ method public java.util.List<com.android.xml.permission.BugreportWhitelisted> getBugreportWhitelisted();
+ method public java.util.List<com.android.xml.permission.DefaultEnabledVrApp> getDefaultEnabledVrApp();
+ method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierApp> getDisabledUntilUsedPreinstalledCarrierApp();
+ method public java.util.List<com.android.xml.permission.DisabledUntilUsedPreinstalledCarrierAssociatedApp> getDisabledUntilUsedPreinstalledCarrierAssociatedApp();
+ method public java.util.List<com.android.xml.permission.Feature> getFeature();
+ method public java.util.List<com.android.xml.permission.Group> getGroup();
+ method public java.util.List<com.android.xml.permission.HiddenApiWhitelistedApp> getHiddenApiWhitelistedApp();
+ method public java.util.List<com.android.xml.permission.Library> getLibrary();
+ method public java.util.List<com.android.xml.permission.OemPermissions> getOemPermissions();
+ method public java.util.List<com.android.xml.permission.Permission> getPermission();
+ method public java.util.List<com.android.xml.permission.PrivappPermissions> getPrivappPermissions();
+ method public java.util.List<com.android.xml.permission.SplitPermission> getSplitPermission();
+ method public java.util.List<com.android.xml.permission.SystemUserBlacklistedApp> getSystemUserBlacklistedApp();
+ method public java.util.List<com.android.xml.permission.SystemUserWhitelistedApp> getSystemUserWhitelistedApp();
+ method public java.util.List<com.android.xml.permission.UnavailableFeature> getUnavailableFeature();
+ }
+
+ public class PrivappPermissions {
+ ctor public PrivappPermissions();
+ method public java.util.List<com.android.xml.permission.PrivappPermissions.DenyPermission> getDenyPermission();
+ method public java.util.List<com.android.xml.permission.PrivappPermissions.Permission> getPermission();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public static class PrivappPermissions.DenyPermission {
+ ctor public PrivappPermissions.DenyPermission();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public static class PrivappPermissions.Permission {
+ ctor public PrivappPermissions.Permission();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class SplitPermission {
+ ctor public SplitPermission();
+ method public java.util.List<com.android.xml.permission.SplitPermission.Library> getLibrary();
+ method public String getName();
+ method public int getTargetSdk();
+ method public void setName(String);
+ method public void setTargetSdk(int);
+ }
+
+ public static class SplitPermission.Library {
+ ctor public SplitPermission.Library();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class SystemUserBlacklistedApp {
+ ctor public SystemUserBlacklistedApp();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class SystemUserWhitelistedApp {
+ ctor public SystemUserWhitelistedApp();
+ method public String get_package();
+ method public void set_package(String);
+ }
+
+ public class UnavailableFeature {
+ ctor public UnavailableFeature();
+ method public String getName();
+ method public void setName(String);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static com.android.xml.permission.Permissions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/core/xsd/schema/last_current.txt b/core/xsd/schema/last_current.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/core/xsd/schema/last_current.txt
diff --git a/core/xsd/schema/last_removed.txt b/core/xsd/schema/last_removed.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/core/xsd/schema/last_removed.txt
diff --git a/core/xsd/schema/removed.txt b/core/xsd/schema/removed.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/core/xsd/schema/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index 18eafa61aa48..2e56e09522e9 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -1718,6 +1718,11 @@ public final class Bitmap implements Parcelable {
* <p>Modifies the bitmap to have the specified {@link ColorSpace}, without
* affecting the underlying allocation backing the bitmap.</p>
*
+ * <p>This affects how the framework will interpret the color at each pixel. A bitmap
+ * with {@link Config#ALPHA_8} never has a color space, since a color space does not
+ * affect the alpha channel. Other {@code Config}s must always have a non-null
+ * {@code ColorSpace}.</p>
+ *
* @throws IllegalArgumentException If the specified color space is {@code null}, not
* {@link ColorSpace.Model#RGB RGB}, has a transfer function that is not an
* {@link ColorSpace.Rgb.TransferParameters ICC parametric curve}, or whose
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index e6233548651e..7345ea4db43d 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -193,7 +193,7 @@ public class HardwareRenderer {
*
* @param name The debug name to use for this HardwareRenderer instance
*/
- public void setName(String name) {
+ public void setName(@NonNull String name) {
nSetName(mNativeProxy, name);
}
@@ -330,7 +330,7 @@ public class HardwareRenderer {
*
* @return this instance
*/
- public FrameRenderRequest setVsyncTime(long vsyncTime) {
+ public @NonNull FrameRenderRequest setVsyncTime(long vsyncTime) {
mFrameInfo.setVsync(vsyncTime, vsyncTime);
mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
return this;
@@ -351,7 +351,7 @@ public class HardwareRenderer {
*
* @return this instance
*/
- public FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
+ public @NonNull FrameRenderRequest setFrameCommitCallback(@NonNull Executor executor,
@NonNull Runnable frameCommitCallback) {
setFrameCompleteCallback(frameNr -> executor.execute(frameCommitCallback));
return this;
@@ -372,7 +372,7 @@ public class HardwareRenderer {
* completion.
* @return this instance
*/
- public FrameRenderRequest setWaitForPresent(boolean shouldWait) {
+ public @NonNull FrameRenderRequest setWaitForPresent(boolean shouldWait) {
mWaitForPresent = shouldWait;
return this;
}
@@ -406,7 +406,7 @@ public class HardwareRenderer {
* @return An instance of {@link FrameRenderRequest}. The instance may be reused for every
* frame, so the caller should not hold onto it for longer than a single render request.
*/
- public FrameRenderRequest createRenderRequest() {
+ public @NonNull FrameRenderRequest createRenderRequest() {
mRenderRequest.reset();
return mRenderRequest;
}
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 2cf802bb9631..2d5babc5ebdb 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -1642,14 +1642,16 @@ public final class ImageDecoder implements AutoCloseable {
mTempStorage = null;
}
- private void checkState() {
+ private void checkState(boolean animated) {
if (mNativePtr == 0) {
throw new IllegalStateException("Cannot use closed ImageDecoder!");
}
checkSubset(mDesiredWidth, mDesiredHeight, mCropRect);
- if (mAllocator == ALLOCATOR_HARDWARE) {
+ // animated ignores the allocator, so no need to check for incompatible
+ // fields.
+ if (!animated && mAllocator == ALLOCATOR_HARDWARE) {
if (mMutable) {
throw new IllegalStateException("Cannot make mutable HARDWARE Bitmap!");
}
@@ -1673,21 +1675,30 @@ public final class ImageDecoder implements AutoCloseable {
}
}
+ private boolean checkForExtended() {
+ if (mDesiredColorSpace == null) {
+ return false;
+ }
+ return mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB)
+ || mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB);
+ }
+
+ private long getColorSpacePtr() {
+ if (mDesiredColorSpace == null) {
+ return 0;
+ }
+ return mDesiredColorSpace.getNativeInstance();
+ }
+
@WorkerThread
@NonNull
private Bitmap decodeBitmapInternal() throws IOException {
- checkState();
- long colorSpacePtr = 0;
- boolean extended = false;
- if (mDesiredColorSpace != null) {
- colorSpacePtr = mDesiredColorSpace.getNativeInstance();
- extended = mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.EXTENDED_SRGB)
- || mDesiredColorSpace == ColorSpace.get(ColorSpace.Named.LINEAR_EXTENDED_SRGB);
- }
+ checkState(false);
return nDecodeBitmap(mNativePtr, this, mPostProcessor != null,
mDesiredWidth, mDesiredHeight, mCropRect,
mMutable, mAllocator, mUnpremultipliedRequired,
- mConserveMemory, mDecodeAsAlphaMask, colorSpacePtr, extended);
+ mConserveMemory, mDecodeAsAlphaMask, getColorSpacePtr(),
+ checkForExtended());
}
private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener,
@@ -1753,9 +1764,11 @@ public final class ImageDecoder implements AutoCloseable {
// mPostProcessor exists.
ImageDecoder postProcessPtr = decoder.mPostProcessor == null ?
null : decoder;
+ decoder.checkState(true);
Drawable d = new AnimatedImageDrawable(decoder.mNativePtr,
postProcessPtr, decoder.mDesiredWidth,
- decoder.mDesiredHeight, srcDensity,
+ decoder.mDesiredHeight, decoder.getColorSpacePtr(),
+ decoder.checkForExtended(), srcDensity,
src.computeDstDensity(), decoder.mCropRect,
decoder.mInputStream, decoder.mAssetFd);
// d has taken ownership of these objects.
diff --git a/graphics/java/android/graphics/RecordingCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
index 30466e1f6b1f..c0e0a24583ec 100644
--- a/graphics/java/android/graphics/RecordingCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -166,7 +166,9 @@ public final class RecordingCanvas extends DisplayListCanvas {
* @param drawGLFunction A native function pointer
*
* @hide
+ * @deprecated Use {@link #drawWebViewFunctor(int)}
*/
+ @Deprecated
public void callDrawGLFunction2(long drawGLFunction) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
}
@@ -184,7 +186,9 @@ public final class RecordingCanvas extends DisplayListCanvas {
* canvas's display list has been released.
*
* @hide
+ * @deprecated Use {@link #drawWebViewFunctor(int)}
*/
+ @Deprecated
public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
}
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 42b6acd3b25a..c3bcbb45c2b4 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -62,7 +62,7 @@ import java.lang.annotation.RetentionPolicy;
*
* <h3>Creating a RenderNode</h3>
* <pre class="prettyprint">
- * RenderNode renderNode = RenderNode.create("myRenderNode");
+ * RenderNode renderNode = new RenderNode("myRenderNode");
* renderNode.setLeftTopRightBottom(0, 0, 50, 50); // Set the size to 50x50
* RecordingCanvas canvas = renderNode.beginRecording();
* try {
@@ -106,7 +106,7 @@ import java.lang.annotation.RetentionPolicy;
*
* <pre class="prettyprint">
* private void createDisplayList() {
- * mRenderNode = RenderNode.create("MyRenderNode");
+ * mRenderNode = new RenderNode("MyRenderNode");
* mRenderNode.setLeftTopRightBottom(0, 0, width, height);
* RecordingCanvas canvas = mRenderNode.beginRecording();
* try {
@@ -338,7 +338,7 @@ public final class RenderNode {
* @see #endRecording()
* @see #hasDisplayList()
*/
- public RecordingCanvas beginRecording(int width, int height) {
+ public @NonNull RecordingCanvas beginRecording(int width, int height) {
if (mCurrentRecordingCanvas != null) {
throw new IllegalStateException(
"Recording currently in progress - missing #endRecording() call?");
@@ -358,7 +358,7 @@ public final class RenderNode {
* @see #endRecording()
* @see #hasDisplayList()
*/
- public RecordingCanvas beginRecording() {
+ public @NonNull RecordingCanvas beginRecording() {
return beginRecording(nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
}
@@ -1285,7 +1285,7 @@ public final class RenderNode {
* @param position The position rectangle in pixels
* @return True if the value changed, false if the new value was the same as the previous value.
*/
- public boolean setPosition(Rect position) {
+ public boolean setPosition(@NonNull Rect position) {
return nSetLeftTopRightBottom(mNativeRenderNode,
position.left, position.top, position.right, position.bottom);
}
diff --git a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
index 3aaec3123d7d..bb6bf243bc76 100644
--- a/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
+++ b/graphics/java/android/graphics/drawable/AnimatedImageDrawable.java
@@ -291,8 +291,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
*/
public AnimatedImageDrawable(long nativeImageDecoder,
@Nullable ImageDecoder decoder, int width, int height,
- int srcDensity, int dstDensity, Rect cropRect,
- InputStream inputStream, AssetFileDescriptor afd)
+ long colorSpaceHandle, boolean extended, int srcDensity, int dstDensity,
+ Rect cropRect, InputStream inputStream, AssetFileDescriptor afd)
throws IOException {
width = Bitmap.scaleFromDensity(width, srcDensity, dstDensity);
height = Bitmap.scaleFromDensity(height, srcDensity, dstDensity);
@@ -309,8 +309,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
mIntrinsicHeight = cropRect.height();
}
- mState = new State(nCreate(nativeImageDecoder, decoder, width, height, cropRect),
- inputStream, afd);
+ mState = new State(nCreate(nativeImageDecoder, decoder, width, height, colorSpaceHandle,
+ extended, cropRect), inputStream, afd);
final long nativeSize = nNativeByteSize(mState.mNativePtr);
NativeAllocationRegistry registry = new NativeAllocationRegistry(
@@ -574,8 +574,8 @@ public class AnimatedImageDrawable extends Drawable implements Animatable2 {
private static native long nCreate(long nativeImageDecoder,
- @Nullable ImageDecoder decoder, int width, int height, Rect cropRect)
- throws IOException;
+ @Nullable ImageDecoder decoder, int width, int height, long colorSpaceHandle,
+ boolean extended, Rect cropRect) throws IOException;
@FastNative
private static native long nGetNativeFinalizer();
private static native long nDraw(long nativePtr, long canvasNativePtr);
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 1894e32c723c..e58e80225292 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -17,9 +17,11 @@
package android.graphics.drawable;
import android.annotation.ColorInt;
+import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.Px;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo.Config;
import android.content.res.ColorStateList;
@@ -670,7 +672,7 @@ public class GradientDrawable extends Drawable {
* @see #mutate()
* @see #setColor(int)
*/
- public void setColors(@ColorInt int[] colors) {
+ public void setColors(@Nullable @ColorInt int[] colors) {
setColors(colors, null);
}
@@ -690,7 +692,7 @@ public class GradientDrawable extends Drawable {
* @see #mutate()
* @see #setColors(int[])
*/
- public void setColors(@ColorInt int[] colors, @Nullable float[] offsets) {
+ public void setColors(@Nullable @ColorInt int[] colors, @Nullable float[] offsets) {
mGradientState.setGradientColors(colors);
mGradientState.mPositions = offsets;
mGradientIsDirty = true;
@@ -877,7 +879,11 @@ public class GradientDrawable extends Drawable {
* @see #getInnerRadiusRatio()
* @attr ref android.R.styleable#GradientDrawable_innerRadiusRatio
*/
- public void setInnerRadiusRatio(float innerRadiusRatio) {
+ public void setInnerRadiusRatio(
+ @FloatRange(from = 0.0f, fromInclusive = false) float innerRadiusRatio) {
+ if (innerRadiusRatio <= 0) {
+ throw new IllegalArgumentException("Ratio must be greater than zero");
+ }
mGradientState.mInnerRadiusRatio = innerRadiusRatio;
mPathIsDirty = true;
invalidateSelf();
@@ -899,7 +905,7 @@ public class GradientDrawable extends Drawable {
* @see #getInnerRadius()
* @attr ref android.R.styleable#GradientDrawable_innerRadius
*/
- public void setInnerRadius(int innerRadius) {
+ public void setInnerRadius(@Px int innerRadius) {
mGradientState.mInnerRadius = innerRadius;
mPathIsDirty = true;
invalidateSelf();
@@ -911,7 +917,7 @@ public class GradientDrawable extends Drawable {
* @see #setInnerRadius(int)
* @attr ref android.R.styleable#GradientDrawable_innerRadius
*/
- public int getInnerRadius() {
+ public @Px int getInnerRadius() {
return mGradientState.mInnerRadius;
}
@@ -921,7 +927,11 @@ public class GradientDrawable extends Drawable {
* @see #getThicknessRatio()
* @attr ref android.R.styleable#GradientDrawable_thicknessRatio
*/
- public void setThicknessRatio(float thicknessRatio) {
+ public void setThicknessRatio(
+ @FloatRange(from = 0.0f, fromInclusive = false) float thicknessRatio) {
+ if (thicknessRatio <= 0) {
+ throw new IllegalArgumentException("Ratio must be greater than zero");
+ }
mGradientState.mThicknessRatio = thicknessRatio;
mPathIsDirty = true;
invalidateSelf();
@@ -942,7 +952,7 @@ public class GradientDrawable extends Drawable {
*
* @attr ref android.R.styleable#GradientDrawable_thickness
*/
- public void setThickness(int thickness) {
+ public void setThickness(@Px int thickness) {
mGradientState.mThickness = thickness;
mPathIsDirty = true;
invalidateSelf();
@@ -954,7 +964,7 @@ public class GradientDrawable extends Drawable {
* @see #setThickness(int)
* @attr ref android.R.styleable#GradientDrawable_thickness
*/
- public int getThickness() {
+ public @Px int getThickness() {
return mGradientState.mThickness;
}
@@ -970,7 +980,7 @@ public class GradientDrawable extends Drawable {
* @attr ref android.R.styleable#GradientDrawablePadding_right
* @attr ref android.R.styleable#GradientDrawablePadding_bottom
*/
- public void setPadding(int left, int top, int right, int bottom) {
+ public void setPadding(@Px int left, @Px int top, @Px int right, @Px int bottom) {
if (mGradientState.mPadding == null) {
mGradientState.mPadding = new Rect();
}
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 2855227a1002..f67188c22609 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -256,7 +256,7 @@ public class StateListDrawable extends DrawableContainer {
* @see #getStateCount()
* @see #getStateDrawable(int)
*/
- public int[] getStateSet(int index) {
+ public @NonNull int[] getStateSet(int index) {
return mStateListState.mStateSets[index];
}
@@ -268,7 +268,7 @@ public class StateListDrawable extends DrawableContainer {
* @see #getStateCount()
* @see #getStateSet(int)
*/
- public Drawable getStateDrawable(int index) {
+ public @Nullable Drawable getStateDrawable(int index) {
return mStateListState.getChild(index);
}
@@ -280,7 +280,7 @@ public class StateListDrawable extends DrawableContainer {
* @see #getStateDrawable(int)
* @see #getStateSet(int)
*/
- public int findStateDrawableIndex(int[] stateSet) {
+ public int findStateDrawableIndex(@NonNull int[] stateSet) {
return mStateListState.indexOfStateSet(stateSet);
}
diff --git a/keystore/java/android/security/keystore/DeviceIdAttestationException.java b/keystore/java/android/security/keystore/DeviceIdAttestationException.java
index 13f50b144e30..8ba0317845d0 100644
--- a/keystore/java/android/security/keystore/DeviceIdAttestationException.java
+++ b/keystore/java/android/security/keystore/DeviceIdAttestationException.java
@@ -16,6 +16,7 @@
package android.security.keystore;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -33,7 +34,7 @@ public class DeviceIdAttestationException extends Exception {
*
* @param detailMessage the detail message for this exception.
*/
- public DeviceIdAttestationException(String detailMessage) {
+ public DeviceIdAttestationException(@Nullable String detailMessage) {
super(detailMessage);
}
@@ -44,7 +45,7 @@ public class DeviceIdAttestationException extends Exception {
* @param message the detail message for this exception.
* @param cause the cause of this exception, may be {@code null}.
*/
- public DeviceIdAttestationException(String message, Throwable cause) {
+ public DeviceIdAttestationException(@Nullable String message, @Nullable Throwable cause) {
super(message, cause);
}
}
diff --git a/libs/incident/include/android/os/IncidentReportArgs.h b/libs/incident/include/android/os/IncidentReportArgs.h
index 5e8eac1833ce..f056d3b6c9e8 100644
--- a/libs/incident/include/android/os/IncidentReportArgs.h
+++ b/libs/incident/include/android/os/IncidentReportArgs.h
@@ -47,12 +47,16 @@ public:
void setAll(bool all);
void setDest(int dest);
void addSection(int section);
+ void setReceiverPkg(const string& pkg);
+ void setReceiverCls(const string& cls);
void addHeader(const vector<uint8_t>& headerProto);
inline bool all() const { return mAll; }
bool containsSection(int section) const;
inline int dest() const { return mDest; }
inline const set<int>& sections() const { return mSections; }
+ inline const String16& receiverPkg() const { return mReceiverPkg; }
+ inline const String16& receiverCls() const { return mReceiverCls; }
inline const vector<vector<uint8_t>>& headers() const { return mHeaders; }
void merge(const IncidentReportArgs& that);
@@ -62,6 +66,8 @@ private:
vector<vector<uint8_t>> mHeaders;
bool mAll;
int mDest;
+ String16 mReceiverPkg;
+ String16 mReceiverCls;
};
}
diff --git a/libs/incident/src/IncidentReportArgs.cpp b/libs/incident/src/IncidentReportArgs.cpp
index 06b7a5b682b1..46c8dcf967d7 100644
--- a/libs/incident/src/IncidentReportArgs.cpp
+++ b/libs/incident/src/IncidentReportArgs.cpp
@@ -81,6 +81,16 @@ IncidentReportArgs::writeToParcel(Parcel* out) const
return err;
}
+ err = out->writeString16(mReceiverPkg);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
+ err = out->writeString16(mReceiverCls);
+ if (err != NO_ERROR) {
+ return err;
+ }
+
return NO_ERROR;
}
@@ -134,6 +144,9 @@ IncidentReportArgs::readFromParcel(const Parcel* in)
}
mDest = dest;
+ mReceiverPkg = in->readString16();
+ mReceiverCls = in->readString16();
+
return OK;
}
@@ -161,6 +174,18 @@ IncidentReportArgs::addSection(int section)
}
void
+IncidentReportArgs::setReceiverPkg(const string& pkg)
+{
+ mReceiverPkg = String16(pkg.c_str());
+}
+
+void
+IncidentReportArgs::setReceiverCls(const string& cls)
+{
+ mReceiverCls = String16(cls.c_str());
+}
+
+void
IncidentReportArgs::addHeader(const vector<uint8_t>& headerProto)
{
mHeaders.push_back(headerProto);
diff --git a/location/java/android/location/GpsStatus.java b/location/java/android/location/GpsStatus.java
index 609a15e1be7e..4e37654e7c65 100644
--- a/location/java/android/location/GpsStatus.java
+++ b/location/java/android/location/GpsStatus.java
@@ -30,6 +30,7 @@ import java.util.NoSuchElementException;
* <p>This class is used in conjunction with the {@link Listener} interface.
*
* @deprecated use {@link GnssStatus} and {@link GnssStatus.Callback}.
+ * @removed
*/
@Deprecated
public final class GpsStatus {
@@ -112,6 +113,7 @@ public final class GpsStatus {
/**
* Used for receiving notifications when GPS status has changed.
* @deprecated use {@link GnssStatus.Callback} instead.
+ * @removed
*/
@Deprecated
public interface Listener {
@@ -142,6 +144,7 @@ public final class GpsStatus {
* You can implement this interface and call {@link LocationManager#addNmeaListener}
* to receive NMEA data from the GPS engine.
* @deprecated use {@link OnNmeaMessageListener} instead.
+ * @removed
*/
@Deprecated
public interface NmeaListener {
diff --git a/location/java/android/location/Location.java b/location/java/android/location/Location.java
index 17e25097cef8..ed74333da895 100644
--- a/location/java/android/location/Location.java
+++ b/location/java/android/location/Location.java
@@ -113,6 +113,10 @@ public class Location implements Parcelable {
* Bit mask for mFieldsMask indicating the presence of mBearingAccuracy.
*/
private static final int HAS_BEARING_ACCURACY_MASK = 128;
+ /**
+ * Bit mask for mFieldsMask indicating the presence of mElapsedRealtimeUncertaintyNanos.
+ */
+ private static final int HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK = 256;
// Cached data to make bearing/distance computations more efficient for the case
// where distanceTo and bearingTo are called in sequence. Assume this typically happens
@@ -130,6 +134,9 @@ public class Location implements Parcelable {
private long mTime = 0;
@UnsupportedAppUsage
private long mElapsedRealtimeNanos = 0;
+ // Estimate of the relative precision of the alignment of this SystemClock
+ // timestamp, with the reported measurements in nanoseconds (68% confidence).
+ private long mElapsedRealtimeUncertaintyNanos = 0;
private double mLatitude = 0.0;
private double mLongitude = 0.0;
private double mAltitude = 0.0f;
@@ -171,6 +178,7 @@ public class Location implements Parcelable {
mProvider = l.mProvider;
mTime = l.mTime;
mElapsedRealtimeNanos = l.mElapsedRealtimeNanos;
+ mElapsedRealtimeUncertaintyNanos = l.mElapsedRealtimeUncertaintyNanos;
mFieldsMask = l.mFieldsMask;
mLatitude = l.mLatitude;
mLongitude = l.mLongitude;
@@ -191,6 +199,7 @@ public class Location implements Parcelable {
mProvider = null;
mTime = 0;
mElapsedRealtimeNanos = 0;
+ mElapsedRealtimeUncertaintyNanos = 0;
mFieldsMask = 0;
mLatitude = 0;
mLongitude = 0;
@@ -586,6 +595,37 @@ public class Location implements Parcelable {
}
/**
+ * Get estimate of the relative precision of the alignment of the
+ * ElapsedRealtimeNanos timestamp, with the reported measurements in
+ * nanoseconds (68% confidence).
+ *
+ * @return uncertainty of elapsed real-time of fix, in nanoseconds.
+ */
+ public long getElapsedRealtimeUncertaintyNanos() {
+ return mElapsedRealtimeUncertaintyNanos;
+ }
+
+ /**
+ * Set estimate of the relative precision of the alignment of the
+ * ElapsedRealtimeNanos timestamp, with the reported measurements in
+ * nanoseconds (68% confidence).
+ *
+ * @param time uncertainty of the elapsed real-time of fix, in nanoseconds.
+ */
+ public void setElapsedRealtimeUncertaintyNanos(long time) {
+ mElapsedRealtimeUncertaintyNanos = time;
+ mFieldsMask |= HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK;
+ }
+
+ /**
+ * True if this location has a elapsed realtime accuracy.
+ */
+ public boolean hasElapsedRealtimeUncertaintyNanos() {
+ return (mFieldsMask & HAS_ELAPSED_REALTIME_UNCERTAINTY_MASK) != 0;
+ }
+
+
+ /**
* Get the latitude, in degrees.
*
* <p>All locations generated by the {@link LocationManager}
@@ -1062,6 +1102,10 @@ public class Location implements Parcelable {
s.append(" et=");
TimeUtils.formatDuration(mElapsedRealtimeNanos / 1000000L, s);
}
+ if (hasElapsedRealtimeUncertaintyNanos()) {
+ s.append(" etAcc=");
+ TimeUtils.formatDuration(mElapsedRealtimeUncertaintyNanos / 1000000L, s);
+ }
if (hasAltitude()) s.append(" alt=").append(mAltitude);
if (hasSpeed()) s.append(" vel=").append(mSpeed);
if (hasBearing()) s.append(" bear=").append(mBearing);
@@ -1092,6 +1136,7 @@ public class Location implements Parcelable {
Location l = new Location(provider);
l.mTime = in.readLong();
l.mElapsedRealtimeNanos = in.readLong();
+ l.mElapsedRealtimeUncertaintyNanos = in.readLong();
l.mFieldsMask = in.readByte();
l.mLatitude = in.readDouble();
l.mLongitude = in.readDouble();
@@ -1122,6 +1167,7 @@ public class Location implements Parcelable {
parcel.writeString(mProvider);
parcel.writeLong(mTime);
parcel.writeLong(mElapsedRealtimeNanos);
+ parcel.writeLong(mElapsedRealtimeUncertaintyNanos);
parcel.writeByte(mFieldsMask);
parcel.writeDouble(mLatitude);
parcel.writeDouble(mLongitude);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 6828c597fe9a..8af153283d70 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -44,12 +44,12 @@ import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
+import android.util.ArrayMap;
import android.util.Log;
import com.android.internal.location.ProviderProperties;
import java.util.ArrayList;
-import java.util.HashMap;
import java.util.List;
/**
@@ -78,14 +78,10 @@ public class LocationManager {
private final GnssMeasurementCallbackTransport mGnssMeasurementCallbackTransport;
private final GnssNavigationMessageCallbackTransport mGnssNavigationMessageCallbackTransport;
private final BatchedLocationCallbackTransport mBatchedLocationCallbackTransport;
- private final HashMap<GpsStatus.Listener, GnssStatusListenerTransport> mGpsStatusListeners =
- new HashMap<>();
- private final HashMap<GpsStatus.NmeaListener, GnssStatusListenerTransport> mGpsNmeaListeners =
- new HashMap<>();
- private final HashMap<GnssStatus.Callback, GnssStatusListenerTransport> mGnssStatusListeners =
- new HashMap<>();
- private final HashMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
- new HashMap<>();
+ private final ArrayMap<GnssStatus.Callback, GnssStatusListenerTransport> mGnssStatusListeners =
+ new ArrayMap<>();
+ private final ArrayMap<OnNmeaMessageListener, GnssStatusListenerTransport> mGnssNmeaListeners =
+ new ArrayMap<>();
// volatile + GnssStatus final-fields pattern to avoid a partially published object
private volatile GnssStatus mGnssStatus;
private int mTimeToFirstFix;
@@ -293,8 +289,7 @@ public class LocationManager {
"com.android.settings.location.FOOTER_STRING";
// Map from LocationListeners to their associated ListenerTransport objects
- private final HashMap<LocationListener, ListenerTransport> mListeners =
- new HashMap<LocationListener,ListenerTransport>();
+ private final ArrayMap<LocationListener, ListenerTransport> mListeners = new ArrayMap<>();
private class ListenerTransport extends ILocationListener.Stub {
private static final int TYPE_LOCATION_CHANGED = 1;
@@ -405,7 +400,7 @@ public class LocationManager {
* @hide
*/
@TestApi
- public String[] getBackgroundThrottlingWhitelist() {
+ public @NonNull String[] getBackgroundThrottlingWhitelist() {
try {
return mService.getBackgroundThrottlingWhitelist();
} catch (RemoteException e) {
@@ -417,7 +412,7 @@ public class LocationManager {
* @hide
*/
@TestApi
- public String[] getIgnoreSettingsWhitelist() {
+ public @NonNull String[] getIgnoreSettingsWhitelist() {
try {
return mService.getIgnoreSettingsWhitelist();
} catch (RemoteException e) {
@@ -431,7 +426,7 @@ public class LocationManager {
* right way to create an instance of this class is using the
* factory Context.getSystemService.
*/
- public LocationManager(Context context, ILocationManager service) {
+ public LocationManager(@NonNull Context context, @NonNull ILocationManager service) {
mService = service;
mContext = context;
mGnssMeasurementCallbackTransport =
@@ -454,7 +449,7 @@ public class LocationManager {
*
* @return list of Strings containing names of the provider
*/
- public List<String> getAllProviders() {
+ public @NonNull List<String> getAllProviders() {
try {
return mService.getAllProviders();
} catch (RemoteException e) {
@@ -469,7 +464,7 @@ public class LocationManager {
* enabled are returned.
* @return list of Strings containing names of the providers
*/
- public List<String> getProviders(boolean enabledOnly) {
+ public @NonNull List<String> getProviders(boolean enabledOnly) {
try {
return mService.getProviders(null, enabledOnly);
} catch (RemoteException e) {
@@ -488,7 +483,7 @@ public class LocationManager {
* @throws SecurityException if the caller is not permitted to access the
* given provider.
*/
- public LocationProvider getProvider(String name) {
+ public @Nullable LocationProvider getProvider(@NonNull String name) {
checkProvider(name);
try {
ProviderProperties properties = mService.getProviderProperties(name);
@@ -511,7 +506,7 @@ public class LocationManager {
* enabled are returned.
* @return list of Strings containing names of the providers
*/
- public List<String> getProviders(Criteria criteria, boolean enabledOnly) {
+ public @NonNull List<String> getProviders(@NonNull Criteria criteria, boolean enabledOnly) {
checkCriteria(criteria);
try {
return mService.getProviders(criteria, enabledOnly);
@@ -542,7 +537,7 @@ public class LocationManager {
* @param enabledOnly if true then only a provider that is currently enabled is returned
* @return name of the provider that best matches the requirements
*/
- public String getBestProvider(Criteria criteria, boolean enabledOnly) {
+ public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) {
checkCriteria(criteria);
try {
return mService.getBestProvider(criteria, enabledOnly);
@@ -572,8 +567,8 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(String provider, long minTime, float minDistance,
- LocationListener listener) {
+ public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ @NonNull LocationListener listener) {
checkProvider(provider);
checkListener(listener);
@@ -604,8 +599,8 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(String provider, long minTime, float minDistance,
- LocationListener listener, Looper looper) {
+ public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ @NonNull LocationListener listener, @Nullable Looper looper) {
checkProvider(provider);
checkListener(listener);
@@ -637,8 +632,8 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
- LocationListener listener, Looper looper) {
+ public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria,
+ @NonNull LocationListener listener, @Nullable Looper looper) {
checkCriteria(criteria);
checkListener(listener);
@@ -665,8 +660,8 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(String provider, long minTime, float minDistance,
- PendingIntent intent) {
+ public void requestLocationUpdates(@NonNull String provider, long minTime, float minDistance,
+ @NonNull PendingIntent intent) {
checkProvider(provider);
checkPendingIntent(intent);
@@ -772,8 +767,8 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(long minTime, float minDistance, Criteria criteria,
- PendingIntent intent) {
+ public void requestLocationUpdates(long minTime, float minDistance, @NonNull Criteria criteria,
+ @NonNull PendingIntent intent) {
checkCriteria(criteria);
checkPendingIntent(intent);
@@ -802,7 +797,8 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(String provider, LocationListener listener, Looper looper) {
+ public void requestSingleUpdate(
+ @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) {
checkProvider(provider);
checkListener(listener);
@@ -832,7 +828,10 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(Criteria criteria, LocationListener listener, Looper looper) {
+ public void requestSingleUpdate(
+ @NonNull Criteria criteria,
+ @NonNull LocationListener listener,
+ @Nullable Looper looper) {
checkCriteria(criteria);
checkListener(listener);
@@ -855,7 +854,7 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(String provider, PendingIntent intent) {
+ public void requestSingleUpdate(@NonNull String provider, @NonNull PendingIntent intent) {
checkProvider(provider);
checkPendingIntent(intent);
@@ -879,7 +878,7 @@ public class LocationManager {
* @throws SecurityException if no suitable permission is present
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestSingleUpdate(Criteria criteria, PendingIntent intent) {
+ public void requestSingleUpdate(@NonNull Criteria criteria, @NonNull PendingIntent intent) {
checkCriteria(criteria);
checkPendingIntent(intent);
@@ -948,8 +947,10 @@ public class LocationManager {
@SystemApi
@TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(LocationRequest request, LocationListener listener,
- Looper looper) {
+ public void requestLocationUpdates(
+ @NonNull LocationRequest request,
+ @NonNull LocationListener listener,
+ @Nullable Looper looper) {
checkListener(listener);
requestLocationUpdates(request, listener, looper, null);
}
@@ -978,7 +979,8 @@ public class LocationManager {
@SystemApi
@TestApi
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void requestLocationUpdates(LocationRequest request, PendingIntent intent) {
+ public void requestLocationUpdates(
+ @NonNull LocationRequest request, @NonNull PendingIntent intent) {
checkPendingIntent(intent);
requestLocationUpdates(request, null, null, intent);
}
@@ -1003,7 +1005,7 @@ public class LocationManager {
* @hide
*/
@RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION})
- public boolean injectLocation(Location newLocation) {
+ public boolean injectLocation(@NonNull Location newLocation) {
try {
return mService.injectLocation(newLocation);
} catch (RemoteException e) {
@@ -1048,7 +1050,7 @@ public class LocationManager {
* @param listener listener object that no longer needs location updates
* @throws IllegalArgumentException if listener is null
*/
- public void removeUpdates(LocationListener listener) {
+ public void removeUpdates(@NonNull LocationListener listener) {
checkListener(listener);
String packageName = mContext.getPackageName();
@@ -1073,7 +1075,7 @@ public class LocationManager {
* @param intent pending intent object that no longer needs location updates
* @throws IllegalArgumentException if intent is null
*/
- public void removeUpdates(PendingIntent intent) {
+ public void removeUpdates(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
@@ -1133,7 +1135,7 @@ public class LocationManager {
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
public void addProximityAlert(double latitude, double longitude, float radius, long expiration,
- PendingIntent intent) {
+ @NonNull PendingIntent intent) {
checkPendingIntent(intent);
if (expiration < 0) expiration = Long.MAX_VALUE;
@@ -1183,7 +1185,10 @@ public class LocationManager {
* @hide
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public void addGeofence(LocationRequest request, Geofence fence, PendingIntent intent) {
+ public void addGeofence(
+ @NonNull LocationRequest request,
+ @NonNull Geofence fence,
+ @NonNull PendingIntent intent) {
checkPendingIntent(intent);
checkGeofence(fence);
@@ -1210,7 +1215,7 @@ public class LocationManager {
* @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
* permission is not present
*/
- public void removeProximityAlert(PendingIntent intent) {
+ public void removeProximityAlert(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
@@ -1237,7 +1242,7 @@ public class LocationManager {
*
* @hide
*/
- public void removeGeofence(Geofence fence, PendingIntent intent) {
+ public void removeGeofence(@NonNull Geofence fence, @NonNull PendingIntent intent) {
checkPendingIntent(intent);
checkGeofence(fence);
String packageName = mContext.getPackageName();
@@ -1260,7 +1265,7 @@ public class LocationManager {
*
* @hide
*/
- public void removeAllGeofences(PendingIntent intent) {
+ public void removeAllGeofences(@NonNull PendingIntent intent) {
checkPendingIntent(intent);
String packageName = mContext.getPackageName();
@@ -1290,7 +1295,7 @@ public class LocationManager {
* @hide
*/
@SystemApi
- public boolean isLocationEnabledForUser(UserHandle userHandle) {
+ public boolean isLocationEnabledForUser(@NonNull UserHandle userHandle) {
try {
return mService.isLocationEnabledForUser(userHandle.getIdentifier());
} catch (RemoteException e) {
@@ -1309,7 +1314,7 @@ public class LocationManager {
@SystemApi
@TestApi
@RequiresPermission(WRITE_SECURE_SETTINGS)
- public void setLocationEnabledForUser(boolean enabled, UserHandle userHandle) {
+ public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) {
Settings.Secure.putIntForUser(
mContext.getContentResolver(),
Settings.Secure.LOCATION_MODE,
@@ -1332,7 +1337,7 @@ public class LocationManager {
*
* @throws IllegalArgumentException if provider is null
*/
- public boolean isProviderEnabled(String provider) {
+ public boolean isProviderEnabled(@NonNull String provider) {
return isProviderEnabledForUser(provider, Process.myUserHandle());
}
@@ -1353,7 +1358,8 @@ public class LocationManager {
* @hide
*/
@SystemApi
- public boolean isProviderEnabledForUser(String provider, UserHandle userHandle) {
+ public boolean isProviderEnabledForUser(
+ @NonNull String provider, @NonNull UserHandle userHandle) {
checkProvider(provider);
try {
@@ -1382,7 +1388,7 @@ public class LocationManager {
@SystemApi
@RequiresPermission(WRITE_SECURE_SETTINGS)
public boolean setProviderEnabledForUser(
- String provider, boolean enabled, UserHandle userHandle) {
+ @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) {
checkProvider(provider);
return Settings.Secure.setLocationProviderEnabledForUser(
@@ -1406,6 +1412,7 @@ public class LocationManager {
*
* @hide
*/
+ @Nullable
public Location getLastLocation() {
String packageName = mContext.getPackageName();
@@ -1434,7 +1441,8 @@ public class LocationManager {
* @throws IllegalArgumentException if provider is null or doesn't exist
*/
@RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION})
- public Location getLastKnownLocation(String provider) {
+ @Nullable
+ public Location getLastKnownLocation(@NonNull String provider) {
checkProvider(provider);
String packageName = mContext.getPackageName();
LocationRequest request = LocationRequest.createFromDeprecatedProvider(
@@ -1447,10 +1455,6 @@ public class LocationManager {
}
}
- // --- Mock provider support ---
- // TODO: It would be fantastic to deprecate mock providers entirely, and replace
- // with something closer to LocationProviderBase.java
-
/**
* Creates a mock location provider and adds it to the set of active providers.
*
@@ -1461,7 +1465,8 @@ public class LocationManager {
* allowed} for your app.
* @throws IllegalArgumentException if a provider with the given name already exists
*/
- public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite,
+ public void addTestProvider(
+ @NonNull String name, boolean requiresNetwork, boolean requiresSatellite,
boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude,
boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) {
ProviderProperties properties = new ProviderProperties(requiresNetwork,
@@ -1488,7 +1493,7 @@ public class LocationManager {
* allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- public void removeTestProvider(String provider) {
+ public void removeTestProvider(@NonNull String provider) {
try {
mService.removeTestProvider(provider, mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1512,7 +1517,7 @@ public class LocationManager {
* @throws IllegalArgumentException if no provider with the given name exists
* @throws IllegalArgumentException if the location is incomplete
*/
- public void setTestProviderLocation(String provider, Location loc) {
+ public void setTestProviderLocation(@NonNull String provider, @NonNull Location loc) {
if (!loc.isComplete()) {
IllegalArgumentException e = new IllegalArgumentException(
"Incomplete location object, missing timestamp or accuracy? " + loc);
@@ -1546,7 +1551,7 @@ public class LocationManager {
* @deprecated This function has always been a no-op, and may be removed in the future.
*/
@Deprecated
- public void clearTestProviderLocation(String provider) {}
+ public void clearTestProviderLocation(@NonNull String provider) {}
/**
* Sets a mock enabled value for the given provider. This value will be used in place
@@ -1560,7 +1565,7 @@ public class LocationManager {
* allowed} for your app.
* @throws IllegalArgumentException if no provider with the given name exists
*/
- public void setTestProviderEnabled(String provider, boolean enabled) {
+ public void setTestProviderEnabled(@NonNull String provider, boolean enabled) {
try {
mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName());
} catch (RemoteException e) {
@@ -1581,7 +1586,7 @@ public class LocationManager {
* @deprecated Use {@link #setTestProviderEnabled(String, boolean)} instead.
*/
@Deprecated
- public void clearTestProviderEnabled(String provider) {
+ public void clearTestProviderEnabled(@NonNull String provider) {
setTestProviderEnabled(provider, false);
}
@@ -1601,7 +1606,8 @@ public class LocationManager {
* @deprecated This method has no effect.
*/
@Deprecated
- public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) {
+ public void setTestProviderStatus(
+ @NonNull String provider, int status, @Nullable Bundle extras, long updateTime) {
try {
mService.setTestProviderStatus(provider, status, extras, updateTime,
mContext.getOpPackageName());
@@ -1622,7 +1628,7 @@ public class LocationManager {
* @deprecated This method has no effect.
*/
@Deprecated
- public void clearTestProviderStatus(String provider) {
+ public void clearTestProviderStatus(@NonNull String provider) {
setTestProviderStatus(provider, LocationProvider.AVAILABLE, null, 0L);
}
@@ -1648,13 +1654,11 @@ public class LocationManager {
// This class is used to send Gnss status events to the client's specific thread.
private class GnssStatusListenerTransport extends IGnssStatusListener.Stub {
- private final GpsStatus.Listener mGpsListener;
- private final GpsStatus.NmeaListener mGpsNmeaListener;
private final GnssStatus.Callback mGnssCallback;
private final OnNmeaMessageListener mGnssNmeaListener;
private class GnssHandler extends Handler {
- public GnssHandler(Handler handler) {
+ GnssHandler(Handler handler) {
super(handler != null ? handler.getLooper() : Looper.myLooper());
}
@@ -1663,24 +1667,22 @@ public class LocationManager {
switch (msg.what) {
case NMEA_RECEIVED:
synchronized (mNmeaBuffer) {
- int length = mNmeaBuffer.size();
- for (int i = 0; i < length; i++) {
- Nmea nmea = mNmeaBuffer.get(i);
+ for (Nmea nmea : mNmeaBuffer) {
mGnssNmeaListener.onNmeaMessage(nmea.mNmea, nmea.mTimestamp);
}
mNmeaBuffer.clear();
}
break;
- case GpsStatus.GPS_EVENT_STARTED:
+ case GNSS_EVENT_STARTED:
mGnssCallback.onStarted();
break;
- case GpsStatus.GPS_EVENT_STOPPED:
+ case GNSS_EVENT_STOPPED:
mGnssCallback.onStopped();
break;
- case GpsStatus.GPS_EVENT_FIRST_FIX:
+ case GNSS_EVENT_FIRST_FIX:
mGnssCallback.onFirstFix(mTimeToFirstFix);
break;
- case GpsStatus.GPS_EVENT_SATELLITE_STATUS:
+ case GNSS_EVENT_SATELLITE_STATUS:
mGnssCallback.onSatelliteStatusChanged(mGnssStatus);
break;
default:
@@ -1691,8 +1693,11 @@ public class LocationManager {
private final Handler mGnssHandler;
- // This must not equal any of the GpsStatus event IDs
- private static final int NMEA_RECEIVED = 1000;
+ private static final int NMEA_RECEIVED = 1;
+ private static final int GNSS_EVENT_STARTED = 2;
+ private static final int GNSS_EVENT_STOPPED = 3;
+ private static final int GNSS_EVENT_FIRST_FIX = 4;
+ private static final int GNSS_EVENT_SATELLITE_STATUS = 5;
private class Nmea {
long mTimestamp;
@@ -1705,98 +1710,31 @@ public class LocationManager {
}
private final ArrayList<Nmea> mNmeaBuffer;
- GnssStatusListenerTransport(GpsStatus.Listener listener) {
- this(listener, null);
- }
-
- GnssStatusListenerTransport(GpsStatus.Listener listener, Handler handler) {
- mGpsListener = listener;
- mGnssHandler = new GnssHandler(handler);
- mGpsNmeaListener = null;
- mNmeaBuffer = null;
- mGnssCallback = mGpsListener != null ? new GnssStatus.Callback() {
- @Override
- public void onStarted() {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED);
- }
-
- @Override
- public void onStopped() {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED);
- }
-
- @Override
- public void onFirstFix(int ttff) {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX);
- }
-
- @Override
- public void onSatelliteStatusChanged(GnssStatus status) {
- mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
- }
- } : null;
- mGnssNmeaListener = null;
- }
-
- GnssStatusListenerTransport(GpsStatus.NmeaListener listener) {
- this(listener, null);
- }
-
- GnssStatusListenerTransport(GpsStatus.NmeaListener listener, Handler handler) {
- mGpsListener = null;
- mGnssHandler = new GnssHandler(handler);
- mGpsNmeaListener = listener;
- mNmeaBuffer = new ArrayList<Nmea>();
- mGnssCallback = null;
- mGnssNmeaListener = mGpsNmeaListener != null ? new OnNmeaMessageListener() {
- @Override
- public void onNmeaMessage(String nmea, long timestamp) {
- mGpsNmeaListener.onNmeaReceived(timestamp, nmea);
- }
- } : null;
- }
-
- GnssStatusListenerTransport(GnssStatus.Callback callback) {
- this(callback, null);
- }
-
GnssStatusListenerTransport(GnssStatus.Callback callback, Handler handler) {
mGnssCallback = callback;
mGnssHandler = new GnssHandler(handler);
mGnssNmeaListener = null;
mNmeaBuffer = null;
- mGpsListener = null;
- mGpsNmeaListener = null;
- }
-
- GnssStatusListenerTransport(OnNmeaMessageListener listener) {
- this(listener, null);
}
GnssStatusListenerTransport(OnNmeaMessageListener listener, Handler handler) {
mGnssCallback = null;
mGnssHandler = new GnssHandler(handler);
mGnssNmeaListener = listener;
- mGpsListener = null;
- mGpsNmeaListener = null;
- mNmeaBuffer = new ArrayList<Nmea>();
+ mNmeaBuffer = new ArrayList<>();
}
@Override
public void onGnssStarted() {
if (mGnssCallback != null) {
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_STARTED;
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(GNSS_EVENT_STARTED).sendToTarget();
}
}
@Override
public void onGnssStopped() {
if (mGnssCallback != null) {
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_STOPPED;
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(GNSS_EVENT_STOPPED).sendToTarget();
}
}
@@ -1804,9 +1742,7 @@ public class LocationManager {
public void onFirstFix(int ttff) {
if (mGnssCallback != null) {
mTimeToFirstFix = ttff;
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_FIRST_FIX;
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(GNSS_EVENT_FIRST_FIX).sendToTarget();
}
}
@@ -1817,11 +1753,8 @@ public class LocationManager {
mGnssStatus = new GnssStatus(svCount, prnWithFlags, cn0s, elevations, azimuths,
carrierFreqs);
- Message msg = Message.obtain();
- msg.what = GpsStatus.GPS_EVENT_SATELLITE_STATUS;
- // remove any SV status messages already in the queue
- mGnssHandler.removeMessages(GpsStatus.GPS_EVENT_SATELLITE_STATUS);
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.removeMessages(GNSS_EVENT_SATELLITE_STATUS);
+ mGnssHandler.obtainMessage(GNSS_EVENT_SATELLITE_STATUS).sendToTarget();
}
}
@@ -1831,11 +1764,9 @@ public class LocationManager {
synchronized (mNmeaBuffer) {
mNmeaBuffer.add(new Nmea(timestamp, nmea));
}
- Message msg = Message.obtain();
- msg.what = NMEA_RECEIVED;
- // remove any NMEA_RECEIVED messages already in the queue
+
mGnssHandler.removeMessages(NMEA_RECEIVED);
- mGnssHandler.sendMessage(msg);
+ mGnssHandler.obtainMessage(NMEA_RECEIVED).sendToTarget();
}
}
}
@@ -1849,27 +1780,12 @@ public class LocationManager {
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
* @deprecated use {@link #registerGnssStatusCallback(GnssStatus.Callback)} instead.
+ * @removed
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addGpsStatusListener(GpsStatus.Listener listener) {
- boolean result;
-
- if (mGpsStatusListeners.get(listener) != null) {
- // listener is already registered
- return true;
- }
- try {
- GnssStatusListenerTransport transport = new GnssStatusListenerTransport(listener);
- result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
- if (result) {
- mGpsStatusListeners.put(listener, transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- return result;
+ return false;
}
/**
@@ -1877,18 +1793,10 @@ public class LocationManager {
*
* @param listener GPS status listener object to remove
* @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead.
+ * @removed
*/
@Deprecated
- public void removeGpsStatusListener(GpsStatus.Listener listener) {
- try {
- GnssStatusListenerTransport transport = mGpsStatusListeners.remove(listener);
- if (transport != null) {
- mService.unregisterGnssStatusCallback(transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ public void removeGpsStatusListener(GpsStatus.Listener listener) {}
/**
* Registers a GNSS status callback.
@@ -1900,7 +1808,7 @@ public class LocationManager {
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssStatusCallback(GnssStatus.Callback callback) {
+ public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
return registerGnssStatusCallback(callback, null);
}
@@ -1915,7 +1823,8 @@ public class LocationManager {
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssStatusCallback(GnssStatus.Callback callback, Handler handler) {
+ public boolean registerGnssStatusCallback(
+ @NonNull GnssStatus.Callback callback, @Nullable Handler handler) {
boolean result;
if (mGnssStatusListeners.get(callback) != null) {
// listener is already registered
@@ -1940,7 +1849,7 @@ public class LocationManager {
*
* @param callback GNSS status callback object to remove
*/
- public void unregisterGnssStatusCallback(GnssStatus.Callback callback) {
+ public void unregisterGnssStatusCallback(@NonNull GnssStatus.Callback callback) {
try {
GnssStatusListenerTransport transport = mGnssStatusListeners.remove(callback);
if (transport != null) {
@@ -1960,27 +1869,12 @@ public class LocationManager {
*
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
* @deprecated use {@link #addNmeaListener(OnNmeaMessageListener)} instead.
+ * @removed
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean addNmeaListener(GpsStatus.NmeaListener listener) {
- boolean result;
-
- if (mGpsNmeaListeners.get(listener) != null) {
- // listener is already registered
- return true;
- }
- try {
- GnssStatusListenerTransport transport = new GnssStatusListenerTransport(listener);
- result = mService.registerGnssStatusCallback(transport, mContext.getPackageName());
- if (result) {
- mGpsNmeaListeners.put(listener, transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
- return result;
+ return false;
}
/**
@@ -1988,18 +1882,10 @@ public class LocationManager {
*
* @param listener a {@link GpsStatus.NmeaListener} object to remove
* @deprecated use {@link #removeNmeaListener(OnNmeaMessageListener)} instead.
+ * @removed
*/
@Deprecated
- public void removeNmeaListener(GpsStatus.NmeaListener listener) {
- try {
- GnssStatusListenerTransport transport = mGpsNmeaListeners.remove(listener);
- if (transport != null) {
- mService.unregisterGnssStatusCallback(transport);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
+ public void removeNmeaListener(GpsStatus.NmeaListener listener) {}
/**
* Adds an NMEA listener.
@@ -2011,7 +1897,7 @@ public class LocationManager {
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean addNmeaListener(OnNmeaMessageListener listener) {
+ public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) {
return addNmeaListener(listener, null);
}
@@ -2026,10 +1912,11 @@ public class LocationManager {
* @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean addNmeaListener(OnNmeaMessageListener listener, Handler handler) {
+ public boolean addNmeaListener(
+ @NonNull OnNmeaMessageListener listener, @Nullable Handler handler) {
boolean result;
- if (mGpsNmeaListeners.get(listener) != null) {
+ if (mGnssNmeaListeners.get(listener) != null) {
// listener is already registered
return true;
}
@@ -2052,7 +1939,7 @@ public class LocationManager {
*
* @param listener a {@link OnNmeaMessageListener} object to remove
*/
- public void removeNmeaListener(OnNmeaMessageListener listener) {
+ public void removeNmeaListener(@NonNull OnNmeaMessageListener listener) {
try {
GnssStatusListenerTransport transport = mGnssNmeaListeners.remove(listener);
if (transport != null) {
@@ -2068,6 +1955,7 @@ public class LocationManager {
* Don't use it. Use {@link #registerGnssMeasurementsCallback} instead.
* @hide
* @deprecated Not supported anymore.
+ * @removed
*/
@Deprecated
@SystemApi
@@ -2083,7 +1971,8 @@ public class LocationManager {
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback) {
+ public boolean registerGnssMeasurementsCallback(
+ @NonNull GnssMeasurementsEvent.Callback callback) {
return registerGnssMeasurementsCallback(callback, null);
}
@@ -2095,8 +1984,8 @@ public class LocationManager {
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
- public boolean registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback,
- Handler handler) {
+ public boolean registerGnssMeasurementsCallback(
+ @NonNull GnssMeasurementsEvent.Callback callback, @Nullable Handler handler) {
return mGnssMeasurementCallbackTransport.add(callback, handler);
}
@@ -2120,15 +2009,12 @@ public class LocationManager {
}
/**
- * Returns an integer with flags representing the capabilities of the GNSS chipset.
+ * Returns the integer capability flags of the GNSS chipset as defined in {@code
+ * IGnssCallback.hal}
*
* @hide
*/
@SystemApi
- /**
- * Returns the integer capability flags of the GNSS chipset as defined in {@code
- * IGnssCallback.hal}
- */
public int getGnssCapabilities() {
try {
return mGnssMeasurementCallbackTransport.getGnssCapabilities();
@@ -2144,6 +2030,7 @@ public class LocationManager {
* @hide
* @deprecated use {@link #unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback)}
* instead.
+ * @removed
*/
@Deprecated
@SystemApi
@@ -2155,7 +2042,8 @@ public class LocationManager {
*
* @param callback a {@link GnssMeasurementsEvent.Callback} object to remove.
*/
- public void unregisterGnssMeasurementsCallback(GnssMeasurementsEvent.Callback callback) {
+ public void unregisterGnssMeasurementsCallback(
+ @NonNull GnssMeasurementsEvent.Callback callback) {
mGnssMeasurementCallbackTransport.remove(callback);
}
@@ -2164,6 +2052,7 @@ public class LocationManager {
* Don't use it. Use {@link #registerGnssNavigationMessageCallback} instead.
* @hide
* @deprecated Not supported anymore.
+ * @removed
*/
@Deprecated
@SystemApi
@@ -2179,12 +2068,12 @@ public class LocationManager {
* @deprecated use
* {@link #unregisterGnssNavigationMessageCallback(GnssNavigationMessage.Callback)}
* instead
+ * @removed
*/
@Deprecated
@SystemApi
@SuppressLint("Doclava125")
- public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {
- }
+ public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {}
/**
* Registers a GNSS Navigation Message callback.
@@ -2193,7 +2082,7 @@ public class LocationManager {
* @return {@code true} if the callback was added successfully, {@code false} otherwise.
*/
public boolean registerGnssNavigationMessageCallback(
- GnssNavigationMessage.Callback callback) {
+ @NonNull GnssNavigationMessage.Callback callback) {
return registerGnssNavigationMessageCallback(callback, null);
}
@@ -2206,7 +2095,7 @@ public class LocationManager {
*/
@RequiresPermission(ACCESS_FINE_LOCATION)
public boolean registerGnssNavigationMessageCallback(
- GnssNavigationMessage.Callback callback, Handler handler) {
+ @NonNull GnssNavigationMessage.Callback callback, @Nullable Handler handler) {
return mGnssNavigationMessageCallbackTransport.add(callback, handler);
}
@@ -2216,7 +2105,7 @@ public class LocationManager {
* @param callback a {@link GnssNavigationMessage.Callback} object to remove.
*/
public void unregisterGnssNavigationMessageCallback(
- GnssNavigationMessage.Callback callback) {
+ @NonNull GnssNavigationMessage.Callback callback) {
mGnssNavigationMessageCallbackTransport.remove(callback);
}
@@ -2230,19 +2119,12 @@ public class LocationManager {
*
* @param status object containing GPS status details, or null.
* @return status object containing updated GPS status.
+ * @removed
*/
@Deprecated
@RequiresPermission(ACCESS_FINE_LOCATION)
- public GpsStatus getGpsStatus(GpsStatus status) {
- if (status == null) {
- status = new GpsStatus();
- }
- // When mGnssStatus is null, that means that this method is called outside
- // onGpsStatusChanged(). Return an empty status to maintain backwards compatibility.
- if (mGnssStatus != null) {
- status.setStatus(mGnssStatus, mTimeToFirstFix);
- }
- return status;
+ public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) {
+ return null;
}
/**
@@ -2319,7 +2201,7 @@ public class LocationManager {
@SystemApi
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
public boolean registerGnssBatchedLocationCallback(long periodNanos, boolean wakeOnFifoFull,
- BatchedLocationCallback callback, Handler handler) {
+ @NonNull BatchedLocationCallback callback, @Nullable Handler handler) {
mBatchedLocationCallbackTransport.add(callback, handler);
try {
@@ -2357,7 +2239,8 @@ public class LocationManager {
*/
@SystemApi
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
- public boolean unregisterGnssBatchedLocationCallback(BatchedLocationCallback callback) {
+ public boolean unregisterGnssBatchedLocationCallback(
+ @NonNull BatchedLocationCallback callback) {
mBatchedLocationCallbackTransport.remove(callback);
@@ -2379,7 +2262,8 @@ public class LocationManager {
*
* @return true if the command succeeds.
*/
- public boolean sendExtraCommand(String provider, String command, Bundle extras) {
+ public boolean sendExtraCommand(
+ @NonNull String provider, @NonNull String command, @Nullable Bundle extras) {
try {
return mService.sendExtraCommand(provider, command, extras);
} catch (RemoteException e) {
@@ -2448,7 +2332,7 @@ public class LocationManager {
* @hide
*/
@SystemApi
- public boolean isProviderPackage(String packageName) {
+ public boolean isProviderPackage(@NonNull String packageName) {
try {
return mService.isProviderPackage(packageName);
} catch (RemoteException e) {
@@ -2464,7 +2348,7 @@ public class LocationManager {
*/
@SystemApi
@RequiresPermission(Manifest.permission.LOCATION_HARDWARE)
- public void setLocationControllerExtraPackage(String packageName) {
+ public void setLocationControllerExtraPackage(@NonNull String packageName) {
try {
mService.setLocationControllerExtraPackage(packageName);
} catch (RemoteException e) {
diff --git a/location/java/android/location/LocationRequest.java b/location/java/android/location/LocationRequest.java
index 6fd063eb62f0..a05d8501bc1f 100644
--- a/location/java/android/location/LocationRequest.java
+++ b/location/java/android/location/LocationRequest.java
@@ -17,6 +17,8 @@
package android.location;
import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.TestApi;
@@ -183,14 +185,16 @@ public final class LocationRequest implements Parcelable {
*
* @return a new location request
*/
+ @NonNull
public static LocationRequest create() {
return new LocationRequest();
}
/** @hide */
@SystemApi
- public static LocationRequest createFromDeprecatedProvider(String provider, long minTime,
- float minDistance, boolean singleShot) {
+ @NonNull
+ public static LocationRequest createFromDeprecatedProvider(
+ @NonNull String provider, long minTime, float minDistance, boolean singleShot) {
if (minTime < 0) minTime = 0;
if (minDistance < 0) minDistance = 0;
@@ -215,8 +219,9 @@ public final class LocationRequest implements Parcelable {
/** @hide */
@SystemApi
- public static LocationRequest createFromDeprecatedCriteria(Criteria criteria, long minTime,
- float minDistance, boolean singleShot) {
+ @NonNull
+ public static LocationRequest createFromDeprecatedCriteria(
+ @NonNull Criteria criteria, long minTime, float minDistance, boolean singleShot) {
if (minTime < 0) minTime = 0;
if (minDistance < 0) minDistance = 0;
@@ -287,7 +292,7 @@ public final class LocationRequest implements Parcelable {
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the quality constant is not valid
*/
- public LocationRequest setQuality(int quality) {
+ public @NonNull LocationRequest setQuality(int quality) {
checkQuality(quality);
mQuality = quality;
return this;
@@ -330,7 +335,7 @@ public final class LocationRequest implements Parcelable {
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the interval is less than zero
*/
- public LocationRequest setInterval(long millis) {
+ public @NonNull LocationRequest setInterval(long millis) {
checkInterval(millis);
mInterval = millis;
if (!mExplicitFastestInterval) {
@@ -362,7 +367,7 @@ public final class LocationRequest implements Parcelable {
* @hide
*/
@SystemApi
- public LocationRequest setLowPowerMode(boolean enabled) {
+ public @NonNull LocationRequest setLowPowerMode(boolean enabled) {
mLowPowerMode = enabled;
return this;
}
@@ -386,7 +391,7 @@ public final class LocationRequest implements Parcelable {
* @return the same object, so that setters can be chained
*/
@RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
- public LocationRequest setLocationSettingsIgnored(boolean locationSettingsIgnored) {
+ public @NonNull LocationRequest setLocationSettingsIgnored(boolean locationSettingsIgnored) {
mLocationSettingsIgnored = locationSettingsIgnored;
return this;
}
@@ -427,7 +432,7 @@ public final class LocationRequest implements Parcelable {
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if the interval is less than zero
*/
- public LocationRequest setFastestInterval(long millis) {
+ public @NonNull LocationRequest setFastestInterval(long millis) {
checkInterval(millis);
mExplicitFastestInterval = true;
mFastestInterval = millis;
@@ -463,7 +468,7 @@ public final class LocationRequest implements Parcelable {
* @param millis duration of request in milliseconds
* @return the same object, so that setters can be chained
*/
- public LocationRequest setExpireIn(long millis) {
+ public @NonNull LocationRequest setExpireIn(long millis) {
long elapsedRealtime = SystemClock.elapsedRealtime();
// Check for > Long.MAX_VALUE overflow (elapsedRealtime > 0):
@@ -491,7 +496,7 @@ public final class LocationRequest implements Parcelable {
* @param millis expiration time of request, in milliseconds since boot including suspend
* @return the same object, so that setters can be chained
*/
- public LocationRequest setExpireAt(long millis) {
+ public @NonNull LocationRequest setExpireAt(long millis) {
mExpireAt = millis;
if (mExpireAt < 0) mExpireAt = 0;
return this;
@@ -522,7 +527,7 @@ public final class LocationRequest implements Parcelable {
* @return the same object, so that setters can be chained
* @throws IllegalArgumentException if numUpdates is 0 or less
*/
- public LocationRequest setNumUpdates(int numUpdates) {
+ public @NonNull LocationRequest setNumUpdates(int numUpdates) {
if (numUpdates <= 0) {
throw new IllegalArgumentException(
"invalid numUpdates: " + numUpdates);
@@ -553,7 +558,8 @@ public final class LocationRequest implements Parcelable {
}
}
- public LocationRequest setProvider(String provider) {
+ /** Sets the provider to use for this location request. */
+ public @NonNull LocationRequest setProvider(@NonNull String provider) {
checkProvider(provider);
mProvider = provider;
return this;
@@ -561,13 +567,13 @@ public final class LocationRequest implements Parcelable {
/** @hide */
@SystemApi
- public String getProvider() {
+ public @NonNull String getProvider() {
return mProvider;
}
/** @hide */
@SystemApi
- public LocationRequest setSmallestDisplacement(float meters) {
+ public @NonNull LocationRequest setSmallestDisplacement(float meters) {
checkDisplacement(meters);
mSmallestDisplacement = meters;
return this;
@@ -590,13 +596,13 @@ public final class LocationRequest implements Parcelable {
* @hide
*/
@SystemApi
- public void setWorkSource(WorkSource workSource) {
+ public void setWorkSource(@Nullable WorkSource workSource) {
mWorkSource = workSource;
}
/** @hide */
@SystemApi
- public WorkSource getWorkSource() {
+ public @Nullable WorkSource getWorkSource() {
return mWorkSource;
}
diff --git a/media/apex/java/android/media/MediaItem2.java b/media/apex/java/android/media/MediaItem2.java
index fc0f08ead46e..ff0d43e41350 100644
--- a/media/apex/java/android/media/MediaItem2.java
+++ b/media/apex/java/android/media/MediaItem2.java
@@ -245,7 +245,7 @@ public final class MediaItem2 implements Parcelable {
/**
* Builder for {@link MediaItem2}.
*/
- public static class Builder {
+ public static final class Builder {
@SuppressWarnings("WeakerAccess") /* synthetic access */
MediaMetadata mMetadata;
@SuppressWarnings("WeakerAccess") /* synthetic access */
diff --git a/media/java/android/media/AudioAttributes.java b/media/java/android/media/AudioAttributes.java
index 46d4204b4d5e..c2f29bc6e3bc 100644
--- a/media/java/android/media/AudioAttributes.java
+++ b/media/java/android/media/AudioAttributes.java
@@ -374,9 +374,15 @@ public final class AudioAttributes implements Parcelable {
*/
public static final int FLAG_NO_CAPTURE = 0x1 << 10;
+ /**
+ * @hide
+ * Flag indicating force muting haptic channels.
+ */
+ public static final int FLAG_MUTE_HAPTIC = 0x1 << 11;
+
private final static int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO |
FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY |
- FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER;
+ FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_MUTE_HAPTIC;
private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
@@ -467,6 +473,14 @@ public final class AudioAttributes implements Parcelable {
}
/**
+ * Return if haptic channels are muted.
+ * @return {@code true} if haptic channels are muted, {@code false} otherwise.
+ */
+ public boolean areHapticChannelsMuted() {
+ return (mFlags & FLAG_MUTE_HAPTIC) != 0;
+ }
+
+ /**
* Builder class for {@link AudioAttributes} objects.
* <p> Here is an example where <code>Builder</code> is used to define the
* {@link AudioAttributes} to be used by a new <code>AudioTrack</code> instance:
@@ -490,6 +504,7 @@ public final class AudioAttributes implements Parcelable {
private int mContentType = CONTENT_TYPE_UNKNOWN;
private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID;
private int mFlags = 0x0;
+ private boolean mMuteHapticChannels = false;
private HashSet<String> mTags = new HashSet<String>();
private Bundle mBundle;
@@ -528,6 +543,9 @@ public final class AudioAttributes implements Parcelable {
aa.mUsage = mUsage;
aa.mSource = mSource;
aa.mFlags = mFlags;
+ if (mMuteHapticChannels) {
+ aa.mFlags |= FLAG_MUTE_HAPTIC;
+ }
aa.mTags = (HashSet<String>) mTags.clone();
aa.mFormattedTags = TextUtils.join(";", mTags);
if (mBundle != null) {
@@ -630,7 +648,7 @@ public final class AudioAttributes implements Parcelable {
* true to allow apps to capture the audio
* @return the same Builder instance
*/
- public Builder setAllowCapture(boolean allowCapture) {
+ public @NonNull Builder setAllowCapture(boolean allowCapture) {
if (allowCapture) {
mFlags &= ~FLAG_NO_CAPTURE;
} else {
@@ -803,6 +821,17 @@ public final class AudioAttributes implements Parcelable {
}
return this;
}
+
+ /**
+ * Specifying if haptic should be muted or not when playing audio-haptic coupled data.
+ * By default, haptic channels are enabled.
+ * @param muted true to force muting haptic channels.
+ * @return the same Builder instance.
+ */
+ public Builder setMuteHapticChannels(boolean muted) {
+ mMuteHapticChannels = muted;
+ return this;
+ }
};
@Override
diff --git a/media/java/android/media/AudioPlaybackCaptureConfiguration.java b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
index 9a16aea1e052..333cd2d4f0cf 100644
--- a/media/java/android/media/AudioPlaybackCaptureConfiguration.java
+++ b/media/java/android/media/AudioPlaybackCaptureConfiguration.java
@@ -72,7 +72,7 @@ public final class AudioPlaybackCaptureConfiguration {
*
* @param audioFormat The format in which to capture the audio.
*/
- AudioMix createAudioMix(AudioFormat audioFormat) {
+ @NonNull AudioMix createAudioMix(@NonNull AudioFormat audioFormat) {
return new AudioMix.Builder(mAudioMixingRule)
.setFormat(audioFormat)
.setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK | AudioMix.ROUTE_FLAG_RENDER)
@@ -123,7 +123,7 @@ public final class AudioPlaybackCaptureConfiguration {
* @throws IllegalStateException if called in conjunction with
* {@link #excludeUsage(AudioAttributes)}.
*/
- public Builder addMatchingUsage(@NonNull AudioAttributes audioAttributes) {
+ public @NonNull Builder addMatchingUsage(@NonNull AudioAttributes audioAttributes) {
Preconditions.checkNotNull(audioAttributes);
Preconditions.checkState(
mUsageMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
@@ -141,7 +141,7 @@ public final class AudioPlaybackCaptureConfiguration {
*
* @throws IllegalStateException if called in conjunction with {@link #excludeUid(int)}.
*/
- public Builder addMatchingUid(int uid) {
+ public @NonNull Builder addMatchingUid(int uid) {
Preconditions.checkState(
mUidMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
mAudioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid);
@@ -158,7 +158,7 @@ public final class AudioPlaybackCaptureConfiguration {
* @throws IllegalStateException if called in conjunction with
* {@link #addMatchingUsage(AudioAttributes)}.
*/
- public Builder excludeUsage(@NonNull AudioAttributes audioAttributes) {
+ public @NonNull Builder excludeUsage(@NonNull AudioAttributes audioAttributes) {
Preconditions.checkNotNull(audioAttributes);
Preconditions.checkState(
mUsageMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
@@ -176,7 +176,7 @@ public final class AudioPlaybackCaptureConfiguration {
*
* @throws IllegalStateException if called in conjunction with {@link #addMatchingUid(int)}.
*/
- public Builder excludeUid(int uid) {
+ public @NonNull Builder excludeUid(int uid) {
Preconditions.checkState(
mUidMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
mAudioMixingRuleBuilder.excludeMixRule(AudioMixingRule.RULE_MATCH_UID, uid);
@@ -189,7 +189,7 @@ public final class AudioPlaybackCaptureConfiguration {
*
* @throws UnsupportedOperationException if the parameters set are incompatible.
*/
- public AudioPlaybackCaptureConfiguration build() {
+ public @NonNull AudioPlaybackCaptureConfiguration build() {
return new AudioPlaybackCaptureConfiguration(mAudioMixingRuleBuilder.build(),
mProjection);
}
diff --git a/media/java/android/media/AudioRecord.java b/media/java/android/media/AudioRecord.java
index 3d5120f86db3..28937a65ad0d 100644
--- a/media/java/android/media/AudioRecord.java
+++ b/media/java/android/media/AudioRecord.java
@@ -618,7 +618,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
* @throws IllegalStateException if called in conjunction with {@link #setAudioSource(int)}.
* @throws NullPointerException if {@code config} is null.
*/
- public Builder setAudioPlaybackCaptureConfig(
+ public @NonNull Builder setAudioPlaybackCaptureConfig(
@NonNull AudioPlaybackCaptureConfiguration config) {
Preconditions.checkNotNull(
config, "Illegal null AudioPlaybackCaptureConfiguration argument");
@@ -647,7 +647,7 @@ public class AudioRecord implements AudioRouting, MicrophoneDirection,
return this;
}
- private AudioRecord buildAudioPlaybackCaptureRecord() {
+ private @NonNull AudioRecord buildAudioPlaybackCaptureRecord() {
AudioMix audioMix = mAudioPlaybackCaptureConfiguration.createAudioMix(mFormat);
MediaProjection projection = mAudioPlaybackCaptureConfiguration.getMediaProjection();
AudioPolicy audioPolicy = new AudioPolicy.Builder(/*context=*/ null)
diff --git a/media/java/android/media/ExifInterface.java b/media/java/android/media/ExifInterface.java
index 31d22327c79f..bc91ca3df3a2 100644
--- a/media/java/android/media/ExifInterface.java
+++ b/media/java/android/media/ExifInterface.java
@@ -1891,7 +1891,7 @@ public class ExifInterface {
*
* @param tag the name of the tag.
*/
- public boolean hasAttribute(String tag) {
+ public boolean hasAttribute(@NonNull String tag) {
return (getExifAttribute(tag) != null);
}
diff --git a/media/java/android/media/HwAudioSource.java b/media/java/android/media/HwAudioSource.java
index d9be0a593e4b..e53b7e898c6d 100644
--- a/media/java/android/media/HwAudioSource.java
+++ b/media/java/android/media/HwAudioSource.java
@@ -129,6 +129,7 @@ public class HwAudioSource extends PlayerBase {
* Starts the playback from {@link AudioDeviceInfo}.
*/
public void start() {
+ Preconditions.checkState(!isPlaying(), "HwAudioSource is currently playing");
baseStart();
mNativeHandle = AudioSystem.startAudioSource(
mAudioDeviceInfo.getPort().activeConfig(),
@@ -136,6 +137,14 @@ public class HwAudioSource extends PlayerBase {
}
/**
+ * Checks whether the HwAudioSource player is playing.
+ * @return true if currently playing, false otherwise
+ */
+ public boolean isPlaying() {
+ return mNativeHandle != 0;
+ }
+
+ /**
* Stops the playback from {@link AudioDeviceInfo}.
*/
public void stop() {
diff --git a/packages/CaptivePortalLogin/Android.bp b/packages/CaptivePortalLogin/Android.bp
index a71977f8cc6c..bc614e9fc14c 100644
--- a/packages/CaptivePortalLogin/Android.bp
+++ b/packages/CaptivePortalLogin/Android.bp
@@ -18,6 +18,7 @@ android_app {
name: "CaptivePortalLogin",
srcs: ["src/**/*.java"],
sdk_version: "system_current",
+ min_sdk_version: "28",
certificate: "networkstack",
static_libs: [
"androidx.legacy_legacy-support-v4",
diff --git a/packages/CaptivePortalLogin/AndroidManifest.xml b/packages/CaptivePortalLogin/AndroidManifest.xml
index a5f3b88fef0a..44e0a659212a 100644
--- a/packages/CaptivePortalLogin/AndroidManifest.xml
+++ b/packages/CaptivePortalLogin/AndroidManifest.xml
@@ -18,7 +18,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.captiveportallogin"
- android:versionCode="10"
+ android:versionCode="11"
android:versionName="Q-initial">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java b/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
index 7755cbc9ca3b..719417e96015 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
+++ b/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/DynamicAndroidInstallationService.java
@@ -114,6 +114,7 @@ public class DynamicAndroidInstallationService extends Service
private NotificationManager mNM;
private long mSystemSize;
+ private long mUserdataSize;
private long mInstalledSize;
private boolean mJustCancelledByUser;
@@ -220,9 +221,11 @@ public class DynamicAndroidInstallationService extends Service
String url = intent.getStringExtra(DynamicAndroidClient.KEY_SYSTEM_URL);
mSystemSize = intent.getLongExtra(DynamicAndroidClient.KEY_SYSTEM_SIZE, 0);
- long userdata = intent.getLongExtra(DynamicAndroidClient.KEY_USERDATA_SIZE, 0);
+ mUserdataSize = intent.getLongExtra(DynamicAndroidClient.KEY_USERDATA_SIZE, 0);
+
+ mInstallTask = new InstallationAsyncTask(
+ url, mSystemSize, mUserdataSize, mDynAndroid, this);
- mInstallTask = new InstallationAsyncTask(url, mSystemSize, userdata, mDynAndroid, this);
mInstallTask.execute();
// start fore ground
@@ -332,8 +335,8 @@ public class DynamicAndroidInstallationService extends Service
case STATUS_IN_PROGRESS:
builder.setContentText(getString(R.string.notification_install_inprogress));
- int max = (int) Math.max(mSystemSize >> 20, 1);
- int progress = (int) mInstalledSize >> 20;
+ int max = (int) Math.max((mSystemSize + mUserdataSize) >> 20, 1);
+ int progress = (int) (mInstalledSize >> 20);
builder.setProgress(max, progress, false);
diff --git a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java b/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
index 3c759e948b4e..03fc7739fcce 100644
--- a/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
+++ b/packages/DynamicAndroidInstallationService/src/com/android/dynandroid/InstallationAsyncTask.java
@@ -16,6 +16,7 @@
package com.android.dynandroid;
+import android.gsi.GsiProgress;
import android.os.AsyncTask;
import android.os.DynamicAndroidManager;
import android.util.Log;
@@ -63,8 +64,6 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> {
private final InstallStatusListener mListener;
private DynamicAndroidManager.Session mInstallationSession;
- private long mInstalledSize;
- private long mReportedInstalledSize;
private int mResult = NO_RESULT;
private InputStream mStream;
@@ -89,8 +88,40 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> {
Log.d(TAG, "Start doInBackground(), URL: " + mUrl);
try {
- // call start in background
- mInstallationSession = mDynamicAndroid.startInstallation(mSystemSize, mUserdataSize);
+ long installedSize = 0;
+ long reportedInstalledSize = 0;
+
+ long minStepToReport = (mSystemSize + mUserdataSize) / 100;
+
+ // init input stream before calling startInstallation(), which takes 90 seconds.
+ initInputStream();
+
+ Thread thread = new Thread(() -> {
+ mInstallationSession =
+ mDynamicAndroid.startInstallation(mSystemSize, mUserdataSize);
+ });
+
+
+ thread.start();
+
+ while (thread.isAlive()) {
+ if (isCancelled()) {
+ boolean aborted = mDynamicAndroid.abort();
+ Log.d(TAG, "Called DynamicAndroidManager.abort(), result = " + aborted);
+ return RESULT_OK;
+ }
+
+ GsiProgress progress = mDynamicAndroid.getInstallationProgress();
+ installedSize = progress.bytes_processed;
+
+ if (installedSize > reportedInstalledSize + minStepToReport) {
+ publishProgress(installedSize);
+ reportedInstalledSize = installedSize;
+ }
+
+ Thread.sleep(10);
+ }
+
if (mInstallationSession == null) {
Log.e(TAG, "Failed to start installation with requested size: "
@@ -99,12 +130,11 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> {
return RESULT_ERROR_IO;
}
- initInputStream();
+ installedSize = mUserdataSize;
byte[] bytes = new byte[READ_BUFFER_SIZE];
int numBytesRead;
- long minStepToReport = mSystemSize / 100;
Log.d(TAG, "Start installation loop");
while ((numBytesRead = mStream.read(bytes, 0, READ_BUFFER_SIZE)) != -1) {
@@ -119,11 +149,11 @@ class InstallationAsyncTask extends AsyncTask<String, Long, Integer> {
throw new IOException("Failed write() to DynamicAndroid");
}
- mInstalledSize += numBytesRead;
+ installedSize += numBytesRead;
- if (mInstalledSize > mReportedInstalledSize + minStepToReport) {
- publishProgress(mInstalledSize);
- mReportedInstalledSize = mInstalledSize;
+ if (installedSize > reportedInstalledSize + minStepToReport) {
+ publishProgress(installedSize);
+ reportedInstalledSize = installedSize;
}
}
diff --git a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
index eeabb866f03f..293b5b8c9d8c 100644
--- a/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
+++ b/packages/ExtServices/tests/src/android/ext/services/notification/AssistantSettingsTest.java
@@ -19,6 +19,8 @@ package android.ext.services.notification;
import static android.ext.services.notification.AssistantSettings.DEFAULT_MAX_SUGGESTIONS;
import static android.provider.DeviceConfig.setProperty;
+import static com.android.compatibility.common.util.SystemUtil.runWithShellPermissionIdentity;
+
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
@@ -89,11 +91,11 @@ public class AssistantSettingsTest {
@Test
public void testGenerateRepliesDisabled() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
"false",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
@@ -104,11 +106,11 @@ public class AssistantSettingsTest {
@Test
public void testGenerateRepliesEnabled() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
"true",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
@@ -119,11 +121,11 @@ public class AssistantSettingsTest {
@Test
public void testGenerateRepliesEmptyFlag() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
"false",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
@@ -131,11 +133,11 @@ public class AssistantSettingsTest {
assertFalse(mAssistantSettings.mGenerateReplies);
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
"",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_REPLIES,
@@ -147,11 +149,11 @@ public class AssistantSettingsTest {
@Test
public void testGenerateActionsDisabled() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
"false",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
@@ -162,11 +164,11 @@ public class AssistantSettingsTest {
@Test
public void testGenerateActionsEnabled() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
"true",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
@@ -177,11 +179,11 @@ public class AssistantSettingsTest {
@Test
public void testGenerateActionsEmptyFlag() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
"false",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
@@ -189,11 +191,11 @@ public class AssistantSettingsTest {
assertFalse(mAssistantSettings.mGenerateActions);
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
"",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_GENERATE_ACTIONS,
@@ -205,11 +207,11 @@ public class AssistantSettingsTest {
@Test
public void testMaxMessagesToExtract() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
"10",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_MAX_MESSAGES_TO_EXTRACT,
@@ -220,11 +222,11 @@ public class AssistantSettingsTest {
@Test
public void testMaxSuggestions() {
- setProperty(
+ runWithShellPermissionIdentity(() -> setProperty(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
"5",
- false /* makeDefault */);
+ false /* makeDefault */));
mAssistantSettings.onDeviceConfigPropertyChanged(
DeviceConfig.NAMESPACE_SYSTEMUI,
SystemUiDeviceConfigFlags.NAS_MAX_SUGGESTIONS,
diff --git a/packages/NetworkStack/Android.bp b/packages/NetworkStack/Android.bp
index 5f1f26d88171..f210840b976f 100644
--- a/packages/NetworkStack/Android.bp
+++ b/packages/NetworkStack/Android.bp
@@ -36,6 +36,7 @@ java_library {
android_app {
name: "NetworkStack",
sdk_version: "system_current",
+ min_sdk_version: "28",
certificate: "networkstack",
privileged: true,
static_libs: [
diff --git a/packages/NetworkStack/AndroidManifest.xml b/packages/NetworkStack/AndroidManifest.xml
index 740c573eb914..003f1e59d743 100644
--- a/packages/NetworkStack/AndroidManifest.xml
+++ b/packages/NetworkStack/AndroidManifest.xml
@@ -19,7 +19,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack"
android:sharedUserId="android.uid.networkstack"
- android:versionCode="10"
+ android:versionCode="11"
android:versionName="Q-initial">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.INTERNET" />
diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
index e82a5d7b4881..c3447fdb3d78 100644
--- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
+++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java
@@ -32,6 +32,7 @@ import static android.net.metrics.ValidationProbeEvent.DNS_SUCCESS;
import static android.net.metrics.ValidationProbeEvent.PROBE_FALLBACK;
import static android.net.metrics.ValidationProbeEvent.PROBE_PRIVDNS;
import static android.net.util.NetworkStackUtils.isEmpty;
+import static android.provider.Settings.Global.DATA_STALL_EVALUATION_TYPE_DNS;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -128,9 +129,8 @@ public class NetworkMonitor extends StateMachine {
private static final int DEFAULT_DATA_STALL_MIN_EVALUATE_TIME_MS = 60 * 1000;
private static final int DEFAULT_DATA_STALL_VALID_DNS_TIME_THRESHOLD_MS = 30 * 60 * 1000;
- private static final int DATA_STALL_EVALUATION_TYPE_DNS = 1;
private static final int DEFAULT_DATA_STALL_EVALUATION_TYPES =
- (1 << DATA_STALL_EVALUATION_TYPE_DNS);
+ DATA_STALL_EVALUATION_TYPE_DNS;
// Reevaluate it as intending to increase the number. Larger log size may cause statsd
// log buffer bust and have stats log lost.
private static final int DEFAULT_DNS_LOG_SIZE = 20;
@@ -1772,7 +1772,7 @@ public class NetworkMonitor extends StateMachine {
}
private boolean dataStallEvaluateTypeEnabled(int type) {
- return (mDataStallEvaluationType & (1 << type)) != 0;
+ return (mDataStallEvaluationType & type) != 0;
}
@VisibleForTesting
@@ -1792,7 +1792,7 @@ public class NetworkMonitor extends StateMachine {
}
// Check dns signal. Suspect it may be a data stall if both :
- // 1. The number of consecutive DNS query timeouts > mConsecutiveDnsTimeoutThreshold.
+ // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold.
// 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms.
if (dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) {
if (mDnsStallDetector.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold,
diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
index 04b906b4b9b1..ee2baf20bb8e 100644
--- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
+++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java
@@ -20,6 +20,7 @@ import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID;
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
+import static android.provider.Settings.Global.DATA_STALL_EVALUATION_TYPE_DNS;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -114,7 +115,6 @@ public class NetworkMonitorTest {
private static final String TEST_OTHER_FALLBACK_URL = "http://otherfallback.google.com/gen_204";
private static final String TEST_MCCMNC = "123456";
- private static final int DATA_STALL_EVALUATION_TYPE_DNS = 1;
private static final int RETURN_CODE_DNS_SUCCESS = 0;
private static final int RETURN_CODE_DNS_TIMEOUT = 255;
private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5;
@@ -186,7 +186,7 @@ public class NetworkMonitorTest {
when(mCm.getNetworkCapabilities(any())).thenReturn(METERED_CAPABILITIES);
setMinDataStallEvaluateInterval(500);
- setDataStallEvaluationType(1 << DATA_STALL_EVALUATION_TYPE_DNS);
+ setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS);
setValidDataStallDnsTimeThreshold(500);
setConsecutiveDnsTimeoutThreshold(5);
}
diff --git a/packages/NetworkStackPermissionStub/Android.bp b/packages/NetworkStackPermissionStub/Android.bp
index dd70cf56b51b..8cee92e5fe6d 100644
--- a/packages/NetworkStackPermissionStub/Android.bp
+++ b/packages/NetworkStackPermissionStub/Android.bp
@@ -21,6 +21,7 @@ android_app {
// a classes.dex.
srcs: ["src/**/*.java"],
platform_apis: true,
+ min_sdk_version: "28",
certificate: "networkstack",
privileged: true,
manifest: "AndroidManifest.xml",
diff --git a/packages/NetworkStackPermissionStub/AndroidManifest.xml b/packages/NetworkStackPermissionStub/AndroidManifest.xml
index 62bf3de3fb95..e83f0503d280 100644
--- a/packages/NetworkStackPermissionStub/AndroidManifest.xml
+++ b/packages/NetworkStackPermissionStub/AndroidManifest.xml
@@ -19,7 +19,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.networkstack.permissionstub"
android:sharedUserId="android.uid.networkstack"
- android:versionCode="10"
+ android:versionCode="11"
android:versionName="Q-initial">
<uses-sdk android:minSdkVersion="28" android:targetSdkVersion="28" />
<!--
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index f5d58d8a2004..f4c7275a828a 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -938,7 +938,7 @@
<!-- [CHAR_LIMIT=60] Label for battery level chart when discharging with duration and using enhanced estimate -->
<string name="power_discharging_duration_enhanced">About <xliff:g id="time_remaining">%1$s</xliff:g> left based on your usage (<xliff:g id="level">%2$s</xliff:g>)</string>
<!-- [CHAR_LIMIT=40] Short label for estimated remaining duration of battery charging/discharging -->
- <string name="power_remaining_duration_only_short"><xliff:g id="time_remaining">%1$s</xliff:g> left</string>
+ <string name="power_remaining_duration_only_short"><xliff:g id="time_remaining">%1$s</xliff:g></string>
<!-- [CHAR_LIMIT=100] Label for enhanced estimated time that phone will run out of battery -->
<string name="power_discharge_by_enhanced">Should last until about <xliff:g id="time">%1$s</xliff:g> based on your usage (<xliff:g id="level">%2$s</xliff:g>)</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 3dd3fb6643a9..3d38837d8964 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -1036,8 +1036,8 @@ public class AccessPoint implements Comparable<AccessPoint> {
public void startOsuProvisioning() {
mContext.getSystemService(WifiManager.class).startSubscriptionProvisioning(
mOsuProvider,
- new AccessPointProvisioningCallback(),
- ThreadUtils.getUiThreadHandler()
+ mContext.getMainExecutor(),
+ new AccessPointProvisioningCallback()
);
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 265d464d9c71..9d6fc9ed85c2 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -42,6 +42,7 @@
<uses-permission android:name="android.permission.INJECT_EVENTS" />
<uses-permission android:name="android.permission.DUMP" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
<uses-permission android:name="android.permission.STATUS_BAR" />
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
new file mode 100644
index 000000000000..7c7268865235
--- /dev/null
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/GlobalActionsPanelPlugin.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+import android.view.View;
+
+import com.android.systemui.plugins.annotations.DependsOn;
+import com.android.systemui.plugins.annotations.ProvidesInterface;
+
+/**
+ * Plugin which provides a "Panel" {@link View} to be rendered inside of the GlobalActions menu.
+ *
+ * Implementations should construct a new {@link PanelViewController} with the given
+ * {@link Callbacks} instance inside of {@link #onPanelShown(Callbacks)}, and should not hold onto
+ * a reference, instead allowing Global Actions to manage the lifetime of the object.
+ *
+ * Under this assumption, {@link PanelViewController} represents the lifetime of a single invocation
+ * of the Global Actions menu. The {@link View} for the Panel is generated when the
+ * {@link PanelViewController} is constructed, and {@link PanelViewController#getPanelContent()}
+ * serves as a simple getter. When Global Actions is dismissed,
+ * {@link PanelViewController#onDismissed()} can be used to cleanup any resources allocated when
+ * constructed. Global Actions will then release the reference, and the {@link PanelViewController}
+ * will be garbage-collected.
+ */
+@ProvidesInterface(
+ action = GlobalActionsPanelPlugin.ACTION, version = GlobalActionsPanelPlugin.VERSION)
+@DependsOn(target = GlobalActionsPanelPlugin.Callbacks.class)
+@DependsOn(target = GlobalActionsPanelPlugin.PanelViewController.class)
+public interface GlobalActionsPanelPlugin extends Plugin {
+ String ACTION = "com.android.systemui.action.PLUGIN_GLOBAL_ACTIONS_PANEL";
+ int VERSION = 0;
+
+ /**
+ * Invoked when the GlobalActions menu is shown.
+ *
+ * @param callbacks {@link Callbacks} instance that can be used by the Panel to interact with
+ * the Global Actions menu.
+ * @return A {@link PanelViewController} instance used to receive Global Actions events.
+ */
+ PanelViewController onPanelShown(Callbacks callbacks);
+
+ /**
+ * Provides methods to interact with the Global Actions menu.
+ */
+ @ProvidesInterface(version = Callbacks.VERSION)
+ interface Callbacks {
+ int VERSION = 0;
+
+ /** Dismisses the Global Actions menu. */
+ void dismissGlobalActionsMenu();
+ }
+
+ /**
+ * Receives Global Actions events, and provides the Panel {@link View}.
+ */
+ @ProvidesInterface(version = PanelViewController.VERSION)
+ interface PanelViewController {
+ int VERSION = 0;
+
+ /**
+ * Returns the {@link View} for the Panel to be rendered in Global Actions. This View can be
+ * any size, and will be rendered above the Global Actions menu when z-ordered.
+ */
+ View getPanelContent();
+
+ /**
+ * Invoked when the Global Actions menu (containing the View returned from
+ * {@link #getPanelContent()}) is dismissed.
+ */
+ void onDismissed();
+ }
+}
diff --git a/packages/SystemUI/res-keyguard/layout/type_clock.xml b/packages/SystemUI/res-keyguard/layout/type_clock.xml
index f4a73765acc1..89bbc09132bd 100644
--- a/packages/SystemUI/res-keyguard/layout/type_clock.xml
+++ b/packages/SystemUI/res-keyguard/layout/type_clock.xml
@@ -21,10 +21,10 @@
>
<com.android.keyguard.clock.TypographicClock
android:id="@+id/type_clock"
- android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:paddingLeft="50dp"
+ android:paddingStart="50dp"
+ android:textAlignment="viewStart"
style="@style/widget_big"
android:textSize="40dp"
/>
diff --git a/packages/SystemUI/res/drawable/global_action_panel_scrim.xml b/packages/SystemUI/res/drawable/global_action_panel_scrim.xml
new file mode 100644
index 000000000000..177b8d204ac8
--- /dev/null
+++ b/packages/SystemUI/res/drawable/global_action_panel_scrim.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <gradient
+ android:centerY="0.45"
+ android:startColor="#be3c4043"
+ android:centerColor="#be3c4043"
+ android:endColor="#4d3c4043"
+ android:angle="270" />
+</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_detail_background.xml b/packages/SystemUI/res/drawable/qs_detail_background.xml
index 84c793f6abd6..672abf14774e 100644
--- a/packages/SystemUI/res/drawable/qs_detail_background.xml
+++ b/packages/SystemUI/res/drawable/qs_detail_background.xml
@@ -14,6 +14,20 @@ Copyright (C) 2014 The Android Open Source Project
limitations under the License.
-->
<transition xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:drawable="@color/qs_detail_transition" />
- <item android:drawable="?android:attr/colorPrimary" />
+ <item>
+ <inset>
+ <shape>
+ <solid android:color="@color/qs_detail_transition"/>
+ <corners android:radius="?android:attr/dialogCornerRadius" />
+ </shape>
+ </inset>
+ </item>
+ <item>
+ <inset>
+ <shape>
+ <solid android:color="?android:attr/colorPrimary"/>
+ <corners android:radius="?android:attr/dialogCornerRadius" />
+ </shape>
+ </inset>
+ </item>
</transition> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid.xml b/packages/SystemUI/res/layout-land/global_actions_grid.xml
index 480f5235f75a..235d0fc62e2d 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid.xml
@@ -10,14 +10,12 @@
android:gravity="top|right"
android:clipChildren="false"
>
-
<LinearLayout
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:gravity="top|right"
android:padding="0dp"
android:orientation="vertical"
- android:layoutDirection="ltr"
android:layout_marginRight="@dimen/global_actions_grid_container_bottom_margin"
>
<!-- Grid of action items -->
@@ -26,7 +24,6 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:layoutDirection="ltr"
android:layout_marginTop="@dimen/global_actions_grid_side_margin"
android:translationZ="@dimen/global_actions_translate"
android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
@@ -39,25 +36,21 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:layoutDirection="ltr"
- android:orientation="horizontal"
+ android:layoutDirection="locale"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:layoutDirection="ltr"
- android:orientation="horizontal"
+ android:layoutDirection="locale"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:layoutDirection="ltr"
- android:orientation="horizontal"
+ android:layoutDirection="locale"
/>
</com.android.systemui.globalactions.ListGridLayout>
-
<!-- For separated items-->
<LinearLayout
android:id="@+id/separated_button"
diff --git a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
index 4f868263226d..e028214532f0 100644
--- a/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
+++ b/packages/SystemUI/res/layout-land/global_actions_grid_seascape.xml
@@ -10,7 +10,6 @@
android:gravity="top|left"
android:clipChildren="false"
>
-
<LinearLayout
android:layout_height="match_parent"
android:layout_width="wrap_content"
@@ -37,11 +36,11 @@
android:gravity="center"
android:translationZ="@dimen/global_actions_translate"
/>
-
<!-- Grid of action items -->
<com.android.systemui.globalactions.ListGridLayout
android:id="@android:id/list"
android:layout_gravity="bottom|left"
+ android:gravity="right"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
@@ -54,28 +53,22 @@
android:background="?android:attr/colorBackgroundFloating"
>
<LinearLayout
- android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:layoutDirection="rtl"
- android:orientation="horizontal"
+ android:layoutDirection="locale"
/>
<LinearLayout
- android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:layoutDirection="rtl"
- android:orientation="horizontal"
+ android:layoutDirection="locale"
/>
<LinearLayout
- android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:layoutDirection="rtl"
- android:orientation="horizontal"
+ android:layoutDirection="locale"
/>
</com.android.systemui.globalactions.ListGridLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/global_actions_grid.xml b/packages/SystemUI/res/layout/global_actions_grid.xml
index 729e96ebc22e..a620a8eb144b 100644
--- a/packages/SystemUI/res/layout/global_actions_grid.xml
+++ b/packages/SystemUI/res/layout/global_actions_grid.xml
@@ -10,7 +10,6 @@
android:gravity="bottom|center"
android:clipChildren="false"
>
-
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="match_parent"
@@ -35,14 +34,13 @@
android:gravity="center"
android:translationZ="@dimen/global_actions_translate"
/>
-
<!-- Grid of action items -->
<com.android.systemui.globalactions.ListGridLayout
android:id="@android:id/list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:layoutDirection="rtl"
+ android:orientation="vertical"
+ android:gravity="right"
android:layout_marginRight="@dimen/global_actions_grid_side_margin"
android:translationZ="@dimen/global_actions_translate"
android:paddingLeft="@dimen/global_actions_grid_horizontal_padding"
@@ -55,19 +53,19 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:orientation="vertical"
+ android:layoutDirection="locale"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:orientation="vertical"
+ android:layoutDirection="locale"
/>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
- android:orientation="vertical"
+ android:layoutDirection="locale"
/>
</com.android.systemui.globalactions.ListGridLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/notification_info.xml b/packages/SystemUI/res/layout/notification_info.xml
index 863c1ccd7eaf..bd9d3fb43528 100644
--- a/packages/SystemUI/res/layout/notification_info.xml
+++ b/packages/SystemUI/res/layout/notification_info.xml
@@ -44,7 +44,7 @@
android:id="@+id/pkgname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.Material.Notification.Info"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Info"
android:layout_marginStart="3dp"
android:layout_marginEnd="2dp"
android:singleLine="true"
@@ -54,7 +54,7 @@
android:id="@+id/pkg_divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.Material.Notification.Info"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Info"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:text="@*android:string/notification_header_divider_symbol"
@@ -64,7 +64,7 @@
android:id="@+id/delegate_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.Material.Notification.Info"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Info"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:ellipsize="end"
@@ -129,7 +129,7 @@ asked for it -->
android:id="@+id/group_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.Material.Notification.Title"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:ellipsize="end"
@@ -139,7 +139,7 @@ asked for it -->
android:id="@+id/pkg_group_divider"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:textAppearance="@*android:style/TextAppearance.Material.Notification.Title"
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
android:layout_marginStart="2dp"
android:layout_marginEnd="2dp"
android:text="@*android:string/notification_header_divider_symbol"
@@ -151,7 +151,7 @@ asked for it -->
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
- style="@android:style/TextAppearance.Material.Notification.Title"
+ style="@*android:style/TextAppearance.DeviceDefault.Notification.Title"
android:layout_toEndOf="@id/pkg_group_divider"/>
</RelativeLayout>
<!-- Question prompt -->
@@ -159,7 +159,7 @@ asked for it -->
android:id="@+id/block_prompt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- style="@android:style/TextAppearance.Material.Notification" />
+ style="@*android:style/TextAppearance.DeviceDefault.Notification" />
</LinearLayout>
<!-- Settings and Done buttons -->
diff --git a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
index 586cdf3fbaae..716e1272f871 100644
--- a/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
+++ b/packages/SystemUI/res/raw/image_wallpaper_fragment_shader.glsl
@@ -1,27 +1,76 @@
precision mediump float;
+// The actual wallpaper texture.
uniform sampler2D uTexture;
-uniform float uCenterReveal;
+
+// The 85th percenile for the luminance histogram of the image (a value between 0 and 1).
+// This value represents the point in histogram that includes 85% of the pixels of the image.
+uniform float uPer85;
+
+// Reveal is the animation value that goes from 1 (the image is hidden) to 0 (the image is visible).
uniform float uReveal;
+
+// The opacity of locked screen (constant value).
uniform float uAod2Opacity;
varying vec2 vTextureCoordinates;
+/*
+ * Calculates the relative luminance of the pixel.
+ */
vec3 luminosity(vec3 color) {
float lum = 0.2126 * color.r + 0.7152 * color.g + 0.0722 * color.b;
return vec3(lum);
}
vec4 transform(vec3 diffuse) {
- // TODO: Add well comments here, tracking on b/123615467.
+ // Getting the luminance for this pixel
vec3 lum = luminosity(diffuse);
- diffuse = mix(diffuse, lum, smoothstep(0., uCenterReveal, uReveal));
- float val = mix(uReveal, uCenterReveal, step(uCenterReveal, uReveal));
- diffuse = smoothstep(val, 1.0, diffuse);
- diffuse *= uAod2Opacity * (1. - smoothstep(uCenterReveal, 1., uReveal));
+
+ /*
+ * while the reveal > per85, it shows the luminance image (B&W image)
+ * then when moving passed that value, the image gets colored.
+ */
+ float trans = smoothstep(0., uPer85, uReveal);
+ diffuse = mix(diffuse, lum, trans);
+
+ // 'lower' value represents the capped 'reveal' value to the range [0, per85]
+ float selector = step(uPer85, uReveal);
+ float lower = mix(uReveal, uPer85, selector);
+
+ /*
+ * Remaps image:
+ * - from reveal=1 to reveal=per85 => lower=per85, diffuse=luminance
+ * That means that remaps black and white image pixel
+ * from a possible values of [0,1] to [per85, 1] (if the pixel is darker than per85,
+ * it's gonna be black, if it's between per85 and 1, it's gonna be gray
+ * and if it's 1 it's gonna be white).
+ * - from reveal=per85 to reveal=0 => lower=reveal, 'diffuse' changes from luminance to color
+ * That means that remaps each image pixel color (rgb)
+ * from a possible values of [0,1] to [lower, 1] (if the pixel color is darker than 'lower',
+ * it's gonna be 0, if it's between 'lower' and 1, it's gonna be remap to a value
+ * between 0 and 1 and if it's 1 it's gonna be 1).
+ * - if reveal=0 => lower=0, diffuse=color image
+ * The image is shown as it is, colored.
+ */
+ vec3 remaps = smoothstep(lower, 1., diffuse);
+
+ // Interpolate between diffuse and remaps using reveal to avoid over saturation.
+ diffuse = mix(diffuse, remaps, uReveal);
+
+ /*
+ * Fades in the pixel value:
+ * - if reveal=1 => fadeInOpacity=0
+ * - from reveal=1 to reveal=per85 => 0<=fadeInOpacity<=1
+ * - if reveal>per85 => fadeInOpacity=1
+ */
+ float fadeInOpacity = 1. - smoothstep(uPer85, 1., uReveal);
+ diffuse *= uAod2Opacity * fadeInOpacity;
+
return vec4(diffuse.r, diffuse.g, diffuse.b, 1.);
}
void main() {
+ // gets the pixel value of the wallpaper for this uv coordinates on screen.
vec4 fragColor = texture2D(uTexture, vTextureCoordinates);
gl_FragColor = transform(fragColor.rgb);
} \ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 50cf37beb878..a40a14a47744 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -856,6 +856,9 @@
<!-- Global actions grid layout -->
<dimen name="global_actions_grid_side_margin">4dp</dimen>
+ <!-- Global actions panel -->
+ <dimen name="global_actions_panel_top_margin">85dp</dimen>
+
<!-- The maximum offset in either direction that elements are moved horizontally to prevent
burn-in on AOD. -->
<dimen name="burn_in_prevention_offset_x">8dp</dimen>
diff --git a/packages/SystemUI/res/values/donottranslate.xml b/packages/SystemUI/res/values/donottranslate.xml
index 38f469e6eda3..67293c57e344 100644
--- a/packages/SystemUI/res/values/donottranslate.xml
+++ b/packages/SystemUI/res/values/donottranslate.xml
@@ -18,8 +18,8 @@
-->
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<!-- Date format for display: should match the lockscreen in /policy. -->
- <string name="system_ui_date_pattern">@*android:string/system_ui_date_pattern</string>
+ <string name="system_ui_date_pattern" translatable="false">@*android:string/system_ui_date_pattern</string>
<!-- Date format for the always on display. -->
- <item type="string" name="system_ui_aod_date_pattern">eeeMMMd</item>
+ <item type="string" name="system_ui_aod_date_pattern" translatable="false">eeeMMMd</item>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
index f5451e952dd9..26c5ef95981f 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -90,7 +90,7 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable {
}
@Override
- public ViewGroup getParentView(boolean separated, int index, boolean reverse) {
+ public ViewGroup getParentView(boolean separated, int index, int rotation) {
if (separated) {
return getSeparatedView();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
index 8c49d56ae348..8259da6efe2d 100644
--- a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
@@ -57,12 +57,12 @@ public abstract class MultiListLayout extends LinearLayout {
* @param separated Whether or not this index refers to a position in the separated or list
* container.
* @param index The index of the item within the container.
- * @param reverse If the MultiListLayout contains sub-lists within the list container, reverse
- * the order that they are filled.
+ * @param rotation Specifies the rotation of the device, which is used in some cases to
+ * determine child ordering.
* @return The parent ViewGroup which will be used to contain the specified item
* after it has been added to the layout.
*/
- public abstract ViewGroup getParentView(boolean separated, int index, boolean reverse);
+ public abstract ViewGroup getParentView(boolean separated, int index, int rotation);
/**
* Sets the divided view, which may have a differently-colored background.
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index ab077d636beb..c0f03a6f4ef8 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -471,6 +471,7 @@ public class ScreenDecorations extends SystemUI implements Tunable {
lp.width = WRAP_CONTENT;
lp.height = MATCH_PARENT;
}
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
return lp;
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
index 471619e897c5..03e453f364eb 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleController.java
@@ -95,6 +95,9 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
/** Flag to position the header below the activity view */
private static final String ENABLE_BUBBLE_FOOTER = "experiment_enable_bubble_footer";
+ private static final String BUBBLE_STIFFNESS = "experiment_bubble_stiffness";
+ private static final String BUBBLE_BOUNCINESS = "experiment_bubble_bounciness";
+
private final Context mContext;
private final NotificationEntryManager mNotificationEntryManager;
private final IActivityTaskManager mActivityTaskManager;
@@ -569,6 +572,20 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
ENABLE_BUBBLE_FOOTER, 0) != 0;
}
+ /** Default stiffness to use for bubble physics animations. */
+ public static int getBubbleStiffness(Context context, int defaultStiffness) {
+ return Settings.Secure.getInt(
+ context.getContentResolver(), BUBBLE_STIFFNESS, defaultStiffness);
+ }
+
+ /** Default bounciness/damping ratio to use for bubble physics animations. */
+ public static float getBubbleBounciness(Context context, float defaultBounciness) {
+ return Settings.Secure.getInt(
+ context.getContentResolver(),
+ BUBBLE_BOUNCINESS,
+ (int) (defaultBounciness * 100)) / 100f;
+ }
+
/** PinnedStackListener that dispatches IME visibility updates to the stack. */
private class BubblesImeListener extends IPinnedStackListener.Stub {
@@ -582,12 +599,9 @@ public class BubbleController implements BubbleExpandedView.OnBubbleBlockedListe
int displayRotation) throws RemoteException {}
@Override
- public void onImeVisibilityChanged(boolean imeVisible, int imeHeight)
- throws RemoteException {
- if (mStackView != null) {
- mStackView.post(() -> {
- mStackView.onImeVisibilityChanged(imeVisible, imeHeight);
- });
+ public void onImeVisibilityChanged(boolean imeVisible, int imeHeight) {
+ if (mStackView != null && mStackView.getBubbleCount() > 0) {
+ mStackView.post(() -> mStackView.onImeVisibilityChanged(imeVisible, imeHeight));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
index 8235d8de3257..4869485a3336 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/BubbleStackView.java
@@ -26,6 +26,7 @@ import android.graphics.Point;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
+import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.util.StatsLog;
@@ -36,6 +37,7 @@ import android.view.ViewOutlineProvider;
import android.view.ViewTreeObserver;
import android.view.WindowInsets;
import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
import androidx.annotation.MainThread;
@@ -205,11 +207,16 @@ public class BubbleStackView extends FrameLayout {
.setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY));
setClipChildren(false);
-
+ setFocusable(true);
mBubbleContainer.bringToFront();
}
@Override
+ public void getBoundsOnScreen(Rect outRect, boolean clipToParent) {
+ getBoundsOnScreen(outRect);
+ }
+
+ @Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
getViewTreeObserver().removeOnPreDrawListener(mViewUpdater);
@@ -227,6 +234,36 @@ public class BubbleStackView extends FrameLayout {
}
}
+ @Override
+ public void onInitializeAccessibilityNodeInfoInternal(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfoInternal(info);
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_DISMISS);
+ if (mIsExpanded) {
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_COLLAPSE);
+ } else {
+ info.addAction(AccessibilityNodeInfo.AccessibilityAction.ACTION_EXPAND);
+ }
+ }
+
+ @Override
+ public boolean performAccessibilityActionInternal(int action, Bundle arguments) {
+ if (super.performAccessibilityActionInternal(action, arguments)) {
+ return true;
+ }
+ switch (action) {
+ case AccessibilityNodeInfo.ACTION_DISMISS:
+ stackDismissed();
+ return true;
+ case AccessibilityNodeInfo.ACTION_COLLAPSE:
+ collapseStack();
+ return true;
+ case AccessibilityNodeInfo.ACTION_EXPAND:
+ expandStack();
+ return true;
+ }
+ return false;
+ }
+
/**
* Updates the visibility of the 'dot' indicating an update on the bubble.
* @param key the {@link NotificationEntry#key} associated with the bubble.
@@ -491,7 +528,9 @@ public class BubbleStackView extends FrameLayout {
if (shouldExpand) {
mBubbleContainer.setController(mExpandedAnimationController);
mExpandedAnimationController.expandFromStack(
- mStackAnimationController.getStackPosition(),
+ /* collapseTo */
+ mStackAnimationController.getStackPositionAlongNearestHorizontalEdge(),
+ /* after */
() -> {
updatePointerPosition();
updateAfter.run();
@@ -719,7 +758,9 @@ public class BubbleStackView extends FrameLayout {
@Override
public void getBoundsOnScreen(Rect outRect) {
if (!mIsExpanded) {
- mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect);
+ if (mBubbleContainer.getChildCount() > 0) {
+ mBubbleContainer.getChildAt(0).getBoundsOnScreen(outRect);
+ }
} else {
mBubbleContainer.getBoundsOnScreen(outRect);
}
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
index f7896b0b1201..1f29883b180a 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/ExpandedAnimationController.java
@@ -49,11 +49,8 @@ public class ExpandedAnimationController
/** How much to scale down bubbles when they're animating in/out. */
private static final float ANIMATE_SCALE_PERCENT = 0.5f;
- /**
- * The stack position from which the bubbles were expanded. Saved in {@link #expandFromStack}
- * and used to return to stack form in {@link #collapseBackToStack}.
- */
- private PointF mExpandedFrom;
+ /** The stack position to collapse back to in {@link #collapseBackToStack}. */
+ private PointF mCollapseToPoint;
/** Horizontal offset between bubbles, which we need to know to re-stack them. */
private float mStackOffsetPx;
@@ -106,8 +103,8 @@ public class ExpandedAnimationController
*
* @return The y-value to which the bubbles were expanded, in case that's useful.
*/
- public float expandFromStack(PointF expandedFrom, Runnable after) {
- mExpandedFrom = expandedFrom;
+ public float expandFromStack(PointF collapseTo, Runnable after) {
+ mCollapseToPoint = collapseTo;
// How much to translate the next bubble, so that it is not overlapping the previous one.
float translateNextBubbleXBy = mBubblePaddingPx;
@@ -123,10 +120,11 @@ public class ExpandedAnimationController
/** Animate collapsing the bubbles back to their stacked position. */
public void collapseBackToStack(Runnable after) {
// Stack to the left if we're going to the left, or right if not.
- final float sideMultiplier = mLayout.isFirstChildXLeftOfCenter(mExpandedFrom.x) ? -1 : 1;
+ final float sideMultiplier = mLayout.isFirstChildXLeftOfCenter(mCollapseToPoint.x) ? -1 : 1;
for (int i = 0; i < mLayout.getChildCount(); i++) {
mLayout.animatePositionForChildAtIndex(
- i, mExpandedFrom.x + (sideMultiplier * i * mStackOffsetPx), mExpandedFrom.y);
+ i,
+ mCollapseToPoint.x + (sideMultiplier * i * mStackOffsetPx), mCollapseToPoint.y);
}
runAfterTranslationsEnd(after);
@@ -268,8 +266,8 @@ public class ExpandedAnimationController
@Override
SpringForce getSpringForce(DynamicAnimation.ViewProperty property, View view) {
return new SpringForce()
- .setStiffness(SpringForce.STIFFNESS_LOW)
- .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY);
+ .setDampingRatio(SpringForce.DAMPING_RATIO_LOW_BOUNCY)
+ .setStiffness(SpringForce.STIFFNESS_LOW);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
index f47fbe0d149f..af5035be1cfe 100644
--- a/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
+++ b/packages/SystemUI/src/com/android/systemui/bubbles/animation/StackAnimationController.java
@@ -30,6 +30,7 @@ import androidx.dynamicanimation.animation.SpringAnimation;
import androidx.dynamicanimation.animation.SpringForce;
import com.android.systemui.R;
+import com.android.systemui.bubbles.BubbleController;
import com.google.android.collect.Sets;
@@ -134,6 +135,18 @@ public class StackAnimationController extends
}
/**
+ * Where the stack would be if it were snapped to the nearest horizontal edge (left or right).
+ */
+ public PointF getStackPositionAlongNearestHorizontalEdge() {
+ final PointF stackPos = getStackPosition();
+ final boolean onLeft = mLayout.isFirstChildXLeftOfCenter(stackPos.x);
+ final RectF bounds = getAllowableStackPositionRegion();
+
+ stackPos.x = onLeft ? bounds.left : bounds.right;
+ return stackPos;
+ }
+
+ /**
* Flings the first bubble along the given property's axis, using the provided configuration
* values. When the animation ends - either by hitting the min/max, or by friction sufficiently
* reducing momentum - a SpringAnimation takes over to snap the bubble to the given final
@@ -325,8 +338,10 @@ public class StackAnimationController extends
@Override
SpringForce getSpringForce(DynamicAnimation.ViewProperty property, View view) {
return new SpringForce()
- .setDampingRatio(DEFAULT_BOUNCINESS)
- .setStiffness(DEFAULT_STIFFNESS);
+ .setDampingRatio(BubbleController.getBubbleBounciness(
+ mLayout.getContext(), DEFAULT_BOUNCINESS))
+ .setStiffness(BubbleController.getBubbleStiffness(
+ mLayout.getContext(), (int) (DEFAULT_STIFFNESS * 100f)));
}
@Override
@@ -440,6 +455,10 @@ public class StackAnimationController extends
DynamicAnimation.ViewProperty property, SpringForce spring,
float vel, float finalPosition) {
+ if (mLayout.getChildCount() == 0) {
+ return;
+ }
+
Log.d(TAG, String.format("Springing %s to final position %f.",
PhysicsAnimationLayout.getReadablePropertyName(property),
finalPosition));
@@ -489,7 +508,7 @@ public class StackAnimationController extends
@Override
public float getValue(StackAnimationController controller) {
- return mProperty.getValue(mLayout.getChildAt(0));
+ return mLayout.getChildCount() > 0 ? mProperty.getValue(mLayout.getChildAt(0)) : 0;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 3fa6035387c7..8a95cc4910ad 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -67,6 +67,7 @@ import android.view.WindowManagerGlobal;
import android.view.accessibility.AccessibilityEvent;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
@@ -88,14 +89,17 @@ import com.android.systemui.Interpolators;
import com.android.systemui.MultiListLayout;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
-import com.android.systemui.statusbar.phone.ScrimController;
+import com.android.systemui.plugins.GlobalActionsPanelPlugin;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.statusbar.policy.ExtensionController;
+import com.android.systemui.statusbar.policy.ExtensionController.Extension;
import com.android.systemui.util.EmergencyDialerConstants;
import com.android.systemui.util.leak.RotationUtils;
import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolator;
import java.util.ArrayList;
import java.util.List;
+import java.util.Locale;
/**
* Helper to show the global actions dialog. Each item is an {@link Action} that
@@ -160,6 +164,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private final ScreenshotHelper mScreenshotHelper;
private final ScreenRecordHelper mScreenRecordHelper;
+ private final Extension<GlobalActionsPanelPlugin> mPanelExtension;
+
/**
* @param context everything needs a context :(
*/
@@ -203,6 +209,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mScreenRecordHelper = new ScreenRecordHelper(context);
Dependency.get(ConfigurationController.class).addCallback(this);
+
+ mPanelExtension = Dependency.get(ExtensionController.class)
+ .newExtension(GlobalActionsPanelPlugin.class)
+ .withPlugin(GlobalActionsPanelPlugin.class)
+ .build();
}
/**
@@ -398,8 +409,16 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
}
return false;
};
+ GlobalActionsPanelPlugin.PanelViewController panelViewController =
+ mPanelExtension.get() != null
+ ? mPanelExtension.get().onPanelShown(() -> {
+ if (mDialog != null) {
+ mDialog.dismiss();
+ }
+ })
+ : null;
ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener,
- mSeparatedEmergencyButtonEnabled);
+ mSeparatedEmergencyButtonEnabled, panelViewController);
dialog.setCanceledOnTouchOutside(false); // Handled by the custom class.
dialog.setKeyguardShowing(mKeyguardShowing);
@@ -1469,20 +1488,22 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private MultiListLayout mGlobalActionsLayout;
private final OnClickListener mClickListener;
private final OnItemLongClickListener mLongClickListener;
- private final GradientDrawable mGradientDrawable;
+ private final Drawable mBackgroundDrawable;
private final ColorExtractor mColorExtractor;
+ private final GlobalActionsPanelPlugin.PanelViewController mPanelController;
private boolean mKeyguardShowing;
private boolean mShouldDisplaySeparatedButton;
private boolean mShowing;
+ private final float mScrimAlpha;
public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter,
- OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton) {
+ OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton,
+ GlobalActionsPanelPlugin.PanelViewController plugin) {
super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions);
mContext = context;
mAdapter = adapter;
mClickListener = clickListener;
mLongClickListener = longClickListener;
- mGradientDrawable = new GradientDrawable(mContext);
mColorExtractor = Dependency.get(SysuiColorExtractor.class);
mShouldDisplaySeparatedButton = shouldDisplaySeparatedButton;
@@ -1503,12 +1524,46 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
| WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH
| WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
- window.setBackgroundDrawable(mGradientDrawable);
window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
initializeLayout();
setTitle(R.string.global_actions);
+
+ mPanelController = plugin;
+ View panelView = initializePanel();
+ if (panelView == null) {
+ mBackgroundDrawable = new GradientDrawable(context);
+ mScrimAlpha = 0.7f;
+ } else {
+ mBackgroundDrawable = context.getDrawable(
+ com.android.systemui.R.drawable.global_action_panel_scrim);
+ mScrimAlpha = 1f;
+ addContentView(
+ panelView,
+ new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.MATCH_PARENT));
+ }
+ window.setBackgroundDrawable(mBackgroundDrawable);
+ }
+
+ private View initializePanel() {
+ if (isPanelEnabled(mContext) && mPanelController != null) {
+ View panelView = mPanelController.getPanelContent();
+ if (panelView != null) {
+ FrameLayout panelContainer = new FrameLayout(mContext);
+ FrameLayout.LayoutParams panelParams =
+ new FrameLayout.LayoutParams(
+ FrameLayout.LayoutParams.MATCH_PARENT,
+ FrameLayout.LayoutParams.WRAP_CONTENT);
+ panelParams.topMargin = mContext.getResources().getDimensionPixelSize(
+ com.android.systemui.R.dimen.global_actions_panel_top_margin);
+ panelContainer.addView(panelView, panelParams);
+ return panelContainer;
+ }
+ }
+ return null;
}
private void initializeLayout() {
@@ -1529,6 +1584,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
mGlobalActionsLayout.setRotationListener(this::onRotate);
}
+ private boolean isPanelEnabled(Context context) {
+ return FeatureFlagUtils.isEnabled(
+ context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED);
+ }
+
private int getGlobalActionsLayoutId(Context context) {
if (isGridEnabled(context)) {
if (RotationUtils.getRotation(context) == RotationUtils.ROTATION_SEASCAPE) {
@@ -1546,33 +1606,40 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
ArrayList<Action> listActions = mAdapter.getListActions(mShouldDisplaySeparatedButton);
mGlobalActionsLayout.setExpectedListItemCount(listActions.size());
mGlobalActionsLayout.setExpectedSeparatedItemCount(separatedActions.size());
+ int rotation = RotationUtils.getRotation(mContext);
+
+ boolean reverse = false; // should we add items to parents in the reverse order?
+ if (isGridEnabled(mContext)) {
+ if (rotation == RotationUtils.ROTATION_NONE
+ || rotation == RotationUtils.ROTATION_SEASCAPE) {
+ reverse = !reverse; // if we're in portrait or seascape, reverse items
+ }
+ if (TextUtils.getLayoutDirectionFromLocale(Locale.getDefault())
+ == View.LAYOUT_DIRECTION_RTL) {
+ reverse = !reverse; // if we're in an RTL language, reverse items (again)
+ }
+ }
for (int i = 0; i < mAdapter.getCount(); i++) {
Action action = mAdapter.getItem(i);
int separatedIndex = separatedActions.indexOf(action);
ViewGroup parent;
if (separatedIndex != -1) {
- parent = mGlobalActionsLayout.getParentView(true, separatedIndex, false);
+ parent = mGlobalActionsLayout.getParentView(true, separatedIndex, rotation);
} else {
- boolean reverse = false;
-
- // If we're using the grid layout and we're in seascape, reverse the order
- // of sublists to make sure they render in the correct positions,
- // since we can't reverse vertical LinearLayouts through the layout xml.
-
- if (isGridEnabled(mContext) && RotationUtils.getRotation(mContext)
- == RotationUtils.ROTATION_SEASCAPE) {
- reverse = true;
- }
int listIndex = listActions.indexOf(action);
- parent = mGlobalActionsLayout.getParentView(false, listIndex, reverse);
+ parent = mGlobalActionsLayout.getParentView(false, listIndex, rotation);
}
View v = mAdapter.getView(i, null, parent);
final int pos = i;
v.setOnClickListener(view -> mClickListener.onClick(this, pos));
v.setOnLongClickListener(view ->
mLongClickListener.onItemLongClick(null, v, pos, 0));
- parent.addView(v);
+ if (reverse) {
+ parent.addView(v, 0); // reverse order of items
+ } else {
+ parent.addView(v);
+ }
}
}
@@ -1582,13 +1649,18 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
super.onStart();
updateList();
- Point displaySize = new Point();
- mContext.getDisplay().getRealSize(displaySize);
- mColorExtractor.addOnColorsChangedListener(this);
- mGradientDrawable.setScreenSize(displaySize.x, displaySize.y);
- GradientColors colors = mColorExtractor.getColors(mKeyguardShowing ?
- WallpaperManager.FLAG_LOCK : WallpaperManager.FLAG_SYSTEM);
- updateColors(colors, false /* animate */);
+ if (mBackgroundDrawable instanceof GradientDrawable) {
+ Point displaySize = new Point();
+ mContext.getDisplay().getRealSize(displaySize);
+ mColorExtractor.addOnColorsChangedListener(this);
+ ((GradientDrawable) mBackgroundDrawable)
+ .setScreenSize(displaySize.x, displaySize.y);
+ GradientColors colors = mColorExtractor.getColors(
+ mKeyguardShowing
+ ? WallpaperManager.FLAG_LOCK
+ : WallpaperManager.FLAG_SYSTEM);
+ updateColors(colors, false /* animate */);
+ }
}
/**
@@ -1597,11 +1669,14 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
* @param animate Interpolates gradient if true, just sets otherwise.
*/
private void updateColors(GradientColors colors, boolean animate) {
- mGradientDrawable.setColors(colors, animate);
+ if (!(mBackgroundDrawable instanceof GradientDrawable)) {
+ return;
+ }
+ ((GradientDrawable) mBackgroundDrawable).setColors(colors, animate);
View decorView = getWindow().getDecorView();
if (colors.supportsDarkText()) {
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR |
- View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
+ View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR);
} else {
decorView.setSystemUiVisibility(0);
}
@@ -1617,7 +1692,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
public void show() {
super.show();
mShowing = true;
- mGradientDrawable.setAlpha(0);
+ mBackgroundDrawable.setAlpha(0);
mGlobalActionsLayout.setTranslationX(getAnimTranslation());
mGlobalActionsLayout.setAlpha(0);
mGlobalActionsLayout.animate()
@@ -1627,8 +1702,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
.setInterpolator(Interpolators.FAST_OUT_SLOW_IN)
.setUpdateListener(animation -> {
int alpha = (int) ((Float) animation.getAnimatedValue()
- * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
- mGradientDrawable.setAlpha(alpha);
+ * mScrimAlpha * 255);
+ mBackgroundDrawable.setAlpha(alpha);
})
.start();
}
@@ -1645,14 +1720,17 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
.alpha(0)
.translationX(getAnimTranslation())
.setDuration(300)
- .withEndAction(() -> super.dismiss())
+ .withEndAction(super::dismiss)
.setInterpolator(new LogAccelerateInterpolator())
.setUpdateListener(animation -> {
int alpha = (int) ((1f - (Float) animation.getAnimatedValue())
- * ScrimController.GRADIENT_SCRIM_ALPHA * 255);
- mGradientDrawable.setAlpha(alpha);
+ * mScrimAlpha * 255);
+ mBackgroundDrawable.setAlpha(alpha);
})
.start();
+ if (mPanelController != null) {
+ mPanelController.onDismissed();
+ }
}
void dismissImmediately() {
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
index 1d042776efc9..036d8ca3afb6 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java
@@ -23,6 +23,7 @@ import android.view.ViewGroup;
import com.android.systemui.HardwareBgDrawable;
import com.android.systemui.MultiListLayout;
+import com.android.systemui.util.leak.RotationUtils;
/**
* Grid-based implementation of the button layout created by the global actions dialog.
@@ -83,11 +84,18 @@ public class GlobalActionsGridLayout extends MultiListLayout {
}
@Override
- public ViewGroup getParentView(boolean separated, int index, boolean reverseOrder) {
+ public ViewGroup getParentView(boolean separated, int index, int rotation) {
if (separated) {
return getSeparatedView();
} else {
- return getListView().getParentView(index, reverseOrder);
+ switch (rotation) {
+ case RotationUtils.ROTATION_LANDSCAPE:
+ return getListView().getParentView(index, false, true);
+ case RotationUtils.ROTATION_SEASCAPE:
+ return getListView().getParentView(index, true, true);
+ default:
+ return getListView().getParentView(index, false, false);
+ }
}
}
@@ -96,6 +104,6 @@ public class GlobalActionsGridLayout extends MultiListLayout {
*/
@Override
public void setDivisionView(View v) {
-
+ // do nothing
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
index d5dcd74c7ea8..4df1c5a43a1b 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java
@@ -62,11 +62,11 @@ public class ListGridLayout extends LinearLayout {
/**
* Get the parent view associated with the item which should be placed at the given position.
*/
- public ViewGroup getParentView(int index, boolean reverseSublists) {
+ public ViewGroup getParentView(int index, boolean reverseSublists, boolean swapRowsAndColumns) {
if (mRows == 0) {
return null;
}
- int column = getParentViewIndex(index, reverseSublists);
+ int column = getParentViewIndex(index, reverseSublists, swapRowsAndColumns);
return (ViewGroup) getChildAt(column);
}
@@ -74,13 +74,18 @@ public class ListGridLayout extends LinearLayout {
return getChildCount() - (index + 1);
}
- private int getParentViewIndex(int index, boolean reverseSublists) {
- int column = (int) Math.floor(index / mRows);
- int columnCount = getChildCount();
+ private int getParentViewIndex(int index, boolean reverseSublists, boolean swapRowsAndColumns) {
+ int sublistIndex;
+ ViewGroup row;
+ if (swapRowsAndColumns) {
+ sublistIndex = (int) Math.floor(index / mRows);
+ } else {
+ sublistIndex = index % mRows;
+ }
if (reverseSublists) {
- column = reverseSublistIndex(column);
+ sublistIndex = reverseSublistIndex(sublistIndex);
}
- return column;
+ return sublistIndex;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 19d85b155cba..a313336e3d71 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -50,7 +50,7 @@ class ImageGLWallpaper {
static final String A_POSITION = "aPosition";
static final String A_TEXTURE_COORDINATES = "aTextureCoordinates";
- static final String U_CENTER_REVEAL = "uCenterReveal";
+ static final String U_PER85 = "uPer85";
static final String U_REVEAL = "uReveal";
static final String U_AOD2OPACITY = "uAod2Opacity";
static final String U_TEXTURE = "uTexture";
@@ -87,7 +87,7 @@ class ImageGLWallpaper {
private int mAttrPosition;
private int mAttrTextureCoordinates;
private int mUniAod2Opacity;
- private int mUniCenterReveal;
+ private int mUniPer85;
private int mUniReveal;
private int mUniTexture;
private int mTextureId;
@@ -131,7 +131,7 @@ class ImageGLWallpaper {
private void setupUniforms() {
mUniAod2Opacity = mProgram.getUniformHandle(U_AOD2OPACITY);
- mUniCenterReveal = mProgram.getUniformHandle(U_CENTER_REVEAL);
+ mUniPer85 = mProgram.getUniformHandle(U_PER85);
mUniReveal = mProgram.getUniformHandle(U_REVEAL);
mUniTexture = mProgram.getUniformHandle(U_TEXTURE);
}
@@ -144,8 +144,8 @@ class ImageGLWallpaper {
return mAttrTextureCoordinates;
case U_AOD2OPACITY:
return mUniAod2Opacity;
- case U_CENTER_REVEAL:
- return mUniCenterReveal;
+ case U_PER85:
+ return mUniPer85;
case U_REVEAL:
return mUniReveal;
case U_TEXTURE:
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 991b1161dde2..72950088eb39 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -93,13 +93,13 @@ public class ImageWallpaperRenderer implements GLSurfaceView.Renderer,
@Override
public void onDrawFrame(GL10 gl) {
- float threshold = mImageProcessHelper.getPercentile85();
+ float per85 = mImageProcessHelper.getPercentile85();
float reveal = mImageRevealHelper.getReveal();
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
- glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_CENTER_REVEAL), threshold);
+ glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), per85);
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
mWallpaper.useTexture();
diff --git a/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
new file mode 100644
index 000000000000..d7a2d9acf3b5
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
@@ -0,0 +1,55 @@
+package com.android.systemui.power
+
+import com.android.systemui.power.PowerUI.NO_ESTIMATE_AVAILABLE
+
+/**
+ * A simple data class to snapshot battery state when a particular check for the
+ * low battery warning is running in the background.
+ */
+data class BatteryStateSnapshot(
+ val batteryLevel: Int,
+ val isPowerSaver: Boolean,
+ val plugged: Boolean,
+ val bucket: Int,
+ val batteryStatus: Int,
+ val severeLevelThreshold: Int,
+ val lowLevelThreshold: Int,
+ val timeRemainingMillis: Long,
+ val severeThresholdMillis: Long,
+ val lowThresholdMillis: Long,
+ val isBasedOnUsage: Boolean
+) {
+ /**
+ * Returns whether hybrid warning logic/copy should be used for this snapshot
+ */
+ var isHybrid: Boolean = false
+ private set
+
+ init {
+ this.isHybrid = true
+ }
+
+ constructor(
+ batteryLevel: Int,
+ isPowerSaver: Boolean,
+ plugged: Boolean,
+ bucket: Int,
+ batteryStatus: Int,
+ severeLevelThreshold: Int,
+ lowLevelThreshold: Int
+ ) : this(
+ batteryLevel,
+ isPowerSaver,
+ plugged,
+ bucket,
+ batteryStatus,
+ severeLevelThreshold,
+ lowLevelThreshold,
+ NO_ESTIMATE_AVAILABLE.toLong(),
+ NO_ESTIMATE_AVAILABLE.toLong(),
+ NO_ESTIMATE_AVAILABLE.toLong(),
+ false
+ ) {
+ this.isHybrid = false
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/power/Estimate.java b/packages/SystemUI/src/com/android/systemui/power/Estimate.java
deleted file mode 100644
index 12a8f0a435b4..000000000000
--- a/packages/SystemUI/src/com/android/systemui/power/Estimate.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.android.systemui.power;
-
-public class Estimate {
- public final long estimateMillis;
- public final boolean isBasedOnUsage;
-
- public Estimate(long estimateMillis, boolean isBasedOnUsage) {
- this.estimateMillis = estimateMillis;
- this.isBasedOnUsage = isBasedOnUsage;
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/power/Estimate.kt b/packages/SystemUI/src/com/android/systemui/power/Estimate.kt
new file mode 100644
index 000000000000..dca0d45c1c9f
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/power/Estimate.kt
@@ -0,0 +1,3 @@
+package com.android.systemui.power
+
+data class Estimate(val estimateMillis: Long, val isBasedOnUsage: Boolean) \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
index fdb0b36ee51e..41bcab53f8e9 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerNotificationWarnings.java
@@ -134,10 +134,6 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private int mShowing;
private long mWarningTriggerTimeMs;
-
- private Estimate mEstimate;
- private long mLowWarningThreshold;
- private long mSevereWarningThreshold;
private boolean mWarning;
private boolean mShowAutoSaverSuggestion;
private boolean mPlaySound;
@@ -148,6 +144,7 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private SystemUIDialog mHighTempDialog;
private SystemUIDialog mThermalShutdownDialog;
@VisibleForTesting SystemUIDialog mUsbHighTempDialog;
+ private BatteryStateSnapshot mCurrentBatterySnapshot;
/**
*/
@@ -195,17 +192,8 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
}
@Override
- public void updateEstimate(Estimate estimate) {
- mEstimate = estimate;
- if (estimate.estimateMillis <= mLowWarningThreshold) {
- mWarningTriggerTimeMs = System.currentTimeMillis();
- }
- }
-
- @Override
- public void updateThresholds(long lowThreshold, long severeThreshold) {
- mLowWarningThreshold = lowThreshold;
- mSevereWarningThreshold = severeThreshold;
+ public void updateSnapshot(BatteryStateSnapshot snapshot) {
+ mCurrentBatterySnapshot = snapshot;
}
private void updateNotification() {
@@ -254,15 +242,17 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
protected void showWarningNotification() {
final String percentage = NumberFormat.getPercentInstance()
- .format((double) mBatteryLevel / 100.0);
+ .format((double) mCurrentBatterySnapshot.getBatteryLevel() / 100.0);
- // get standard notification copy
+ // get shared standard notification copy
String title = mContext.getString(R.string.battery_low_title);
- String contentText = mContext.getString(R.string.battery_low_percent_format, percentage);
+ String contentText;
- // override notification copy if hybrid notification enabled
- if (mEstimate != null) {
+ // get correct content text if notification is hybrid or not
+ if (mCurrentBatterySnapshot.isHybrid()) {
contentText = getHybridContentString(percentage);
+ } else {
+ contentText = mContext.getString(R.string.battery_low_percent_format, percentage);
}
final Notification.Builder nb =
@@ -282,8 +272,9 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
}
// Make the notification red if the percentage goes below a certain amount or the time
// remaining estimate is disabled
- if (mEstimate == null || mBucket < 0
- || mEstimate.estimateMillis < mSevereWarningThreshold) {
+ if (!mCurrentBatterySnapshot.isHybrid() || mBucket < 0
+ || mCurrentBatterySnapshot.getTimeRemainingMillis()
+ < mCurrentBatterySnapshot.getSevereThresholdMillis()) {
nb.setColor(Utils.getColorAttrDefaultColor(mContext, android.R.attr.colorError));
}
@@ -324,10 +315,10 @@ public class PowerNotificationWarnings implements PowerUI.WarningsUI {
private String getHybridContentString(String percentage) {
return PowerUtil.getBatteryRemainingStringFormatted(
- mContext,
- mEstimate.estimateMillis,
- percentage,
- mEstimate.isBasedOnUsage);
+ mContext,
+ mCurrentBatterySnapshot.getTimeRemainingMillis(),
+ percentage,
+ mCurrentBatterySnapshot.isBasedOnUsage());
}
private PendingIntent pendingBroadcast(String action) {
diff --git a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
index e27c25efd88f..18638606a251 100644
--- a/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
+++ b/packages/SystemUI/src/com/android/systemui/power/PowerUI.java
@@ -55,6 +55,7 @@ import java.util.Arrays;
import java.util.concurrent.Future;
public class PowerUI extends SystemUI {
+
static final String TAG = "PowerUI";
static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final long TEMPERATURE_INTERVAL = 30 * DateUtils.SECOND_IN_MILLIS;
@@ -63,6 +64,7 @@ public class PowerUI extends SystemUI {
static final long THREE_HOURS_IN_MILLIS = DateUtils.HOUR_IN_MILLIS * 3;
private static final int CHARGE_CYCLE_PERCENT_RESET = 45;
private static final long SIX_HOURS_MILLIS = Duration.ofHours(6).toMillis();
+ public static final int NO_ESTIMATE_AVAILABLE = -1;
private final Handler mHandler = new Handler();
@VisibleForTesting
@@ -71,13 +73,9 @@ public class PowerUI extends SystemUI {
private PowerManager mPowerManager;
private WarningsUI mWarnings;
private final Configuration mLastConfiguration = new Configuration();
- private long mTimeRemaining = Long.MAX_VALUE;
private int mPlugType = 0;
private int mInvalidCharger = 0;
private EnhancedEstimates mEnhancedEstimates;
- private Estimate mLastEstimate;
- private boolean mLowWarningShownThisChargeCycle;
- private boolean mSevereWarningShownThisChargeCycle;
private Future mLastShowWarningTask;
private boolean mEnableSkinTemperatureWarning;
private boolean mEnableUsbTemperatureAlarm;
@@ -87,6 +85,10 @@ public class PowerUI extends SystemUI {
private long mScreenOffTime = -1;
+ @VisibleForTesting boolean mLowWarningShownThisChargeCycle;
+ @VisibleForTesting boolean mSevereWarningShownThisChargeCycle;
+ @VisibleForTesting BatteryStateSnapshot mCurrentBatteryStateSnapshot;
+ @VisibleForTesting BatteryStateSnapshot mLastBatteryStateSnapshot;
@VisibleForTesting IThermalService mThermalService;
@VisibleForTesting int mBatteryLevel = 100;
@@ -205,6 +207,7 @@ public class PowerUI extends SystemUI {
mPlugType = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 1);
final int oldInvalidCharger = mInvalidCharger;
mInvalidCharger = intent.getIntExtra(BatteryManager.EXTRA_INVALID_CHARGER, 0);
+ mLastBatteryStateSnapshot = mCurrentBatteryStateSnapshot;
final boolean plugged = mPlugType != 0;
final boolean oldPlugged = oldPlugType != 0;
@@ -233,16 +236,22 @@ public class PowerUI extends SystemUI {
mWarnings.dismissInvalidChargerWarning();
} else if (mWarnings.isInvalidChargerWarningShowing()) {
// if invalid charger is showing, don't show low battery
+ if (DEBUG) {
+ Slog.d(TAG, "Bad Charger");
+ }
return;
}
// Show the correct version of low battery warning if needed
if (mLastShowWarningTask != null) {
mLastShowWarningTask.cancel(true);
+ if (DEBUG) {
+ Slog.d(TAG, "cancelled task");
+ }
}
mLastShowWarningTask = ThreadUtils.postOnBackgroundThread(() -> {
- maybeShowBatteryWarning(
- oldBatteryLevel, plugged, oldPlugged, oldBucket, bucket);
+ maybeShowBatteryWarningV2(
+ plugged, bucket);
});
} else if (Intent.ACTION_SCREEN_OFF.equals(action)) {
@@ -257,118 +266,176 @@ public class PowerUI extends SystemUI {
}
}
- protected void maybeShowBatteryWarning(int oldBatteryLevel, boolean plugged, boolean oldPlugged,
- int oldBucket, int bucket) {
- boolean isPowerSaver = mPowerManager.isPowerSaveMode();
- // only play SFX when the dialog comes up or the bucket changes
- final boolean playSound = bucket != oldBucket || oldPlugged;
+ protected void maybeShowBatteryWarningV2(boolean plugged, int bucket) {
final boolean hybridEnabled = mEnhancedEstimates.isHybridNotificationEnabled();
+ final boolean isPowerSaverMode = mPowerManager.isPowerSaveMode();
+
+ // Stick current battery state into an immutable container to determine if we should show
+ // a warning.
+ if (DEBUG) {
+ Slog.d(TAG, "evaluating which notification to show");
+ }
if (hybridEnabled) {
- Estimate estimate = mLastEstimate;
- if (estimate == null || mBatteryLevel != oldBatteryLevel) {
- estimate = mEnhancedEstimates.getEstimate();
- mLastEstimate = estimate;
+ if (DEBUG) {
+ Slog.d(TAG, "using hybrid");
}
- // Turbo is not always booted once SysUI is running so we have to make sure we actually
- // get data back
- if (estimate != null) {
- mTimeRemaining = estimate.estimateMillis;
- mWarnings.updateEstimate(estimate);
- mWarnings.updateThresholds(mEnhancedEstimates.getLowWarningThreshold(),
- mEnhancedEstimates.getSevereWarningThreshold());
-
- // if we are now over 45% battery & 6 hours remaining we can trigger hybrid
- // notification again
- if (mBatteryLevel >= CHARGE_CYCLE_PERCENT_RESET
- && mTimeRemaining > SIX_HOURS_MILLIS) {
- mLowWarningShownThisChargeCycle = false;
- mSevereWarningShownThisChargeCycle = false;
- }
+ Estimate estimate = refreshEstimateIfNeeded();
+ mCurrentBatteryStateSnapshot = new BatteryStateSnapshot(mBatteryLevel, isPowerSaverMode,
+ plugged, bucket, mBatteryStatus, mLowBatteryReminderLevels[1],
+ mLowBatteryReminderLevels[0], estimate.getEstimateMillis(),
+ mEnhancedEstimates.getSevereWarningThreshold(),
+ mEnhancedEstimates.getLowWarningThreshold(), estimate.isBasedOnUsage());
+ } else {
+ if (DEBUG) {
+ Slog.d(TAG, "using standard");
}
+ mCurrentBatteryStateSnapshot = new BatteryStateSnapshot(mBatteryLevel, isPowerSaverMode,
+ plugged, bucket, mBatteryStatus, mLowBatteryReminderLevels[1],
+ mLowBatteryReminderLevels[0]);
}
- if (shouldShowLowBatteryWarning(plugged, oldPlugged, oldBucket, bucket,
- mTimeRemaining, isPowerSaver, mBatteryStatus)) {
- mWarnings.showLowBatteryWarning(playSound);
+ mWarnings.updateSnapshot(mCurrentBatteryStateSnapshot);
+ if (mCurrentBatteryStateSnapshot.isHybrid()) {
+ maybeShowHybridWarning(mCurrentBatteryStateSnapshot, mLastBatteryStateSnapshot);
+ } else {
+ maybeShowBatteryWarning(mCurrentBatteryStateSnapshot, mLastBatteryStateSnapshot);
+ }
+ }
+ // updates the time estimate if we don't have one or battery level has changed.
+ @VisibleForTesting
+ Estimate refreshEstimateIfNeeded() {
+ if (mLastBatteryStateSnapshot == null
+ || mLastBatteryStateSnapshot.getTimeRemainingMillis() == NO_ESTIMATE_AVAILABLE
+ || mBatteryLevel != mLastBatteryStateSnapshot.getBatteryLevel()) {
+ final Estimate estimate = mEnhancedEstimates.getEstimate();
+ if (DEBUG) {
+ Slog.d(TAG, "updated estimate: " + estimate.getEstimateMillis());
+ }
+ return estimate;
+ }
+ return new Estimate(mLastBatteryStateSnapshot.getTimeRemainingMillis(),
+ mLastBatteryStateSnapshot.isBasedOnUsage());
+ }
+
+ @VisibleForTesting
+ void maybeShowHybridWarning(BatteryStateSnapshot currentSnapshot,
+ BatteryStateSnapshot lastSnapshot) {
+ // if we are now over 45% battery & 6 hours remaining so we can trigger hybrid
+ // notification again
+ if (currentSnapshot.getBatteryLevel() >= CHARGE_CYCLE_PERCENT_RESET
+ && currentSnapshot.getTimeRemainingMillis() > SIX_HOURS_MILLIS) {
+ mLowWarningShownThisChargeCycle = false;
+ mSevereWarningShownThisChargeCycle = false;
+ if (DEBUG) {
+ Slog.d(TAG, "Charge cycle reset! Can show warnings again");
+ }
+ }
+
+ final boolean playSound = currentSnapshot.getBucket() != lastSnapshot.getBucket()
+ || lastSnapshot.getPlugged();
+
+ if (shouldShowHybridWarning(currentSnapshot)) {
+ mWarnings.showLowBatteryWarning(playSound);
// mark if we've already shown a warning this cycle. This will prevent the notification
// trigger from spamming users by only showing low/critical warnings once per cycle
- if (hybridEnabled) {
- if (mTimeRemaining <= mEnhancedEstimates.getSevereWarningThreshold()
- || mBatteryLevel <= mLowBatteryReminderLevels[1]) {
- mSevereWarningShownThisChargeCycle = true;
- mLowWarningShownThisChargeCycle = true;
- } else {
- mLowWarningShownThisChargeCycle = true;
+ if (currentSnapshot.getTimeRemainingMillis()
+ <= currentSnapshot.getSevereLevelThreshold()
+ || currentSnapshot.getBatteryLevel() <= mLowBatteryReminderLevels[1]) {
+ mSevereWarningShownThisChargeCycle = true;
+ mLowWarningShownThisChargeCycle = true;
+ if (DEBUG) {
+ Slog.d(TAG, "Severe warning marked as shown this cycle");
}
+ } else {
+ Slog.d(TAG, "Low warning marked as shown this cycle");
+ mLowWarningShownThisChargeCycle = true;
+ }
+
+ } else if (shouldDismissHybridWarning(currentSnapshot)) {
+ if (DEBUG) {
+ Slog.d(TAG, "Dismissing warning");
}
- } else if (shouldDismissLowBatteryWarning(plugged, oldBucket, bucket, mTimeRemaining,
- isPowerSaver)) {
mWarnings.dismissLowBatteryWarning();
} else {
+ if (DEBUG) {
+ Slog.d(TAG, "Updating warning");
+ }
mWarnings.updateLowBatteryWarning();
}
}
@VisibleForTesting
- boolean shouldShowLowBatteryWarning(boolean plugged, boolean oldPlugged, int oldBucket,
- int bucket, long timeRemaining, boolean isPowerSaver, int batteryStatus) {
- if (mEnhancedEstimates.isHybridNotificationEnabled()) {
- // triggering logic when enhanced estimate is available
- return isEnhancedTrigger(plugged, timeRemaining, isPowerSaver, batteryStatus);
- }
- // legacy triggering logic
- return !plugged
- && !isPowerSaver
- && (((bucket < oldBucket || oldPlugged) && bucket < 0))
- && batteryStatus != BatteryManager.BATTERY_STATUS_UNKNOWN;
- }
-
- @VisibleForTesting
- boolean shouldDismissLowBatteryWarning(boolean plugged, int oldBucket, int bucket,
- long timeRemaining, boolean isPowerSaver) {
- final boolean hybridEnabled = mEnhancedEstimates.isHybridNotificationEnabled();
- final boolean hybridWouldDismiss = hybridEnabled
- && timeRemaining > mEnhancedEstimates.getLowWarningThreshold();
- final boolean standardWouldDismiss = (bucket > oldBucket && bucket > 0);
- return (isPowerSaver && !hybridEnabled)
- || plugged
- || (standardWouldDismiss && (!mEnhancedEstimates.isHybridNotificationEnabled()
- || hybridWouldDismiss));
- }
-
- private boolean isEnhancedTrigger(boolean plugged, long timeRemaining, boolean isPowerSaver,
- int batteryStatus) {
- if (plugged || batteryStatus == BatteryManager.BATTERY_STATUS_UNKNOWN) {
+ boolean shouldShowHybridWarning(BatteryStateSnapshot snapshot) {
+ if (snapshot.getPlugged()
+ || snapshot.getBatteryStatus() == BatteryManager.BATTERY_STATUS_UNKNOWN) {
+ Slog.d(TAG, "can't show warning due to - plugged: " + snapshot.getPlugged()
+ + " status unknown: "
+ + (snapshot.getBatteryStatus() == BatteryManager.BATTERY_STATUS_UNKNOWN));
return false;
}
- int warnLevel = mLowBatteryReminderLevels[0];
- int critLevel = mLowBatteryReminderLevels[1];
// Only show the low warning once per charge cycle & no battery saver
- final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !isPowerSaver
- && (timeRemaining < mEnhancedEstimates.getLowWarningThreshold()
- || mBatteryLevel <= warnLevel);
+ final boolean canShowWarning = !mLowWarningShownThisChargeCycle && !snapshot.isPowerSaver()
+ && (snapshot.getTimeRemainingMillis() < snapshot.getLowThresholdMillis()
+ || snapshot.getBatteryLevel() <= snapshot.getLowLevelThreshold());
// Only show the severe warning once per charge cycle
final boolean canShowSevereWarning = !mSevereWarningShownThisChargeCycle
- && (timeRemaining < mEnhancedEstimates.getSevereWarningThreshold()
- || mBatteryLevel <= critLevel);
+ && (snapshot.getTimeRemainingMillis() < snapshot.getSevereThresholdMillis()
+ || snapshot.getBatteryLevel() <= snapshot.getSevereLevelThreshold());
final boolean canShow = canShowWarning || canShowSevereWarning;
if (DEBUG) {
- Slog.d(TAG, "Enhanced trigger is: " + canShow + "\nwith values: "
+ Slog.d(TAG, "Enhanced trigger is: " + canShow + "\nwith battery snapshot:"
+ " mLowWarningShownThisChargeCycle: " + mLowWarningShownThisChargeCycle
+ " mSevereWarningShownThisChargeCycle: " + mSevereWarningShownThisChargeCycle
- + " mEnhancedEstimates.timeremaining: " + timeRemaining
- + " mBatteryLevel: " + mBatteryLevel
- + " canShowWarning: " + canShowWarning
- + " canShowSevereWarning: " + canShowSevereWarning
- + " plugged: " + plugged
- + " batteryStatus: " + batteryStatus
- + " isPowerSaver: " + isPowerSaver);
+ + "\n" + snapshot.toString());
+ }
+ return canShow;
+ }
+
+ @VisibleForTesting
+ boolean shouldDismissHybridWarning(BatteryStateSnapshot snapshot) {
+ return snapshot.getPlugged()
+ || snapshot.getTimeRemainingMillis() > snapshot.getLowThresholdMillis();
+ }
+
+ protected void maybeShowBatteryWarning(
+ BatteryStateSnapshot currentSnapshot,
+ BatteryStateSnapshot lastSnapshot) {
+ final boolean playSound = currentSnapshot.getBucket() != lastSnapshot.getBucket()
+ || lastSnapshot.getPlugged();
+
+ if (shouldShowLowBatteryWarning(currentSnapshot, lastSnapshot)) {
+ mWarnings.showLowBatteryWarning(playSound);
+ } else if (shouldDismissLowBatteryWarning(currentSnapshot, lastSnapshot)) {
+ mWarnings.dismissLowBatteryWarning();
+ } else {
+ mWarnings.updateLowBatteryWarning();
}
- return canShowWarning || canShowSevereWarning;
+ }
+
+ @VisibleForTesting
+ boolean shouldShowLowBatteryWarning(
+ BatteryStateSnapshot currentSnapshot,
+ BatteryStateSnapshot lastSnapshot) {
+ return !currentSnapshot.getPlugged()
+ && !currentSnapshot.isPowerSaver()
+ && (((currentSnapshot.getBucket() < lastSnapshot.getBucket()
+ || lastSnapshot.getPlugged())
+ && currentSnapshot.getBucket() < 0))
+ && currentSnapshot.getBatteryStatus() != BatteryManager.BATTERY_STATUS_UNKNOWN;
+ }
+
+ @VisibleForTesting
+ boolean shouldDismissLowBatteryWarning(
+ BatteryStateSnapshot currentSnapshot,
+ BatteryStateSnapshot lastSnapshot) {
+ return currentSnapshot.isPowerSaver()
+ || currentSnapshot.getPlugged()
+ || (currentSnapshot.getBucket() > lastSnapshot.getBucket()
+ && currentSnapshot.getBucket() > 0);
}
private void initTemperature() {
@@ -453,12 +520,20 @@ public class PowerUI extends SystemUI {
mWarnings.dump(pw);
}
+ /**
+ * The interface to allow PowerUI to communicate with whatever implementation of WarningsUI
+ * is being used by the system.
+ */
public interface WarningsUI {
- void update(int batteryLevel, int bucket, long screenOffTime);
- void updateEstimate(Estimate estimate);
-
- void updateThresholds(long lowThreshold, long severeThreshold);
+ /**
+ * Updates battery and screen info for determining whether to trigger battery warnings or
+ * not.
+ * @param batteryLevel The current battery level
+ * @param bucket The current battery bucket
+ * @param screenOffTime How long the screen has been off in millis
+ */
+ void update(int batteryLevel, int bucket, long screenOffTime);
void dismissLowBatteryWarning();
@@ -486,6 +561,12 @@ public class PowerUI extends SystemUI {
void dump(PrintWriter pw);
void userSwitched();
+
+ /**
+ * Updates the snapshot of battery state used for evaluating battery warnings
+ * @param snapshot object containing relevant values for making battery warning decisions.
+ */
+ void updateSnapshot(BatteryStateSnapshot snapshot);
}
// Thermal event received from thermal service manager subsystem
diff --git a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
index 625eacd7e2a7..1c0974a0c987 100644
--- a/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+++ b/packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
@@ -61,7 +61,8 @@ class PrivacyItemController @Inject constructor(
@VisibleForTesting
internal var privacyList = emptyList<PrivacyItem>()
- get() = field.toList() // Provides a shallow copy of the list
+ @Synchronized get() = field.toList() // Returns a shallow copy of the list
+ @Synchronized set
private val userManager = context.getSystemService(UserManager::class.java)
private var currentUserIds = emptyList<Int>()
@@ -71,7 +72,8 @@ class PrivacyItemController @Inject constructor(
private val callbacks = mutableListOf<WeakReference<Callback>>()
private val notifyChanges = Runnable {
- callbacks.forEach { it.get()?.privacyChanged(privacyList) }
+ val list = privacyList
+ callbacks.forEach { it.get()?.privacyChanged(list) }
}
private val updateListAndNotifyChanges = Runnable {
@@ -157,8 +159,10 @@ class PrivacyItemController @Inject constructor(
}
private fun updatePrivacyList() {
- privacyList = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
+
+ val list = currentUserIds.flatMap { appOpsController.getActiveAppOpsForUser(it) }
.mapNotNull { toPrivacyItem(it) }.distinct()
+ privacyList = list
}
private fun toPrivacyItem(appOpItem: AppOpItem): PrivacyItem? {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
index 52b8cc2b685b..b7ae4edc1522 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
@@ -51,8 +51,15 @@ class MediaArtworkProcessor @Inject constructor() {
val renderScript = RenderScript.create(context)
val rect = Rect(0, 0, artwork.width, artwork.height)
MathUtils.fitRect(rect, Math.max(mTmpSize.x / DOWNSAMPLE, mTmpSize.y / DOWNSAMPLE))
- val inBitmap = Bitmap.createScaledBitmap(artwork, rect.width(), rect.height(),
+ var inBitmap = Bitmap.createScaledBitmap(artwork, rect.width(), rect.height(),
true /* filter */)
+ // Render script blurs only support ARGB_8888, we need a conversion if we got a
+ // different bitmap config.
+ if (inBitmap.config != Bitmap.Config.ARGB_8888) {
+ val oldIn = inBitmap
+ inBitmap = oldIn.copy(Bitmap.Config.ARGB_8888, false /* isMutable */)
+ oldIn.recycle()
+ }
val input = Allocation.createFromBitmap(renderScript, inBitmap,
Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_GRAPHICS_TEXTURE)
val outBitmap = Bitmap.createBitmap(inBitmap.width, inBitmap.height,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index ad5aa57f12ea..eb386dcdbf46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -18,15 +18,19 @@ package com.android.systemui.statusbar;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
+import android.text.format.DateFormat;
import android.util.FloatProperty;
import android.view.animation.Interpolator;
import com.android.internal.annotations.GuardedBy;
+import com.android.systemui.Dumpable;
import com.android.systemui.Interpolators;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.policy.CallbackController;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;
@@ -38,8 +42,10 @@ import javax.inject.Singleton;
*/
@Singleton
public class StatusBarStateControllerImpl implements SysuiStatusBarStateController,
- CallbackController<StateListener> {
+ CallbackController<StateListener>, Dumpable {
private static final String TAG = "SbStateController";
+ // Must be a power of 2
+ private static final int HISTORY_SIZE = 32;
private static final int MAX_STATE = StatusBarState.FULLSCREEN_USER_SWITCHER;
private static final int MIN_STATE = StatusBarState.SHADE;
@@ -66,6 +72,10 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
private boolean mLeaveOpenOnKeyguardHide;
private boolean mKeyguardRequested;
+ // Record the HISTORY_SIZE most recent states
+ private int mHistoryIndex = 0;
+ private HistoricalState[] mHistoricalRecords = new HistoricalState[HISTORY_SIZE];
+
/**
* If the device is currently dozing or not.
*/
@@ -93,6 +103,9 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
@Inject
public StatusBarStateControllerImpl() {
+ for (int i = 0; i < HISTORY_SIZE; i++) {
+ mHistoricalRecords[i] = new HistoricalState();
+ }
}
@Override
@@ -108,6 +121,10 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
if (state == mState) {
return false;
}
+
+ // Record the to-be mState and mLastState
+ recordHistoricalState(state, mState);
+
synchronized (mListeners) {
for (RankedListener rl : new ArrayList<>(mListeners)) {
rl.mListener.onStatePreChange(mState, state);
@@ -281,4 +298,58 @@ public class StatusBarStateControllerImpl implements SysuiStatusBarStateControll
public static String describe(int state) {
return StatusBarState.toShortString(state);
}
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ pw.println("StatusBarStateController: ");
+ pw.println(" mState=" + mState + " (" + describe(mState) + ")");
+ pw.println(" mLastState=" + mLastState + " (" + describe(mLastState) + ")");
+ pw.println(" mLeaveOpenOnKeyguardHide=" + mLeaveOpenOnKeyguardHide);
+ pw.println(" mKeyguardRequested=" + mKeyguardRequested);
+ pw.println(" mIsDozing=" + mIsDozing);
+ pw.println(" Historical states:");
+ // Ignore records without a timestamp
+ int size = 0;
+ for (int i = 0; i < HISTORY_SIZE; i++) {
+ if (mHistoricalRecords[i].mTimestamp != 0) size++;
+ }
+ for (int i = mHistoryIndex + HISTORY_SIZE;
+ i >= mHistoryIndex + HISTORY_SIZE - size + 1; i--) {
+ pw.println(" (" + (mHistoryIndex + HISTORY_SIZE - i + 1) + ")"
+ + mHistoricalRecords[i & (HISTORY_SIZE - 1)]);
+ }
+ }
+
+ private void recordHistoricalState(int currentState, int lastState) {
+ mHistoryIndex = (mHistoryIndex + 1) % HISTORY_SIZE;
+ HistoricalState state = mHistoricalRecords[mHistoryIndex];
+ state.mState = currentState;
+ state.mLastState = lastState;
+ state.mTimestamp = System.currentTimeMillis();
+ }
+
+ /**
+ * For keeping track of our previous state to help with debugging
+ */
+ private static class HistoricalState {
+ int mState;
+ int mLastState;
+ long mTimestamp;
+
+ @Override
+ public String toString() {
+ if (mTimestamp != 0) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("state=").append(mState)
+ .append(" (").append(describe(mState)).append(")");
+ sb.append("lastState=").append(mLastState).append(" (").append(describe(mLastState))
+ .append(")");
+ sb.append("timestamp=")
+ .append(DateFormat.format("MM-dd HH:mm:ss", mTimestamp));
+
+ return sb.toString();
+ }
+ return "Empty " + getClass().getSimpleName();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index 9be47f742ed9..3fc60cdcdc70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -990,6 +990,7 @@ public class NavigationBarFragment extends LifecycleFragment implements Callback
lp.setTitle("NavigationBar" + context.getDisplayId());
lp.accessibilityTitle = context.getString(R.string.nav_bar);
lp.windowAnimations = 0;
+ lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
View navigationBarView = LayoutInflater.from(context).inflate(
R.layout.navigation_bar_window, null);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 7bbd3b526892..8714a51f98d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -114,6 +114,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
private final DozeParameters mDozeParameters;
private final AlarmTimeout mTimeTicker;
private final KeyguardVisibilityCallback mKeyguardVisibilityCallback;
+ private final Handler mHandler;
private final SysuiColorExtractor mColorExtractor;
private GradientColors mLockColors;
@@ -174,8 +175,9 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
mKeyguardVisibilityCallback = new KeyguardVisibilityCallback();
mKeyguardUpdateMonitor.registerCallback(mKeyguardVisibilityCallback);
mScrimBehindAlphaResValue = mContext.getResources().getFloat(R.dimen.scrim_behind_alpha);
+ mHandler = getHandler();
mTimeTicker = new AlarmTimeout(alarmManager, this::onHideWallpaperTimeout,
- "hide_aod_wallpaper", new Handler());
+ "hide_aod_wallpaper", mHandler);
mWakeLock = createWakeLock();
// Scrim alpha is initially set to the value on the resource but might be changed
// to make sure that text on top of it is legible.
@@ -253,8 +255,8 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
mScrimBehind.removeCallbacks(mPendingFrameCallback);
mPendingFrameCallback = null;
}
- if (getHandler().hasCallbacks(mBlankingTransitionRunnable)) {
- getHandler().removeCallbacks(mBlankingTransitionRunnable);
+ if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) {
+ mHandler.removeCallbacks(mBlankingTransitionRunnable);
mBlankingTransitionRunnable = null;
}
@@ -768,7 +770,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
if (DEBUG) {
Log.d(TAG, "Fading out scrims with delay: " + delay);
}
- getHandler().postDelayed(mBlankingTransitionRunnable, delay);
+ mHandler.postDelayed(mBlankingTransitionRunnable, delay);
};
doOnTheNextFrame(mPendingFrameCallback);
}
@@ -786,7 +788,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
@VisibleForTesting
protected Handler getHandler() {
- return Handler.getMain();
+ return new Handler();
}
public int getBackgroundColor() {
@@ -821,8 +823,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
@VisibleForTesting
protected WakeLock createWakeLock() {
- return new DelayedWakeLock(getHandler(),
- WakeLock.createPartial(mContext, "Scrims"));
+ return new DelayedWakeLock(mHandler, WakeLock.createPartial(mContext, "Scrims"));
}
@Override
@@ -853,12 +854,11 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
*/
public void onScreenTurnedOn() {
mScreenOn = true;
- final Handler handler = getHandler();
- if (handler.hasCallbacks(mBlankingTransitionRunnable)) {
+ if (mHandler.hasCallbacks(mBlankingTransitionRunnable)) {
if (DEBUG) {
Log.d(TAG, "Shorter blanking because screen turned on. All good.");
}
- handler.removeCallbacks(mBlankingTransitionRunnable);
+ mHandler.removeCallbacks(mBlankingTransitionRunnable);
mBlankingTransitionRunnable.run();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index ce69a489737a..8d71ab810710 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -280,6 +280,15 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
}
}
+ private void applyStatusBarColorSpaceAgnosticFlag(State state) {
+ if (!isExpanded(state)) {
+ mLpChanged.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
+ } else {
+ mLpChanged.privateFlags &=
+ ~WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC;
+ }
+ }
+
private void apply(State state) {
applyKeyguardFlags(state);
applyForceStatusBarVisibleFlag(state);
@@ -294,6 +303,7 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
applyBrightness(state);
applyHasTopUi(state);
applyNotTouchable(state);
+ applyStatusBarColorSpaceAgnosticFlag(state);
if (mLp != null && mLp.copyFrom(mLpChanged) != 0) {
mWindowManager.updateViewLayout(mStatusBarView, mLp);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index af3c96f73642..3fa3e1a6e6d4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -226,7 +226,7 @@ public class BatteryControllerImpl extends BroadcastReceiver implements BatteryC
String percentage = NumberFormat.getPercentInstance().format((double) mLevel / 100.0);
return PowerUtil.getBatteryRemainingShortStringFormatted(
- mContext, mEstimate.estimateMillis);
+ mContext, mEstimate.getEstimateMillis());
}
private void updateEstimateInBackground() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
index 5876ae1910be..58c931190c83 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerNotificationWarningsTest.java
@@ -30,6 +30,7 @@ import static org.mockito.Mockito.verify;
import android.app.Notification;
import android.app.NotificationManager;
+import android.os.BatteryManager;
import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -57,6 +58,9 @@ public class PowerNotificationWarningsTest extends SysuiTestCase {
// Test Instance.
mContext.addMockSystemService(NotificationManager.class, mMockNotificationManager);
mPowerNotificationWarnings = new PowerNotificationWarnings(mContext);
+ BatteryStateSnapshot snapshot = new BatteryStateSnapshot(100, false, false, 1,
+ BatteryManager.BATTERY_HEALTH_GOOD, 5, 15);
+ mPowerNotificationWarnings.updateSnapshot(snapshot);
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
index 0aed63d25112..f51e4731a390 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/power/PowerUITest.java
@@ -17,8 +17,7 @@ package com.android.systemui.power;
import static android.provider.Settings.Global.SHOW_TEMPERATURE_WARNING;
import static android.provider.Settings.Global.SHOW_USB_TEMPERATURE_ALARM;
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
+import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.anyObject;
@@ -29,7 +28,6 @@ import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
-import android.content.Intent;
import android.os.BatteryManager;
import android.os.IThermalEventListener;
import android.os.IThermalService;
@@ -42,22 +40,20 @@ import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.TestableResources;
-import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.power.PowerUI.WarningsUI;
import com.android.systemui.statusbar.phone.StatusBar;
+import java.time.Duration;
+import java.util.concurrent.TimeUnit;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
-import java.time.Duration;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.TimeUnit;
-
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@SmallTest
@@ -75,6 +71,7 @@ public class PowerUITest extends SysuiTestCase {
private static final int OLD_BATTERY_LEVEL_NINE = 9;
private static final int OLD_BATTERY_LEVEL_10 = 10;
private static final long VERY_BELOW_SEVERE_HYBRID_THRESHOLD = TimeUnit.MINUTES.toMillis(15);
+ public static final int BATTERY_LEVEL_10 = 10;
private WarningsUI mMockWarnings;
private PowerUI mPowerUI;
private EnhancedEstimates mEnhancedEstimates;
@@ -176,368 +173,333 @@ public class PowerUITest extends SysuiTestCase {
}
@Test
- public void testShouldShowLowBatteryWarning_showHybridOnly_overrideThresholdHigh_returnsNoShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold())
- .thenReturn(Duration.ofHours(1).toMillis());
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
+ public void testMaybeShowHybridWarning() {
mPowerUI.start();
- // unplugged device that would not show the non-hybrid notification but would show the
- // hybrid but the threshold has been overriden to be too low
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertFalse(shouldShow);
- }
+ // verify low warning shown this cycle noticed
+ BatteryStateSnapshotWrapper state = new BatteryStateSnapshotWrapper();
+ BatteryStateSnapshot lastState = state.get();
+ state.mTimeRemainingMillis = Duration.ofHours(2).toMillis();
+ state.mBatteryLevel = 15;
- @Test
- public void testShouldShowLowBatteryWarning_showHybridOnly_overrideThresholdHigh_returnsShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold())
- .thenReturn(Duration.ofHours(5).toMillis());
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- mPowerUI.start();
+ mPowerUI.maybeShowHybridWarning(state.get(), lastState);
- // unplugged device that would not show the non-hybrid notification but would show the
- // hybrid since the threshold has been overriden to be much higher
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertTrue(shouldShow);
- }
+ assertThat(mPowerUI.mLowWarningShownThisChargeCycle).isTrue();
+ assertThat(mPowerUI.mSevereWarningShownThisChargeCycle).isFalse();
- @Test
- public void testShouldShowLowBatteryWarning_showHybridOnly_returnsShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- mPowerUI.start();
+ // verify severe warning noticed this cycle
+ lastState = state.get();
+ state.mBatteryLevel = 1;
+ state.mTimeRemainingMillis = Duration.ofMinutes(10).toMillis();
- // unplugged device that would not show the non-hybrid notification but would show the
- // hybrid
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertTrue(shouldShow);
- }
+ mPowerUI.maybeShowHybridWarning(state.get(), lastState);
- @Test
- public void testShouldShowLowBatteryWarning_showHybrid_showStandard_returnsShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- mPowerUI.mBatteryLevel = 10;
- mPowerUI.start();
+ assertThat(mPowerUI.mLowWarningShownThisChargeCycle).isTrue();
+ assertThat(mPowerUI.mSevereWarningShownThisChargeCycle).isTrue();
- // unplugged device that would show the non-hybrid notification and the hybrid
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertTrue(shouldShow);
- }
+ // verify getting past threshold resets values
+ lastState = state.get();
+ state.mBatteryLevel = 100;
+ state.mTimeRemainingMillis = Duration.ofDays(1).toMillis();
- @Test
- public void testShouldShowLowBatteryWarning_showStandardOnly_returnsShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- mPowerUI.mBatteryLevel = 10;
- mPowerUI.start();
+ mPowerUI.maybeShowHybridWarning(state.get(), lastState);
- // unplugged device that would show the non-hybrid but not the hybrid
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertTrue(shouldShow);
+ assertThat(mPowerUI.mLowWarningShownThisChargeCycle).isFalse();
+ assertThat(mPowerUI.mSevereWarningShownThisChargeCycle).isFalse();
}
@Test
- public void testShouldShowLowBatteryWarning_deviceHighBattery_returnsNoShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
+ public void testShouldShowHybridWarning_lowLevelWarning() {
mPowerUI.start();
-
- // unplugged device that would show the neither due to battery level being good
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertFalse(shouldShow);
+ mPowerUI.mLowWarningShownThisChargeCycle = false;
+ mPowerUI.mSevereWarningShownThisChargeCycle = false;
+ BatteryStateSnapshotWrapper state = new BatteryStateSnapshotWrapper();
+
+ // sanity check to make sure we can show for a valid config
+ state.mBatteryLevel = 10;
+ state.mTimeRemainingMillis = Duration.ofHours(2).toMillis();
+ boolean shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // Shouldn't show if plugged in
+ state.mPlugged = true;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ // Shouldn't show if battery is unknown
+ state.mPlugged = false;
+ state.mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ state.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
+ // Already shown both warnings
+ mPowerUI.mLowWarningShownThisChargeCycle = true;
+ mPowerUI.mSevereWarningShownThisChargeCycle = true;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ // Can show low warning
+ mPowerUI.mLowWarningShownThisChargeCycle = false;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // Can't show if above the threshold for time & battery
+ state.mTimeRemainingMillis = Duration.ofHours(1000).toMillis();
+ state.mBatteryLevel = 100;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ // Battery under low percentage threshold but not time
+ state.mBatteryLevel = 10;
+ state.mLowLevelThreshold = 50;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // Should also trigger if both level and time remaining under low threshold
+ state.mTimeRemainingMillis = Duration.ofHours(2).toMillis();
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // battery saver should block the low level warning though
+ state.mIsPowerSaver = true;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
}
@Test
- public void testShouldShowLowBatteryWarning_devicePlugged_returnsNoShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- mPowerUI.start();
-
- // plugged device that would show the neither due to being plugged
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(!UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertFalse(shouldShow);
- }
-
- @Test
- public void testShouldShowLowBatteryWarning_deviceBatteryStatusUnknown_returnsNoShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
+ public void testShouldShowHybridWarning_severeLevelWarning() {
mPowerUI.start();
-
- // Unknown battery status device that would show the neither due to the battery status being
- // unknown
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
- !POWER_SAVER_OFF, BatteryManager.BATTERY_STATUS_UNKNOWN);
- assertFalse(shouldShow);
+ mPowerUI.mLowWarningShownThisChargeCycle = false;
+ mPowerUI.mSevereWarningShownThisChargeCycle = false;
+ BatteryStateSnapshotWrapper state = new BatteryStateSnapshotWrapper();
+
+ // sanity check to make sure we can show for a valid config
+ state.mBatteryLevel = 1;
+ state.mTimeRemainingMillis = Duration.ofMinutes(1).toMillis();
+ boolean shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // Shouldn't show if plugged in
+ state.mPlugged = true;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ // Shouldn't show if battery is unknown
+ state.mPlugged = false;
+ state.mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ state.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
+ // Already shown both warnings
+ mPowerUI.mLowWarningShownThisChargeCycle = true;
+ mPowerUI.mSevereWarningShownThisChargeCycle = true;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ // Can show severe warning
+ mPowerUI.mSevereWarningShownThisChargeCycle = false;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // Can't show if above the threshold for time & battery
+ state.mTimeRemainingMillis = Duration.ofHours(1000).toMillis();
+ state.mBatteryLevel = 100;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isFalse();
+
+ // Battery under low percentage threshold but not time
+ state.mBatteryLevel = 1;
+ state.mSevereLevelThreshold = 5;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // Should also trigger if both level and time remaining under low threshold
+ state.mTimeRemainingMillis = Duration.ofHours(2).toMillis();
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
+
+ // battery saver should not block the severe level warning though
+ state.mIsPowerSaver = true;
+ shouldShow = mPowerUI.shouldShowHybridWarning(state.get());
+ assertThat(shouldShow).isTrue();
}
@Test
- public void testShouldShowLowBatteryWarning_batterySaverEnabled_returnsNoShow() {
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
+ public void testShouldDismissHybridWarning() {
mPowerUI.start();
-
- // BatterySaverEnabled device that would show the neither due to battery saver
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
- !POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertFalse(shouldShow);
+ BatteryStateSnapshotWrapper state = new BatteryStateSnapshotWrapper();
+
+ // We should dismiss if the device is plugged in
+ state.mPlugged = true;
+ state.mTimeRemainingMillis = Duration.ofHours(1).toMillis();
+ state.mLowThresholdMillis = Duration.ofHours(2).toMillis();
+ boolean shouldDismiss = mPowerUI.shouldDismissHybridWarning(state.get());
+ assertThat(shouldDismiss).isTrue();
+
+ // If not plugged in and below the threshold we should not dismiss
+ state.mPlugged = false;
+ shouldDismiss = mPowerUI.shouldDismissHybridWarning(state.get());
+ assertThat(shouldDismiss).isFalse();
+
+ // If we go over the low warning threshold we should dismiss
+ state.mTimeRemainingMillis = Duration.ofHours(3).toMillis();
+ shouldDismiss = mPowerUI.shouldDismissHybridWarning(state.get());
+ assertThat(shouldDismiss).isTrue();
}
@Test
- public void testShouldShowLowBatteryWarning_onlyShowsOncePerChargeCycle() {
+ public void testRefreshEstimateIfNeeded_onlyQueriesEstimateOnBatteryLevelChangeOrNull() {
mPowerUI.start();
+ Estimate estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true);
when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- when(mEnhancedEstimates.getEstimate())
- .thenReturn(new Estimate(BELOW_HYBRID_THRESHOLD, true));
- mPowerUI.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
-
- mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_NINE, UNPLUGGED, UNPLUGGED,
- ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
-
- // reduce battery level to handle time based trigger -> level trigger interactions
+ when(mEnhancedEstimates.getEstimate()).thenReturn(estimate);
mPowerUI.mBatteryLevel = 10;
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertFalse(shouldShow);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_dismissWhenPowerSaverEnabledLegacy() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(false);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- // device that gets power saver turned on should dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, !POWER_SAVER_OFF);
- assertTrue(shouldDismiss);
- }
- @Test
- public void testShouldNotDismissLowBatteryWarning_dismissWhenPowerSaverEnabledHybrid() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- // device that gets power saver turned on should dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, !POWER_SAVER_OFF);
- assertFalse(shouldDismiss);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_dismissWhenPlugged() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- // device that gets plugged in should dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(!UNPLUGGED, BELOW_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
- assertTrue(shouldDismiss);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_dismissHybridSignal_showStandardSignal_shouldShow() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- // would dismiss hybrid but not non-hybrid should not dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
- assertFalse(shouldDismiss);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_showHybridSignal_dismissStandardSignal_shouldShow() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- // would dismiss non-hybrid but not hybrid should not dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD, POWER_SAVER_OFF);
- assertFalse(shouldDismiss);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_showBothSignal_shouldShow() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- // should not dismiss when both would not dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
- BELOW_WARNING_BUCKET, BELOW_HYBRID_THRESHOLD, POWER_SAVER_OFF);
- assertFalse(shouldDismiss);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_dismissBothSignal_shouldDismiss() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- //should dismiss if both would dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
- assertTrue(shouldDismiss);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_dismissStandardSignal_hybridDisabled_shouldDismiss() {
- mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(false);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
-
- // would dismiss non-hybrid with hybrid disabled should dismiss
- boolean shouldDismiss =
- mPowerUI.shouldDismissLowBatteryWarning(UNPLUGGED, BELOW_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, ABOVE_HYBRID_THRESHOLD, POWER_SAVER_OFF);
- assertTrue(shouldDismiss);
- }
-
- @Test
- public void testShouldDismissLowBatteryWarning_powerSaverModeEnabled()
- throws InterruptedException {
- when(mPowerManager.isPowerSaveMode()).thenReturn(true);
-
- mPowerUI.start();
- mPowerUI.mReceiver.onReceive(mContext,
- new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
-
- CountDownLatch latch = new CountDownLatch(1);
- ThreadUtils.postOnBackgroundThread(() -> latch.countDown());
- latch.await(5, TimeUnit.SECONDS);
-
- verify(mMockWarnings).dismissLowBatteryWarning();
- }
-
- @Test
- public void testShouldNotDismissLowBatteryWarning_powerSaverModeDisabled()
- throws InterruptedException {
- when(mPowerManager.isPowerSaveMode()).thenReturn(false);
-
- mPowerUI.start();
- mPowerUI.mReceiver.onReceive(mContext,
- new Intent(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED));
-
- CountDownLatch latch = new CountDownLatch(1);
- ThreadUtils.postOnBackgroundThread(() -> latch.countDown());
- latch.await(5, TimeUnit.SECONDS);
+ // we expect that the first time it will query since there is no last battery snapshot.
+ // However an invalid estimate (-1) is returned.
+ Estimate refreshedEstimate = mPowerUI.refreshEstimateIfNeeded();
+ assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_HYBRID_THRESHOLD);
+ BatteryStateSnapshot snapshot = new BatteryStateSnapshot(
+ BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD,
+ 0, 0, -1, 0, 0, false);
+ mPowerUI.mLastBatteryStateSnapshot = snapshot;
+
+ // query again since the estimate was -1
+ estimate = new Estimate(BELOW_SEVERE_HYBRID_THRESHOLD, true);
+ when(mEnhancedEstimates.getEstimate()).thenReturn(estimate);
+ refreshedEstimate = mPowerUI.refreshEstimateIfNeeded();
+ assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_SEVERE_HYBRID_THRESHOLD);
+ snapshot = new BatteryStateSnapshot(
+ BATTERY_LEVEL_10, false, false, 0, BatteryManager.BATTERY_HEALTH_GOOD, 0,
+ 0, BELOW_SEVERE_HYBRID_THRESHOLD, 0, 0, false);
+ mPowerUI.mLastBatteryStateSnapshot = snapshot;
+
+ // Battery level hasn't changed, so we don't query again
+ estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true);
+ when(mEnhancedEstimates.getEstimate()).thenReturn(estimate);
+ refreshedEstimate = mPowerUI.refreshEstimateIfNeeded();
+ assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_SEVERE_HYBRID_THRESHOLD);
- verify(mMockWarnings, never()).dismissLowBatteryWarning();
+ // Battery level changes so we update again
+ mPowerUI.mBatteryLevel = 9;
+ refreshedEstimate = mPowerUI.refreshEstimateIfNeeded();
+ assertThat(refreshedEstimate.getEstimateMillis()).isEqualTo(BELOW_HYBRID_THRESHOLD);
}
@Test
- public void testSevereWarning_countsAsLowAndSevere_WarningOnlyShownOnce() {
+ public void testShouldShowStandardWarning() {
mPowerUI.start();
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- when(mEnhancedEstimates.getEstimate())
- .thenReturn(new Estimate(BELOW_SEVERE_HYBRID_THRESHOLD, true));
- mPowerUI.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
-
- // reduce battery level to handle time based trigger -> level trigger interactions
- mPowerUI.mBatteryLevel = 5;
- boolean shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, BELOW_SEVERE_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertTrue(shouldShow);
-
- // actually run the end to end since it handles changing the internal state.
- mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_10, UNPLUGGED, UNPLUGGED,
- ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
-
- shouldShow =
- mPowerUI.shouldShowLowBatteryWarning(UNPLUGGED, UNPLUGGED, ABOVE_WARNING_BUCKET,
- ABOVE_WARNING_BUCKET, VERY_BELOW_SEVERE_HYBRID_THRESHOLD,
- POWER_SAVER_OFF, BatteryManager.BATTERY_HEALTH_GOOD);
- assertFalse(shouldShow);
+ BatteryStateSnapshotWrapper state = new BatteryStateSnapshotWrapper();
+ state.mIsHybrid = false;
+ BatteryStateSnapshot lastState = state.get();
+
+ // sanity check to make sure we can show for a valid config
+ state.mBatteryLevel = 10;
+ state.mBucket = -1;
+ boolean shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isTrue();
+ lastState = state.get();
+
+ // Shouldn't show if plugged in
+ state.mPlugged = true;
+ shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isFalse();
+
+ state.mPlugged = false;
+ // Shouldn't show if battery saver
+ state.mIsPowerSaver = true;
+ shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isFalse();
+
+ state.mIsPowerSaver = false;
+ // Shouldn't show if battery is unknown
+ state.mPlugged = false;
+ state.mBatteryStatus = BatteryManager.BATTERY_STATUS_UNKNOWN;
+ shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isFalse();
+
+ state.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
+ // show if plugged -> unplugged, bucket -1 -> -1
+ state.mPlugged = true;
+ state.mBucket = -1;
+ lastState = state.get();
+ state.mPlugged = false;
+ state.mBucket = -1;
+ shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isTrue();
+
+ // don't show if plugged -> unplugged, bucket 0 -> 0
+ state.mPlugged = true;
+ state.mBucket = 0;
+ lastState = state.get();
+ state.mPlugged = false;
+ state.mBucket = 0;
+ shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isFalse();
+
+ // show if unplugged -> unplugged, bucket 0 -> -1
+ state.mPlugged = false;
+ state.mBucket = 0;
+ lastState = state.get();
+ state.mPlugged = false;
+ state.mBucket = -1;
+ shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isTrue();
+
+ // don't show if unplugged -> unplugged, bucket -1 -> 1
+ state.mPlugged = false;
+ state.mBucket = -1;
+ lastState = state.get();
+ state.mPlugged = false;
+ state.mBucket = 1;
+ shouldShow = mPowerUI.shouldShowLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldShow).isFalse();
}
@Test
- public void testMaybeShowBatteryWarning_onlyQueriesEstimateOnBatteryLevelChangeOrNull() {
+ public void testShouldDismissStandardWarning() {
mPowerUI.start();
- Estimate estimate = new Estimate(BELOW_HYBRID_THRESHOLD, true);
- when(mEnhancedEstimates.isHybridNotificationEnabled()).thenReturn(true);
- when(mEnhancedEstimates.getLowWarningThreshold()).thenReturn(PowerUI.THREE_HOURS_IN_MILLIS);
- when(mEnhancedEstimates.getSevereWarningThreshold()).thenReturn(ONE_HOUR_MILLIS);
- when(mEnhancedEstimates.getEstimate()).thenReturn(estimate);
- mPowerUI.mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
-
- // we expect that the first time it will query even if the level is the same
- mPowerUI.mBatteryLevel = 9;
- mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_NINE, UNPLUGGED, UNPLUGGED,
- ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
- verify(mEnhancedEstimates, times(1)).getEstimate();
-
- // We should NOT query again if the battery level hasn't changed
- mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_NINE, UNPLUGGED, UNPLUGGED,
- ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
- verify(mEnhancedEstimates, times(1)).getEstimate();
-
- // Battery level has changed, so we should query again
- mPowerUI.maybeShowBatteryWarning(OLD_BATTERY_LEVEL_10, UNPLUGGED, UNPLUGGED,
- ABOVE_WARNING_BUCKET, ABOVE_WARNING_BUCKET);
- verify(mEnhancedEstimates, times(2)).getEstimate();
+ BatteryStateSnapshotWrapper state = new BatteryStateSnapshotWrapper();
+ state.mIsHybrid = false;
+ BatteryStateSnapshot lastState = state.get();
+
+ // should dismiss if battery saver
+ state.mIsPowerSaver = true;
+ boolean shouldDismiss = mPowerUI.shouldDismissLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldDismiss).isTrue();
+
+ state.mIsPowerSaver = false;
+ // should dismiss if plugged
+ state.mPlugged = true;
+ shouldDismiss = mPowerUI.shouldDismissLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldDismiss).isTrue();
+
+ state.mPlugged = false;
+ // should dismiss if bucket 0 -> 1
+ state.mBucket = 0;
+ lastState = state.get();
+ state.mBucket = 1;
+ shouldDismiss = mPowerUI.shouldDismissLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldDismiss).isTrue();
+
+ // shouldn't dismiss if bucket -1 -> 0
+ state.mBucket = -1;
+ lastState = state.get();
+ state.mBucket = 0;
+ shouldDismiss = mPowerUI.shouldDismissLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldDismiss).isFalse();
+
+ // should dismiss if powersaver & bucket 0 -> 1
+ state.mIsPowerSaver = true;
+ state.mBucket = 0;
+ lastState = state.get();
+ state.mBucket = 1;
+ shouldDismiss = mPowerUI.shouldDismissLowBatteryWarning(state.get(), lastState);
+ assertThat(shouldDismiss).isTrue();
}
private Temperature getEmergencyStatusTemp(int type, String name) {
@@ -556,4 +518,35 @@ public class PowerUITest extends SysuiTestCase {
mPowerUI.mComponents = mContext.getComponents();
mPowerUI.mThermalService = mThermalServiceMock;
}
+
+ /**
+ * A simple wrapper class that sets values by default and makes them not final to improve
+ * test clarity.
+ */
+ private class BatteryStateSnapshotWrapper {
+ public int mBatteryLevel = 100;
+ public boolean mIsPowerSaver = false;
+ public boolean mPlugged = false;
+ public long mSevereThresholdMillis = Duration.ofHours(1).toMillis();
+ public long mLowThresholdMillis = Duration.ofHours(3).toMillis();
+ public int mSevereLevelThreshold = 5;
+ public int mLowLevelThreshold = 15;
+ public int mBucket = 1;
+ public int mBatteryStatus = BatteryManager.BATTERY_HEALTH_GOOD;
+ public long mTimeRemainingMillis = Duration.ofHours(24).toMillis();
+ public boolean mIsBasedOnUsage = true;
+ public boolean mIsHybrid = true;
+
+ public BatteryStateSnapshot get() {
+ if (mIsHybrid) {
+ return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket,
+ mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold,
+ mTimeRemainingMillis, mSevereThresholdMillis, mLowThresholdMillis,
+ mIsBasedOnUsage);
+ } else {
+ return new BatteryStateSnapshot(mBatteryLevel, mIsPowerSaver, mPlugged, mBucket,
+ mBatteryStatus, mSevereLevelThreshold, mLowLevelThreshold);
+ }
+ }
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
index 1783d9dacd3b..6033ed26579c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
@@ -264,7 +264,8 @@ class PrivacyItemControllerTest : SysuiTestCase() {
val list = listOf(PrivacyItem(PrivacyType.TYPE_CAMERA,
PrivacyApplication("", TEST_UID, mContext)))
privacyItemController.privacyList = list
- assertEquals(list, privacyItemController.privacyList)
- assertTrue(list !== privacyItemController.privacyList)
+ val privacyList = privacyItemController.privacyList
+ assertEquals(list, privacyList)
+ assertTrue(list !== privacyList)
}
} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index f88b64a65e28..6db36243bb07 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -37,12 +37,10 @@ import android.animation.ValueAnimator;
import android.app.AlarmManager;
import android.graphics.Color;
import android.os.Handler;
-import android.os.Looper;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
-import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
import com.android.internal.colorextraction.ColorExtractor.GradientColors;
@@ -78,6 +76,7 @@ public class ScrimControllerTest extends SysuiTestCase {
private WakeLock mWakeLock;
private boolean mAlwaysOnEnabled;
private AlarmManager mAlarmManager;
+ private TestableLooper mLooper;
@Before
@@ -88,6 +87,7 @@ public class ScrimControllerTest extends SysuiTestCase {
mAlarmManager = mock(AlarmManager.class);
mAlwaysOnEnabled = true;
mDozeParamenters = mock(DozeParameters.class);
+ mLooper = TestableLooper.get(this);
when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront,
@@ -253,7 +253,6 @@ public class ScrimControllerTest extends SysuiTestCase {
assertScrimTint(mScrimBehind, false /* tinted */);
}
- @FlakyTest(bugId = 124858892)
@Test
public void transitionToUnlocked() {
mScrimController.setPanelExpansion(0f);
@@ -298,7 +297,6 @@ public class ScrimControllerTest extends SysuiTestCase {
Assert.assertEquals(mScrimState, ScrimState.BOUNCER_SCRIMMED);
}
- @FlakyTest(bugId = 124858892)
@Test
public void panelExpansion() {
mScrimController.setPanelExpansion(0f);
@@ -321,7 +319,6 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f);
}
- @FlakyTest(bugId = 124858892)
@Test
public void panelExpansionAffectsAlpha() {
mScrimController.setPanelExpansion(0f);
@@ -666,7 +663,6 @@ public class ScrimControllerTest extends SysuiTestCase {
*/
private class SynchronousScrimController extends ScrimController {
- private FakeHandler mHandler;
private boolean mAnimationCancelled;
boolean mOnPreDrawCalled;
@@ -676,7 +672,6 @@ public class ScrimControllerTest extends SysuiTestCase {
AlarmManager alarmManager) {
super(scrimBehind, scrimInFront, scrimStateListener, scrimVisibleListener,
dozeParameters, alarmManager);
- mHandler = new FakeHandler(Looper.myLooper());
}
@Override
@@ -688,13 +683,10 @@ public class ScrimControllerTest extends SysuiTestCase {
void finishAnimationsImmediately() {
boolean[] animationFinished = {false};
setOnAnimationFinished(()-> animationFinished[0] = true);
-
// Execute code that will trigger animations.
onPreDraw();
-
- // Force finish screen blanking.
- mHandler.dispatchQueuedMessages();
// Force finish all animations.
+ mLooper.processAllMessages();
endAnimation(mScrimBehind, TAG_KEY_ANIM);
endAnimation(mScrimInFront, TAG_KEY_ANIM);
@@ -724,7 +716,7 @@ public class ScrimControllerTest extends SysuiTestCase {
@Override
protected Handler getHandler() {
- return mHandler;
+ return new FakeHandler(mLooper.getLooper());
}
@Override
diff --git a/proto/src/metrics_constants/metrics_constants.proto b/proto/src/metrics_constants/metrics_constants.proto
index 0a6e92371d6a..91b161d3192f 100644
--- a/proto/src/metrics_constants/metrics_constants.proto
+++ b/proto/src/metrics_constants/metrics_constants.proto
@@ -7078,6 +7078,15 @@ message MetricsEvent {
// Open: Settings will show the conditional when Grayscale mode is on
SETTINGS_CONDITION_GRAYSCALE_MODE = 1683;
+ // ACTION: Individual contextual card loading time
+ ACTION_CONTEXTUAL_CARD_LOAD = 1684;
+
+ //ACTION: Contextual card loading timeout
+ ACTION_CONTEXTUAL_CARD_LOAD_TIMEOUT = 1685;
+
+ //ACTION: Log result for each card's eligibility check
+ ACTION_CONTEXTUAL_CARD_ELIGIBILITY = 1686;
+
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 3f33813ff4e7..62deaffd9ea4 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -72,6 +72,7 @@ import android.view.autofill.IAutoFillManagerClient;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.infra.WhitelistHelper;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.server.LocalServices;
@@ -173,10 +174,10 @@ final class AutofillManagerServiceImpl
private ServiceInfo mRemoteAugmentedAutofillServiceInfo;
/**
- * List of packages that are whitelisted to be trigger augmented autofill.
+ * List of packages/activities that are whitelisted to be trigger augmented autofill.
*/
@GuardedBy("mLock")
- private final ArraySet<String> mWhitelistedAugmentAutofillPackages = new ArraySet<>();
+ private final WhitelistHelper mAugmentedWhitelistHelper = new WhitelistHelper();
AutofillManagerServiceImpl(AutofillManagerService master, Object lock,
LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui,
@@ -905,13 +906,8 @@ final class AutofillManagerServiceImpl
pw.println(mRemoteAugmentedAutofillServiceInfo);
}
- final int whitelistSize = mWhitelistedAugmentAutofillPackages.size();
- pw.print(prefix); pw.print("Packages whitelisted for augmented autofill: ");
- pw.println(whitelistSize);
- for (int i = 0; i < whitelistSize; i++) {
- final String whitelistedPkg = mWhitelistedAugmentAutofillPackages.valueAt(i);
- pw.print(prefix2); pw.print(i + 1); pw.print(": "); pw.println(whitelistedPkg);
- }
+ pw.print(prefix); pw.print("augmented autofill whitelist: ");
+ mAugmentedWhitelistHelper.dump(prefix2, "Whitelist", pw);
pw.print(prefix); pw.print("Field classification enabled: ");
pw.println(isFieldClassificationEnabledLocked());
@@ -1129,9 +1125,8 @@ final class AutofillManagerServiceImpl
Slog.v(TAG, "setAugmentedAutofillWhitelistLocked(packages=" + packages + ", activities="
+ activities + ")");
}
- whitelistForAugmentedAutofillPackages(packages);
+ whitelistForAugmentedAutofillPackages(packages, activities);
- // TODO(b/123100824): whitelist activities as well
// TODO(b/122858578): log metrics
return true;
}
@@ -1171,28 +1166,30 @@ final class AutofillManagerServiceImpl
@GuardedBy("mLock")
boolean isWhitelistedForAugmentedAutofillLocked(@NonNull ComponentName componentName) {
- // TODO(b/122595322): need to check whitelisted activities as well.
- final String packageName = componentName.getPackageName();
- return mWhitelistedAugmentAutofillPackages.contains(packageName);
+ return mAugmentedWhitelistHelper.isWhitelisted(componentName);
}
@GuardedBy("mLock")
void setAugmentedAutofillWhitelistLocked(@NonNull AutofillOptions options,
@NonNull String packageName) {
- // TODO(b/122595322): need to setwhitelisted activities as well.
- options.augmentedEnabled = mWhitelistedAugmentAutofillPackages.contains(packageName);
+ options.augmentedAutofillEnabled = mAugmentedWhitelistHelper.isWhitelisted(packageName);
+ options.whitelistedActivitiesForAugmentedAutofill = mAugmentedWhitelistHelper
+ .getWhitelistedComponents(packageName);
}
- private void whitelistForAugmentedAutofillPackages(@NonNull List<String> packages) {
+ /**
+ *
+ * @throws IllegalArgumentException if packages or components are empty.
+ */
+ private void whitelistForAugmentedAutofillPackages(@Nullable List<String> packages,
+ @Nullable List<ComponentName> components) {
// TODO(b/123100824): add CTS test for when it's null
synchronized (mLock) {
- if (packages == null) {
- if (mMaster.verbose) Slog.v(TAG, "clearing all whitelisted augmented packages");
- mWhitelistedAugmentAutofillPackages.clear();
- } else {
- if (mMaster.verbose) Slog.v(TAG, "whitelisting augmented packages: " + packages);
- mWhitelistedAugmentAutofillPackages.addAll(packages);
+ if (mMaster.verbose) {
+ Slog.v(TAG, "whitelisting packages: " + packages + "and activities: " + components);
}
+ mAugmentedWhitelistHelper.setWhitelist(new ArraySet<>(packages),
+ new ArraySet<>(components));
mRemoteAugmentedAutofillService = getRemoteAugmentedAutofillServiceLocked();
}
}
diff --git a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
index b33259d369a0..955d764797c8 100644
--- a/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
+++ b/services/contentcapture/java/com/android/server/contentcapture/ContentCapturePerUserService.java
@@ -20,8 +20,8 @@ import static android.service.contentcapture.ContentCaptureService.setClientStat
import static android.view.contentcapture.ContentCaptureSession.STATE_DISABLED;
import static android.view.contentcapture.ContentCaptureSession.STATE_DUPLICATED_ID;
import static android.view.contentcapture.ContentCaptureSession.STATE_INTERNAL_ERROR;
+import static android.view.contentcapture.ContentCaptureSession.STATE_NOT_WHITELISTED;
import static android.view.contentcapture.ContentCaptureSession.STATE_NO_SERVICE;
-import static android.view.contentcapture.ContentCaptureSession.STATE_PACKAGE_NOT_WHITELISTED;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
@@ -29,6 +29,7 @@ import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUC
import android.Manifest;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
@@ -55,6 +56,7 @@ import android.util.Slog;
import android.view.contentcapture.UserDataRemovalRequest;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.infra.WhitelistHelper;
import com.android.internal.os.IResultReceiver;
import com.android.server.LocalServices;
import com.android.server.contentcapture.RemoteContentCaptureService.ContentCaptureServiceCallbacks;
@@ -94,7 +96,7 @@ final class ContentCapturePerUserService
* List of packages that are whitelisted to be content captured.
*/
@GuardedBy("mLock")
- private final ArraySet<String> mWhitelistedPackages = new ArraySet<>();
+ private final WhitelistHelper mWhitelistHelper = new WhitelistHelper();
// TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's
@@ -194,7 +196,7 @@ final class ContentCapturePerUserService
final int taskId = activityPresentationInfo.taskId;
final int displayId = activityPresentationInfo.displayId;
final ComponentName componentName = activityPresentationInfo.componentName;
- final boolean whitelisted = isWhitelistedLocked(componentName);
+ final boolean whiteListed = isWhitelistedLocked(componentName);
final ComponentName serviceComponentName = getServiceComponentName();
final boolean enabled = isEnabledLocked();
if (mMaster.mRequestsHistory != null) {
@@ -204,7 +206,7 @@ final class ContentCapturePerUserService
+ " t=" + taskId + " d=" + displayId
+ " s=" + ComponentName.flattenToShortString(serviceComponentName)
+ " u=" + mUserId + " f=" + flags + (enabled ? "" : " (disabled)")
- + " w=" + whitelisted;
+ + " w=" + whiteListed;
mMaster.mRequestsHistory.log(historyItem);
}
@@ -225,12 +227,12 @@ final class ContentCapturePerUserService
return;
}
- if (!whitelisted) {
+ if (!whiteListed) {
if (mMaster.debug) {
- Slog.d(TAG, "startSession(" + componentName + "): not whitelisted");
+ Slog.d(TAG, "startSession(" + componentName + "): package or component "
+ + "not whitelisted");
}
- // TODO(b/122595322): need to return STATE_ACTIVITY_NOT_WHITELISTED as well
- setClientState(clientReceiver, STATE_DISABLED | STATE_PACKAGE_NOT_WHITELISTED,
+ setClientState(clientReceiver, STATE_DISABLED | STATE_NOT_WHITELISTED,
/* binder= */ null);
return;
}
@@ -270,21 +272,20 @@ final class ContentCapturePerUserService
@GuardedBy("mLock")
private boolean isWhitelistedLocked(@NonNull ComponentName componentName) {
- // TODO(b/122595322): need to check whitelisted activities as well.
- final String packageName = componentName.getPackageName();
- return mWhitelistedPackages.contains(packageName);
+ return mWhitelistHelper.isWhitelisted(componentName);
}
- private void whitelistPackages(@NonNull List<String> packages) {
+ /**
+ * @throws IllegalArgumentException if packages or components are empty.
+ */
+ private void setWhitelist(@Nullable List<String> packages,
+ @Nullable List<ComponentName> components) {
// TODO(b/122595322): add CTS test for when it's null
synchronized (mLock) {
- if (packages == null) {
- if (mMaster.verbose) Slog.v(TAG, "clearing all whitelisted packages");
- mWhitelistedPackages.clear();
- } else {
- if (mMaster.verbose) Slog.v(TAG, "whitelisting packages: " + packages);
- mWhitelistedPackages.addAll(packages);
+ if (mMaster.verbose) {
+ Slog.v(TAG, "whitelisting packages: " + packages + "and activities: " + components);
}
+ mWhitelistHelper.setWhitelist(new ArraySet<>(packages), new ArraySet<>(components));
}
}
@@ -411,15 +412,15 @@ final class ContentCapturePerUserService
@GuardedBy("mLock")
ContentCaptureOptions getOptionsForPackageLocked(@NonNull String packageName) {
- if (!mWhitelistedPackages.contains(packageName)) {
+ if (!mWhitelistHelper.isWhitelisted(packageName)) {
if (mMaster.verbose) {
Slog.v(mTag, "getOptionsForPackage(" + packageName + "): not whitelisted");
}
return null;
}
- // TODO(b/122595322): need to check whitelisted activities as well.
- final ArraySet<ComponentName> whitelistedComponents = null;
+ final ArraySet<ComponentName> whitelistedComponents = mWhitelistHelper
+ .getWhitelistedComponents(packageName);
ContentCaptureOptions options = new ContentCaptureOptions(mMaster.mDevCfgLoggingLevel,
mMaster.mDevCfgMaxBufferSize, mMaster.mDevCfgIdleFlushingFrequencyMs,
mMaster.mDevCfgTextChangeFlushingFrequencyMs, mMaster.mDevCfgLogHistorySize,
@@ -440,12 +441,7 @@ final class ContentCapturePerUserService
mRemoteService.dump(prefix2, pw);
}
- final int whitelistSize = mWhitelistedPackages.size();
- pw.print(prefix); pw.print("Whitelisted packages: "); pw.println(whitelistSize);
- for (int i = 0; i < whitelistSize; i++) {
- final String whitelistedPkg = mWhitelistedPackages.valueAt(i);
- pw.print(prefix2); pw.print(i + 1); pw.print(": "); pw.println(whitelistedPkg);
- }
+ pw.print(prefix); pw.print("Whitelist: "); pw.println(mWhitelistHelper);
if (mSessions.isEmpty()) {
pw.print(prefix); pw.println("no sessions");
@@ -485,9 +481,8 @@ final class ContentCapturePerUserService
Slog.v(TAG, "setContentCaptureWhitelist(packages=" + packages + ", activities="
+ activities + ")");
}
- whitelistPackages(packages);
+ setWhitelist(packages, activities);
- // TODO(b/122595322): whitelist activities as well
// TODO(b/119613670): log metrics
}
diff --git a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
index a18686da653e..9b70272ed952 100644
--- a/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
+++ b/services/contentsuggestions/java/com/android/server/contentsuggestions/ContentSuggestionsPerUserService.java
@@ -16,6 +16,7 @@
package com.android.server.contentsuggestions;
+import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
@@ -73,6 +74,13 @@ public final class ContentSuggestionsPerUserService extends
throw new PackageManager.NameNotFoundException(
"Could not get service for " + serviceComponent);
}
+ if (!Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE.equals(si.permission)) {
+ Slog.w(TAG, "ContentSuggestionsService from '" + si.packageName
+ + "' does not require permission "
+ + Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE);
+ throw new SecurityException("Service does not require permission "
+ + Manifest.permission.BIND_CONTENT_SUGGESTIONS_SERVICE);
+ }
return si;
}
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 18e990676fbc..bbd51ad2743e 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -1176,7 +1176,7 @@ public class LocationManagerService extends ILocationManager.Stub {
@GuardedBy("mLock")
public boolean isUseableForUserLocked(int userId) {
- return userId == mCurrentUserId && mUseable;
+ return isCurrentProfileLocked(userId) && mUseable;
}
@GuardedBy("mLock")
diff --git a/services/core/java/com/android/server/PackageWatchdog.java b/services/core/java/com/android/server/PackageWatchdog.java
index ec40971c38ee..660109cf6114 100644
--- a/services/core/java/com/android/server/PackageWatchdog.java
+++ b/services/core/java/com/android/server/PackageWatchdog.java
@@ -21,6 +21,7 @@ import static java.lang.annotation.RetentionPolicy.SOURCE;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.os.Environment;
import android.os.Handler;
@@ -76,6 +77,7 @@ public class PackageWatchdog {
private static final String ATTR_VERSION = "version";
private static final String ATTR_NAME = "name";
private static final String ATTR_DURATION = "duration";
+ private static final String ATTR_PASSED_HEALTH_CHECK = "passed-health-check";
private static PackageWatchdog sPackageWatchdog;
@@ -102,7 +104,7 @@ public class PackageWatchdog {
// 0 if mPackageCleanup not running.
private long mDurationAtLastReschedule;
- // TODO(zezeozue): Remove redundant context param
+ // TODO(b/120598832): Remove redundant context param
private PackageWatchdog(Context context) {
mContext = context;
mPolicyFile = new AtomicFile(new File(new File(Environment.getDataDirectory(), "system"),
@@ -161,21 +163,29 @@ public class PackageWatchdog {
* Starts observing the health of the {@code packages} for {@code observer} and notifies
* {@code observer} of any package failures within the monitoring duration.
*
+ * <p>If monitoring a package with {@code withExplicitHealthCheck}, at the end of the monitoring
+ * duration if {@link #onExplicitHealthCheckPassed} was never called,
+ * {@link PackageHealthObserver#execute} will be called as if the package failed.
+ *
* <p>If {@code observer} is already monitoring a package in {@code packageNames},
- * the monitoring window of that package will be reset to {@code durationMs}.
+ * the monitoring window of that package will be reset to {@code durationMs} and the health
+ * check state will be reset to a default depending on {@code withExplictHealthCheck}.
*
* @throws IllegalArgumentException if {@code packageNames} is empty
* or {@code durationMs} is less than 1
*/
public void startObservingHealth(PackageHealthObserver observer, List<String> packageNames,
- long durationMs) {
+ long durationMs, boolean withExplicitHealthCheck) {
if (packageNames.isEmpty() || durationMs < 1) {
throw new IllegalArgumentException("Observation not started, no packages specified"
+ "or invalid duration");
}
List<MonitoredPackage> packages = new ArrayList<>();
for (int i = 0; i < packageNames.size(); i++) {
- packages.add(new MonitoredPackage(packageNames.get(i), durationMs));
+ // When observing packages withExplicitHealthCheck,
+ // MonitoredPackage#mHasExplicitHealthCheckPassed will be false initially.
+ packages.add(new MonitoredPackage(packageNames.get(i), durationMs,
+ !withExplicitHealthCheck));
}
synchronized (mLock) {
ObserverInternal oldObserver = mAllObservers.get(observer.getName());
@@ -276,7 +286,38 @@ public class PackageWatchdog {
});
}
- // TODO(zezeozue): Optimize write? Maybe only write a separate smaller file?
+ /**
+ * Updates the observers monitoring {@code packageName} that explicit health check has passed.
+ *
+ * <p> This update is strictly for registered observers at the time of the call
+ * Observers that register after this signal will have no knowledge of prior signals and will
+ * effectively behave as if the explicit health check hasn't passed for {@code packageName}.
+ *
+ * <p> {@code packageName} can still be considered failed if reported by
+ * {@link #onPackageFailure} before the package expires.
+ *
+ * <p> Triggered by components outside the system server when they are fully functional after an
+ * update.
+ */
+ public void onExplicitHealthCheckPassed(String packageName) {
+ Slog.i(TAG, "Health check passed for package: " + packageName);
+ boolean shouldUpdateFile = false;
+ synchronized (mLock) {
+ for (int observerIdx = 0; observerIdx < mAllObservers.size(); observerIdx++) {
+ ObserverInternal observer = mAllObservers.valueAt(observerIdx);
+ MonitoredPackage monitoredPackage = observer.mPackages.get(packageName);
+ if (monitoredPackage != null && !monitoredPackage.mHasPassedHealthCheck) {
+ monitoredPackage.mHasPassedHealthCheck = true;
+ shouldUpdateFile = true;
+ }
+ }
+ }
+ if (shouldUpdateFile) {
+ saveToFileAsync();
+ }
+ }
+
+ // TODO(b/120598832): Optimize write? Maybe only write a separate smaller file?
// This currently adds about 7ms extra to shutdown thread
/** Writes the package information to file during shutdown. */
public void writeNow() {
@@ -322,7 +363,7 @@ public class PackageWatchdog {
*/
boolean execute(VersionedPackage versionedPackage);
- // TODO(zezeozue): Ensure uniqueness?
+ // TODO(b/120598832): Ensure uniqueness?
/**
* Identifier for the observer, should not change across device updates otherwise the
* watchdog may drop observing packages with the old name.
@@ -393,7 +434,12 @@ public class PackageWatchdog {
Iterator<ObserverInternal> it = mAllObservers.values().iterator();
while (it.hasNext()) {
ObserverInternal observer = it.next();
- if (!observer.updateMonitoringDurations(elapsedMs)) {
+ List<MonitoredPackage> failedPackages =
+ observer.updateMonitoringDurations(elapsedMs);
+ if (!failedPackages.isEmpty()) {
+ onExplicitHealthCheckFailed(observer, failedPackages);
+ }
+ if (observer.mPackages.isEmpty()) {
Slog.i(TAG, "Discarding observer " + observer.mName + ". All packages expired");
it.remove();
}
@@ -402,6 +448,32 @@ public class PackageWatchdog {
saveToFileAsync();
}
+ private void onExplicitHealthCheckFailed(ObserverInternal observer,
+ List<MonitoredPackage> failedPackages) {
+ mWorkerHandler.post(() -> {
+ synchronized (mLock) {
+ PackageHealthObserver registeredObserver = observer.mRegisteredObserver;
+ if (registeredObserver != null) {
+ PackageManager pm = mContext.getPackageManager();
+ for (int i = 0; i < failedPackages.size(); i++) {
+ String packageName = failedPackages.get(i).mName;
+ long versionCode = 0;
+ try {
+ versionCode = pm.getPackageInfo(
+ packageName, 0 /* flags */).getLongVersionCode();
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Explicit health check failed but could not find package "
+ + packageName);
+ // TODO(b/120598832): Skip. We only continue to pass tests for now since
+ // the tests don't install any packages
+ }
+ registeredObserver.execute(new VersionedPackage(packageName, versionCode));
+ }
+ }
+ }
+ });
+ }
+
/**
* Loads mAllObservers from file.
*
@@ -480,6 +552,7 @@ public class PackageWatchdog {
*/
static class ObserverInternal {
public final String mName;
+ //TODO(b/120598832): Add getter for mPackages
public final ArrayMap<String, MonitoredPackage> mPackages;
@Nullable
public PackageHealthObserver mRegisteredObserver;
@@ -505,6 +578,8 @@ public class PackageWatchdog {
out.startTag(null, TAG_PACKAGE);
out.attribute(null, ATTR_NAME, p.mName);
out.attribute(null, ATTR_DURATION, String.valueOf(p.mDurationMs));
+ out.attribute(null, ATTR_PASSED_HEALTH_CHECK,
+ String.valueOf(p.mHasPassedHealthCheck));
out.endTag(null, TAG_PACKAGE);
}
out.endTag(null, TAG_OBSERVER);
@@ -529,10 +604,12 @@ public class PackageWatchdog {
* {@code elapsedMs}. If any duration is less than 0, the package is removed from
* observation.
*
- * @returns {@code true} if there are still packages to be observed, {@code false} otherwise
+ * @returns a {@link List} of packages that were removed from the observer without explicit
+ * health check passing, or an empty list if no package expired for which an explicit health
+ * check was still pending
*/
- public boolean updateMonitoringDurations(long elapsedMs) {
- List<MonitoredPackage> packages = new ArrayList<>();
+ public List<MonitoredPackage> updateMonitoringDurations(long elapsedMs) {
+ List<MonitoredPackage> removedPackages = new ArrayList<>();
synchronized (mName) {
Iterator<MonitoredPackage> it = mPackages.values().iterator();
while (it.hasNext()) {
@@ -541,10 +618,13 @@ public class PackageWatchdog {
if (newDuration > 0) {
p.mDurationMs = newDuration;
} else {
+ if (!p.mHasPassedHealthCheck) {
+ removedPackages.add(p);
+ }
it.remove();
}
}
- return !mPackages.isEmpty();
+ return removedPackages;
}
}
@@ -574,6 +654,7 @@ public class PackageWatchdog {
if (TAG_OBSERVER.equals(parser.getName())) {
observerName = parser.getAttributeValue(null, ATTR_NAME);
if (TextUtils.isEmpty(observerName)) {
+ Slog.wtf(TAG, "Unable to read observer name");
return null;
}
}
@@ -582,17 +663,24 @@ public class PackageWatchdog {
try {
while (XmlUtils.nextElementWithin(parser, innerDepth)) {
if (TAG_PACKAGE.equals(parser.getName())) {
- String packageName = parser.getAttributeValue(null, ATTR_NAME);
- long duration = Long.parseLong(
- parser.getAttributeValue(null, ATTR_DURATION));
- if (!TextUtils.isEmpty(packageName)) {
- packages.add(new MonitoredPackage(packageName, duration));
+ try {
+ String packageName = parser.getAttributeValue(null, ATTR_NAME);
+ long duration = Long.parseLong(
+ parser.getAttributeValue(null, ATTR_DURATION));
+ boolean hasPassedHealthCheck = Boolean.parseBoolean(
+ parser.getAttributeValue(null, ATTR_PASSED_HEALTH_CHECK));
+ if (!TextUtils.isEmpty(packageName)) {
+ packages.add(new MonitoredPackage(packageName, duration,
+ hasPassedHealthCheck));
+ }
+ } catch (NumberFormatException e) {
+ Slog.wtf(TAG, "Skipping package for observer " + observerName, e);
+ continue;
}
}
}
- } catch (IOException e) {
- return null;
- } catch (XmlPullParserException e) {
+ } catch (XmlPullParserException | IOException e) {
+ Slog.wtf(TAG, "Unable to read observer " + observerName, e);
return null;
}
if (packages.isEmpty()) {
@@ -605,6 +693,8 @@ public class PackageWatchdog {
/** Represents a package along with the time it should be monitored for. */
static class MonitoredPackage {
public final String mName;
+ // Whether an explicit health check has passed
+ public boolean mHasPassedHealthCheck;
// System uptime duration to monitor package
public long mDurationMs;
// System uptime of first package failure
@@ -612,9 +702,10 @@ public class PackageWatchdog {
// Number of failures since mUptimeStartMs
private int mFailures;
- MonitoredPackage(String name, long durationMs) {
+ MonitoredPackage(String name, long durationMs, boolean hasPassedHealthCheck) {
mName = name;
mDurationMs = durationMs;
+ mHasPassedHealthCheck = hasPassedHealthCheck;
}
/**
@@ -626,7 +717,7 @@ public class PackageWatchdog {
final long now = SystemClock.uptimeMillis();
final long duration = now - mUptimeStartMs;
if (duration > TRIGGER_DURATION_MS) {
- // TODO(zezeozue): Reseting to 1 is not correct
+ // TODO(b/120598832): Reseting to 1 is not correct
// because there may be more than 1 failure in the last trigger window from now
// This is the RescueParty impl, will leave for now
mFailures = 1;
diff --git a/services/core/java/com/android/server/RescueParty.java b/services/core/java/com/android/server/RescueParty.java
index 18c272202990..1fe0271ac1ec 100644
--- a/services/core/java/com/android/server/RescueParty.java
+++ b/services/core/java/com/android/server/RescueParty.java
@@ -38,9 +38,11 @@ import android.util.StatsLog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
+import com.android.server.am.SettingsToPropertiesMapper;
import com.android.server.utils.FlagNamespaceUtils;
import java.io.File;
+import java.util.Arrays;
/**
* Utilities to help rescue the system from crash loops. Callers are expected to
@@ -129,10 +131,10 @@ public class RescueParty {
}
/**
- * Take note of a persistent app crash. If we notice too many of these
+ * Take note of a persistent app or apex module crash. If we notice too many of these
* events happening in rapid succession, we'll send out a rescue party.
*/
- public static void notePersistentAppCrash(Context context, int uid) {
+ public static void noteAppCrash(Context context, int uid) {
if (isDisabled()) return;
Threshold t = sApps.get(uid);
if (t == null) {
@@ -158,6 +160,7 @@ public class RescueParty {
* opportunity to reset any settings depending on our rescue level.
*/
public static void onSettingsProviderPublished(Context context) {
+ handleNativeRescuePartyResets();
executeRescueLevel(context);
}
@@ -176,6 +179,13 @@ public class RescueParty {
return SystemClock.elapsedRealtime();
}
+ private static void handleNativeRescuePartyResets() {
+ if (SettingsToPropertiesMapper.isNativeFlagsResetPerformed()) {
+ FlagNamespaceUtils.resetDeviceConfig(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ Arrays.asList(SettingsToPropertiesMapper.getResetNativeCategories()));
+ }
+ }
+
/**
* Escalate to the next rescue level. After incrementing the level you'll
* probably want to call {@link #executeRescueLevel(Context)}.
@@ -235,14 +245,14 @@ public class RescueParty {
Exception res = null;
final ContentResolver resolver = context.getContentResolver();
try {
- Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM);
+ FlagNamespaceUtils.resetDeviceConfig(mode);
} catch (Exception e) {
- res = new RuntimeException("Failed to reset global settings", e);
+ res = new RuntimeException("Failed to reset config settings", e);
}
try {
- FlagNamespaceUtils.resetDeviceConfig(mode);
+ Settings.Global.resetToDefaultsAsUser(resolver, null, mode, UserHandle.USER_SYSTEM);
} catch (Exception e) {
- res = new RuntimeException("Failed to reset config settings", e);
+ res = new RuntimeException("Failed to reset global settings", e);
}
for (int userId : getAllUserIds()) {
try {
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 0955cc56fe14..1a705828554d 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -259,7 +259,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
| PhoneStateListener.LISTEN_MESSAGE_WAITING_INDICATOR
| PhoneStateListener.LISTEN_EMERGENCY_NUMBER_LIST
- | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE;
+ | PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
static final int PRECISE_PHONE_STATE_PERMISSION_MASK =
PhoneStateListener.LISTEN_PRECISE_CALL_STATE |
@@ -819,7 +819,8 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
remove(r.binder);
}
}
- if ((events & PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE) != 0) {
+ if ((events & PhoneStateListener
+ .LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE) != 0) {
try {
r.callback.onActiveDataSubIdChanged(mActiveDataSubId);
} catch (RemoteException ex) {
@@ -1748,7 +1749,7 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
for (Record r : mRecords) {
if (r.matchPhoneStateListenerEvent(
- PhoneStateListener.LISTEN_ACTIVE_DATA_SUBID_CHANGE)) {
+ PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE)) {
try {
r.callback.onActiveDataSubIdChanged(activeDataSubId);
} catch (RemoteException ex) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 415a8927295d..f9fcef68381e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -27,6 +27,8 @@ import android.provider.DeviceConfig;
import android.provider.DeviceConfig.OnPropertyChangedListener;
import android.provider.Settings;
import android.text.TextUtils;
+import android.text.TextUtils.SimpleStringSplitter;
+import android.util.ArraySet;
import android.util.KeyValueListParser;
import android.util.Slog;
@@ -235,6 +237,8 @@ final class ActivityManagerConstants extends ContentObserver {
// Controlled by Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED
volatile boolean mFlagBackgroundActivityStartsEnabled;
+ volatile ArraySet<String> mPackageNamesWhitelistedForBgActivityStarts = new ArraySet<>();
+
private final ActivityManagerService mService;
private ContentResolver mResolver;
private final KeyValueListParser mParser = new KeyValueListParser(',');
@@ -273,6 +277,10 @@ final class ActivityManagerConstants extends ContentObserver {
Settings.Global.getUriFor(
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED);
+ private static final Uri BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI =
+ Settings.Global.getUriFor(
+ Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
+
private final OnPropertyChangedListener mOnDeviceConfigChangedListener =
new OnPropertyChangedListener() {
@Override
@@ -293,9 +301,12 @@ final class ActivityManagerConstants extends ContentObserver {
mResolver.registerContentObserver(ACTIVITY_MANAGER_CONSTANTS_URI, false, this);
mResolver.registerContentObserver(ACTIVITY_STARTS_LOGGING_ENABLED_URI, false, this);
mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_ENABLED_URI, false, this);
+ mResolver.registerContentObserver(BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI,
+ false, this);
updateConstants();
updateActivityStartsLoggingEnabled();
updateBackgroundActivityStartsEnabled();
+ updateBackgroundActivityStartsPackageNamesWhitelist();
DeviceConfig.addOnPropertyChangedListener(DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
ActivityThread.currentApplication().getMainExecutor(),
mOnDeviceConfigChangedListener);
@@ -325,6 +336,8 @@ final class ActivityManagerConstants extends ContentObserver {
updateActivityStartsLoggingEnabled();
} else if (BACKGROUND_ACTIVITY_STARTS_ENABLED_URI.equals(uri)) {
updateBackgroundActivityStartsEnabled();
+ } else if (BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST_URI.equals(uri)) {
+ updateBackgroundActivityStartsPackageNamesWhitelist();
}
}
@@ -414,6 +427,21 @@ final class ActivityManagerConstants extends ContentObserver {
Settings.Global.BACKGROUND_ACTIVITY_STARTS_ENABLED, 1) == 1;
}
+ private void updateBackgroundActivityStartsPackageNamesWhitelist() {
+ final String setting = Settings.Global.getString(mResolver,
+ Settings.Global.BACKGROUND_ACTIVITY_STARTS_PACKAGE_NAMES_WHITELIST);
+ if (TextUtils.isEmpty(setting)) {
+ return;
+ }
+ ArraySet<String> newSet = new ArraySet<>();
+ SimpleStringSplitter splitter = new SimpleStringSplitter(':');
+ splitter.setString(setting);
+ while (splitter.hasNext()) {
+ newSet.add(splitter.next());
+ }
+ mPackageNamesWhitelistedForBgActivityStarts = newSet;
+ }
+
private void updateMaxCachedProcesses() {
String maxCachedProcessesFlag = DeviceConfig.getProperty(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER, KEY_MAX_CACHED_PROCESSES);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ccb9d82571f7..73884a000f44 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -17623,6 +17623,16 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
+ public void killProcess(String processName, int uid, String reason) {
+ synchronized (ActivityManagerService.this) {
+ final ProcessRecord proc = getProcessRecordLocked(processName, uid,
+ true /* keepIfLarge */);
+ mProcessList.removeProcessLocked(proc, false /* callerWillRestart */,
+ true /* allowRestart */, reason);
+ }
+ }
+
+ @Override
public boolean hasRunningActivity(int uid, @Nullable String packageName) {
if (packageName == null) return false;
@@ -17862,6 +17872,10 @@ public class ActivityManagerService extends IActivityManager.Stub
return mConstants.mFlagActivityStartsLoggingEnabled;
}
+ public boolean isPackageNameWhitelistedForBgActivityStarts(String packageName) {
+ return mConstants.mPackageNamesWhitelistedForBgActivityStarts.contains(packageName);
+ }
+
public boolean isBackgroundActivityStartsEnabled() {
return mConstants.mFlagBackgroundActivityStartsEnabled;
}
@@ -18475,7 +18489,12 @@ public class ActivityManagerService extends IActivityManager.Stub
public int checkPermission(String permName, String pkgName, int userId,
TriFunction<String, String, Integer, Integer> superImpl) {
if (mTargetPackageName.equals(pkgName) && isTargetPermission(permName)) {
- return superImpl.apply(permName, "com.android.shell", userId);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return superImpl.apply(permName, "com.android.shell", userId);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
return superImpl.apply(permName, pkgName, userId);
}
@@ -18484,7 +18503,12 @@ public class ActivityManagerService extends IActivityManager.Stub
public int checkUidPermission(String permName, int uid,
BiFunction<String, Integer, Integer> superImpl) {
if (uid == mTargetUid && isTargetPermission(permName)) {
- return superImpl.apply(permName, Process.SHELL_UID);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return superImpl.apply(permName, Process.SHELL_UID);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
}
return superImpl.apply(permName, uid);
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index f153ab9cfa9e..1ff6f4dac724 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -34,6 +34,8 @@ import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ModuleInfo;
+import android.content.pm.PackageManager;
import android.content.pm.VersionedPackage;
import android.net.Uri;
import android.os.Binder;
@@ -406,15 +408,29 @@ class AppErrors {
}
if (r != null) {
- if (r.isPersistent()) {
- // If a persistent app is stuck in a crash loop, the device isn't very
- // usable, so we want to consider sending out a rescue party.
- RescueParty.notePersistentAppCrash(mContext, r.uid);
- } else {
- // If a non-persistent app is stuck in crash loop, we want to inform
- // the package watchdog, maybe an update or experiment can be rolled back.
- mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode());
+ boolean isApexModule = false;
+ try {
+ for (String androidPackage : r.getPackageList()) {
+ ModuleInfo moduleInfo = mContext.getPackageManager().getModuleInfo(
+ androidPackage, /*flags=*/ 0);
+ if (moduleInfo != null) {
+ isApexModule = true;
+ break;
+ }
+ }
+ } catch (IllegalStateException | PackageManager.NameNotFoundException e) {
+ // Call to PackageManager#getModuleInfo() can result in NameNotFoundException or
+ // IllegalStateException. In case they are thrown, there isn't much we can do
+ // other than proceed with app crash handling.
}
+
+ if (r.isPersistent() || isApexModule) {
+ // If a persistent app or apex module is stuck in a crash loop, the device isn't
+ // very usable, so we want to consider sending out a rescue party.
+ RescueParty.noteAppCrash(mContext, r.uid);
+ }
+
+ mPackageWatchdog.onPackageFailure(r.getPackageListWithVersionCode());
}
final int relaunchReason = r != null
diff --git a/services/core/java/com/android/server/am/BroadcastDispatcher.java b/services/core/java/com/android/server/am/BroadcastDispatcher.java
index 0b38ef94de1e..b0b1840214f1 100644
--- a/services/core/java/com/android/server/am/BroadcastDispatcher.java
+++ b/services/core/java/com/android/server/am/BroadcastDispatcher.java
@@ -617,11 +617,9 @@ public class BroadcastDispatcher {
* Cancel all current deferrals; that is, make all currently-deferred broadcasts
* immediately deliverable. Used by the wait-for-broadcast-idle mechanism.
*/
- public void cancelDeferrals() {
- synchronized (mLock) {
- zeroDeferralTimes(mAlarmBroadcasts);
- zeroDeferralTimes(mDeferredBroadcasts);
- }
+ public void cancelDeferralsLocked() {
+ zeroDeferralTimes(mAlarmBroadcasts);
+ zeroDeferralTimes(mDeferredBroadcasts);
}
private static void zeroDeferralTimes(ArrayList<Deferrals> list) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index c1ed54e647d7..70733efa68bd 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -1870,7 +1870,10 @@ public final class BroadcastQueue {
// Used by wait-for-broadcast-idle : fast-forward all current deferrals to
// be immediately deliverable.
void cancelDeferrals() {
- mDispatcher.cancelDeferrals();
+ synchronized (mService) {
+ mDispatcher.cancelDeferralsLocked();
+ scheduleBroadcastsLocked();
+ }
}
String describeState() {
diff --git a/services/core/java/com/android/server/am/ProcessList.java b/services/core/java/com/android/server/am/ProcessList.java
index 399b818659a4..02d31b80db59 100644
--- a/services/core/java/com/android/server/am/ProcessList.java
+++ b/services/core/java/com/android/server/am/ProcessList.java
@@ -249,6 +249,10 @@ public final class ProcessList {
// Threshold of number of cached+empty where we consider memory critical.
static final int TRIM_LOW_THRESHOLD = 5;
+ // If true, then we pass the flag to ART to load the app image startup cache.
+ private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE =
+ "persist.device_config.runtime_native.use_app_image_startup_cache";
+
// Low Memory Killer Daemon command codes.
// These must be kept in sync with the definitions in lmkd.c
//
@@ -1559,6 +1563,13 @@ public final class ProcessList {
runtimeFlags |= policyBits;
}
+ String useAppImageCache = SystemProperties.get(
+ PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, "");
+ // Property defaults to true currently.
+ if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) {
+ runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE;
+ }
+
String invokeWith = null;
if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
// Debuggable apps may include a wrapper script with their library directory.
@@ -2852,6 +2863,15 @@ public final class ProcessList {
pos--;
}
mLruProcesses.add(pos, app);
+ if (pos == mLruProcessActivityStart) {
+ mLruProcessActivityStart++;
+ }
+ if (pos == mLruProcessServiceStart) {
+ // Unless {@code #hasService} is implemented, currently the starting position
+ // for activity and service are the same, so the incoming position may equal to
+ // the starting position of service.
+ mLruProcessServiceStart++;
+ }
// If this process is part of a group, need to pull up any other processes
// in that group to be with it.
int endIndex = pos - 1;
diff --git a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
index 5da1ce610079..194549f15ecf 100644
--- a/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
+++ b/services/core/java/com/android/server/am/SettingsToPropertiesMapper.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import android.annotation.NonNull;
import android.content.ContentResolver;
import android.database.ContentObserver;
import android.net.Uri;
@@ -167,7 +168,7 @@ public class SettingsToPropertiesMapper {
* booting.
* @return
*/
- public static String[] getResetNativeCategories() {
+ public static @NonNull String[] getResetNativeCategories() {
if (!isNativeFlagsResetPerformed()) {
return new String[0];
}
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 280bc026a76e..d723c7b5826d 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -146,7 +146,7 @@ final class HistoricalRegistry {
* Whether history is enabled.
*/
@GuardedBy("mInMemoryLock")
- private int mMode = AppOpsManager.HISTORICAL_MODE_DISABLED;
+ private int mMode = AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE;
/**
* This granularity has been chosen to allow clean delineation for intervals
diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING
index f2e2782e8eea..a53797dfa9e0 100644
--- a/services/core/java/com/android/server/appop/TEST_MAPPING
+++ b/services/core/java/com/android/server/appop/TEST_MAPPING
@@ -7,13 +7,7 @@
"name": "FrameworksServicesTests",
"options": [
{
- "include-filter": "com.android.server.appop.AppOpsUpgradeTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsServiceTest"
- },
- {
- "include-filter": "com.android.server.appop.AppOpsActiveWatcherTest"
+ "include-filter": "com.android.server.appop"
}
]
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 71ec5b00608e..9ab99753ed00 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -142,6 +142,7 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
// these need to match ElapsedRealtimeFlags enum in types.hal
private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
+ private static final int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
// IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
private static final int GPS_DELETE_EPHEMERIS = 0x0001;
@@ -768,15 +769,18 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
long timestamp = location.getTime();
- int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS;
+ int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS
+ | (location.hasElapsedRealtimeUncertaintyNanos()
+ ? ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
+ long elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
native_inject_best_location(
gnssLocationFlags, latitudeDegrees, longitudeDegrees,
altitudeMeters, speedMetersPerSec, bearingDegrees,
horizontalAccuracyMeters, verticalAccuracyMeters,
speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
- elapsedRealtimeFlags, elapsedRealtimeNanos);
+ elapsedRealtimeFlags, elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
}
/** Returns true if the location request is too frequent. */
@@ -2170,7 +2174,8 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
float horizontalAccuracyMeters, float verticalAccuracyMeters,
float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
- long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos);
+ long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
+ long elapsedRealtimeUncertaintyNanos);
private native void native_inject_location(double latitude, double longitude, float accuracy);
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index ee968c87e753..0bc46f190e0b 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -1973,8 +1973,7 @@ public class LockSettingsService extends ILockSettings.Stub {
} catch (RemoteException ex) {
Slog.w(TAG, "unable to clear GK secure user id");
}
- UserInfo userInfo = mUserManager.getUserInfo(userId);
- if (unknownUser || userInfo == null || userInfo.isManagedProfile()) {
+ if (unknownUser || mUserManager.getUserInfo(userId).isManagedProfile()) {
removeKeystoreProfileKey(userId);
}
}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java
index cd5e8cf65a2d..3e7b0a7e4c01 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/storage/RecoverableKeyStoreDbHelper.java
@@ -80,7 +80,7 @@ class RecoverableKeyStoreDbHelper extends SQLiteOpenHelper {
+ RootOfTrustEntry._ID + " INTEGER PRIMARY KEY,"
+ RootOfTrustEntry.COLUMN_NAME_USER_ID + " INTEGER,"
+ RootOfTrustEntry.COLUMN_NAME_UID + " INTEGER,"
- + RootOfTrustEntry.COLUMN_NAME_ROOT_ALIAS + " TEST,"
+ + RootOfTrustEntry.COLUMN_NAME_ROOT_ALIAS + " TEXT,"
+ RootOfTrustEntry.COLUMN_NAME_CERT_PATH + " BLOB,"
+ RootOfTrustEntry.COLUMN_NAME_CERT_SERIAL + " INTEGER,"
+ "UNIQUE("
diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java
index cf09b8fc4c84..8480830b7698 100644
--- a/services/core/java/com/android/server/notification/ManagedServices.java
+++ b/services/core/java/com/android/server/notification/ManagedServices.java
@@ -333,6 +333,7 @@ abstract public class ManagedServices {
out.attribute(null, ATT_APPROVED_LIST, allowedItems);
out.attribute(null, ATT_USER_ID, Integer.toString(approvedUserId));
out.attribute(null, ATT_IS_PRIMARY, Boolean.toString(isPrimary));
+ writeExtraAttributes(out, approvedUserId);
out.endTag(null, TAG_MANAGED_SERVICES);
if (!forBackup && isPrimary) {
@@ -345,10 +346,14 @@ abstract public class ManagedServices {
}
}
}
-
out.endTag(null, getConfig().xmlTag);
}
+ /**
+ * Writes extra xml attributes to {@link #TAG_MANAGED_SERVICES} tag.
+ */
+ protected void writeExtraAttributes(XmlSerializer out, int userId) throws IOException {}
+
protected void migrateToXml() {
loadAllowedComponentsFromSettings();
}
@@ -377,7 +382,7 @@ abstract public class ManagedServices {
? userId : XmlUtils.readIntAttribute(parser, ATT_USER_ID, 0);
final boolean isPrimary =
XmlUtils.readBooleanAttribute(parser, ATT_IS_PRIMARY, true);
-
+ readExtraAttributes(tag, parser, resolvedUserId);
if (allowedManagedServicePackages == null ||
allowedManagedServicePackages.test(getPackageName(approved))) {
if (mUm.getUserInfo(resolvedUserId) != null) {
@@ -391,6 +396,12 @@ abstract public class ManagedServices {
rebindServices(false, USER_ALL);
}
+ /**
+ * Read extra attributes in the {@link #TAG_MANAGED_SERVICES} tag.
+ */
+ protected void readExtraAttributes(String tag, XmlPullParser parser, int userId)
+ throws IOException {}
+
private void loadAllowedComponentsFromSettings() {
for (UserInfo user : mUm.getUsers()) {
final ContentResolver cr = mContext.getContentResolver();
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index e8c402c770c7..22f0b9db85b2 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -153,6 +153,7 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.VibrationEffect;
import android.os.Vibrator;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.service.notification.Adjustment;
import android.service.notification.Condition;
@@ -190,6 +191,7 @@ import android.widget.Toast;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -515,26 +517,32 @@ public class NotificationManagerService extends SystemService {
}
}
- readDefaultAssistant(userId);
+ setDefaultAssistantForUser(userId);
}
- protected void readDefaultAssistant(int userId) {
- String defaultAssistantAccess = getContext().getResources().getString(
- com.android.internal.R.string.config_defaultAssistantAccessPackage);
- if (defaultAssistantAccess != null) {
- // Gather all notification assistant components for candidate pkg. There should
- // only be one
- Set<ComponentName> approvedAssistants =
- mAssistants.queryPackageForServices(defaultAssistantAccess,
- MATCH_DIRECT_BOOT_AWARE
- | MATCH_DIRECT_BOOT_UNAWARE, userId);
- for (ComponentName cn : approvedAssistants) {
- try {
- getBinderService().setNotificationAssistantAccessGrantedForUser(
- cn, userId, true);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
+ protected void setDefaultAssistantForUser(int userId) {
+ List<ComponentName> validAssistants = new ArrayList<>(
+ mAssistants.queryPackageForServices(
+ null, MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, userId));
+
+ List<String> candidateStrs = new ArrayList<>();
+ candidateStrs.add(DeviceConfig.getProperty(
+ DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE));
+ candidateStrs.add(getContext().getResources().getString(
+ com.android.internal.R.string.config_defaultAssistantAccessComponent));
+
+ for (String candidateStr : candidateStrs) {
+ if (TextUtils.isEmpty(candidateStr)) {
+ continue;
+ }
+ ComponentName candidate = ComponentName.unflattenFromString(candidateStr);
+ if (candidate != null && validAssistants.contains(candidate)) {
+ setNotificationAssistantAccessGrantedForUserInternal(candidate, userId, true);
+ Slog.d(TAG, String.format("Set default NAS to be %s in %d", candidateStr, userId));
+ return;
+ } else {
+ Slog.w(TAG, "Invalid default NAS config is found: " + candidateStr);
}
}
}
@@ -594,6 +602,8 @@ public class NotificationManagerService extends SystemService {
mConditionProviders.migrateToXml();
handleSavePolicyFile();
}
+
+ mAssistants.resetDefaultAssistantsIfNecessary();
}
private void loadPolicyFile() {
@@ -1740,6 +1750,21 @@ public class NotificationManagerService extends SystemService {
publishLocalService(NotificationManagerInternal.class, mInternalService);
}
+ private void registerDeviceConfigChange() {
+ DeviceConfig.addOnPropertyChangedListener(
+ DeviceConfig.NAMESPACE_SYSTEMUI,
+ getContext().getMainExecutor(),
+ (namespace, name, value) -> {
+ if (!DeviceConfig.NAMESPACE_SYSTEMUI.equals(namespace)) {
+ return;
+ }
+ if (SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE.equals(name)) {
+ mAssistants.resetDefaultAssistantsIfNecessary();
+ }
+ });
+ }
+
+
private GroupHelper getGroupHelper() {
mAutoGroupAtCount =
getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
@@ -1803,6 +1828,7 @@ public class NotificationManagerService extends SystemService {
mListeners.onBootPhaseAppsCanStart();
mAssistants.onBootPhaseAppsCanStart();
mConditionProviders.onBootPhaseAppsCanStart();
+ registerDeviceConfigChange();
}
}
@@ -3733,14 +3759,14 @@ public class NotificationManagerService extends SystemService {
@Override
public void setNotificationAssistantAccessGranted(ComponentName assistant,
- boolean granted) throws RemoteException {
+ boolean granted) {
setNotificationAssistantAccessGrantedForUser(
assistant, getCallingUserHandle().getIdentifier(), granted);
}
@Override
public void setNotificationListenerAccessGrantedForUser(ComponentName listener, int userId,
- boolean granted) throws RemoteException {
+ boolean granted) {
Preconditions.checkNotNull(listener);
checkCallerIsSystemOrShell();
final long identity = Binder.clearCallingIdentity();
@@ -3766,32 +3792,12 @@ public class NotificationManagerService extends SystemService {
@Override
public void setNotificationAssistantAccessGrantedForUser(ComponentName assistant,
- int userId, boolean granted) throws RemoteException {
+ int userId, boolean granted) {
checkCallerIsSystemOrShell();
- if (assistant == null) {
- ComponentName allowedAssistant = CollectionUtils.firstOrNull(
- mAssistants.getAllowedComponents(userId));
- if (allowedAssistant != null) {
- setNotificationAssistantAccessGrantedForUser(allowedAssistant, userId, false);
- }
- return;
- }
+ mAssistants.setUserSet(userId, true);
final long identity = Binder.clearCallingIdentity();
try {
- if (mAllowedManagedServicePackages.test(assistant.getPackageName())) {
- mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(),
- userId, false, granted);
- mAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
- userId, true, granted);
-
- getContext().sendBroadcastAsUser(new Intent(
- NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
- .setPackage(assistant.getPackageName())
- .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
- UserHandle.of(userId), null);
-
- handleSavePolicyFile();
- }
+ setNotificationAssistantAccessGrantedForUserInternal(assistant, userId, granted);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -4004,6 +4010,34 @@ public class NotificationManagerService extends SystemService {
}
};
+ @VisibleForTesting
+ protected void setNotificationAssistantAccessGrantedForUserInternal(
+ ComponentName assistant, int userId, boolean granted) {
+ if (assistant == null) {
+ ComponentName allowedAssistant = CollectionUtils.firstOrNull(
+ mAssistants.getAllowedComponents(userId));
+ if (allowedAssistant != null) {
+ setNotificationAssistantAccessGrantedForUserInternal(
+ allowedAssistant, userId, false);
+ }
+ return;
+ }
+ if (mAllowedManagedServicePackages.test(assistant.getPackageName())) {
+ mConditionProviders.setPackageOrComponentEnabled(assistant.flattenToString(),
+ userId, false, granted);
+ mAssistants.setPackageOrComponentEnabled(assistant.flattenToString(),
+ userId, true, granted);
+
+ getContext().sendBroadcastAsUser(new Intent(
+ NotificationManager.ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED)
+ .setPackage(assistant.getPackageName())
+ .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY),
+ UserHandle.of(userId), null);
+
+ handleSavePolicyFile();
+ }
+ }
+
private void applyAdjustment(NotificationRecord r, Adjustment adjustment) {
if (r == null) {
return;
@@ -7091,6 +7125,13 @@ public class NotificationManagerService extends SystemService {
public class NotificationAssistants extends ManagedServices {
static final String TAG_ENABLED_NOTIFICATION_ASSISTANTS = "enabled_assistants";
+ private static final String ATT_USER_SET = "user_set";
+
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
+ private ArrayMap<Integer, Boolean> mUserSetMap = new ArrayMap<>();
+
public NotificationAssistants(Context context, Object lock, UserProfiles up,
IPackageManager pm) {
super(context, lock, up, pm);
@@ -7157,6 +7198,30 @@ public class NotificationManagerService extends SystemService {
}
}
+ boolean hasUserSet(int userId) {
+ synchronized (mLock) {
+ return mUserSetMap.getOrDefault(userId, false);
+ }
+ }
+
+ void setUserSet(int userId, boolean set) {
+ synchronized (mLock) {
+ mUserSetMap.put(userId, set);
+ }
+ }
+
+ @Override
+ protected void writeExtraAttributes(XmlSerializer out, int userId) throws IOException {
+ out.attribute(null, ATT_USER_SET, Boolean.toString(hasUserSet(userId)));
+ }
+
+ @Override
+ protected void readExtraAttributes(String tag, XmlPullParser parser, int userId)
+ throws IOException {
+ boolean userSet = XmlUtils.readBooleanAttribute(parser, ATT_USER_SET, false);
+ setUserSet(userId, userSet);
+ }
+
private void notifySeen(final ManagedServiceInfo info,
final ArrayList<String> keys) {
final INotificationListener assistant = (INotificationListener) info.service;
@@ -7314,13 +7379,13 @@ public class NotificationManagerService extends SystemService {
return !getServices().isEmpty();
}
- protected void ensureAssistant() {
+ protected void resetDefaultAssistantsIfNecessary() {
final List<UserInfo> activeUsers = mUm.getUsers(true);
for (UserInfo userInfo : activeUsers) {
int userId = userInfo.getUserHandle().getIdentifier();
- if (getAllowedPackages(userId).isEmpty()) {
+ if (!hasUserSet(userId)) {
Slog.d(TAG, "Approving default notification assistant for user " + userId);
- readDefaultAssistant(userId);
+ setDefaultAssistantForUser(userId);
}
}
}
@@ -7334,16 +7399,24 @@ public class NotificationManagerService extends SystemService {
if (!allowedComponents.isEmpty()) {
ComponentName currentComponent = CollectionUtils.firstOrNull(allowedComponents);
if (currentComponent.flattenToString().equals(pkgOrComponent)) return;
- try {
- getBinderService().setNotificationAssistantAccessGrantedForUser(
- currentComponent, userId, false);
- } catch (RemoteException e) {
- e.rethrowFromSystemServer();
- }
+ setNotificationAssistantAccessGrantedForUserInternal(
+ currentComponent, userId, false);
}
}
super.setPackageOrComponentEnabled(pkgOrComponent, userId, isPrimary, enabled);
}
+
+ @Override
+ public void dump(PrintWriter pw, DumpFilter filter) {
+ super.dump(pw, filter);
+ pw.println(" Has user set:");
+ synchronized (mLock) {
+ Set<Integer> userIds = mUserSetMap.keySet();
+ for (int userId : userIds) {
+ pw.println(" userId=" + userId + " value=" + mUserSetMap.get(userId));
+ }
+ }
+ }
}
public class NotificationListeners extends ManagedServices {
@@ -7896,6 +7969,19 @@ public class NotificationManagerService extends SystemService {
}
@VisibleForTesting
+ void resetAssistantUserSet(int userId) {
+ mAssistants.setUserSet(userId, false);
+ handleSavePolicyFile();
+ }
+
+ @VisibleForTesting
+ @Nullable
+ ComponentName getApprovedAssistant(int userId) {
+ List<ComponentName> allowedComponents = mAssistants.getAllowedComponents(userId);
+ return CollectionUtils.firstOrNull(allowedComponents);
+ }
+
+ @VisibleForTesting
protected void simulatePackageSuspendBroadcast(boolean suspend, String pkg) {
// only use for testing: mimic receive broadcast that package is (un)suspended
// but does not actually (un)suspend the package
diff --git a/services/core/java/com/android/server/notification/NotificationShellCmd.java b/services/core/java/com/android/server/notification/NotificationShellCmd.java
index 26cc0c10ccb3..dd0f420b6df5 100644
--- a/services/core/java/com/android/server/notification/NotificationShellCmd.java
+++ b/services/core/java/com/android/server/notification/NotificationShellCmd.java
@@ -58,6 +58,8 @@ public class NotificationShellCmd extends ShellCommand {
+ " disallow_dnd PACKAGE [user_id (current user if not specified)]\n"
+ " suspend_package PACKAGE\n"
+ " unsuspend_package PACKAGE\n"
+ + " reset_assistant_user_set [user_id (current user if not specified)]\n"
+ + " get_approved_assistant [user_id (current user if not specified)]\n"
+ " post [--help | flags] TAG TEXT";
private static final String NOTIFY_USAGE =
@@ -199,8 +201,29 @@ public class NotificationShellCmd extends ShellCommand {
mDirectService.simulatePackageDistractionBroadcast(
Integer.parseInt(getNextArgRequired()),
getNextArgRequired().split(","));
+ break;
+ }
+ case "reset_assistant_user_set": {
+ int userId = ActivityManager.getCurrentUser();
+ if (peekNextArg() != null) {
+ userId = Integer.parseInt(getNextArgRequired());
+ }
+ mDirectService.resetAssistantUserSet(userId);
+ break;
+ }
+ case "get_approved_assistant": {
+ int userId = ActivityManager.getCurrentUser();
+ if (peekNextArg() != null) {
+ userId = Integer.parseInt(getNextArgRequired());
+ }
+ ComponentName approvedAssistant = mDirectService.getApprovedAssistant(userId);
+ if (approvedAssistant == null) {
+ pw.println("null");
+ } else {
+ pw.println(approvedAssistant.flattenToString());
+ }
+ break;
}
- break;
case "post":
case "notify":
doNotify(pw);
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index f52f3a3627ad..e241ba63f082 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -599,6 +599,8 @@ class RollbackManagerServiceImpl extends IRollbackManager.Stub {
}
}
}
+
+ mPackageHealthObserver.onBootCompleted();
});
}
diff --git a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
index d24f21781b39..9348806c0e59 100644
--- a/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
+++ b/services/core/java/com/android/server/rollback/RollbackPackageHealthObserver.java
@@ -26,6 +26,8 @@ import android.content.pm.VersionedPackage;
import android.content.rollback.PackageRollbackInfo;
import android.content.rollback.RollbackInfo;
import android.content.rollback.RollbackManager;
+import android.os.Environment;
+import android.os.FileUtils;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.PowerManager;
@@ -39,6 +41,12 @@ import com.android.server.PackageWatchdog;
import com.android.server.PackageWatchdog.PackageHealthObserver;
import com.android.server.PackageWatchdog.PackageHealthObserverImpact;
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
import java.util.Collections;
import java.util.List;
@@ -50,14 +58,19 @@ import java.util.List;
public final class RollbackPackageHealthObserver implements PackageHealthObserver {
private static final String TAG = "RollbackPackageHealthObserver";
private static final String NAME = "rollback-observer";
- private Context mContext;
- private Handler mHandler;
+ private static final int INVALID_ROLLBACK_ID = -1;
+ private final Context mContext;
+ private final Handler mHandler;
+ private final File mLastStagedRollbackIdFile;
RollbackPackageHealthObserver(Context context) {
mContext = context;
HandlerThread handlerThread = new HandlerThread("RollbackPackageHealthObserver");
handlerThread.start();
mHandler = handlerThread.getThreadHandler();
+ File dataDir = new File(Environment.getDataDirectory(), "rollback-observer");
+ dataDir.mkdirs();
+ mLastStagedRollbackIdFile = new File(dataDir, "last-staged-rollback-id");
PackageWatchdog.getInstance(mContext).registerHealthObserver(this);
}
@@ -112,15 +125,19 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
int status = result.getIntExtra(RollbackManager.EXTRA_STATUS,
RollbackManager.STATUS_FAILURE);
if (status == RollbackManager.STATUS_SUCCESS) {
- StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
- StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
- moduleMetadataPackage.getPackageName(),
- moduleMetadataPackage.getVersionCode());
if (rollback.isStaged()) {
int rollbackId = rollback.getRollbackId();
BroadcastReceiver listener =
- listenForStagedSessionReady(rollbackManager, rollbackId);
- handleStagedSessionChange(rollbackManager, rollbackId, listener);
+ listenForStagedSessionReady(rollbackManager, rollbackId,
+ moduleMetadataPackage);
+ handleStagedSessionChange(rollbackManager, rollbackId, listener,
+ moduleMetadataPackage);
+ } else {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
}
} else {
StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
@@ -149,7 +166,73 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
* This may cause {@code packages} to be rolled back if they crash too freqeuntly.
*/
public void startObservingHealth(List<String> packages, long durationMs) {
- PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs);
+ PackageWatchdog.getInstance(mContext).startObservingHealth(this, packages, durationMs,
+ false /* withExplicitHealthCheck */);
+ }
+
+ /** Verifies the rollback state after a reboot. */
+ public void onBootCompleted() {
+ int rollbackId = popLastStagedRollbackId();
+ if (rollbackId == INVALID_ROLLBACK_ID) {
+ // No staged rollback before reboot
+ return;
+ }
+
+ RollbackManager rollbackManager = mContext.getSystemService(RollbackManager.class);
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ RollbackInfo rollback = null;
+ for (RollbackInfo info : rollbackManager.getRecentlyCommittedRollbacks()) {
+ if (rollbackId == info.getRollbackId()) {
+ rollback = info;
+ break;
+ }
+ }
+
+ if (rollback == null) {
+ Slog.e(TAG, "rollback info not found for last staged rollback: " + rollbackId);
+ return;
+ }
+
+ String moduleMetadataPackageName = getModuleMetadataPackageName();
+ if (moduleMetadataPackageName == null) {
+ // Only log mainline staged rollbacks
+ return;
+ }
+
+ // Use the version of the metadata package that was installed before
+ // we rolled back for logging purposes.
+ VersionedPackage moduleMetadataPackage = null;
+ for (PackageRollbackInfo packageRollback : rollback.getPackages()) {
+ if (moduleMetadataPackageName.equals(packageRollback.getPackageName())) {
+ moduleMetadataPackage = packageRollback.getVersionRolledBackFrom();
+ break;
+ }
+ }
+
+ if (moduleMetadataPackage == null) {
+ // Only log mainline staged rollbacks
+ return;
+ }
+
+ int sessionId = rollback.getCommittedSessionId();
+ PackageInstaller.SessionInfo sessionInfo = packageInstaller.getSessionInfo(sessionId);
+ if (sessionInfo == null) {
+ Slog.e(TAG, "On boot completed, could not load session id " + sessionId);
+ return;
+ }
+ if (sessionInfo.isStagedSessionApplied()) {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_SUCCESS,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
+ } else if (sessionInfo.isStagedSessionReady()) {
+ // TODO: What do for staged session ready but not applied
+ } else {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog.WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
+ }
}
private Pair<RollbackInfo, Boolean> getAvailableRollback(RollbackManager rollbackManager,
@@ -174,12 +257,20 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
return null;
}
- private VersionedPackage getModuleMetadataPackage() {
+ private String getModuleMetadataPackageName() {
String packageName = mContext.getResources().getString(
R.string.config_defaultModuleMetadataProvider);
if (TextUtils.isEmpty(packageName)) {
return null;
}
+ return packageName;
+ }
+
+ private VersionedPackage getModuleMetadataPackage() {
+ String packageName = getModuleMetadataPackageName();
+ if (packageName == null) {
+ return null;
+ }
try {
return new VersionedPackage(packageName, mContext.getPackageManager().getPackageInfo(
@@ -191,12 +282,12 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
}
private BroadcastReceiver listenForStagedSessionReady(RollbackManager rollbackManager,
- int rollbackId) {
+ int rollbackId, VersionedPackage moduleMetadataPackage) {
BroadcastReceiver sessionUpdatedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
handleStagedSessionChange(rollbackManager,
- rollbackId, this /* BroadcastReceiver */);
+ rollbackId, this /* BroadcastReceiver */, moduleMetadataPackage);
}
};
IntentFilter sessionUpdatedFilter =
@@ -206,7 +297,7 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
}
private void handleStagedSessionChange(RollbackManager rollbackManager, int rollbackId,
- BroadcastReceiver listener) {
+ BroadcastReceiver listener, VersionedPackage moduleMetadataPackage) {
PackageInstaller packageInstaller =
mContext.getPackageManager().getPackageInstaller();
List<RollbackInfo> recentRollbacks =
@@ -220,11 +311,52 @@ public final class RollbackPackageHealthObserver implements PackageHealthObserve
packageInstaller.getSessionInfo(sessionId);
if (sessionInfo.isStagedSessionReady()) {
mContext.unregisterReceiver(listener);
+ saveLastStagedRollbackId(rollbackId);
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_BOOT_TRIGGERED,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
mContext.getSystemService(PowerManager.class).reboot("Rollback staged install");
} else if (sessionInfo.isStagedSessionFailed()) {
+ StatsLog.write(StatsLog.WATCHDOG_ROLLBACK_OCCURRED,
+ StatsLog
+ .WATCHDOG_ROLLBACK_OCCURRED__ROLLBACK_TYPE__ROLLBACK_FAILURE,
+ moduleMetadataPackage.getPackageName(),
+ moduleMetadataPackage.getVersionCode());
mContext.unregisterReceiver(listener);
}
}
}
}
+
+ private void saveLastStagedRollbackId(int stagedRollbackId) {
+ try {
+ FileOutputStream fos = new FileOutputStream(mLastStagedRollbackIdFile);
+ PrintWriter pw = new PrintWriter(fos);
+ pw.println(stagedRollbackId);
+ pw.flush();
+ FileUtils.sync(fos);
+ pw.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to save last staged rollback id", e);
+ mLastStagedRollbackIdFile.delete();
+ }
+ }
+
+ private int popLastStagedRollbackId() {
+ int rollbackId = INVALID_ROLLBACK_ID;
+ if (!mLastStagedRollbackIdFile.exists()) {
+ return rollbackId;
+ }
+
+ try {
+ rollbackId = Integer.parseInt(
+ IoUtils.readFileAsString(mLastStagedRollbackIdFile.getAbsolutePath()).trim());
+ } catch (IOException | NumberFormatException e) {
+ Slog.e(TAG, "Failed to retrieve last staged rollback id", e);
+ }
+ mLastStagedRollbackIdFile.delete();
+ return rollbackId;
+ }
}
diff --git a/services/core/java/com/android/server/signedconfig/TEST_MAPPING b/services/core/java/com/android/server/signedconfig/TEST_MAPPING
new file mode 100644
index 000000000000..88e068f5e120
--- /dev/null
+++ b/services/core/java/com/android/server/signedconfig/TEST_MAPPING
@@ -0,0 +1,7 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsSignedConfigHostTestCases"
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index ef771406805b..a5d291f94751 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -27,12 +27,8 @@ import android.os.Binder;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.service.textclassifier.IConversationActionsCallback;
-import android.service.textclassifier.ITextClassificationCallback;
+import android.service.textclassifier.ITextClassifierCallback;
import android.service.textclassifier.ITextClassifierService;
-import android.service.textclassifier.ITextLanguageCallback;
-import android.service.textclassifier.ITextLinksCallback;
-import android.service.textclassifier.ITextSelectionCallback;
import android.service.textclassifier.TextClassifierService;
import android.util.Slog;
import android.util.SparseArray;
@@ -132,7 +128,7 @@ public final class TextClassificationManagerService extends ITextClassifierServi
@Override
public void onSuggestSelection(
TextClassificationSessionId sessionId,
- TextSelection.Request request, ITextSelectionCallback callback)
+ TextSelection.Request request, ITextClassifierCallback callback)
throws RemoteException {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
@@ -155,7 +151,7 @@ public final class TextClassificationManagerService extends ITextClassifierServi
@Override
public void onClassifyText(
TextClassificationSessionId sessionId,
- TextClassification.Request request, ITextClassificationCallback callback)
+ TextClassification.Request request, ITextClassifierCallback callback)
throws RemoteException {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
@@ -178,7 +174,7 @@ public final class TextClassificationManagerService extends ITextClassifierServi
@Override
public void onGenerateLinks(
TextClassificationSessionId sessionId,
- TextLinks.Request request, ITextLinksCallback callback)
+ TextLinks.Request request, ITextClassifierCallback callback)
throws RemoteException {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
@@ -241,7 +237,7 @@ public final class TextClassificationManagerService extends ITextClassifierServi
public void onDetectLanguage(
TextClassificationSessionId sessionId,
TextLanguage.Request request,
- ITextLanguageCallback callback) throws RemoteException {
+ ITextClassifierCallback callback) throws RemoteException {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
validateInput(mContext, request.getCallingPackageName());
@@ -264,7 +260,7 @@ public final class TextClassificationManagerService extends ITextClassifierServi
public void onSuggestConversationActions(
TextClassificationSessionId sessionId,
ConversationActions.Request request,
- IConversationActionsCallback callback) throws RemoteException {
+ ITextClassifierCallback callback) throws RemoteException {
Preconditions.checkNotNull(request);
Preconditions.checkNotNull(callback);
validateInput(mContext, request.getCallingPackageName());
diff --git a/services/core/java/com/android/server/utils/FlagNamespaceUtils.java b/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
index f26121eac939..f8c7447fc55d 100644
--- a/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
+++ b/services/core/java/com/android/server/utils/FlagNamespaceUtils.java
@@ -19,6 +19,7 @@ package com.android.server.utils;
import android.annotation.Nullable;
import android.provider.DeviceConfig;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.server.RescueParty;
import java.util.ArrayList;
@@ -41,20 +42,23 @@ public final class FlagNamespaceUtils {
/**
* Name of the special namespace in DeviceConfig table used for communicating resets.
*/
- private static final String NAMESPACE_RESCUE_PARTY = "rescue_party_namespace";
+ @VisibleForTesting
+ public static final String NAMESPACE_RESCUE_PARTY = "rescue_party_namespace";
/**
* Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY}, holding all known {@link
* DeviceConfig} namespaces, as a {@link #DELIMITER} separated String. It's updated after the
* first time flags are written to the new namespace in the {@link DeviceConfig}.
*/
- private static final String ALL_KNOWN_NAMESPACES_FLAG = "all_known_namespaces";
+ @VisibleForTesting
+ public static final String ALL_KNOWN_NAMESPACES_FLAG = "all_known_namespaces";
/**
* Flag in the {@link DeviceConfig} in {@link #NAMESPACE_RESCUE_PARTY} with integer counter
* suffix added to it, holding {@link DeviceConfig} namespace value whose flags were recently
* reset by the {@link RescueParty}. It's updated by {@link RescueParty} every time given
* namespace flags are reset.
*/
- private static final String RESET_PLATFORM_PACKAGE_FLAG = "reset_platform_package";
+ @VisibleForTesting
+ public static final String RESET_PLATFORM_PACKAGE_FLAG = "reset_platform_package";
private static final String DELIMITER = ":";
/**
* Maximum value of the counter used in combination with {@link #RESET_PLATFORM_PACKAGE_FLAG}
@@ -97,11 +101,25 @@ public final class FlagNamespaceUtils {
* Reset all namespaces in DeviceConfig with consumed resetMode.
*/
public static void resetDeviceConfig(int resetMode) {
- List<String> allKnownNamespaces = getAllKnownDeviceConfigNamespacesList();
- for (String namespace : allKnownNamespaces) {
+ resetDeviceConfig(resetMode, getAllKnownDeviceConfigNamespacesList());
+ }
+
+ /**
+ * Reset all consumed namespaces in DeviceConfig with consumed resetMode.
+ */
+ public static void resetDeviceConfig(int resetMode, List<String> namespacesList) {
+ for (String namespace : namespacesList) {
DeviceConfig.resetToDefaults(resetMode, namespace);
}
- addToKnownResetNamespaces(allKnownNamespaces);
+ addToKnownResetNamespaces(namespacesList);
+ }
+
+ /**
+ * Resets known reset namespaces flag counter for tests only.
+ */
+ @VisibleForTesting
+ public static void resetKnownResetNamespacesFlagCounterForTest() {
+ sKnownResetNamespacesFlagCounter = -1;
}
/**
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index bb1e00113174..e53fde96e844 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -474,7 +474,13 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
int wallpaperId;
if (wallpaper.equals(mFallbackWallpaper)) {
- extractDefaultImageWallpaperColors();
+ synchronized (mLock) {
+ if (mFallbackWallpaper.primaryColors != null) return;
+ }
+ final WallpaperColors colors = extractDefaultImageWallpaperColors();
+ synchronized (mLock) {
+ mFallbackWallpaper.primaryColors = colors;
+ }
return;
}
@@ -499,23 +505,7 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
} else if (defaultImageWallpaper) {
// There is no crop and source file because this is default image wallpaper.
- try (final InputStream is =
- WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM)) {
- if (is != null) {
- try {
- final BitmapFactory.Options options = new BitmapFactory.Options();
- final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
- if (bitmap != null) {
- colors = WallpaperColors.fromBitmap(bitmap);
- bitmap.recycle();
- }
- } catch (OutOfMemoryError e) {
- Slog.w(TAG, "Can't decode default wallpaper stream", e);
- }
- }
- } catch (IOException e) {
- Slog.w(TAG, "Can't close default wallpaper stream", e);
- }
+ colors = extractDefaultImageWallpaperColors();
}
if (colors == null) {
@@ -535,37 +525,41 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
}
}
- private void extractDefaultImageWallpaperColors() {
+ private WallpaperColors extractDefaultImageWallpaperColors() {
+ if (DEBUG) Slog.d(TAG, "Extract default image wallpaper colors");
+
synchronized (mLock) {
- if (mFallbackWallpaper.primaryColors != null) return;
+ if (mCacheDefaultImageWallpaperColors != null) return mCacheDefaultImageWallpaperColors;
}
- if (DEBUG) Slog.d(TAG, "Extract default image wallpaper colors");
WallpaperColors colors = null;
- final InputStream is = WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM);
- if (is != null) {
- try {
- final BitmapFactory.Options options = new BitmapFactory.Options();
- final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
- if (bitmap != null) {
- colors = WallpaperColors.fromBitmap(bitmap);
- bitmap.recycle();
- }
- } catch (OutOfMemoryError e) {
- Slog.w(TAG, "Can't decode default wallpaper stream", e);
- } finally {
- IoUtils.closeQuietly(is);
+ try (InputStream is = WallpaperManager.openDefaultWallpaper(mContext, FLAG_SYSTEM)) {
+ if (is == null) {
+ Slog.w(TAG, "Can't open default wallpaper stream");
+ return null;
}
+
+ final BitmapFactory.Options options = new BitmapFactory.Options();
+ final Bitmap bitmap = BitmapFactory.decodeStream(is, null, options);
+ if (bitmap != null) {
+ colors = WallpaperColors.fromBitmap(bitmap);
+ bitmap.recycle();
+ }
+ } catch (OutOfMemoryError e) {
+ Slog.w(TAG, "Can't decode default wallpaper stream", e);
+ } catch (IOException e) {
+ Slog.w(TAG, "Can't close default wallpaper stream", e);
}
if (colors == null) {
Slog.e(TAG, "Extract default image wallpaper colors failed");
- return;
+ } else {
+ synchronized (mLock) {
+ mCacheDefaultImageWallpaperColors = colors;
+ }
}
- synchronized (mLock) {
- mFallbackWallpaper.primaryColors = colors;
- }
+ return colors;
}
/**
@@ -815,6 +809,12 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
private final ComponentName mImageWallpaper;
/**
+ * Default image wallpaper shall never changed after system service started, caching it when we
+ * first read the image file.
+ */
+ private WallpaperColors mCacheDefaultImageWallpaperColors;
+
+ /**
* Name of the default wallpaper component; might be different from mImageWallpaper
*/
private final ComponentName mDefaultWallpaperComponent;
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index f882fdee8c1f..a33b454d51dc 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -126,6 +126,13 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
private boolean mSingleTaskInstance;
/**
+ * Non-null if the last size compatibility mode activity is using non-native screen
+ * configuration. The activity is not able to put in multi-window mode, so it exists only one
+ * per display.
+ */
+ private ActivityRecord mLastCompatModeActivity;
+
+ /**
* A focusable stack that is purposely to be positioned at the top. Although the stack may not
* have the topmost index, it is used as a preferred candidate to prevent being unable to resume
* target stack properly when there are other focusable always-on-top stacks.
@@ -1032,6 +1039,28 @@ class ActivityDisplay extends ConfigurationContainer<ActivityStack>
mSplitScreenPrimaryStack = null;
}
+ /** Checks whether the given activity is in size compatibility mode and notifies the change. */
+ void handleActivitySizeCompatModeIfNeeded(ActivityRecord r) {
+ if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
+ // The callback is only interested in the foreground changes of fullscreen activity.
+ return;
+ }
+ if (!r.inSizeCompatMode()) {
+ if (mLastCompatModeActivity != null) {
+ mService.getTaskChangeNotificationController()
+ .notifySizeCompatModeActivityChanged(mDisplayId, null /* activityToken */);
+ }
+ mLastCompatModeActivity = null;
+ return;
+ }
+ if (mLastCompatModeActivity == r) {
+ return;
+ }
+ mLastCompatModeActivity = r;
+ mService.getTaskChangeNotificationController()
+ .notifySizeCompatModeActivityChanged(mDisplayId, r.appToken);
+ }
+
ActivityStack getSplitScreenPrimaryStack() {
return mSplitScreenPrimaryStack;
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 178359159eb6..4706930928f4 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -101,6 +101,7 @@ import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
+import static com.android.server.wm.ActivityStack.ActivityState.RESTARTING_PROCESS;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
import static com.android.server.wm.ActivityStack.ActivityState.STOPPED;
import static com.android.server.wm.ActivityStack.ActivityState.STOPPING;
@@ -160,6 +161,7 @@ import android.app.servertransaction.NewIntentItem;
import android.app.servertransaction.PauseActivityItem;
import android.app.servertransaction.PipModeChangeItem;
import android.app.servertransaction.ResumeActivityItem;
+import android.app.servertransaction.StopActivityItem;
import android.app.servertransaction.TopResumedActivityChangeItem;
import android.app.servertransaction.WindowVisibilityItem;
import android.app.usage.UsageEvents.Event;
@@ -2128,6 +2130,11 @@ final class ActivityRecord extends ConfigurationContainer {
r.icicle = null;
r.haveState = false;
}
+
+ final ActivityDisplay display = r.getDisplay();
+ if (display != null) {
+ display.handleActivitySizeCompatModeIfNeeded(r);
+ }
}
/**
@@ -2189,7 +2196,8 @@ final class ActivityRecord extends ConfigurationContainer {
final void activityStoppedLocked(Bundle newIcicle, PersistableBundle newPersistentState,
CharSequence description) {
final ActivityStack stack = getActivityStack();
- if (mState != STOPPING) {
+ final boolean isStopping = mState == STOPPING;
+ if (!isStopping && mState != RESTARTING_PROCESS) {
Slog.i(TAG, "Activity reported stop, but no longer stopping: " + this);
stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
return;
@@ -2212,7 +2220,9 @@ final class ActivityRecord extends ConfigurationContainer {
if (DEBUG_STATES) Slog.v(TAG_STATES, "Moving to STOPPED: " + this + " (stop complete)");
stack.mHandler.removeMessages(STOP_TIMEOUT_MSG, this);
stopped = true;
- setState(STOPPED, "activityStoppedLocked");
+ if (isStopping) {
+ setState(STOPPED, "activityStoppedLocked");
+ }
if (mAppWindowToken != null) {
mAppWindowToken.notifyAppStopped();
@@ -2693,13 +2703,39 @@ final class ActivityRecord extends ConfigurationContainer {
}
/**
+ * @return {@code true} if this activity is in size compatibility mode that uses the different
+ * density or bounds from its parent.
+ */
+ boolean inSizeCompatMode() {
+ if (!shouldUseSizeCompatMode()) {
+ return false;
+ }
+ final Configuration parentConfig = getParent().getConfiguration();
+ final Configuration resolvedConfig = getResolvedOverrideConfiguration();
+ // Although colorMode, screenLayout, smallestScreenWidthDp are also fixed, generally these
+ // fields should be changed with density and bounds, so here only compares the most
+ // significant field.
+ if (parentConfig.densityDpi != resolvedConfig.densityDpi) {
+ return true;
+ }
+ final Rect parentAppBounds = parentConfig.windowConfiguration.getAppBounds();
+ final Rect parentBounds = parentAppBounds != null
+ ? parentAppBounds : parentConfig.windowConfiguration.getBounds();
+ final Rect overrideBounds = resolvedConfig.windowConfiguration.getBounds();
+ // If the width or height is the same as parent, it is already the best fit of the override
+ // bounds, therefore this condition is considered as not size compatibility mode.
+ return parentBounds.width() != overrideBounds.width()
+ && parentBounds.height() != overrideBounds.height();
+ }
+
+ /**
* Indicates the activity will keep the bounds and screen configuration when it was first
* launched, no matter how its parent changes.
*
* @return {@code true} if this activity is declared as non-resizable and fixed orientation or
* aspect ratio.
*/
- private boolean inSizeCompatMode() {
+ private boolean shouldUseSizeCompatMode() {
return !isResizeable() && (info.isFixedOrientation() || info.hasFixedAspectRatio())
// The configuration of non-standard type should be enforced by system.
&& isActivityTypeStandard()
@@ -2708,8 +2744,8 @@ final class ActivityRecord extends ConfigurationContainer {
// TODO(b/36505427): Consider moving this method and similar ones to ConfigurationContainer.
private void updateOverrideConfiguration() {
- final boolean inSizeCompatMode = inSizeCompatMode();
- if (inSizeCompatMode) {
+ final boolean shouldUseSizeCompatMode = shouldUseSizeCompatMode();
+ if (shouldUseSizeCompatMode) {
if (!matchParentBounds()) {
// The override configuration is set only once in size compatible mode.
return;
@@ -2724,7 +2760,7 @@ final class ActivityRecord extends ConfigurationContainer {
computeBounds(mTmpBounds);
- if (inSizeCompatMode && mTmpBounds.isEmpty()) {
+ if (shouldUseSizeCompatMode && mTmpBounds.isEmpty()) {
mTmpBounds.set(task.getWindowConfiguration().getBounds());
}
if (mTmpBounds.equals(getRequestedOverrideBounds())) {
@@ -2736,7 +2772,7 @@ final class ActivityRecord extends ConfigurationContainer {
overrideConfig.unset();
if (!mTmpBounds.isEmpty()) {
overrideConfig.windowConfiguration.setBounds(mTmpBounds);
- if (inSizeCompatMode) {
+ if (shouldUseSizeCompatMode) {
// Ensure the screen related fields are set. It is used to prevent activity relaunch
// when moving between displays. For screenWidthDp and screenWidthDp, because they
// are relative to bounds and density, they will be calculated in
@@ -2771,7 +2807,7 @@ final class ActivityRecord extends ConfigurationContainer {
}
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
- if (!inSizeCompatMode()) {
+ if (!shouldUseSizeCompatMode()) {
computeConfigResourceOverrides(resolvedConfig, newParentConfiguration,
ORIENTATION_UNDEFINED, true /* insideParentBounds */);
return;
@@ -2851,6 +2887,11 @@ final class ActivityRecord extends ConfigurationContainer {
getResolvedOverrideConfiguration().seq;
mAppWindowToken.onMergedOverrideConfigurationChanged();
}
+
+ final ActivityDisplay display = getDisplay();
+ if (display != null) {
+ display.handleActivitySizeCompatModeIfNeeded(this);
+ }
}
/** Returns true if the configuration is compatible with this activity. */
@@ -2985,7 +3026,7 @@ final class ActivityRecord extends ConfigurationContainer {
* state. This is useful for the case where we know the activity will be
* visible soon and we want to ensure its configuration before we make it
* visible.
- * @return True if the activity was relaunched and false if it wasn't relaunched because we
+ * @return False if the activity was relaunched and true if it wasn't relaunched because we
* can't or the app handles the specific configuration that is changing.
*/
boolean ensureActivityConfiguration(int globalChanges, boolean preserveWindow,
@@ -3307,6 +3348,54 @@ final class ActivityRecord extends ConfigurationContainer {
preserveWindowOnDeferredRelaunch = false;
}
+ /**
+ * Request the process of the activity to restart with its saved state (from
+ * {@link android.app.Activity#onSaveInstanceState}) if possible. It also forces to recompute
+ * the override configuration. Note if the activity is in background, the process will be killed
+ * directly with keeping its record.
+ */
+ void restartProcessIfVisible() {
+ Slog.i(TAG, "Request to restart process of " + this);
+
+ // Reset the existing override configuration to the latest configuration.
+ getRequestedOverrideConfiguration().setToDefaults();
+ getResolvedOverrideConfiguration().setToDefaults();
+ if (visible) {
+ // Configuration will be ensured when becoming visible, so if it is already visible,
+ // then the manual update is needed.
+ updateOverrideConfiguration();
+ }
+
+ if (!attachedToProcess()) {
+ return;
+ }
+
+ // The restarting state avoids removing this record when process is died.
+ setState(RESTARTING_PROCESS, "restartActivityProcess");
+
+ if (!visible || haveState) {
+ // Kill its process immediately because the activity should be in background.
+ // The activity state will be update to {@link #DESTROYED} in
+ // {@link ActivityStack#cleanUpActivityLocked} when handling process died.
+ mAtmService.mH.post(() -> mAtmService.mAmInternal.killProcess(
+ app.mName, app.mUid, "restartActivityProcess"));
+ return;
+ }
+
+ if (mAppWindowToken != null) {
+ mAppWindowToken.startFreezingScreen();
+ }
+ // The process will be killed until the activity reports stopped with saved state (see
+ // {@link ActivityTaskManagerService.activityStopped}).
+ try {
+ mAtmService.getLifecycleManager().scheduleTransaction(app.getThread(), appToken,
+ StopActivityItem.obtain(false /* showWindow */, 0 /* configChanges */));
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Exception thrown during restart " + this, e);
+ }
+ mStackSupervisor.scheduleRestartTimeout(this);
+ }
+
private boolean isProcessRunning() {
WindowProcessController proc = app;
if (proc == null) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 82c0e213f12b..ad989704b823 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -297,7 +297,8 @@ class ActivityStack extends ConfigurationContainer {
STOPPED,
FINISHING,
DESTROYING,
- DESTROYED
+ DESTROYED,
+ RESTARTING_PROCESS
}
@VisibleForTesting
@@ -4741,7 +4742,8 @@ class ActivityStack extends ConfigurationContainer {
// it has failed more than twice. Skip activities that's already finishing
// cleanly by itself.
remove = false;
- } else if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
+ } else if ((!r.haveState && !r.stateNotNeeded
+ && !r.isState(ActivityState.RESTARTING_PROCESS)) || r.finishing) {
// Don't currently have state for the activity, or
// it is finishing -- always remove it.
remove = true;
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index d1108cc68eca..a8e8c7c5c142 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -179,6 +179,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
+ static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
static final int REPORT_HOME_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 16;
@@ -2389,6 +2390,16 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
mHandler.sendEmptyMessageDelayed(SLEEP_TIMEOUT_MSG, SLEEP_TIMEOUT);
}
+ void removeRestartTimeouts(ActivityRecord r) {
+ mHandler.removeMessages(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r);
+ }
+
+ final void scheduleRestartTimeout(ActivityRecord r) {
+ removeRestartTimeouts(r);
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG, r),
+ WindowManagerService.WINDOW_FREEZE_TIMEOUT_DURATION);
+ }
+
void handleNonResizableTaskIfNeeded(TaskRecord task, int preferredWindowingMode,
int preferredDisplayId, ActivityStack actualStack) {
handleNonResizableTaskIfNeeded(task, preferredWindowingMode, preferredDisplayId,
@@ -2655,6 +2666,22 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
}
}
} break;
+ case RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG: {
+ final ActivityRecord r = (ActivityRecord) msg.obj;
+ String processName = null;
+ int uid = 0;
+ synchronized (mService.mGlobalLock) {
+ if (r.attachedToProcess()
+ && r.isState(ActivityStack.ActivityState.RESTARTING_PROCESS)) {
+ processName = r.app.mName;
+ uid = r.app.mUid;
+ }
+ }
+ if (processName != null) {
+ mService.mAmInternal.killProcess(processName, uid,
+ "restartActivityProcessTimeout");
+ }
+ } break;
case REPORT_HOME_CHANGED_MSG: {
synchronized (mService.mGlobalLock) {
mHandler.removeMessages(REPORT_HOME_CHANGED_MSG);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index 9f04166ea4c0..23bed7b4d4b8 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1009,6 +1009,12 @@ class ActivityStarter {
if (mService.isDeviceOwner(callingPackage)) {
return false;
}
+ // don't abort if the callingPackage is temporarily whitelisted
+ if (mService.isPackageNameWhitelistedForBgActivityStarts(callingPackage)) {
+ Slog.w(TAG, "Background activity start for " + callingPackage
+ + " temporarily whitelisted. This will not be supported in future Q builds.");
+ return false;
+ }
// anything that has fallen through would currently be aborted
Slog.w(TAG, "Background activity start [callingPackage: " + callingPackage
+ "; callingUid: " + callingUid
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index d747198bc3f1..75f299c54e79 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -1666,13 +1666,32 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
final long origId = Binder.clearCallingIdentity();
+ String restartingName = null;
+ int restartingUid = 0;
+ final ActivityRecord r;
synchronized (mGlobalLock) {
- final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ r = ActivityRecord.isInStackLocked(token);
if (r != null) {
+ if (r.attachedToProcess()
+ && r.isState(ActivityStack.ActivityState.RESTARTING_PROCESS)) {
+ // The activity was requested to restart from
+ // {@link #restartActivityProcessIfVisible}.
+ restartingName = r.app.mName;
+ restartingUid = r.app.mUid;
+ }
r.activityStoppedLocked(icicle, persistentState, description);
}
}
+ if (restartingName != null) {
+ // In order to let the foreground activity can be restarted with its saved state from
+ // {@link android.app.Activity#onSaveInstanceState}, the kill operation is postponed
+ // until the activity reports stopped with the state. And the activity record will be
+ // kept because the record state is restarting, then the activity will be restarted
+ // immediately if it is still the top one.
+ mStackSupervisor.removeRestartTimeouts(r);
+ mAmInternal.killProcess(restartingName, restartingUid, "restartActivityProcess");
+ }
mAmInternal.trimApplications();
Binder.restoreCallingIdentity(origId);
@@ -2014,6 +2033,23 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
@Override
+ public void restartActivityProcessIfVisible(IBinder activityToken) {
+ mAmInternal.enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "restartActivityProcess()");
+ final long callingId = Binder.clearCallingIdentity();
+ try {
+ synchronized (mGlobalLock) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
+ if (r == null) {
+ return;
+ }
+ r.restartProcessIfVisible();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(callingId);
+ }
+ }
+
+ @Override
public boolean removeTask(int taskId) {
enforceCallerIsRecentsOrHasPermission(REMOVE_TASKS, "removeTask()");
synchronized (mGlobalLock) {
@@ -5210,6 +5246,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return mAmInternal.isBackgroundActivityStartsEnabled();
}
+ boolean isPackageNameWhitelistedForBgActivityStarts(String packageName) {
+ return mAmInternal.isPackageNameWhitelistedForBgActivityStarts(packageName);
+ }
+
void enableScreenAfterBoot(boolean booted) {
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
SystemClock.uptimeMillis());
diff --git a/services/core/java/com/android/server/wm/Letterbox.java b/services/core/java/com/android/server/wm/Letterbox.java
index f8f693c53888..3110fb9a40fe 100644
--- a/services/core/java/com/android/server/wm/Letterbox.java
+++ b/services/core/java/com/android/server/wm/Letterbox.java
@@ -236,6 +236,7 @@ public class Letterbox {
.setFlags(HIDDEN).setColorLayer().build();
mSurface.setLayer(-1);
mSurface.setColor(new float[]{0, 0, 0});
+ mSurface.setColorSpaceAgnostic(true);
}
void attachInput(WindowState win) {
diff --git a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
index 42d25833000d..3d57219209d7 100644
--- a/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/wm/TaskChangeNotificationController.java
@@ -24,6 +24,7 @@ import android.app.TaskInfo;
import android.content.ComponentName;
import android.os.Binder;
import android.os.Handler;
+import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteCallbackList;
@@ -51,6 +52,7 @@ class TaskChangeNotificationController {
private static final int NOTIFY_ACTIVITY_UNPINNED_LISTENERS_MSG = 17;
private static final int NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_FAILED_MSG = 18;
private static final int NOTIFY_ACTIVITY_LAUNCH_ON_SECONDARY_DISPLAY_REROUTED_MSG = 19;
+ private static final int NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG = 20;
// Delay in notifying task stack change listeners (in millis)
private static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
@@ -143,6 +145,10 @@ class TaskChangeNotificationController {
l.onTaskSnapshotChanged(m.arg1, (TaskSnapshot) m.obj);
};
+ private final TaskStackConsumer mOnSizeCompatModeActivityChanged = (l, m) -> {
+ l.onSizeCompatModeActivityChanged(m.arg1, (IBinder) m.obj);
+ };
+
@FunctionalInterface
public interface TaskStackConsumer {
void accept(ITaskStackListener t, Message m) throws RemoteException;
@@ -216,6 +222,9 @@ class TaskChangeNotificationController {
case NOTIFY_TASK_SNAPSHOT_CHANGED_LISTENERS_MSG:
forAllRemoteListeners(mNotifyTaskSnapshotChanged, msg);
break;
+ case NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG:
+ forAllRemoteListeners(mOnSizeCompatModeActivityChanged, msg);
+ break;
}
}
}
@@ -438,4 +447,15 @@ class TaskChangeNotificationController {
forAllLocalListeners(mNotifyTaskSnapshotChanged, msg);
msg.sendToTarget();
}
+
+ /**
+ * Notify listeners that whether a size compatibility mode activity is using the override
+ * bounds which is not fit its parent.
+ */
+ void notifySizeCompatModeActivityChanged(int displayId, IBinder activityToken) {
+ final Message msg = mHandler.obtainMessage(NOTIFY_SIZE_COMPAT_MODE_ACTIVITY_CHANGED_MSG,
+ displayId, 0 /* unused */, activityToken);
+ forAllLocalListeners(mOnSizeCompatModeActivityChanged, msg);
+ msg.sendToTarget();
+ }
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d3f387c1ebe2..e3a8be5d52d4 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -232,6 +232,7 @@ import android.view.WindowManagerPolicyConstants.PointerEventListener;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
import com.android.internal.policy.IKeyguardDismissCallback;
import com.android.internal.policy.IShortcutService;
@@ -414,6 +415,14 @@ public class WindowManagerService extends IWindowManager.Stub
@Override
public void dumpCritical(FileDescriptor fd, PrintWriter pw, String[] args,
boolean asProto) {
+ // Bugreport dumps the trace 2x, 1x as proto and 1x as text. Save file to disk only 1x.
+ if (asProto && mWindowTracing.isEnabled()) {
+ mWindowTracing.stopTrace(null, false /* writeToFile */);
+ BackgroundThread.getHandler().post(() -> {
+ mWindowTracing.writeTraceToFile();
+ mWindowTracing.startTrace(null);
+ });
+ }
doDump(fd, pw, new String[] {"-a"}, asProto);
}
@@ -1985,6 +1994,10 @@ public class WindowManagerService extends IWindowManager.Stub
updateNonSystemOverlayWindowsVisibilityIfNeeded(
win, win.mWinAnimator.getShown());
}
+ if ((attrChanges & (WindowManager.LayoutParams.PRIVATE_FLAGS_CHANGED)) != 0) {
+ winAnimator.setColorSpaceAgnosticLocked((win.mAttrs.privateFlags
+ & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
+ }
}
if (DEBUG_LAYOUT) Slog.v(TAG_WM, "Relayout " + win + ": viewVisibility=" + viewVisibility
@@ -6182,9 +6195,6 @@ public class WindowManagerService extends IWindowManager.Stub
return;
} else if ("trace".equals(cmd)) {
dumpTraceStatus(pw);
- synchronized (mGlobalLock) {
- mWindowTracing.writeTraceToFile();
- }
return;
} else {
// Dumping a single name?
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 969ced43b942..92bb082eca59 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -487,6 +487,8 @@ class WindowStateAnimator {
mSurfaceController = new WindowSurfaceController(mSession.mSurfaceSession,
attrs.getTitle().toString(), width, height, format, flags, this,
windowType, ownerUid);
+ mSurfaceController.setColorSpaceAgnostic((attrs.privateFlags
+ & WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC) != 0);
setOffsetPositionForStackResize(false);
mSurfaceFormat = format;
@@ -1258,6 +1260,13 @@ class WindowStateAnimator {
mSurfaceController.setSecure(isSecure);
}
+ void setColorSpaceAgnosticLocked(boolean agnostic) {
+ if (mSurfaceController == null) {
+ return;
+ }
+ mSurfaceController.setColorSpaceAgnostic(agnostic);
+ }
+
/**
* Have the surface flinger show a surface, robustly dealing with
* error conditions. In particular, if there is not enough memory
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index e796b99f3989..acb98237b5d1 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -399,6 +399,28 @@ class WindowSurfaceController {
}
}
+ void setColorSpaceAgnostic(boolean agnostic) {
+ if (SHOW_TRANSACTIONS) {
+ logSurface("isColorSpaceAgnostic=" + agnostic, null);
+ }
+
+ if (mSurfaceControl == null) {
+ return;
+ }
+ if (SHOW_LIGHT_TRANSACTIONS) {
+ Slog.i(TAG, ">>> OPEN TRANSACTION setColorSpaceAgnosticLocked");
+ }
+ mService.openSurfaceTransaction();
+ try {
+ mSurfaceControl.setColorSpaceAgnostic(agnostic);
+ } finally {
+ mService.closeSurfaceTransaction("setColorSpaceAgnostic");
+ if (SHOW_LIGHT_TRANSACTIONS) {
+ Slog.i(TAG, "<<< CLOSE TRANSACTION setColorSpaceAgnosticLocked");
+ }
+ }
+ }
+
void getContainerRect(Rect rect) {
mAnimator.getContainerRect(rect);
}
diff --git a/services/core/java/com/android/server/wm/WindowTracing.java b/services/core/java/com/android/server/wm/WindowTracing.java
index 48b9340c4857..4cf234424acc 100644
--- a/services/core/java/com/android/server/wm/WindowTracing.java
+++ b/services/core/java/com/android/server/wm/WindowTracing.java
@@ -100,7 +100,20 @@ class WindowTracing {
}
}
+ /**
+ * Stops the trace and write the current buffer to disk
+ * @param pw Print writer
+ */
void stopTrace(@Nullable PrintWriter pw) {
+ stopTrace(pw, true /* writeToFile */);
+ }
+
+ /**
+ * Stops the trace
+ * @param pw Print writer
+ * @param writeToFile If the current buffer should be written to disk or not
+ */
+ void stopTrace(@Nullable PrintWriter pw, boolean writeToFile) {
if (IS_USER) {
logAndPrintln(pw, "Error: Tracing is not supported on user builds.");
return;
@@ -113,8 +126,10 @@ class WindowTracing {
logAndPrintln(pw, "ERROR: tracing was re-enabled while waiting for flush.");
throw new IllegalStateException("tracing enabled while waiting for flush.");
}
- writeTraceToFileLocked();
- logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ if (writeToFile) {
+ writeTraceToFileLocked();
+ logAndPrintln(pw, "Trace written to " + mTraceFile + ".");
+ }
}
}
diff --git a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
index d39f20c0f214..298b664beb95 100644
--- a/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
+++ b/services/core/jni/com_android_server_location_GnssLocationProvider.cpp
@@ -491,6 +491,10 @@ static jobject translateGnssLocation(JNIEnv* env,
SET(ElapsedRealtimeNanos, location.elapsedRealtime.timestampNs);
}
+ if (flags & ElapsedRealtimeFlags::HAS_TIME_UNCERTAINTY_NS) {
+ SET(ElapsedRealtimeUncertaintyNanos, location.elapsedRealtime.timeUncertaintyNs);
+ }
+
return object.get();
}
@@ -521,7 +525,8 @@ static GnssLocation_V2_0 createGnssLocation_V2_0(
jdouble altitudeMeters, jfloat speedMetersPerSec, jfloat bearingDegrees,
jfloat horizontalAccuracyMeters, jfloat verticalAccuracyMeters,
jfloat speedAccuracyMetersPerSecond, jfloat bearingAccuracyDegrees,
- jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos) {
+ jlong timestamp, jint elapsedRealtimeFlags, jlong elapsedRealtimeNanos,
+ jlong elapsedRealtimeUncertaintyNanos) {
GnssLocation_V2_0 location;
location.v1_0 = createGnssLocation_V1_0(
gnssLocationFlags, latitudeDegrees, longitudeDegrees, altitudeMeters,
@@ -531,6 +536,7 @@ static GnssLocation_V2_0 createGnssLocation_V2_0(
location.elapsedRealtime.flags = static_cast<uint16_t>(elapsedRealtimeFlags);
location.elapsedRealtime.timestampNs = static_cast<uint64_t>(elapsedRealtimeNanos);
+ location.elapsedRealtime.timeUncertaintyNs = static_cast<uint64_t>(elapsedRealtimeUncertaintyNanos);
return location;
}
@@ -1887,7 +1893,8 @@ static void android_location_GnssLocationProvider_inject_best_location(
jfloat bearingAccuracyDegrees,
jlong timestamp,
jint elapsedRealtimeFlags,
- jlong elapsedRealtimeNanos) {
+ jlong elapsedRealtimeNanos,
+ jlong elapsedRealtimeUncertaintyNanos) {
if (gnssHal_V2_0 != nullptr) {
GnssLocation_V2_0 location = createGnssLocation_V2_0(
gnssLocationFlags,
@@ -1902,7 +1909,8 @@ static void android_location_GnssLocationProvider_inject_best_location(
bearingAccuracyDegrees,
timestamp,
elapsedRealtimeFlags,
- elapsedRealtimeNanos);
+ elapsedRealtimeNanos,
+ elapsedRealtimeUncertaintyNanos);
auto result = gnssHal_V2_0->injectBestLocation_2_0(location);
if (!result.isOk() || !result) {
@@ -2813,7 +2821,7 @@ static const JNINativeMethod sMethods[] = {
android_location_GnssLocationProvider_read_nmea)},
{"native_inject_time", "(JJI)V", reinterpret_cast<void *>(
android_location_GnssLocationProvider_inject_time)},
- {"native_inject_best_location", "(IDDDFFFFFFJIJ)V", reinterpret_cast<void *>(
+ {"native_inject_best_location", "(IDDDFFFFFFJIJJ)V", reinterpret_cast<void *>(
android_location_GnssLocationProvider_inject_best_location)},
{"native_inject_location", "(DDF)V", reinterpret_cast<void *>(
android_location_GnssLocationProvider_inject_location)},
diff --git a/services/core/xsd/Android.bp b/services/core/xsd/Android.bp
new file mode 100644
index 000000000000..5e1ea897b86e
--- /dev/null
+++ b/services/core/xsd/Android.bp
@@ -0,0 +1,6 @@
+xsd_config {
+ name: "default-permissions",
+ srcs: ["default-permissions.xsd"],
+ api_dir: "schema",
+ package_name: "com.android.server.pm.permission",
+}
diff --git a/services/core/xsd/default-permissions.xsd b/services/core/xsd/default-permissions.xsd
new file mode 100644
index 000000000000..d800a26cdceb
--- /dev/null
+++ b/services/core/xsd/default-permissions.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- TODO: define a targetNamespace. Note that it will break retrocompatibility -->
+<xs:schema version="2.0"
+ elementFormDefault="qualified"
+ attributeFormDefault="unqualified"
+ xmlns:xs="http://www.w3.org/2001/XMLSchema">
+ <xs:element name="exceptions">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="exception" type="exception" maxOccurs="unbounded"/>
+ </xs:sequence>
+ </xs:complexType>
+ </xs:element>
+ <xs:complexType name="exception">
+ <xs:sequence>
+ <xs:element name="permission" type="permission"/>
+ </xs:sequence>
+ <xs:attribute name="package" type="xs:string"/>
+ <xs:attribute name="sha256-cert-digest" type="xs:string"/>
+ <xs:attribute name="brand" type="xs:string"/>
+ </xs:complexType>
+ <xs:complexType name="permission">
+ <xs:attribute name="name" type="xs:string"/>
+ <xs:attribute name="fixed" type="xs:boolean"/>
+ </xs:complexType>
+</xs:schema>
diff --git a/services/core/xsd/schema/README.md b/services/core/xsd/schema/README.md
new file mode 100644
index 000000000000..f52d93d2b65a
--- /dev/null
+++ b/services/core/xsd/schema/README.md
@@ -0,0 +1 @@
+Please see the [README](https://android.googlesource.com/platform/system/tools/xsdc/+/refs/heads/master/README.md) for details regarding the Configfile as API.
diff --git a/services/core/xsd/schema/current.txt b/services/core/xsd/schema/current.txt
new file mode 100644
index 000000000000..4e67e5c235a0
--- /dev/null
+++ b/services/core/xsd/schema/current.txt
@@ -0,0 +1,37 @@
+// Signature format: 2.0
+package com.android.server.pm.permission {
+
+ public class Exception {
+ ctor public Exception();
+ method public String getBrand();
+ method public com.android.server.pm.permission.Permission getPermission();
+ method public String getSha256CertDigest();
+ method public String get_package();
+ method public void setBrand(String);
+ method public void setPermission(com.android.server.pm.permission.Permission);
+ method public void setSha256CertDigest(String);
+ method public void set_package(String);
+ }
+
+ public class Exceptions {
+ ctor public Exceptions();
+ method public java.util.List<com.android.server.pm.permission.Exception> getException();
+ }
+
+ public class Permission {
+ ctor public Permission();
+ method public boolean getFixed();
+ method public String getName();
+ method public void setFixed(boolean);
+ method public void setName(String);
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static com.android.server.pm.permission.Exceptions read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/services/core/xsd/schema/last_current.txt b/services/core/xsd/schema/last_current.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/services/core/xsd/schema/last_current.txt
diff --git a/services/core/xsd/schema/last_removed.txt b/services/core/xsd/schema/last_removed.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/services/core/xsd/schema/last_removed.txt
diff --git a/services/core/xsd/schema/removed.txt b/services/core/xsd/schema/removed.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/services/core/xsd/schema/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a19d5d5a5d76..eba0081291ca 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1881,19 +1881,6 @@ public final class SystemServer {
mSystemServiceManager.startService(IncidentCompanionService.class);
traceEnd();
- if (safeMode) {
- traceBeginAndSlog("EnterSafeModeAndDisableJitCompilation");
- mActivityManagerService.enterSafeMode();
- // Disable the JIT for the system_server process
- VMRuntime.getRuntime().disableJitCompilation();
- traceEnd();
- } else {
- // Enable the JIT for the system_server process
- traceBeginAndSlog("StartJitCompilation");
- VMRuntime.getRuntime().startJitCompilation();
- traceEnd();
- }
-
// MMS service broker
traceBeginAndSlog("StartMmsService");
mmsService = mSystemServiceManager.startService(MmsServiceBroker.class);
diff --git a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
index b13735cbf3b7..0d6020c3d06d 100644
--- a/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/RescuePartyTest.java
@@ -35,9 +35,12 @@ import android.content.Context;
import android.os.RecoverySystem;
import android.os.SystemProperties;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import com.android.dx.mockito.inline.extended.ExtendedMockito;
+import com.android.server.am.SettingsToPropertiesMapper;
+import com.android.server.utils.FlagNamespaceUtils;
import org.junit.After;
import org.junit.Before;
@@ -56,6 +59,10 @@ import java.util.HashMap;
public class RescuePartyTest {
private static final int PERSISTENT_APP_UID = 12;
private static final long CURRENT_NETWORK_TIME_MILLIS = 0L;
+ private static final String FAKE_NATIVE_NAMESPACE1 = "native1";
+ private static final String FAKE_NATIVE_NAMESPACE2 = "native2";
+ private static final String[] FAKE_RESET_NATIVE_NAMESPACES =
+ {FAKE_NATIVE_NAMESPACE1, FAKE_NATIVE_NAMESPACE2};
private MockitoSession mSession;
@@ -73,9 +80,11 @@ public class RescuePartyTest {
ExtendedMockito.mockitoSession().initMocks(
this)
.strictness(Strictness.LENIENT)
+ .spyStatic(DeviceConfig.class)
.spyStatic(SystemProperties.class)
.spyStatic(Settings.Global.class)
.spyStatic(Settings.Secure.class)
+ .spyStatic(SettingsToPropertiesMapper.class)
.spyStatic(RecoverySystem.class)
.spyStatic(RescueParty.class)
.startMocking();
@@ -121,8 +130,17 @@ public class RescuePartyTest {
}
).when(() -> SystemProperties.getLong(anyString(), anyLong()));
+ // Mock DeviceConfig
+ doAnswer((Answer<Boolean>) invocationOnMock -> true)
+ .when(() -> DeviceConfig.setProperty(anyString(), anyString(), anyString(),
+ anyBoolean()));
+ doAnswer((Answer<Void>) invocationOnMock -> null)
+ .when(() -> DeviceConfig.resetToDefaults(anyInt(), anyString()));
+
+
doReturn(CURRENT_NETWORK_TIME_MILLIS).when(() -> RescueParty.getElapsedRealtime());
RescueParty.resetAllThresholds();
+ FlagNamespaceUtils.resetKnownResetNamespacesFlagCounterForTest();
SystemProperties.set(RescueParty.PROP_RESCUE_LEVEL,
Integer.toString(RescueParty.LEVEL_NONE));
@@ -278,10 +296,32 @@ public class RescuePartyTest {
SystemProperties.getInt(RescueParty.PROP_RESCUE_LEVEL, RescueParty.LEVEL_NONE));
}
+ @Test
+ public void testNativeRescuePartyResets() {
+ doReturn(true).when(() -> SettingsToPropertiesMapper.isNativeFlagsResetPerformed());
+ doReturn(FAKE_RESET_NATIVE_NAMESPACES).when(
+ () -> SettingsToPropertiesMapper.getResetNativeCategories());
+
+ RescueParty.onSettingsProviderPublished(mMockContext);
+
+ verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ FAKE_NATIVE_NAMESPACE1));
+ verify(() -> DeviceConfig.resetToDefaults(Settings.RESET_MODE_TRUSTED_DEFAULTS,
+ FAKE_NATIVE_NAMESPACE2));
+
+ ExtendedMockito.verify(
+ () -> DeviceConfig.setProperty(FlagNamespaceUtils.NAMESPACE_RESCUE_PARTY,
+ FlagNamespaceUtils.RESET_PLATFORM_PACKAGE_FLAG + 0,
+ FAKE_NATIVE_NAMESPACE1, /*makeDefault=*/true));
+ ExtendedMockito.verify(
+ () -> DeviceConfig.setProperty(FlagNamespaceUtils.NAMESPACE_RESCUE_PARTY,
+ FlagNamespaceUtils.RESET_PLATFORM_PACKAGE_FLAG + 1,
+ FAKE_NATIVE_NAMESPACE2, /*makeDefault=*/true));
+ }
+
private void verifySettingsResets(int resetMode) {
verify(() -> Settings.Global.resetToDefaultsAsUser(mMockContentResolver, null,
- resetMode,
- UserHandle.USER_SYSTEM));
+ resetMode, UserHandle.USER_SYSTEM));
verify(() -> Settings.Secure.resetToDefaultsAsUser(eq(mMockContentResolver), isNull(),
eq(resetMode), anyInt()));
}
@@ -294,7 +334,7 @@ public class RescuePartyTest {
private void notePersistentAppCrash(int numTimes) {
for (int i = 0; i < numTimes; i++) {
- RescueParty.notePersistentAppCrash(mMockContext, PERSISTENT_APP_UID);
+ RescueParty.noteAppCrash(mMockContext, PERSISTENT_APP_UID);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index 72357ceee099..133e9f84092d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -15,6 +15,8 @@
*/
package com.android.server.pm;
+import static android.content.res.Resources.ID_NULL;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
@@ -454,7 +456,7 @@ public class PackageParserTest {
pkg.applicationInfo = new ApplicationInfo();
pkg.permissions.add(new PackageParser.Permission(pkg));
- pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg));
+ pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg, ID_NULL, ID_NULL, ID_NULL));
final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs(
pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0);
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index e4ab257c8d28..92198fa8cb0c 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -22,6 +22,7 @@ android_test {
"platform-test-annotations",
"hamcrest-library",
"testables",
+ "truth-prebuilt",
],
libs: [
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
index 19b567f6951b..88186cdb3873 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java
@@ -114,10 +114,10 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
@Test
public void testXmlUpgrade() {
- mAssistants.ensureAssistant();
+ mAssistants.resetDefaultAssistantsIfNecessary();
//once per user
- verify(mNm, times(mUm.getUsers().size())).readDefaultAssistant(anyInt());
+ verify(mNm, times(mUm.getUsers().size())).setDefaultAssistantForUser(anyInt());
}
@Test
@@ -132,7 +132,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
parser.nextTag();
mAssistants.readXml(parser, null, false, UserHandle.USER_ALL);
- verify(mNm, never()).readDefaultAssistant(anyInt());
+ verify(mNm, never()).setDefaultAssistantForUser(anyInt());
verify(mAssistants, times(1)).addApprovedList(
new ComponentName("b", "b").flattenToString(),10, true);
}
@@ -143,13 +143,13 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
ComponentName component2 = ComponentName.unflattenFromString("package/Component2");
mAssistants.setPackageOrComponentEnabled(component1.flattenToString(), mZero.id, true,
true);
- verify(mINm, never()).setNotificationAssistantAccessGrantedForUser(any(ComponentName.class),
- eq(mZero.id), anyBoolean());
+ verify(mNm, never()).setNotificationAssistantAccessGrantedForUserInternal(
+ any(ComponentName.class), eq(mZero.id), anyBoolean());
mAssistants.setPackageOrComponentEnabled(component2.flattenToString(), mZero.id, true,
true);
- verify(mINm, times(1)).setNotificationAssistantAccessGrantedForUser(component1, mZero.id,
- false);
+ verify(mNm, times(1)).setNotificationAssistantAccessGrantedForUserInternal(
+ component1, mZero.id, false);
}
@Test
@@ -159,7 +159,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
true);
mAssistants.setPackageOrComponentEnabled(component1.flattenToString(), mZero.id, true,
true);
- verify(mINm, never()).setNotificationAssistantAccessGrantedForUser(any(ComponentName.class),
- eq(mZero.id), anyBoolean());
+ verify(mNm, never()).setNotificationAssistantAccessGrantedForUserInternal(
+ any(ComponentName.class), eq(mZero.id), anyBoolean());
}
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 31788ae9b194..5df19410d55b 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -98,7 +98,9 @@ import android.os.IBinder;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.provider.DeviceConfig;
import android.provider.MediaStore;
+import android.provider.Settings;
import android.service.notification.Adjustment;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationStats;
@@ -111,9 +113,13 @@ import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.text.Html;
import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.AtomicFile;
+import androidx.annotation.Nullable;
+
import com.android.internal.R;
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.server.LocalServices;
import com.android.server.SystemService;
@@ -142,6 +148,7 @@ import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
@@ -153,6 +160,13 @@ import java.util.function.Consumer;
@RunWithLooper
public class NotificationManagerServiceTest extends UiServiceTestCase {
private static final String TEST_CHANNEL_ID = "NotificationManagerServiceTestChannelId";
+ private static final String CLEAR_DEVICE_CONFIG_KEY_CMD =
+ "device_config delete " + DeviceConfig.NAMESPACE_SYSTEMUI + " "
+ + SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE;
+ private static final String SET_DEFAULT_ASSISTANT_DEVICE_CONFIG_CMD =
+ "device_config put " + DeviceConfig.NAMESPACE_SYSTEMUI + " "
+ + SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE;
+
private final int mUid = Binder.getCallingUid();
private TestableNotificationManagerService mService;
private INotificationManager mBinderService;
@@ -208,6 +222,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
AppOpsManager mAppOpsManager;
@Mock
private UserManagerService mUserMangerService;
+ @Mock
+ private TestableNotificationManagerService.NotificationAssistantAccessGrantedCallback
+ mNotificationAssistantAccessGrantedCallback;
// Use a Testable subclass so we can simulate calls from the system without failing.
private static class TestableNotificationManagerService extends NotificationManagerService {
@@ -215,6 +232,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
boolean isSystemUid = true;
int countLogSmartSuggestionsVisible = 0;
UserManagerService mUserManagerService;
+ @Nullable
+ NotificationAssistantAccessGrantedCallback mNotificationAssistantAccessGrantedCallback;
TestableNotificationManagerService(Context context, UserManagerService userManagerService) {
super(context);
@@ -258,6 +277,26 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
UserManagerService getUserManagerService() {
return mUserManagerService;
}
+
+ @Override
+ protected void setNotificationAssistantAccessGrantedForUserInternal(
+ ComponentName assistant, int userId, boolean granted) {
+ if (mNotificationAssistantAccessGrantedCallback != null) {
+ mNotificationAssistantAccessGrantedCallback.onGranted(assistant, userId, granted);
+ return;
+ }
+ super.setNotificationAssistantAccessGrantedForUserInternal(assistant, userId, granted);
+ }
+
+ private void setNotificationAssistantAccessGrantedCallback(
+ @Nullable NotificationAssistantAccessGrantedCallback callback) {
+ this.mNotificationAssistantAccessGrantedCallback = callback;
+ }
+
+ interface NotificationAssistantAccessGrantedCallback {
+ void onGranted(ComponentName assistant, int userId, boolean granted);
+ }
+
}
private class TestableToastCallback extends ITransientNotification.Stub {
@@ -352,6 +391,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
@After
public void tearDown() throws Exception {
mFile.delete();
+ clearDeviceConfig();
}
public void waitForIdle() {
@@ -2029,6 +2069,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(mContext, times(1)).sendBroadcastAsUser(any(), eq(user), any());
verify(mAssistants, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), user.getIdentifier(), true, true);
+ verify(mAssistants).setUserSet(10, true);
verify(mConditionProviders, times(1)).setPackageOrComponentEnabled(
c.flattenToString(), user.getIdentifier(), false, true);
verify(mListeners, never()).setPackageOrComponentEnabled(
@@ -2518,7 +2559,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(mListeners, times(1)).migrateToXml();
verify(mConditionProviders, times(1)).migrateToXml();
verify(mAssistants, times(1)).migrateToXml();
- verify(mAssistants, never()).ensureAssistant();
+ verify(mAssistants, times(2)).resetDefaultAssistantsIfNecessary();
}
@Test
@@ -2538,7 +2579,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(mListeners, times(2)).migrateToXml();
verify(mConditionProviders, times(2)).migrateToXml();
verify(mAssistants, times(2)).migrateToXml();
- verify(mAssistants, never()).ensureAssistant();
+ verify(mAssistants, times(2)).resetDefaultAssistantsIfNecessary();
}
@Test
@@ -4101,4 +4142,78 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
verify(mListeners).notifyRemovedLocked(any(), anyInt(), captor.capture());
assertNotNull(captor.getValue());
}
+
+ @Test
+ public void setDefaultAssistantForUser_fromConfigXml() {
+ clearDeviceConfig();
+ ComponentName xmlConfig = new ComponentName("config", "xml");
+ when(mResources
+ .getString(
+ com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn(xmlConfig.flattenToString());
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mAssistants.queryPackageForServices(eq(null), anyInt(), eq(0)))
+ .thenReturn(Collections.singleton(xmlConfig));
+ mService.setNotificationAssistantAccessGrantedCallback(
+ mNotificationAssistantAccessGrantedCallback);
+
+ mService.setDefaultAssistantForUser(0);
+
+ verify(mNotificationAssistantAccessGrantedCallback)
+ .onGranted(eq(xmlConfig), eq(0), eq(true));
+ }
+
+ @Test
+ public void setDefaultAssistantForUser_fromDeviceConfig() {
+ ComponentName xmlConfig = new ComponentName("xml", "config");
+ ComponentName deviceConfig = new ComponentName("device", "config");
+ setDefaultAssistantInDeviceConfig(deviceConfig.flattenToString());
+ when(mResources
+ .getString(com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn(xmlConfig.flattenToString());
+ when(mContext.getResources()).thenReturn(mResources);
+ when(mAssistants.queryPackageForServices(eq(null), anyInt(), eq(0)))
+ .thenReturn(new ArraySet<>(Arrays.asList(xmlConfig, deviceConfig)));
+ mService.setNotificationAssistantAccessGrantedCallback(
+ mNotificationAssistantAccessGrantedCallback);
+
+ mService.setDefaultAssistantForUser(0);
+
+ verify(mNotificationAssistantAccessGrantedCallback)
+ .onGranted(eq(deviceConfig), eq(0), eq(true));
+ }
+
+ @Test
+ public void setDefaultAssistantForUser_deviceConfigInvalid() {
+ ComponentName xmlConfig = new ComponentName("xml", "config");
+ ComponentName deviceConfig = new ComponentName("device", "config");
+ setDefaultAssistantInDeviceConfig(deviceConfig.flattenToString());
+ when(mResources
+ .getString(com.android.internal.R.string.config_defaultAssistantAccessComponent))
+ .thenReturn(xmlConfig.flattenToString());
+ when(mContext.getResources()).thenReturn(mResources);
+ // Only xmlConfig is valid, deviceConfig is not.
+ when(mAssistants.queryPackageForServices(eq(null), anyInt(), eq(0)))
+ .thenReturn(Collections.singleton(xmlConfig));
+ mService.setNotificationAssistantAccessGrantedCallback(
+ mNotificationAssistantAccessGrantedCallback);
+
+ mService.setDefaultAssistantForUser(0);
+
+ verify(mNotificationAssistantAccessGrantedCallback)
+ .onGranted(eq(xmlConfig), eq(0), eq(true));
+ }
+
+ private void clearDeviceConfig() {
+ DeviceConfig.resetToDefaults(
+ Settings.RESET_MODE_PACKAGE_DEFAULTS, DeviceConfig.NAMESPACE_SYSTEMUI);
+ }
+
+ private void setDefaultAssistantInDeviceConfig(String componentName) {
+ DeviceConfig.setProperty(
+ DeviceConfig.NAMESPACE_SYSTEMUI,
+ SystemUiDeviceConfigFlags.NAS_DEFAULT_SERVICE,
+ componentName,
+ false);
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index 56f4a8544f00..85e8a1453e6f 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -40,13 +40,19 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
+import android.app.TaskStackListener;
+import android.content.pm.ActivityInfo;
+import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import org.junit.Before;
import org.junit.Test;
+import java.util.ArrayList;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.TimeUnit;
+
/**
* Tests for the {@link ActivityDisplay} class.
*
@@ -331,4 +337,45 @@ public class ActivityDisplayTests extends ActivityTestsBase {
verify(mSupervisor).removeTaskByIdLocked(eq(task1.taskId), anyBoolean(), anyBoolean(),
any());
}
+
+ /**
+ * Ensures that {@link TaskStackListener} can receive callback about the activity in size
+ * compatibility mode.
+ */
+ @Test
+ public void testHandleActivitySizeCompatMode() throws Exception {
+ final ActivityDisplay display = mRootActivityContainer.getDefaultDisplay();
+ final ActivityRecord activity = createFullscreenStackWithSimpleActivityAt(
+ display).topRunningActivityLocked();
+ activity.setState(ActivityStack.ActivityState.RESUMED, "testHandleActivitySizeCompatMode");
+ activity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+ activity.info.screenOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
+ activity.getTaskRecord().getConfiguration().windowConfiguration.getBounds().set(
+ 0, 0, 1000, 2000);
+
+ final ArrayList<CompletableFuture<IBinder>> resultWrapper = new ArrayList<>();
+ mService.getTaskChangeNotificationController().registerTaskStackListener(
+ new TaskStackListener() {
+ @Override
+ public void onSizeCompatModeActivityChanged(int displayId,
+ IBinder activityToken) {
+ resultWrapper.get(0).complete(activityToken);
+ }
+ });
+
+ // Expect the exact component name when the activity is in size compatible mode.
+ activity.getResolvedOverrideConfiguration().windowConfiguration.getBounds().set(
+ 0, 0, 800, 1600);
+ resultWrapper.add(new CompletableFuture<>());
+ display.handleActivitySizeCompatModeIfNeeded(activity);
+
+ assertEquals(activity.appToken, resultWrapper.get(0).get(2, TimeUnit.SECONDS));
+
+ // Expect null component name when switching to non-size-compat mode activity.
+ activity.info.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
+ resultWrapper.set(0, new CompletableFuture<>());
+ display.handleActivitySizeCompatModeIfNeeded(activity);
+
+ assertNull(resultWrapper.get(0).get(2, TimeUnit.SECONDS));
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 1319bad7a5ce..457d9c0f2dee 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -21,6 +21,7 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.any;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.anyInt;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doAnswer;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.eq;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
@@ -38,6 +39,7 @@ import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE_BEHIN
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
@@ -171,6 +173,24 @@ public class ActivityRecordTests extends ActivityTestsBase {
}
@Test
+ public void testRestartProcessIfVisible() {
+ doNothing().when(mSupervisor).scheduleRestartTimeout(mActivity);
+ mActivity.getParent().getWindowConfiguration().setAppBounds(0, 0, 500, 1000);
+ mActivity.visible = true;
+ mActivity.haveState = false;
+ mActivity.info.resizeMode = ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+ mActivity.info.maxAspectRatio = 1.5f;
+ mActivity.setState(ActivityStack.ActivityState.RESUMED, "testRestart");
+ final Rect originalOverrideBounds = new Rect(0, 0, 400, 600);
+ mActivity.setBounds(originalOverrideBounds);
+
+ mService.restartActivityProcessIfVisible(mActivity.appToken);
+
+ assertEquals(ActivityStack.ActivityState.RESTARTING_PROCESS, mActivity.getState());
+ assertNotEquals(originalOverrideBounds, mActivity.getBounds());
+ }
+
+ @Test
public void testsApplyOptionsLocked() {
ActivityOptions activityOptions = ActivityOptions.makeBasic();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index 606ab31f638e..d02db7b2af22 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -561,7 +561,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
runAndVerifyBackgroundActivityStartsSubtest("allowed_noStartsAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
}
/**
@@ -576,7 +576,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
"disallowed_unsupportedUsecase_aborted", true,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
}
/**
@@ -591,61 +591,66 @@ public class ActivityStarterTests extends ActivityTestsBase {
runAndVerifyBackgroundActivityStartsSubtest("disallowed_rootUid_notAborted", false,
Process.ROOT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest("disallowed_systemUid_notAborted", false,
Process.SYSTEM_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest("disallowed_nfcUid_notAborted", false,
Process.NFC_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callingUidHasVisibleWindow_notAborted", false,
UNIMPORTANT_UID, true, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callingUidProcessStateTop_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_realCallingUidHasVisibleWindow_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, true, PROCESS_STATE_TOP + 1,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_realCallingUidProcessStateTop_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP,
- false, false, false, false, false);
+ false, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_hasForegroundActivities_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- true, false, false, false, false);
+ true, false, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callerIsRecents_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, true, false, false, false);
+ false, true, false, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callerIsWhitelisted_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, true, false, false);
+ false, false, true, false, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callerIsInstrumentingWithBackgroundActivityStartPrivileges_notAborted",
false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, true, false);
+ false, false, false, true, false, false);
runAndVerifyBackgroundActivityStartsSubtest(
"disallowed_callingPackageNameIsDeviceOwner_notAborted", false,
UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
- false, false, false, false, true);
+ false, false, false, false, true, false);
+ runAndVerifyBackgroundActivityStartsSubtest(
+ "disallowed_callingPackageNameIsTempWhitelisted_notAborted", false,
+ UNIMPORTANT_UID, false, PROCESS_STATE_TOP + 1,
+ UNIMPORTANT_UID2, false, PROCESS_STATE_TOP + 1,
+ false, false, false, false, false, true);
}
private void runAndVerifyBackgroundActivityStartsSubtest(String name, boolean shouldHaveAborted,
@@ -654,7 +659,7 @@ public class ActivityStarterTests extends ActivityTestsBase {
boolean hasForegroundActivities, boolean callerIsRecents,
boolean callerIsTempWhitelisted,
boolean callerIsInstrumentingWithBackgroundActivityStartPrivileges,
- boolean isCallingPackageNameDeviceOwner) {
+ boolean isCallingPackageNameDeviceOwner, boolean isCallingPackageTempWhitelisted) {
// window visibility
doReturn(callingUidHasVisibleWindow).when(mService.mWindowManager.mRoot)
.isAnyNonToastWindowVisibleForUid(callingUid);
@@ -680,11 +685,15 @@ public class ActivityStarterTests extends ActivityTestsBase {
// caller is instrumenting with background activity starts privileges
callerApp.setInstrumenting(callerIsInstrumentingWithBackgroundActivityStartPrivileges,
callerIsInstrumentingWithBackgroundActivityStartPrivileges);
- // calling package name is whitelisted
+ // calling package name is the device owner
doReturn(isCallingPackageNameDeviceOwner).when(mService).isDeviceOwner(any());
+ // calling package name is temporarily whitelisted
+ doReturn(isCallingPackageTempWhitelisted).when(mService)
+ .isPackageNameWhitelistedForBgActivityStarts("com.whatever.dude");
final ActivityOptions options = spy(ActivityOptions.makeBasic());
ActivityStarter starter = prepareStarter(FLAG_ACTIVITY_NEW_TASK)
+ .setCallingPackage("com.whatever.dude")
.setCaller(caller)
.setCallingUid(callingUid)
.setRealCallingUid(realCallingUid)
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 57729b5450e3..1bf07233fc4d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -16,9 +16,6 @@
package com.android.server.voiceinteraction;
-import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
-import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
-import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
import static android.app.AppOpsManager.OP_ASSIST_SCREENSHOT;
import static android.app.AppOpsManager.OP_ASSIST_STRUCTURE;
import static android.content.Intent.FLAG_GRANT_READ_URI_PERMISSION;
@@ -26,6 +23,10 @@ import static android.content.Intent.FLAG_GRANT_WRITE_URI_PERMISSION;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION;
+import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
+import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
+import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
+
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.app.AppOpsManager;
@@ -256,7 +257,10 @@ final class VoiceInteractionSessionConnection implements ServiceConnection,
final Bundle assistData = data.getBundle(ASSIST_KEY_DATA);
final AssistStructure structure = data.getParcelable(ASSIST_KEY_STRUCTURE);
final AssistContent content = data.getParcelable(ASSIST_KEY_CONTENT);
- final int uid = data.getInt(Intent.EXTRA_ASSIST_UID, -1);
+ int uid = -1;
+ if (assistData != null) {
+ uid = assistData.getInt(Intent.EXTRA_ASSIST_UID, -1);
+ }
if (uid >= 0 && content != null) {
Intent intent = content.getIntent();
if (intent != null) {
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 9d46300b2b88..67477cf81109 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -3829,6 +3829,42 @@ public final class Telephony {
*/
public static final String CARRIER_ID = "carrier_id";
+ /**
+ * The skip 464xlat flag. Flag works as follows.
+ * {@link #SKIP_464XLAT_DEFAULT}: the APN will skip only APN is IMS and no internet.
+ * {@link #SKIP_464XLAT_DISABLE}: the APN will NOT skip 464xlat
+ * {@link #SKIP_464XLAT_ENABLE}: the APN will skip 464xlat
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final String SKIP_464XLAT = "skip_464xlat";
+
+ /**
+ * Possible value for the {@link #SKIP_464XLAT} field.
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final int SKIP_464XLAT_DEFAULT = -1;
+
+ /**
+ * Possible value for the {@link #SKIP_464XLAT} field.
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final int SKIP_464XLAT_DISABLE = 0;
+
+ /**
+ * Possible value for the {@link #SKIP_464XLAT} field.
+ * <p>Type: INTEGER</p>
+ *
+ * @hide
+ */
+ public static final int SKIP_464XLAT_ENABLE = 1;
+
+
/** @hide */
@IntDef({
UNEDITED,
@@ -3839,6 +3875,16 @@ public final class Telephony {
})
@Retention(RetentionPolicy.SOURCE)
public @interface EditStatus {}
+
+ /** @hide */
+ @IntDef({
+ SKIP_464XLAT_DEFAULT,
+ SKIP_464XLAT_DISABLE,
+ SKIP_464XLAT_ENABLE,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface Skip464XlatStatus {}
+
}
/**
diff --git a/telephony/java/android/telephony/NetworkRegistrationState.java b/telephony/java/android/telephony/NetworkRegistrationState.java
index a9d307953ced..a6c81db520a6 100644
--- a/telephony/java/android/telephony/NetworkRegistrationState.java
+++ b/telephony/java/android/telephony/NetworkRegistrationState.java
@@ -17,11 +17,13 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.AccessNetworkConstants.TransportType;
+import android.telephony.TelephonyManager.NetworkType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -140,6 +142,7 @@ public class NetworkRegistrationState implements Parcelable {
@ServiceState.RoamingType
private int mRoamingType;
+ @NetworkType
private int mAccessNetworkTechnology;
@NRStatus
@@ -149,6 +152,7 @@ public class NetworkRegistrationState implements Parcelable {
private final boolean mEmergencyOnly;
+ @ServiceType
private final int[] mAvailableServices;
@Nullable
@@ -167,9 +171,8 @@ public class NetworkRegistrationState implements Parcelable {
* @param regState Network registration state. Must be one of the {@link RegState}. For
* {@link TransportType#WLAN} transport, only {@link #REG_STATE_HOME} and
* {@link #REG_STATE_NOT_REG_NOT_SEARCHING} are valid states.
- * @param accessNetworkTechnology Access network technology. Must be one of TelephonyManager
- * NETWORK_TYPE_XXXX. For {@link TransportType#WLAN} transport, set to
- * {@link TelephonyManager#NETWORK_TYPE_IWLAN}.
+ * @param accessNetworkTechnology Access network technology.For {@link TransportType#WLAN}
+ * transport, set to {@link TelephonyManager#NETWORK_TYPE_IWLAN}.
* @param rejectCause Reason for denial if the registration state is {@link #REG_STATE_DENIED}.
* Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
* 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA. If
@@ -182,8 +185,9 @@ public class NetworkRegistrationState implements Parcelable {
* information is not available.
*/
public NetworkRegistrationState(@Domain int domain, int transportType, @RegState int regState,
- int accessNetworkTechnology, int rejectCause,
- boolean emergencyOnly, int[] availableServices,
+ @NetworkType int accessNetworkTechnology, int rejectCause,
+ boolean emergencyOnly,
+ @NonNull @ServiceType int[] availableServices,
@Nullable CellIdentity cellIdentity) {
mDomain = domain;
mTransportType = transportType;
@@ -230,7 +234,7 @@ public class NetworkRegistrationState implements Parcelable {
updateNrStatus(mDataSpecificStates);
}
- protected NetworkRegistrationState(Parcel source) {
+ private NetworkRegistrationState(Parcel source) {
mDomain = source.readInt();
mTransportType = source.readInt();
mRegState = source.readInt();
@@ -317,25 +321,29 @@ public class NetworkRegistrationState implements Parcelable {
/**
* @return List of available service types.
*/
+ @NonNull
+ @ServiceType
public int[] getAvailableServices() { return mAvailableServices; }
/**
- * @return The access network technology {@link TelephonyManager.NetworkType}.
+ * @return The access network technology {@link NetworkType}.
*/
- public @TelephonyManager.NetworkType int getAccessNetworkTechnology() {
+ public @NetworkType int getAccessNetworkTechnology() {
return mAccessNetworkTechnology;
}
/**
- * override the access network technology {@link TelephonyManager.NetworkType} e.g, rat ratchet.
+ * override the access network technology {@link NetworkType} e.g, rat ratchet.
* @hide
*/
- public void setAccessNetworkTechnology(@TelephonyManager.NetworkType int tech) {
+ public void setAccessNetworkTechnology(@NetworkType int tech) {
mAccessNetworkTechnology = tech;
}
/**
- * @return Network reject cause
+ * @return Reason for denial if the registration state is {@link #REG_STATE_DENIED}.
+ * Depending on {@code accessNetworkTechnology}, the values are defined in 3GPP TS 24.008
+ * 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2 A.S0001 6.2.2.44 for CDMA
*/
public int getRejectCause() {
return mRejectCause;
@@ -344,6 +352,7 @@ public class NetworkRegistrationState implements Parcelable {
/**
* @return The cell information.
*/
+ @Nullable
public CellIdentity getCellIdentity() {
return mCellIdentity;
}
@@ -547,4 +556,192 @@ public class NetworkRegistrationState implements Parcelable {
p.recycle();
return result;
}
+
+ /**
+ * Provides a convenient way to set the fields of a {@link NetworkRegistrationState} when
+ * creating a new instance.
+ *
+ * <p>The example below shows how you might create a new {@code NetworkRegistrationState}:
+ *
+ * <pre><code>
+ *
+ * NetworkRegistrationState nrs = new NetworkRegistrationState.Builder()
+ * .setApnTypeBitmask(ApnSetting.TYPE_DEFAULT | ApnSetting.TYPE_MMS)
+ * .setApnName("apn.example.com")
+ * .setEntryName("Example Carrier APN")
+ * .setMmsc(Uri.parse("http://mms.example.com:8002"))
+ * .setMmsProxyAddress(mmsProxy)
+ * .setMmsProxyPort(8799)
+ * .build();
+ * </code></pre>
+ */
+ public static class Builder{
+ @Domain
+ private int mDomain;
+
+ private int mTransportType;
+
+ @RegState
+ private int mRegState;
+
+ @ServiceState.RoamingType
+ private int mRoamingType;
+
+ @NetworkType
+ private int mAccessNetworkTechnology;
+
+ @NRStatus
+ private int mNrStatus;
+
+ private int mRejectCause;
+
+ private boolean mEmergencyOnly;
+
+ @ServiceType
+ private int[] mAvailableServices;
+
+ @Nullable
+ private CellIdentity mCellIdentity;
+
+ /**
+ * Default constructor for Builder.
+ */
+ public Builder() {}
+
+ /**
+ * Set the network domain.
+ *
+ * @param domain Network domain.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setDomain(@Domain int domain) {
+ mDomain = domain;
+ return this;
+ }
+
+ /**
+ * Set the transport type.
+ *
+ * @param transportType Transport type.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setTransportType(int transportType) {
+ mTransportType = transportType;
+ return this;
+ }
+
+ /**
+ * Set the registration state.
+ *
+ * @param regState The registration state.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setRegState(@RegState int regState) {
+ mRegState = regState;
+ return this;
+ }
+
+ /**
+ * Set the roaming type.
+ *
+ * @param roamingType Roaming type.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setRoamingType(@ServiceState.RoamingType int roamingType) {
+ mRoamingType = roamingType;
+ return this;
+ }
+
+ /**
+ * Set tne access network technology.
+ *
+ * @return The same instance of the builder.
+ *
+ * @param accessNetworkTechnology The access network technology
+ */
+ public @NonNull Builder setAccessNetworkTechnology(
+ @NetworkType int accessNetworkTechnology) {
+ mAccessNetworkTechnology = accessNetworkTechnology;
+ return this;
+ }
+
+ /**
+ * Set the 5G NR connection status.
+ *
+ * @param nrStatus 5G NR connection status.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setNrStatus(@NRStatus int nrStatus) {
+ mNrStatus = nrStatus;
+ return this;
+ }
+
+ /**
+ * Set the network reject cause.
+ *
+ * @param rejectCause Reason for denial if the registration state is
+ * {@link #REG_STATE_DENIED}.Depending on {@code accessNetworkTechnology}, the values are
+ * defined in 3GPP TS 24.008 10.5.3.6 for UMTS, 3GPP TS 24.301 9.9.3.9 for LTE, and 3GPP2
+ * A.S0001 6.2.2.44 for CDMA. If the reject cause is not supported or unknown, set it to 0.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setRejectCause(int rejectCause) {
+ mRejectCause = rejectCause;
+ return this;
+ }
+
+ /**
+ * Set emergency only.
+ *
+ * @param emergencyOnly True if this network registration is for emergency use only.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setEmergencyOnly(boolean emergencyOnly) {
+ mEmergencyOnly = emergencyOnly;
+ return this;
+ }
+
+ /**
+ * Set the available services.
+ *
+ * @param availableServices Available services.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setAvailableServices(
+ @NonNull @ServiceType int[] availableServices) {
+ mAvailableServices = availableServices;
+ return this;
+ }
+
+ /**
+ * Set the cell identity.
+ *
+ * @param cellIdentity The cell identity.
+ *
+ * @return The same instance of the builder.
+ */
+ public @NonNull Builder setCellIdentity(@Nullable CellIdentity cellIdentity) {
+ mCellIdentity = cellIdentity;
+ return this;
+ }
+
+ /**
+ * Build the NetworkRegistrationState.
+ *
+ * @return the NetworkRegistrationState object.
+ */
+ public @NonNull NetworkRegistrationState build() {
+ return new NetworkRegistrationState(mDomain, mTransportType, mRegState,
+ mAccessNetworkTechnology, mRejectCause, mEmergencyOnly, mAvailableServices,
+ mCellIdentity);
+ }
+ }
}
diff --git a/telephony/java/android/telephony/NetworkService.java b/telephony/java/android/telephony/NetworkService.java
index bec949406b6c..f1240e9fcf34 100644
--- a/telephony/java/android/telephony/NetworkService.java
+++ b/telephony/java/android/telephony/NetworkService.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.app.Service;
import android.content.Intent;
@@ -82,27 +83,30 @@ public abstract class NetworkService extends Service {
* service is associated with one physical SIM slot.
*/
public abstract class NetworkServiceProvider implements AutoCloseable {
- private final int mSlotId;
+ private final int mSlotIndex;
private final List<INetworkServiceCallback>
mNetworkRegistrationStateChangedCallbacks = new ArrayList<>();
- public NetworkServiceProvider(int slotId) {
- mSlotId = slotId;
+ /**
+ * Constructor
+ * @param slotIndex SIM slot id the data service provider associated with.
+ */
+ public NetworkServiceProvider(int slotIndex) {
+ mSlotIndex = slotIndex;
}
/**
- * @return SIM slot id the network service associated with.
+ * @return SIM slot index the network service associated with.
*/
- public final int getSlotId() {
- return mSlotId;
+ public final int getSlotIndex() {
+ return mSlotIndex;
}
/**
* API to get network registration state. The result will be passed to the callback.
* @param domain Network domain
* @param callback The callback for reporting network registration state
- * @return SIM slot id the network service associated with.
*/
public void getNetworkRegistrationState(@Domain int domain,
@NonNull NetworkServiceCallback callback) {
@@ -110,9 +114,12 @@ public abstract class NetworkService extends Service {
NetworkServiceCallback.RESULT_ERROR_UNSUPPORTED, null);
}
+ /**
+ * Notify the system that network registration state is changed.
+ */
public final void notifyNetworkRegistrationStateChanged() {
mHandler.obtainMessage(NETWORK_SERVICE_INDICATION_NETWORK_STATE_CHANGED,
- mSlotId, 0, null).sendToTarget();
+ mSlotIndex, 0, null).sendToTarget();
}
private void registerForStateChanged(@NonNull INetworkServiceCallback callback) {
@@ -154,23 +161,23 @@ public abstract class NetworkService extends Service {
@Override
public void handleMessage(Message message) {
- final int slotId = message.arg1;
+ final int slotIndex = message.arg1;
final INetworkServiceCallback callback = (INetworkServiceCallback) message.obj;
- NetworkServiceProvider serviceProvider = mServiceMap.get(slotId);
+ NetworkServiceProvider serviceProvider = mServiceMap.get(slotIndex);
switch (message.what) {
case NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER:
// If the service provider doesn't exist yet, we try to create it.
if (serviceProvider == null) {
- mServiceMap.put(slotId, createNetworkServiceProvider(slotId));
+ mServiceMap.put(slotIndex, onCreateNetworkServiceProvider(slotIndex));
}
break;
case NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER:
// If the service provider doesn't exist yet, we try to create it.
if (serviceProvider != null) {
serviceProvider.close();
- mServiceMap.remove(slotId);
+ mServiceMap.remove(slotIndex);
}
break;
case NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS:
@@ -223,12 +230,12 @@ public abstract class NetworkService extends Service {
* this method to facilitate the creation of {@link NetworkServiceProvider} instances. The system
* will call this method after binding the network service for each active SIM slot id.
*
- * @param slotId SIM slot id the network service associated with.
+ * @param slotIndex SIM slot id the network service associated with.
* @return Network service object
*/
- protected abstract NetworkServiceProvider createNetworkServiceProvider(int slotId);
+ @Nullable
+ public abstract NetworkServiceProvider onCreateNetworkServiceProvider(int slotIndex);
- /** @hide */
@Override
public IBinder onBind(Intent intent) {
if (intent == null || !NETWORK_SERVICE_INTERFACE.equals(intent.getAction())) {
@@ -239,7 +246,6 @@ public abstract class NetworkService extends Service {
return mBinder;
}
- /** @hide */
@Override
public boolean onUnbind(Intent intent) {
mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_ALL_NETWORK_SERVICE_PROVIDERS, 0,
@@ -252,6 +258,7 @@ public abstract class NetworkService extends Service {
@Override
public void onDestroy() {
mHandlerThread.quit();
+ super.onDestroy();
}
/**
@@ -261,35 +268,35 @@ public abstract class NetworkService extends Service {
private class INetworkServiceWrapper extends INetworkService.Stub {
@Override
- public void createNetworkServiceProvider(int slotId) {
- mHandler.obtainMessage(NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER, slotId,
+ public void createNetworkServiceProvider(int slotIndex) {
+ mHandler.obtainMessage(NETWORK_SERVICE_CREATE_NETWORK_SERVICE_PROVIDER, slotIndex,
0, null).sendToTarget();
}
@Override
- public void removeNetworkServiceProvider(int slotId) {
- mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER, slotId,
+ public void removeNetworkServiceProvider(int slotIndex) {
+ mHandler.obtainMessage(NETWORK_SERVICE_REMOVE_NETWORK_SERVICE_PROVIDER, slotIndex,
0, null).sendToTarget();
}
@Override
public void getNetworkRegistrationState(
- int slotId, int domain, INetworkServiceCallback callback) {
- mHandler.obtainMessage(NETWORK_SERVICE_GET_REGISTRATION_STATE, slotId,
+ int slotIndex, int domain, INetworkServiceCallback callback) {
+ mHandler.obtainMessage(NETWORK_SERVICE_GET_REGISTRATION_STATE, slotIndex,
domain, callback).sendToTarget();
}
@Override
public void registerForNetworkRegistrationStateChanged(
- int slotId, INetworkServiceCallback callback) {
- mHandler.obtainMessage(NETWORK_SERVICE_REGISTER_FOR_STATE_CHANGE, slotId,
+ int slotIndex, INetworkServiceCallback callback) {
+ mHandler.obtainMessage(NETWORK_SERVICE_REGISTER_FOR_STATE_CHANGE, slotIndex,
0, callback).sendToTarget();
}
@Override
public void unregisterForNetworkRegistrationStateChanged(
- int slotId,INetworkServiceCallback callback) {
- mHandler.obtainMessage(NETWORK_SERVICE_UNREGISTER_FOR_STATE_CHANGE, slotId,
+ int slotIndex, INetworkServiceCallback callback) {
+ mHandler.obtainMessage(NETWORK_SERVICE_UNREGISTER_FOR_STATE_CHANGE, slotIndex,
0, callback).sendToTarget();
}
}
diff --git a/telephony/java/android/telephony/NetworkServiceCallback.java b/telephony/java/android/telephony/NetworkServiceCallback.java
index dbad02fd5640..c2fcfb7a0759 100644
--- a/telephony/java/android/telephony/NetworkServiceCallback.java
+++ b/telephony/java/android/telephony/NetworkServiceCallback.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.IntDef;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.RemoteException;
import android.telephony.NetworkService.NetworkServiceProvider;
@@ -75,7 +76,8 @@ public class NetworkServiceCallback {
* {@link NetworkServiceCallback#RESULT_ERROR_UNSUPPORTED}
* @param state The state information to be returned to callback.
*/
- public void onGetNetworkRegistrationStateComplete(int result, NetworkRegistrationState state) {
+ public void onGetNetworkRegistrationStateComplete(int result,
+ @Nullable NetworkRegistrationState state) {
INetworkServiceCallback callback = mCallback.get();
if (callback != null) {
try {
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index 5fd36f4fb253..918bf60c9fa7 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -292,17 +292,16 @@ public class PhoneStateListener {
public static final int LISTEN_PHONE_CAPABILITY_CHANGE = 0x00200000;
/**
- * Listen for changes to active data subId. Active data subscription
- * is whichever is being used for Internet data. For most of the case, it's
- * default data subscription but it could be others. For example, when data is
- * switched to opportunistic subscription, that becomes the active data sub.
+ * Listen for changes to active data subId. Active data subscription is
+ * the current subscription used to setup Cellular Internet data. For example,
+ * it could be the current active opportunistic subscription in use, or the
+ * subscription user selected as default data subscription in DSDS mode.
*
* Requires Permission: {@link android.Manifest.permission#READ_PHONE_STATE
* READ_PHONE_STATE}
- * @see #onActiveDataSubIdChanged
- * @hide
+ * @see #onActiveDataSubscriptionIdChanged
*/
- public static final int LISTEN_ACTIVE_DATA_SUBID_CHANGE = 0x00400000;
+ public static final int LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE = 0x00400000;
/**
* Listen for changes to the radio power state.
@@ -709,12 +708,11 @@ public class PhoneStateListener {
/**
* Callback invoked when active data subId changes. Requires
* the READ_PHONE_STATE permission.
- * @param subId current data subId used for Internet data. It will be default data subscription
- * most cases. And it could be other subscriptions for example opportunistic
- * subscription if data is switched onto it.
- * @hide
+ * @param subId current subscription used to setup Cellular Internet data.
+ * For example, it could be the current active opportunistic subscription in use,
+ * or the subscription user selected as default data subscription in DSDS mode.
*/
- public void onActiveDataSubIdChanged(int subId) {
+ public void onActiveDataSubscriptionIdChanged(int subId) {
// default implementation empty
}
@@ -1003,7 +1001,7 @@ public class PhoneStateListener {
if (psl == null) return;
Binder.withCleanCallingIdentity(
- () -> mExecutor.execute(() -> psl.onActiveDataSubIdChanged(subId)));
+ () -> mExecutor.execute(() -> psl.onActiveDataSubscriptionIdChanged(subId)));
}
public void onImsCallDisconnectCauseChanged(ImsReasonInfo disconnectCause) {
diff --git a/telephony/java/android/telephony/RadioAccessFamily.java b/telephony/java/android/telephony/RadioAccessFamily.java
index 4fdfcbe045c3..48c07e8d54e1 100644
--- a/telephony/java/android/telephony/RadioAccessFamily.java
+++ b/telephony/java/android/telephony/RadioAccessFamily.java
@@ -22,6 +22,7 @@ import android.hardware.radio.V1_4.CellInfo.Info;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.TelephonyManager.PrefNetworkMode;
import com.android.internal.telephony.RILConstants;
@@ -170,7 +171,8 @@ public class RadioAccessFamily implements Parcelable {
};
@UnsupportedAppUsage
- public static int getRafFromNetworkType(int type) {
+ @TelephonyManager.NetworkTypeBitMask
+ public static int getRafFromNetworkType(@PrefNetworkMode int type) {
switch (type) {
case RILConstants.NETWORK_MODE_WCDMA_PREF:
return GSM | WCDMA;
@@ -279,6 +281,7 @@ public class RadioAccessFamily implements Parcelable {
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+ @PrefNetworkMode
public static int getNetworkTypeFromRaf(int raf) {
raf = getAdjustedRaf(raf);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index 683905e0cf24..bddf978cee78 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -438,7 +438,11 @@ public class ServiceState implements Parcelable {
/**
* Construct a ServiceState object from the given parcel.
+ *
+ * @deprecated The constructor takes parcel should not be public at the beginning. Use
+ * {@link #ServiceState()} instead.
*/
+ @Deprecated
public ServiceState(Parcel in) {
mVoiceRegState = in.readInt();
mDataRegState = in.readInt();
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index d7a0e50e5df7..8edc5b4f404a 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -2600,7 +2600,7 @@ public class SubscriptionManager {
@SystemApi
@RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
public void setPreferredDataSubscriptionId(int subId, boolean needValidation,
- @NonNull @CallbackExecutor Executor executor, Consumer<Integer> callback) {
+ @Nullable @CallbackExecutor Executor executor, @Nullable Consumer<Integer> callback) {
if (VDBG) logd("[setPreferredDataSubscriptionId]+ subId:" + subId);
try {
ISub iSub = ISub.Stub.asInterface(ServiceManager.getService("isub"));
@@ -2609,10 +2609,11 @@ public class SubscriptionManager {
ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
@Override
public void onComplete(int result) {
+ if (executor == null || callback == null) {
+ return;
+ }
Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
- if (callback != null) {
- callback.accept(result);
- }
+ callback.accept(result);
}));
}
};
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index aaf5f33346f5..04f3c6b395b2 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -81,6 +81,7 @@ import com.android.internal.telephony.CellNetworkScanResult;
import com.android.internal.telephony.INumberVerificationCallback;
import com.android.internal.telephony.IOns;
import com.android.internal.telephony.IPhoneSubInfo;
+import com.android.internal.telephony.ISetOpportunisticDataCallback;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephonyRegistry;
import com.android.internal.telephony.OperatorInfo;
@@ -98,6 +99,7 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.Executor;
+import java.util.function.Consumer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -6861,12 +6863,12 @@ public class TelephonyManager {
* app has carrier privileges (see {@link #hasCarrierPrivileges}).
*
* @param subId the id of the subscription to set the preferred network type for.
- * @param networkType the preferred network type, defined in RILConstants.java.
+ * @param networkType the preferred network type
* @return true on success; false on any failure.
* @hide
*/
@UnsupportedAppUsage
- public boolean setPreferredNetworkType(int subId, int networkType) {
+ public boolean setPreferredNetworkType(int subId, @PrefNetworkMode int networkType) {
try {
ITelephony telephony = getITelephony();
if (telephony != null) {
@@ -10185,21 +10187,40 @@ public class TelephonyManager {
* @param subId which opportunistic subscription
* {@link SubscriptionManager#getOpportunisticSubscriptions} is preferred for cellular data.
* Pass {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} to unset the preference
- * @return true if request is accepted, else false.
+ * @param needValidation whether validation is needed before switch happens.
+ * @param executor The executor of where the callback will execute.
+ * @param callback Callback will be triggered once it succeeds or failed.
+ * See {@link TelephonyManager.SetOpportunisticSubscriptionResult}
+ * for more details. Pass null if don't care about the result.
*
*/
- public boolean setPreferredOpportunisticDataSubscription(int subId) {
+ public void setPreferredOpportunisticDataSubscription(int subId, boolean needValidation,
+ @Nullable @CallbackExecutor Executor executor, @Nullable Consumer<Integer> callback) {
String pkgForDebug = mContext != null ? mContext.getOpPackageName() : "<unknown>";
try {
IOns iOpportunisticNetworkService = getIOns();
- if (iOpportunisticNetworkService != null) {
- return iOpportunisticNetworkService
- .setPreferredDataSubscriptionId(subId, pkgForDebug);
+ if (iOpportunisticNetworkService == null) {
+ return;
}
+ ISetOpportunisticDataCallback callbackStub = new ISetOpportunisticDataCallback.Stub() {
+ @Override
+ public void onComplete(int result) {
+ if (executor == null || callback == null) {
+ return;
+ }
+ Binder.withCleanCallingIdentity(() -> executor.execute(() -> {
+ callback.accept(result);
+ }));
+ }
+ };
+
+ iOpportunisticNetworkService
+ .setPreferredDataSubscriptionId(subId, needValidation, callbackStub,
+ pkgForDebug);
} catch (RemoteException ex) {
Rlog.e(TAG, "setPreferredDataSubscriptionId RemoteException", ex);
}
- return false;
+ return;
}
/**
@@ -10366,6 +10387,10 @@ public class TelephonyManager {
* <p>Requires Permission:
* {@link android.Manifest.permission#MODIFY_PHONE_STATE MODIFY_PHONE_STATE} or that the
* calling app has carrier privileges (see {@link #hasCarrierPrivileges}).
+ *
+ * Note: with only carrier privileges, it is not allowed to switch from multi-sim
+ * to single-sim
+ *
* @param numOfSims number of live SIMs we want to switch to
* @throws android.os.RemoteException
*/
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index 9d072f008bed..be6f3834e58e 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -61,6 +61,7 @@ public class ApnSetting implements Parcelable {
private static final String V4_FORMAT_REGEX = "^\\[ApnSettingV4\\]\\s*";
private static final String V5_FORMAT_REGEX = "^\\[ApnSettingV5\\]\\s*";
private static final String V6_FORMAT_REGEX = "^\\[ApnSettingV6\\]\\s*";
+ private static final String V7_FORMAT_REGEX = "^\\[ApnSettingV7\\]\\s*";
/**
* Default value for mtu if it's not set. Moved from PhoneConstants.
@@ -286,6 +287,8 @@ public class ApnSetting implements Parcelable {
private boolean mPermanentFailed = false;
private final int mCarrierId;
+ private final int mSkip464Xlat;
+
/**
* Returns the MTU size of the mobile interface to which the APN connected.
*
@@ -623,6 +626,17 @@ public class ApnSetting implements Parcelable {
return mCarrierId;
}
+ /**
+ * Returns the skip464xlat flag for this APN.
+ *
+ * @return SKIP_464XLAT_DEFAULT, SKIP_464XLAT_DISABLE or SKIP_464XLAT_ENABLE
+ * @hide
+ */
+ @Carriers.Skip464XlatStatus
+ public int getSkip464Xlat() {
+ return mSkip464Xlat;
+ }
+
private ApnSetting(Builder builder) {
this.mEntryName = builder.mEntryName;
this.mApnName = builder.mApnName;
@@ -651,6 +665,7 @@ public class ApnSetting implements Parcelable {
this.mMvnoMatchData = builder.mMvnoMatchData;
this.mApnSetId = builder.mApnSetId;
this.mCarrierId = builder.mCarrierId;
+ this.mSkip464Xlat = builder.mSkip464Xlat;
}
/**
@@ -662,7 +677,7 @@ public class ApnSetting implements Parcelable {
int authType, int mApnTypeBitmask, int protocol, int roamingProtocol,
boolean carrierEnabled, int networkTypeBitmask, int profileId,
boolean modemCognitive, int maxConns, int waitTime, int maxConnsTime, int mtu,
- int mvnoType, String mvnoMatchData, int apnSetId, int carrierId) {
+ int mvnoType, String mvnoMatchData, int apnSetId, int carrierId, int skip464xlat) {
return new Builder()
.setId(id)
.setOperatorNumeric(operatorNumeric)
@@ -691,6 +706,7 @@ public class ApnSetting implements Parcelable {
.setMvnoMatchData(mvnoMatchData)
.setApnSetId(apnSetId)
.setCarrierId(carrierId)
+ .setSkip464Xlat(skip464xlat)
.buildWithoutCheck();
}
@@ -708,7 +724,8 @@ public class ApnSetting implements Parcelable {
mmsc, mmsProxyAddress, mmsProxyPort, user, password, authType, mApnTypeBitmask,
protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, profileId,
modemCognitive, maxConns, waitTime, maxConnsTime, mtu, mvnoType, mvnoMatchData,
- Carriers.NO_APN_SET_ID, TelephonyManager.UNKNOWN_CARRIER_ID);
+ Carriers.NO_APN_SET_ID, TelephonyManager.UNKNOWN_CARRIER_ID,
+ Carriers.SKIP_464XLAT_DEFAULT);
}
/**
@@ -767,7 +784,8 @@ public class ApnSetting implements Parcelable {
cursor.getString(cursor.getColumnIndexOrThrow(
Telephony.Carriers.MVNO_MATCH_DATA)),
cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.APN_SET_ID)),
- cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.CARRIER_ID)));
+ cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers.CARRIER_ID)),
+ cursor.getInt(cursor.getColumnIndexOrThrow(Carriers.SKIP_464XLAT)));
}
/**
@@ -780,7 +798,7 @@ public class ApnSetting implements Parcelable {
apn.mProtocol, apn.mRoamingProtocol, apn.mCarrierEnabled, apn.mNetworkTypeBitmask,
apn.mProfileId, apn.mPersistent, apn.mMaxConns, apn.mWaitTime,
apn.mMaxConnsTime, apn.mMtu, apn.mMvnoType, apn.mMvnoMatchData, apn.mApnSetId,
- apn.mCarrierId);
+ apn.mCarrierId, apn.mSkip464Xlat);
}
/**
@@ -829,6 +847,13 @@ public class ApnSetting implements Parcelable {
* <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
* <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>, <carrierId>
*
+ * v7 format:
+ * [ApnSettingV7] <carrier>, <apn>, <proxy>, <port>, <user>, <password>, <server>,
+ * <mmsc>, <mmsproxy>, <mmsport>, <mcc>, <mnc>, <authtype>,
+ * <type>[| <type>...], <protocol>, <roaming_protocol>, <carrierEnabled>, <bearerBitmask>,
+ * <profileId>, <modemCognitive>, <maxConns>, <waitTime>, <maxConnsTime>, <mtu>,
+ * <mvnoType>, <mvnoMatchData>, <networkTypeBitmask>, <apnSetId>, <carrierId>, <skip464xlat>
+ *
* Note that the strings generated by {@link #toString()} do not contain the username
* and password and thus cannot be read by this method.
*
@@ -841,7 +866,10 @@ public class ApnSetting implements Parcelable {
int version;
// matches() operates on the whole string, so append .* to the regex.
- if (data.matches(V6_FORMAT_REGEX + ".*")) {
+ if (data.matches(V7_FORMAT_REGEX + ".*")) {
+ version = 7;
+ data = data.replaceFirst(V7_FORMAT_REGEX, "");
+ } else if (data.matches(V6_FORMAT_REGEX + ".*")) {
version = 6;
data = data.replaceFirst(V6_FORMAT_REGEX, "");
} else if (data.matches(V5_FORMAT_REGEX + ".*")) {
@@ -887,6 +915,7 @@ public class ApnSetting implements Parcelable {
String mvnoMatchData = "";
int apnSetId = Carriers.NO_APN_SET_ID;
int carrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+ int skip464xlat = Carriers.SKIP_464XLAT_DEFAULT;
if (version == 1) {
typeArray = new String[a.length - 13];
System.arraycopy(a, 13, typeArray, 0, a.length - 13);
@@ -933,6 +962,12 @@ public class ApnSetting implements Parcelable {
if (a.length > 28) {
carrierId = Integer.parseInt(a[28]);
}
+ if (a.length > 29) {
+ try {
+ skip464xlat = Integer.parseInt(a[29]);
+ } catch (NumberFormatException e) {
+ }
+ }
}
// If both bearerBitmask and networkTypeBitmask were specified, bearerBitmask would be
@@ -948,7 +983,7 @@ public class ApnSetting implements Parcelable {
getProtocolIntFromString(protocol), getProtocolIntFromString(roamingProtocol),
carrierEnabled, networkTypeBitmask, profileId, modemCognitive, maxConns, waitTime,
maxConnsTime, mtu, getMvnoTypeIntFromString(mvnoType), mvnoMatchData, apnSetId,
- carrierId);
+ carrierId, skip464xlat);
}
/**
@@ -984,7 +1019,7 @@ public class ApnSetting implements Parcelable {
*/
public String toString() {
StringBuilder sb = new StringBuilder();
- sb.append("[ApnSettingV6] ")
+ sb.append("[ApnSettingV7] ")
.append(mEntryName)
.append(", ").append(mId)
.append(", ").append(mOperatorNumeric)
@@ -1012,6 +1047,7 @@ public class ApnSetting implements Parcelable {
sb.append(", ").append(mNetworkTypeBitmask);
sb.append(", ").append(mApnSetId);
sb.append(", ").append(mCarrierId);
+ sb.append(", ").append(mSkip464Xlat);
return sb.toString();
}
@@ -1105,7 +1141,8 @@ public class ApnSetting implements Parcelable {
&& Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
&& Objects.equals(mNetworkTypeBitmask, other.mNetworkTypeBitmask)
&& Objects.equals(mApnSetId, other.mApnSetId)
- && Objects.equals(mCarrierId, other.mCarrierId);
+ && Objects.equals(mCarrierId, other.mCarrierId)
+ && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
}
/**
@@ -1151,7 +1188,8 @@ public class ApnSetting implements Parcelable {
&& Objects.equals(mMvnoType, other.mMvnoType)
&& Objects.equals(mMvnoMatchData, other.mMvnoMatchData)
&& Objects.equals(mApnSetId, other.mApnSetId)
- && Objects.equals(mCarrierId, other.mCarrierId);
+ && Objects.equals(mCarrierId, other.mCarrierId)
+ && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
}
/**
@@ -1179,7 +1217,8 @@ public class ApnSetting implements Parcelable {
&& xorEqualsInt(this.mMmsProxyPort, other.mMmsProxyPort))
&& Objects.equals(this.mNetworkTypeBitmask, other.mNetworkTypeBitmask)
&& Objects.equals(mApnSetId, other.mApnSetId)
- && Objects.equals(mCarrierId, other.mCarrierId);
+ && Objects.equals(mCarrierId, other.mCarrierId)
+ && Objects.equals(mSkip464Xlat, other.mSkip464Xlat);
}
// Equal or one is null.
@@ -1226,6 +1265,7 @@ public class ApnSetting implements Parcelable {
apnValue.put(Telephony.Carriers.MVNO_TYPE, getMvnoTypeStringFromInt(mMvnoType));
apnValue.put(Telephony.Carriers.NETWORK_TYPE_BITMASK, mNetworkTypeBitmask);
apnValue.put(Telephony.Carriers.CARRIER_ID, mCarrierId);
+ apnValue.put(Telephony.Carriers.SKIP_464XLAT, mSkip464Xlat);
return apnValue;
}
@@ -1385,6 +1425,7 @@ public class ApnSetting implements Parcelable {
dest.writeInt(mNetworkTypeBitmask);
dest.writeInt(mApnSetId);
dest.writeInt(mCarrierId);
+ dest.writeInt(mSkip464Xlat);
}
private static ApnSetting readFromParcel(Parcel in) {
@@ -1408,11 +1449,12 @@ public class ApnSetting implements Parcelable {
final int networkTypeBitmask = in.readInt();
final int apnSetId = in.readInt();
final int carrierId = in.readInt();
+ final int skip464xlat = in.readInt();
return makeApnSetting(id, operatorNumeric, entryName, apnName,
- proxy, port, mmsc, mmsProxy, mmsPort, user, password, authType, apnTypesBitmask,
- protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, 0, false,
- 0, 0, 0, 0, mvnoType, null, apnSetId, carrierId);
+ proxy, port, mmsc, mmsProxy, mmsPort, user, password, authType, apnTypesBitmask,
+ protocol, roamingProtocol, carrierEnabled, networkTypeBitmask, 0, false,
+ 0, 0, 0, 0, mvnoType, null, apnSetId, carrierId, skip464xlat);
}
public static final @android.annotation.NonNull Parcelable.Creator<ApnSetting> CREATOR =
@@ -1489,6 +1531,7 @@ public class ApnSetting implements Parcelable {
private String mMvnoMatchData;
private int mApnSetId;
private int mCarrierId = TelephonyManager.UNKNOWN_CARRIER_ID;
+ private int mSkip464Xlat = Carriers.SKIP_464XLAT_DEFAULT;
/**
* Default constructor for Builder.
@@ -1831,6 +1874,17 @@ public class ApnSetting implements Parcelable {
}
/**
+ * Sets skip464xlat flag for this APN.
+ *
+ * @param skip464xlat skip464xlat for this APN
+ * @hide
+ */
+ public Builder setSkip464Xlat(@Carriers.Skip464XlatStatus int skip464xlat) {
+ this.mSkip464Xlat = skip464xlat;
+ return this;
+ }
+
+ /**
* Builds {@link ApnSetting} from this builder.
*
* @return {@code null} if {@link #setApnName(String)} or {@link #setEntryName(String)}
diff --git a/telephony/java/android/telephony/data/DataCallResponse.java b/telephony/java/android/telephony/data/DataCallResponse.java
index 6024143493ec..0622cddcbb99 100644
--- a/telephony/java/android/telephony/data/DataCallResponse.java
+++ b/telephony/java/android/telephony/data/DataCallResponse.java
@@ -25,6 +25,8 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.telephony.data.ApnSetting.ProtocolType;
+import com.android.internal.annotations.VisibleForTesting;
+
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.List;
@@ -90,6 +92,8 @@ public final class DataCallResponse implements Parcelable {
mMtu = mtu;
}
+ /** @hide */
+ @VisibleForTesting
public DataCallResponse(Parcel source) {
mStatus = source.readInt();
mSuggestedRetryTime = source.readInt();
diff --git a/telephony/java/android/telephony/data/DataProfile.java b/telephony/java/android/telephony/data/DataProfile.java
index f45954bb390f..332aae156149 100644
--- a/telephony/java/android/telephony/data/DataProfile.java
+++ b/telephony/java/android/telephony/data/DataProfile.java
@@ -19,6 +19,8 @@ package android.telephony.data;
import static android.telephony.data.ApnSetting.ProtocolType;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.os.Build;
import android.os.Parcel;
@@ -158,6 +160,7 @@ public final class DataProfile implements Parcelable {
/**
* @return The APN to establish data connection.
*/
+ @NonNull
public String getApn() { return mApn; }
/**
@@ -173,11 +176,13 @@ public final class DataProfile implements Parcelable {
/**
* @return The username for APN. Can be null.
*/
+ @Nullable
public String getUserName() { return mUserName; }
/**
* @return The password for APN. Can be null.
*/
+ @Nullable
public String getPassword() { return mPassword; }
/**
diff --git a/telephony/java/android/telephony/data/DataService.java b/telephony/java/android/telephony/data/DataService.java
index a3fa77bd9b47..59d1e1e7115a 100644
--- a/telephony/java/android/telephony/data/DataService.java
+++ b/telephony/java/android/telephony/data/DataService.java
@@ -116,23 +116,23 @@ public abstract class DataService extends Service {
*/
public abstract class DataServiceProvider implements AutoCloseable {
- private final int mSlotId;
+ private final int mSlotIndex;
private final List<IDataServiceCallback> mDataCallListChangedCallbacks = new ArrayList<>();
/**
* Constructor
- * @param slotId SIM slot id the data service provider associated with.
+ * @param slotIndex SIM slot index the data service provider associated with.
*/
- public DataServiceProvider(int slotId) {
- mSlotId = slotId;
+ public DataServiceProvider(int slotIndex) {
+ mSlotIndex = slotIndex;
}
/**
- * @return SIM slot id the data service provider associated with.
+ * @return SIM slot index the data service provider associated with.
*/
- public final int getSlotId() {
- return mSlotId;
+ public final int getSlotIndex() {
+ return mSlotIndex;
}
/**
@@ -251,9 +251,9 @@ public abstract class DataService extends Service {
public final void notifyDataCallListChanged(List<DataCallResponse> dataCallList) {
synchronized (mDataCallListChangedCallbacks) {
for (IDataServiceCallback callback : mDataCallListChangedCallbacks) {
- mHandler.obtainMessage(DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED, mSlotId,
- 0, new DataCallListChangedIndication(dataCallList, callback))
- .sendToTarget();
+ mHandler.obtainMessage(DATA_SERVICE_INDICATION_DATA_CALL_LIST_CHANGED,
+ mSlotIndex, 0, new DataCallListChangedIndication(dataCallList,
+ callback)).sendToTarget();
}
}
}
@@ -342,20 +342,20 @@ public abstract class DataService extends Service {
@Override
public void handleMessage(Message message) {
IDataServiceCallback callback;
- final int slotId = message.arg1;
- DataServiceProvider serviceProvider = mServiceMap.get(slotId);
+ final int slotIndex = message.arg1;
+ DataServiceProvider serviceProvider = mServiceMap.get(slotIndex);
switch (message.what) {
case DATA_SERVICE_CREATE_DATA_SERVICE_PROVIDER:
- serviceProvider = createDataServiceProvider(message.arg1);
+ serviceProvider = onCreateDataServiceProvider(message.arg1);
if (serviceProvider != null) {
- mServiceMap.put(slotId, serviceProvider);
+ mServiceMap.put(slotIndex, serviceProvider);
}
break;
case DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER:
if (serviceProvider != null) {
serviceProvider.close();
- mServiceMap.remove(slotId);
+ mServiceMap.remove(slotIndex);
}
break;
case DATA_SERVICE_REMOVE_ALL_DATA_SERVICE_PROVIDERS:
@@ -454,12 +454,12 @@ public abstract class DataService extends Service {
* this method to facilitate the creation of {@link DataServiceProvider} instances. The system
* will call this method after binding the data service for each active SIM slot id.
*
- * @param slotId SIM slot id the data service associated with.
+ * @param slotIndex SIM slot id the data service associated with.
* @return Data service object
*/
- public abstract DataServiceProvider createDataServiceProvider(int slotId);
+ @Nullable
+ public abstract DataServiceProvider onCreateDataServiceProvider(int slotIndex);
- /** @hide */
@Override
public IBinder onBind(Intent intent) {
if (intent == null || !DATA_SERVICE_INTERFACE.equals(intent.getAction())) {
@@ -469,17 +469,16 @@ public abstract class DataService extends Service {
return mBinder;
}
- /** @hide */
@Override
public boolean onUnbind(Intent intent) {
mHandler.obtainMessage(DATA_SERVICE_REMOVE_ALL_DATA_SERVICE_PROVIDERS).sendToTarget();
return false;
}
- /** @hide */
@Override
public void onDestroy() {
mHandlerThread.quit();
+ super.onDestroy();
}
/**
@@ -487,78 +486,78 @@ public abstract class DataService extends Service {
*/
private class IDataServiceWrapper extends IDataService.Stub {
@Override
- public void createDataServiceProvider(int slotId) {
- mHandler.obtainMessage(DATA_SERVICE_CREATE_DATA_SERVICE_PROVIDER, slotId, 0)
+ public void createDataServiceProvider(int slotIndex) {
+ mHandler.obtainMessage(DATA_SERVICE_CREATE_DATA_SERVICE_PROVIDER, slotIndex, 0)
.sendToTarget();
}
@Override
- public void removeDataServiceProvider(int slotId) {
- mHandler.obtainMessage(DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER, slotId, 0)
+ public void removeDataServiceProvider(int slotIndex) {
+ mHandler.obtainMessage(DATA_SERVICE_REMOVE_DATA_SERVICE_PROVIDER, slotIndex, 0)
.sendToTarget();
}
@Override
- public void setupDataCall(int slotId, int accessNetworkType, DataProfile dataProfile,
+ public void setupDataCall(int slotIndex, int accessNetworkType, DataProfile dataProfile,
boolean isRoaming, boolean allowRoaming, int reason,
LinkProperties linkProperties, IDataServiceCallback callback) {
- mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, slotId, 0,
+ mHandler.obtainMessage(DATA_SERVICE_REQUEST_SETUP_DATA_CALL, slotIndex, 0,
new SetupDataCallRequest(accessNetworkType, dataProfile, isRoaming,
allowRoaming, reason, linkProperties, callback))
.sendToTarget();
}
@Override
- public void deactivateDataCall(int slotId, int cid, int reason,
+ public void deactivateDataCall(int slotIndex, int cid, int reason,
IDataServiceCallback callback) {
- mHandler.obtainMessage(DATA_SERVICE_REQUEST_DEACTIVATE_DATA_CALL, slotId, 0,
+ mHandler.obtainMessage(DATA_SERVICE_REQUEST_DEACTIVATE_DATA_CALL, slotIndex, 0,
new DeactivateDataCallRequest(cid, reason, callback))
.sendToTarget();
}
@Override
- public void setInitialAttachApn(int slotId, DataProfile dataProfile, boolean isRoaming,
+ public void setInitialAttachApn(int slotIndex, DataProfile dataProfile, boolean isRoaming,
IDataServiceCallback callback) {
- mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_INITIAL_ATTACH_APN, slotId, 0,
+ mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_INITIAL_ATTACH_APN, slotIndex, 0,
new SetInitialAttachApnRequest(dataProfile, isRoaming, callback))
.sendToTarget();
}
@Override
- public void setDataProfile(int slotId, List<DataProfile> dps, boolean isRoaming,
+ public void setDataProfile(int slotIndex, List<DataProfile> dps, boolean isRoaming,
IDataServiceCallback callback) {
- mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_DATA_PROFILE, slotId, 0,
+ mHandler.obtainMessage(DATA_SERVICE_REQUEST_SET_DATA_PROFILE, slotIndex, 0,
new SetDataProfileRequest(dps, isRoaming, callback)).sendToTarget();
}
@Override
- public void getDataCallList(int slotId, IDataServiceCallback callback) {
+ public void getDataCallList(int slotIndex, IDataServiceCallback callback) {
if (callback == null) {
loge("getDataCallList: callback is null");
return;
}
- mHandler.obtainMessage(DATA_SERVICE_REQUEST_GET_DATA_CALL_LIST, slotId, 0,
+ mHandler.obtainMessage(DATA_SERVICE_REQUEST_GET_DATA_CALL_LIST, slotIndex, 0,
callback).sendToTarget();
}
@Override
- public void registerForDataCallListChanged(int slotId, IDataServiceCallback callback) {
+ public void registerForDataCallListChanged(int slotIndex, IDataServiceCallback callback) {
if (callback == null) {
loge("registerForDataCallListChanged: callback is null");
return;
}
- mHandler.obtainMessage(DATA_SERVICE_REQUEST_REGISTER_DATA_CALL_LIST_CHANGED, slotId,
+ mHandler.obtainMessage(DATA_SERVICE_REQUEST_REGISTER_DATA_CALL_LIST_CHANGED, slotIndex,
0, callback).sendToTarget();
}
@Override
- public void unregisterForDataCallListChanged(int slotId, IDataServiceCallback callback) {
+ public void unregisterForDataCallListChanged(int slotIndex, IDataServiceCallback callback) {
if (callback == null) {
loge("unregisterForDataCallListChanged: callback is null");
return;
}
- mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_DATA_CALL_LIST_CHANGED, slotId,
- 0, callback).sendToTarget();
+ mHandler.obtainMessage(DATA_SERVICE_REQUEST_UNREGISTER_DATA_CALL_LIST_CHANGED,
+ slotIndex, 0, callback).sendToTarget();
}
}
diff --git a/telephony/java/android/telephony/data/DataServiceCallback.java b/telephony/java/android/telephony/data/DataServiceCallback.java
index bef11425b470..2d0cfe80366c 100644
--- a/telephony/java/android/telephony/data/DataServiceCallback.java
+++ b/telephony/java/android/telephony/data/DataServiceCallback.java
@@ -17,6 +17,8 @@
package android.telephony.data;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.LinkProperties;
import android.os.RemoteException;
@@ -74,7 +76,8 @@ public class DataServiceCallback {
* @param result The result code. Must be one of the {@link ResultCode}.
* @param response Setup data call response.
*/
- public void onSetupDataCallComplete(@ResultCode int result, DataCallResponse response) {
+ public void onSetupDataCallComplete(@ResultCode int result,
+ @Nullable DataCallResponse response) {
IDataServiceCallback callback = mCallback.get();
if (callback != null) {
try {
@@ -141,10 +144,11 @@ public class DataServiceCallback {
* DataServiceCallback)}.
*
* @param result The result code. Must be one of the {@link ResultCode}.
- * @param dataCallList List of the current active data connection.
+ * @param dataCallList List of the current active data connection. If no data call is presented,
+ * set it to an empty list.
*/
public void onGetDataCallListComplete(@ResultCode int result,
- List<DataCallResponse> dataCallList) {
+ @NonNull List<DataCallResponse> dataCallList) {
IDataServiceCallback callback = mCallback.get();
if (callback != null) {
try {
@@ -156,11 +160,12 @@ public class DataServiceCallback {
}
/**
- * Called to indicate that data connection list changed.
+ * Called to indicate that data connection list changed. If no data call is presented, set it to
+ * an empty list.
*
* @param dataCallList List of the current active data connection.
*/
- public void onDataCallListChanged(List<DataCallResponse> dataCallList) {
+ public void onDataCallListChanged(@NonNull List<DataCallResponse> dataCallList) {
IDataServiceCallback callback = mCallback.get();
if (callback != null) {
try {
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index ac4d17a0ce65..bdaad5bffe5e 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -86,7 +86,8 @@ public class ImsException extends Exception {
* @param message an optional message to detail the error condition more specifically.
* @param cause the {@link Throwable} that caused this {@link ImsException} to be created.
*/
- public ImsException(@Nullable String message, @ImsErrorCode int code, Throwable cause) {
+ public ImsException(@Nullable String message, @ImsErrorCode int code,
+ @Nullable Throwable cause) {
super(getMessage(message, code), cause);
mCode = code;
}
diff --git a/telephony/java/android/telephony/ims/ImsExternalCallState.java b/telephony/java/android/telephony/ims/ImsExternalCallState.java
index a58f361e6601..37b11eda6916 100644
--- a/telephony/java/android/telephony/ims/ImsExternalCallState.java
+++ b/telephony/java/android/telephony/ims/ImsExternalCallState.java
@@ -17,6 +17,8 @@
package android.telephony.ims;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.Uri;
import android.os.Parcel;
@@ -124,9 +126,9 @@ public final class ImsExternalCallState implements Parcelable {
* @param callType The type of external call.
* @param isCallheld A flag determining if the external connection is currently held.
*/
- public ImsExternalCallState(String callId, Uri address, Uri localAddress,
- boolean isPullable, @ExternalCallState int callState, @ExternalCallType int callType,
- boolean isCallheld) {
+ public ImsExternalCallState(@NonNull String callId, @NonNull Uri address,
+ @Nullable Uri localAddress, boolean isPullable, @ExternalCallState int callState,
+ @ExternalCallType int callType, boolean isCallheld) {
mCallId = getIdForString(callId);
mAddress = address;
mLocalAddress = localAddress;
@@ -184,14 +186,14 @@ public final class ImsExternalCallState implements Parcelable {
return mCallId;
}
- public Uri getAddress() {
+ public @NonNull Uri getAddress() {
return mAddress;
}
/**
* @return A {@link Uri} containing the local address from the Multiendpoint Dialog Information.
*/
- public Uri getLocalAddress() {
+ public @Nullable Uri getLocalAddress() {
return mLocalAddress;
}
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index bb85be16eb3a..58ddf21888fc 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -21,6 +21,7 @@ import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.content.Context;
@@ -199,7 +200,7 @@ public class ImsMmTelManager {
*
* @param info the {@link ImsReasonInfo} associated with why registration was disconnected.
*/
- public void onUnregistered(ImsReasonInfo info) {
+ public void onUnregistered(@Nullable ImsReasonInfo info) {
}
/**
@@ -211,7 +212,7 @@ public class ImsMmTelManager {
* transport type that has failed to handover registration to.
* @param info A {@link ImsReasonInfo} that identifies the reason for failure.
*/
- public void onTechnologyChangeFailed(int imsTransportType, ImsReasonInfo info) {
+ public void onTechnologyChangeFailed(int imsTransportType, @Nullable ImsReasonInfo info) {
}
/**
@@ -223,7 +224,7 @@ public class ImsMmTelManager {
* subscription.
* @hide
*/
- public void onSubscriberAssociatedUriChanged(Uri[] uris) {
+ public void onSubscriberAssociatedUriChanged(@Nullable Uri[] uris) {
}
/**@hide*/
@@ -294,7 +295,7 @@ public class ImsMmTelManager {
* @param capabilities The new availability of the capabilities.
*/
public void onCapabilitiesStatusChanged(
- MmTelFeature.MmTelCapabilities capabilities) {
+ @NonNull MmTelFeature.MmTelCapabilities capabilities) {
}
/**@hide*/
@@ -319,7 +320,7 @@ public class ImsMmTelManager {
* @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
* @throws IllegalArgumentException if the subscription is invalid.
*/
- public static ImsMmTelManager createForSubscriptionId(int subId) {
+ public static @NonNull ImsMmTelManager createForSubscriptionId(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid subscription ID");
}
@@ -357,7 +358,7 @@ public class ImsMmTelManager {
* reason.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void registerImsRegistrationCallback(@CallbackExecutor Executor executor,
+ public void registerImsRegistrationCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull RegistrationCallback c) throws ImsException {
if (c == null) {
throw new IllegalArgumentException("Must include a non-null RegistrationCallback.");
diff --git a/telephony/java/android/telephony/ims/ProvisioningManager.java b/telephony/java/android/telephony/ims/ProvisioningManager.java
index 6e98a0af244a..9104d9f4f110 100644
--- a/telephony/java/android/telephony/ims/ProvisioningManager.java
+++ b/telephony/java/android/telephony/ims/ProvisioningManager.java
@@ -19,6 +19,7 @@ package android.telephony.ims;
import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.WorkerThread;
@@ -177,7 +178,7 @@ public class ProvisioningManager {
* @see android.telephony.SubscriptionManager#getActiveSubscriptionInfoList()
* @throws IllegalArgumentException if the subscription is invalid.
*/
- public static ProvisioningManager createForSubscriptionId(int subId) {
+ public static @NonNull ProvisioningManager createForSubscriptionId(int subId) {
if (!SubscriptionManager.isValidSubscriptionId(subId)) {
throw new IllegalArgumentException("Invalid subscription ID");
}
@@ -206,7 +207,7 @@ public class ProvisioningManager {
* reason.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public void registerProvisioningChangedCallback(@CallbackExecutor Executor executor,
+ public void registerProvisioningChangedCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull Callback callback) throws ImsException {
callback.setExecutor(executor);
try {
@@ -271,7 +272,7 @@ public class ProvisioningManager {
*/
@WorkerThread
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
- public String getProvisioningStringValue(int key) {
+ public @Nullable String getProvisioningStringValue(int key) {
try {
return getITelephony().getImsProvisioningString(mSubId, key);
} catch (RemoteException e) {
@@ -313,7 +314,7 @@ public class ProvisioningManager {
@WorkerThread
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public @ImsConfigImplBase.SetConfigResult int setProvisioningStringValue(int key,
- String value) {
+ @NonNull String value) {
try {
return getITelephony().setImsProvisioningString(mSubId, key, value);
} catch (RemoteException e) {
diff --git a/telephony/java/com/android/internal/telephony/IOns.aidl b/telephony/java/com/android/internal/telephony/IOns.aidl
index 0e3d12b7f838..0364477ead8c 100755
--- a/telephony/java/com/android/internal/telephony/IOns.aidl
+++ b/telephony/java/com/android/internal/telephony/IOns.aidl
@@ -18,6 +18,8 @@ package com.android.internal.telephony;
import android.telephony.AvailableNetworkInfo;
+import com.android.internal.telephony.ISetOpportunisticDataCallback;
+
interface IOns {
/**
@@ -62,11 +64,13 @@ interface IOns {
* @param subId which opportunistic subscription
* {@link SubscriptionManager#getOpportunisticSubscriptions} is preferred for cellular data.
* Pass {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} to unset the preference
+ * @param needValidation whether validation is needed before switch happens.
+ * @param callback callback upon request completion.
* @param callingPackage caller's package name
- * @return true if request is accepted, else false.
*
*/
- boolean setPreferredDataSubscriptionId(int subId, String callingPackage);
+ void setPreferredDataSubscriptionId(int subId, boolean needValidation,
+ ISetOpportunisticDataCallback callbackStub, String callingPackage);
/**
* Get preferred opportunistic data subscription Id
diff --git a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
index 598f60ad7c8d..d0c261279c9d 100644
--- a/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
+++ b/tests/PackageWatchdog/src/com/android/server/PackageWatchdogTest.java
@@ -77,11 +77,12 @@ public class PackageWatchdogTest {
TestObserver observer3 = new TestObserver(OBSERVER_NAME_3);
// Start observing for observer1 which will be unregistered
- watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
// Start observing for observer2 which will expire
- watchdog.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION,
+ false);
// Start observing for observer3 which will have expiry duration reduced
- watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), LONG_DURATION);
+ watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), LONG_DURATION, false);
// Verify packages observed at start
// 1
@@ -144,8 +145,9 @@ public class PackageWatchdogTest {
TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
- watchdog1.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
- watchdog1.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION);
+ watchdog1.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
+ watchdog1.startObservingHealth(observer2, Arrays.asList(APP_A, APP_B), SHORT_DURATION,
+ false);
// Verify 2 observers are registered and saved internally
// 1
@@ -191,8 +193,8 @@ public class PackageWatchdogTest {
TestObserver observer1 = new TestObserver(OBSERVER_NAME_1);
TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
- watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
- watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false);
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
// Then fail APP_A below the threshold
for (int i = 0; i < TRIGGER_FAILURE_COUNT - 1; i++) {
@@ -218,8 +220,8 @@ public class PackageWatchdogTest {
TestObserver observer2 = new TestObserver(OBSERVER_NAME_2);
- watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
- watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false);
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_B), SHORT_DURATION, false);
// Then fail APP_C (not observed) above the threshold
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -253,7 +255,7 @@ public class PackageWatchdogTest {
}
};
- watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.startObservingHealth(observer, Arrays.asList(APP_A), SHORT_DURATION, false);
// Then fail APP_A (different version) above the threshold
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -286,13 +288,13 @@ public class PackageWatchdogTest {
// Start observing for all impact observers
watchdog.startObservingHealth(observerNone, Arrays.asList(APP_A, APP_B, APP_C, APP_D),
- SHORT_DURATION);
+ SHORT_DURATION, false);
watchdog.startObservingHealth(observerHigh, Arrays.asList(APP_A, APP_B, APP_C),
- SHORT_DURATION);
+ SHORT_DURATION, false);
watchdog.startObservingHealth(observerMid, Arrays.asList(APP_A, APP_B),
- SHORT_DURATION);
+ SHORT_DURATION, false);
watchdog.startObservingHealth(observerLow, Arrays.asList(APP_A),
- SHORT_DURATION);
+ SHORT_DURATION, false);
// Then fail all apps above the threshold
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -344,8 +346,8 @@ public class PackageWatchdogTest {
PackageHealthObserverImpact.USER_IMPACT_MEDIUM);
// Start observing for observerFirst and observerSecond with failure handling
- watchdog.startObservingHealth(observerFirst, Arrays.asList(APP_A), LONG_DURATION);
- watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION);
+ watchdog.startObservingHealth(observerFirst, Arrays.asList(APP_A), LONG_DURATION, false);
+ watchdog.startObservingHealth(observerSecond, Arrays.asList(APP_A), LONG_DURATION, false);
// Then fail APP_A above the threshold
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -422,8 +424,8 @@ public class PackageWatchdogTest {
PackageHealthObserverImpact.USER_IMPACT_HIGH);
// Start observing for observer1 and observer2 with failure handling
- watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION);
- watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_A), SHORT_DURATION, false);
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, false);
// Then fail APP_A above the threshold
for (int i = 0; i < TRIGGER_FAILURE_COUNT; i++) {
@@ -439,6 +441,49 @@ public class PackageWatchdogTest {
assertEquals(0, observer2.mFailedPackages.size());
}
+ /**
+ * Test explicit health check status determines package failure or success on expiry
+ */
+ @Test
+ public void testPackageFailureExplicitHealthCheck() throws Exception {
+ PackageWatchdog watchdog = createWatchdog();
+ TestObserver observer1 = new TestObserver(OBSERVER_NAME_1,
+ PackageHealthObserverImpact.USER_IMPACT_HIGH);
+ TestObserver observer2 = new TestObserver(OBSERVER_NAME_2,
+ PackageHealthObserverImpact.USER_IMPACT_HIGH);
+ TestObserver observer3 = new TestObserver(OBSERVER_NAME_3,
+ PackageHealthObserverImpact.USER_IMPACT_HIGH);
+
+
+ // Start observing with explicit health checks for APP_A and APP_B respectively
+ // with observer1 and observer2
+ watchdog.startObservingHealth(observer1, Arrays.asList(APP_A), SHORT_DURATION, true);
+ watchdog.startObservingHealth(observer2, Arrays.asList(APP_B), SHORT_DURATION, true);
+ // Explicit health check passed for APP_A (observer1 is aware)
+ watchdog.onExplicitHealthCheckPassed(APP_A);
+ // Start observing APP_A with explicit health checks for observer3.
+ // Observer3 didn't exist when we got the explicit health check above, so
+ // it starts out with a non-passing explicit health check and has to wait for a pass
+ // otherwise it would be notified of APP_A failure on expiry
+ watchdog.startObservingHealth(observer3, Arrays.asList(APP_A), SHORT_DURATION, true);
+
+ // Then expire observers
+ Thread.sleep(SHORT_DURATION);
+ // Run handler so package failures are dispatched to observers
+ mTestLooper.dispatchAll();
+
+ // Verify observer1 is not notified
+ assertEquals(0, observer1.mFailedPackages.size());
+
+ // Verify observer2 is notifed because health checks for APP_B never passed
+ assertEquals(1, observer2.mFailedPackages.size());
+ assertEquals(APP_B, observer2.mFailedPackages.get(0));
+
+ // Verify observer3 is notifed because health checks for APP_A did not pass before expiry
+ assertEquals(1, observer3.mFailedPackages.size());
+ assertEquals(APP_A, observer3.mFailedPackages.get(0));
+ }
+
private PackageWatchdog createWatchdog() {
return new PackageWatchdog(InstrumentationRegistry.getContext(),
mTestLooper.getLooper());
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
index 4780f30d5f7f..7e183db58fb4 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTest.java
@@ -379,6 +379,83 @@ public class RollbackTest {
// Check that the data has expired after the expiration time (with a buffer of 1 second)
Thread.sleep(expirationTime / 2);
assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+
+ } finally {
+ DeviceConfig.setProperty(DeviceConfig.Rollback.BOOT_NAMESPACE,
+ DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS,
+ Long.toString(defaultExpirationTime), false /* makeDefault*/);
+ RollbackTestUtils.dropShellPermissionIdentity();
+ }
+ }
+
+ /**
+ * Test that changing time on device does not affect the duration of time that we keep
+ * rollback available
+ */
+ @Test
+ public void testTimeChangeDoesNotAffectLifetime() throws Exception {
+ long expirationTime = TimeUnit.SECONDS.toMillis(30);
+ long defaultExpirationTime = TimeUnit.HOURS.toMillis(48);
+ RollbackManager rm = RollbackTestUtils.getRollbackManager();
+
+ try {
+ RollbackTestUtils.adoptShellPermissionIdentity(
+ Manifest.permission.INSTALL_PACKAGES,
+ Manifest.permission.DELETE_PACKAGES,
+ Manifest.permission.MANAGE_ROLLBACKS,
+ Manifest.permission.WRITE_DEVICE_CONFIG,
+ Manifest.permission.SET_TIME);
+
+ DeviceConfig.setProperty(DeviceConfig.Rollback.BOOT_NAMESPACE,
+ DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS,
+ Long.toString(expirationTime), false /* makeDefault*/);
+
+ // Pull the new expiration time from DeviceConfig
+ rm.reloadPersistedData();
+
+ // Install app A with rollback enabled
+ RollbackTestUtils.uninstall(TEST_APP_A);
+ RollbackTestUtils.install("RollbackTestAppAv1.apk", false);
+ RollbackTestUtils.install("RollbackTestAppAv2.apk", true);
+ assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_A));
+
+ Thread.sleep(expirationTime / 2);
+
+ // Install app B with rollback enabled
+ RollbackTestUtils.uninstall(TEST_APP_B);
+ RollbackTestUtils.install("RollbackTestAppBv1.apk", false);
+ RollbackTestUtils.install("RollbackTestAppBv2.apk", true);
+ assertEquals(2, RollbackTestUtils.getInstalledVersion(TEST_APP_B));
+ // 1 second buffer
+ Thread.sleep(1000);
+
+ try {
+ // Change the time
+ RollbackTestUtils.forwardTimeBy(expirationTime);
+
+ // 1 second buffer to allow Rollback Manager to handle time change before loading
+ // persisted data
+ Thread.sleep(1000);
+
+ // Load timestamps from storage
+ rm.reloadPersistedData();
+
+ // Wait until rollback for app A has expired
+ // This will trigger an expiration run that should expire app A but not B
+ Thread.sleep(expirationTime / 2);
+ assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_A));
+
+ // Rollback for app B should not be expired
+ RollbackInfo rollback = getUniqueRollbackInfoForPackage(
+ rm.getAvailableRollbacks(), TEST_APP_B);
+ assertRollbackInfoEquals(TEST_APP_B, 2, 1, rollback);
+
+ // Wait until rollback for app B has expired
+ Thread.sleep(expirationTime / 2);
+ assertNull(getUniqueRollbackInfoForPackage(rm.getAvailableRollbacks(), TEST_APP_B));
+ } finally {
+ RollbackTestUtils.forwardTimeBy(-expirationTime);
+ }
} finally {
DeviceConfig.setProperty(DeviceConfig.Rollback.BOOT_NAMESPACE,
DeviceConfig.Rollback.ROLLBACK_LIFETIME_IN_MILLIS,
diff --git a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
index e8cbd60ae649..ed8a53364ec6 100644
--- a/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
+++ b/tests/RollbackTest/RollbackTest/src/com/android/tests/rollback/RollbackTestUtils.java
@@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;
+import android.app.AlarmManager;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -63,6 +64,17 @@ class RollbackTestUtils {
return rm;
}
+ private static void setTime(long millis) {
+ Context context = InstrumentationRegistry.getContext();
+ AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
+ am.setTime(millis);
+ }
+
+ static void forwardTimeBy(long offsetMillis) {
+ setTime(System.currentTimeMillis() + offsetMillis);
+ Log.i(TAG, "Forwarded time on device by " + offsetMillis + " millis");
+ }
+
/**
* Returns the version of the given package installed on device.
* Returns -1 if the package is not currently installed.
diff --git a/tools/apilint/apilint.py b/tools/apilint/apilint.py
index 295e3de544ee..f967c2fa6bcb 100644
--- a/tools/apilint/apilint.py
+++ b/tools/apilint/apilint.py
@@ -170,6 +170,7 @@ class Class():
self.ctors = []
self.fields = []
self.methods = []
+ self.annotations = []
if sig_format == 2:
V2LineParser(raw).parse_into_class(self)
@@ -196,8 +197,10 @@ class Class():
if "implements" in raw:
self.implements = raw[raw.index("implements")+1]
+ self.implements_all = [self.implements]
else:
self.implements = None
+ self.implements_all = []
else:
raise ValueError("Unknown signature format: " + sig_format)
@@ -224,7 +227,7 @@ class Class():
class Package():
- NAME = re.compile("package(?: .*)? ([A-Za-z.]+)")
+ NAME = re.compile("package(?: .*)? ([A-Za-z0-9.]+)")
def __init__(self, line, raw, blame):
self.line = line
@@ -351,8 +354,8 @@ class V2LineParser(object):
def parse_into_class(self, clazz):
clazz.split = []
- annotations = self.parse_annotations()
- if "@Deprecated" in annotations:
+ clazz.annotations = self.parse_annotations()
+ if "@Deprecated" in clazz.annotations:
clazz.split.append("deprecated")
clazz.split.extend(self.parse_modifiers())
kind = self.parse_one_of("class", "interface", "@interface", "enum")
@@ -364,12 +367,12 @@ class V2LineParser(object):
self.parse_matching_paren("<", ">")
extends = self.parse_extends()
clazz.extends = extends[0] if extends else None
- implements = self.parse_implements()
- clazz.implements = implements[0] if implements else None
+ clazz.implements_all = self.parse_implements()
# The checks assume that interfaces are always found in implements, which isn't true for
# subinterfaces.
- if not implements and "interface" in clazz.split:
- clazz.implements = clazz.extends
+ if not clazz.implements_all and "interface" in clazz.split:
+ clazz.implements_all = [clazz.extends]
+ clazz.implements = clazz.implements_all[0] if clazz.implements_all else None
self.parse_token("{")
self.parse_eof()
@@ -761,6 +764,14 @@ def notice(clazz):
noticed[clazz.fullname] = hash(clazz)
+verifiers = {}
+
+def verifier(f):
+ verifiers[f.__name__] = f
+ return f
+
+
+@verifier
def verify_constants(clazz):
"""All static final constants must be FOO_NAME style."""
if re.match("android\.R\.[a-z]+", clazz.fullname): return
@@ -778,13 +789,13 @@ def verify_constants(clazz):
if f.typ in req and f.value is None:
error(clazz, f, None, "All constants must be defined at compile time")
-
+@verifier
def verify_enums(clazz):
"""Enums are bad, mmkay?"""
if clazz.extends == "java.lang.Enum" or "enum" in clazz.split:
error(clazz, None, "F5", "Enums are not allowed")
-
+@verifier
def verify_class_names(clazz):
"""Try catching malformed class names like myMtp or MTPUser."""
if clazz.fullname.startswith("android.opengl"): return
@@ -799,6 +810,7 @@ def verify_class_names(clazz):
error(clazz, None, None, "Don't expose your implementation details")
+@verifier
def verify_method_names(clazz):
"""Try catching malformed method names, like Foo() or getMTU()."""
if clazz.fullname.startswith("android.opengl"): return
@@ -812,9 +824,9 @@ def verify_method_names(clazz):
error(clazz, m, "S1", "Method name must start with lowercase char")
+@verifier
def verify_callbacks(clazz):
"""Verify Callback classes.
- All callback classes must be abstract.
All methods must follow onFoo() naming style."""
if clazz.fullname == "android.speech.tts.SynthesisCallback": return
@@ -824,14 +836,12 @@ def verify_callbacks(clazz):
warn(clazz, None, "L1", "Class should be named FooCallback")
if clazz.name.endswith("Callback"):
- if "interface" in clazz.split:
- error(clazz, None, "CL3", "Callbacks must be abstract class to enable extension in future API levels")
-
for m in clazz.methods:
if not re.match("on[A-Z][a-z]*", m.name):
error(clazz, m, "L1", "Callback method names must be onFoo() style")
+@verifier
def verify_listeners(clazz):
"""Verify Listener classes.
All Listener classes must be interface.
@@ -853,6 +863,7 @@ def verify_listeners(clazz):
error(clazz, m, "L1", "Single listener method name must match class name")
+@verifier
def verify_actions(clazz):
"""Verify intent actions.
All action names must be named ACTION_FOO.
@@ -884,6 +895,7 @@ def verify_actions(clazz):
error(clazz, f, "C4", "Inconsistent action value; expected '%s'" % (expected))
+@verifier
def verify_extras(clazz):
"""Verify intent extras.
All extra names must be named EXTRA_FOO.
@@ -914,6 +926,7 @@ def verify_extras(clazz):
error(clazz, f, "C4", "Inconsistent extra value; expected '%s'" % (expected))
+@verifier
def verify_equals(clazz):
"""Verify that equals() and hashCode() must be overridden together."""
eq = False
@@ -926,6 +939,7 @@ def verify_equals(clazz):
error(clazz, None, "M8", "Must override both equals and hashCode; missing one")
+@verifier
def verify_parcelable(clazz):
"""Verify that Parcelable objects aren't hiding required bits."""
if clazz.implements == "android.os.Parcelable":
@@ -944,6 +958,7 @@ def verify_parcelable(clazz):
error(clazz, c, "FW3", "Parcelable inflation is exposed through CREATOR, not raw constructors")
+@verifier
def verify_protected(clazz):
"""Verify that no protected methods or fields are allowed."""
for m in clazz.methods:
@@ -955,6 +970,7 @@ def verify_protected(clazz):
error(clazz, f, "M7", "Protected fields not allowed; must be public")
+@verifier
def verify_fields(clazz):
"""Verify that all exposed fields are final.
Exposed fields must follow myName style.
@@ -1000,6 +1016,7 @@ def verify_fields(clazz):
error(clazz, f, "C2", "Constants must be marked static final")
+@verifier
def verify_register(clazz):
"""Verify parity of registration methods.
Callback objects use register/unregister methods.
@@ -1033,6 +1050,7 @@ def verify_register(clazz):
error(clazz, m, "L3", "Listener methods should be named add/remove")
+@verifier
def verify_sync(clazz):
"""Verify synchronized methods aren't exposed."""
for m in clazz.methods:
@@ -1040,6 +1058,7 @@ def verify_sync(clazz):
error(clazz, m, "M5", "Internal locks must not be exposed")
+@verifier
def verify_intent_builder(clazz):
"""Verify that Intent builders are createFooIntent() style."""
if clazz.name == "Intent": return
@@ -1052,6 +1071,7 @@ def verify_intent_builder(clazz):
warn(clazz, m, "FW1", "Methods creating an Intent should be named createFooIntent()")
+@verifier
def verify_helper_classes(clazz):
"""Verify that helper classes are named consistently with what they extend.
All developer extendable methods should be named onFoo()."""
@@ -1100,6 +1120,7 @@ def verify_helper_classes(clazz):
warn(clazz, m, None, "If implemented by developer, should be named onFoo(); otherwise consider marking final")
+@verifier
def verify_builder(clazz):
"""Verify builder classes.
Methods should return the builder to enable chaining."""
@@ -1132,12 +1153,14 @@ def verify_builder(clazz):
error(clazz, None, None, "Builder should be final")
+@verifier
def verify_aidl(clazz):
"""Catch people exposing raw AIDL."""
if clazz.extends == "android.os.Binder" or clazz.implements == "android.os.IInterface":
error(clazz, None, None, "Raw AIDL interfaces must not be exposed")
+@verifier
def verify_internal(clazz):
"""Catch people exposing internal classes."""
if clazz.pkg.name.startswith("com.android"):
@@ -1172,6 +1195,7 @@ LAYERING_PACKAGE_RANKING = layering_build_ranking([
"android.util"
])
+@verifier
def verify_layering(clazz):
"""Catch package layering violations.
For example, something in android.os depending on android.app."""
@@ -1206,6 +1230,7 @@ def verify_layering(clazz):
warn(clazz, m, "FW6", "Method argument type violates package layering")
+@verifier
def verify_boolean(clazz):
"""Verifies that boolean accessors are named correctly.
For example, hasFoo() and setHasFoo()."""
@@ -1246,9 +1271,11 @@ def verify_boolean(clazz):
error_if_exists(sets, m.name, expected, "has" + target)
+@verifier
def verify_collections(clazz):
"""Verifies that collection types are interfaces."""
if clazz.fullname == "android.os.Bundle": return
+ if clazz.fullname == "android.os.Parcel": return
bad = ["java.util.Vector", "java.util.LinkedList", "java.util.ArrayList", "java.util.Stack",
"java.util.HashMap", "java.util.HashSet", "android.util.ArraySet", "android.util.ArrayMap"]
@@ -1260,6 +1287,23 @@ def verify_collections(clazz):
error(clazz, m, "CL2", "Argument is concrete collection; must be higher-level interface")
+@verifier
+def verify_uris(clazz):
+ bad = ["java.net.URL", "java.net.URI", "android.net.URL"]
+
+ for f in clazz.fields:
+ if f.typ in bad:
+ error(clazz, f, None, "Field must be android.net.Uri instead of " + f.typ)
+
+ for m in clazz.methods + clazz.ctors:
+ if m.typ in bad:
+ error(clazz, m, None, "Must return android.net.Uri instead of " + m.typ)
+ for arg in m.args:
+ if arg in bad:
+ error(clazz, m, None, "Argument must take android.net.Uri instead of " + arg)
+
+
+@verifier
def verify_flags(clazz):
"""Verifies that flags are non-overlapping."""
known = collections.defaultdict(int)
@@ -1276,6 +1320,7 @@ def verify_flags(clazz):
known[scope] |= val
+@verifier
def verify_exception(clazz):
"""Verifies that methods don't throw generic exceptions."""
for m in clazz.methods:
@@ -1284,17 +1329,19 @@ def verify_exception(clazz):
error(clazz, m, "S1", "Methods must not throw generic exceptions")
if t in ["android.os.RemoteException"]:
- if clazz.name == "android.content.ContentProviderClient": continue
- if clazz.name == "android.os.Binder": continue
- if clazz.name == "android.os.IBinder": continue
+ if clazz.fullname == "android.content.ContentProviderClient": continue
+ if clazz.fullname == "android.os.Binder": continue
+ if clazz.fullname == "android.os.IBinder": continue
error(clazz, m, "FW9", "Methods calling into system server should rethrow RemoteException as RuntimeException")
if len(m.args) == 0 and t in ["java.lang.IllegalArgumentException", "java.lang.NullPointerException"]:
warn(clazz, m, "S1", "Methods taking no arguments should throw IllegalStateException")
+
GOOGLE_IGNORECASE = re.compile("google", re.IGNORECASE)
+# Not marked as @verifier, because it is only conditionally applied.
def verify_google(clazz):
"""Verifies that APIs never reference Google."""
@@ -1307,6 +1354,7 @@ def verify_google(clazz):
error(clazz, t, None, "Must never reference Google")
+@verifier
def verify_bitset(clazz):
"""Verifies that we avoid using heavy BitSet."""
@@ -1322,6 +1370,7 @@ def verify_bitset(clazz):
error(clazz, m, None, "Argument type must not be heavy BitSet")
+@verifier
def verify_manager(clazz):
"""Verifies that FooManager is only obtained from Context."""
@@ -1335,6 +1384,7 @@ def verify_manager(clazz):
error(clazz, m, None, "Managers must always be obtained from Context")
+@verifier
def verify_boxed(clazz):
"""Verifies that methods avoid boxed primitives."""
@@ -1357,6 +1407,7 @@ def verify_boxed(clazz):
error(clazz, m, "M11", "Must avoid boxed primitives")
+@verifier
def verify_static_utils(clazz):
"""Verifies that helper classes can't be constructed."""
if clazz.fullname.startswith("android.opengl"): return
@@ -1376,6 +1427,7 @@ def verify_static_utils(clazz):
error(clazz, None, None, "Fully-static utility classes must not have constructor")
+# @verifier # Disabled for now
def verify_overload_args(clazz):
"""Verifies that method overloads add new arguments at the end."""
if clazz.fullname.startswith("android.opengl"): return
@@ -1416,6 +1468,7 @@ def verify_overload_args(clazz):
error(clazz, m, "M2", "Expected consistent argument ordering between overloads: %s..." % (", ".join(locked_sig)))
+@verifier
def verify_callback_handlers(clazz):
"""Verifies that methods adding listener/callback have overload
for specifying delivery thread."""
@@ -1467,6 +1520,7 @@ def verify_callback_handlers(clazz):
warn(clazz, f, "L1", "Registration methods should have overload that accepts delivery Executor")
+@verifier
def verify_context_first(clazz):
"""Verifies that methods accepting a Context keep it the first argument."""
examine = clazz.ctors + clazz.methods
@@ -1479,6 +1533,7 @@ def verify_context_first(clazz):
error(clazz, m, "M3", "ContentResolver is distinct, so it must be the first argument")
+@verifier
def verify_listener_last(clazz):
"""Verifies that methods accepting a Listener or Callback keep them as last arguments."""
examine = clazz.ctors + clazz.methods
@@ -1492,6 +1547,7 @@ def verify_listener_last(clazz):
warn(clazz, m, "M3", "Listeners should always be at end of argument list")
+@verifier
def verify_resource_names(clazz):
"""Verifies that resource names have consistent case."""
if not re.match("android\.R\.[a-z]+", clazz.fullname): return
@@ -1523,6 +1579,7 @@ def verify_resource_names(clazz):
error(clazz, f, "C7", "Expected resource name in this class to be FooBar_Baz style")
+@verifier
def verify_files(clazz):
"""Verifies that methods accepting File also accept streams."""
@@ -1544,6 +1601,7 @@ def verify_files(clazz):
warn(clazz, m, "M10", "Methods accepting File should also accept FileDescriptor or streams")
+@verifier
def verify_manager_list(clazz):
"""Verifies that managers return List<? extends Parcelable> instead of arrays."""
@@ -1554,6 +1612,7 @@ def verify_manager_list(clazz):
warn(clazz, m, None, "Methods should return List<? extends Parcelable> instead of Parcelable[] to support ParceledListSlice under the hood")
+@verifier
def verify_abstract_inner(clazz):
"""Verifies that abstract inner classes are static."""
@@ -1562,6 +1621,7 @@ def verify_abstract_inner(clazz):
warn(clazz, None, None, "Abstract inner classes should be static to improve testability")
+@verifier
def verify_runtime_exceptions(clazz):
"""Verifies that runtime exceptions aren't listed in throws."""
@@ -1606,6 +1666,7 @@ def verify_runtime_exceptions(clazz):
error(clazz, m, None, "Methods must not mention RuntimeException subclasses in throws clauses")
+@verifier
def verify_error(clazz):
"""Verifies that we always use Exception instead of Error."""
if not clazz.extends: return
@@ -1615,6 +1676,7 @@ def verify_error(clazz):
error(clazz, None, None, "Exceptions must be named FooException")
+@verifier
def verify_units(clazz):
"""Verifies that we use consistent naming for units."""
@@ -1651,10 +1713,11 @@ def verify_units(clazz):
error(clazz, m, None, "Percentage must use ints")
+@verifier
def verify_closable(clazz):
"""Verifies that classes are AutoClosable."""
- if clazz.implements == "java.lang.AutoCloseable": return
- if clazz.implements == "java.io.Closeable": return
+ if "java.lang.AutoCloseable" in clazz.implements_all: return
+ if "java.io.Closeable" in clazz.implements_all: return
for m in clazz.methods:
if len(m.args) > 0: continue
@@ -1663,6 +1726,7 @@ def verify_closable(clazz):
return
+@verifier
def verify_member_name_not_kotlin_keyword(clazz):
"""Prevent method names which are keywords in Kotlin."""
@@ -1688,6 +1752,7 @@ def verify_member_name_not_kotlin_keyword(clazz):
error(clazz, f, None, "Field name must not be a Kotlin keyword")
+@verifier
def verify_method_name_not_kotlin_operator(clazz):
"""Warn about method names which become operators in Kotlin."""
@@ -1737,6 +1802,7 @@ def verify_method_name_not_kotlin_operator(clazz):
unique_binary_op(m, m.name[:-6]) # Remove 'Assign' suffix
+@verifier
def verify_collections_over_arrays(clazz):
"""Warn that [] should be Collections."""
@@ -1752,6 +1818,7 @@ def verify_collections_over_arrays(clazz):
warn(clazz, m, None, "Method argument should be Collection<> (or subclass) instead of raw array")
+@verifier
def verify_user_handle(clazz):
"""Methods taking UserHandle should be ForUser or AsUser."""
if clazz.name.endswith("Listener") or clazz.name.endswith("Callback") or clazz.name.endswith("Callbacks"): return
@@ -1776,6 +1843,7 @@ def verify_user_handle(clazz):
"or 'queryFooForUser'")
+@verifier
def verify_params(clazz):
"""Parameter classes should be 'Params'."""
if clazz.name.endswith("Params"): return
@@ -1791,6 +1859,7 @@ def verify_params(clazz):
error(clazz, None, None, "Classes holding a set of parameters should be called 'FooParams'")
+@verifier
def verify_services(clazz):
"""Service name should be FOO_BAR_SERVICE = 'foo_bar'."""
if clazz.fullname != "android.content.Context": return
@@ -1804,6 +1873,7 @@ def verify_services(clazz):
error(clazz, f, "C4", "Inconsistent service value; expected '%s'" % (expected))
+@verifier
def verify_tense(clazz):
"""Verify tenses of method names."""
if clazz.fullname.startswith("android.opengl"): return
@@ -1813,6 +1883,7 @@ def verify_tense(clazz):
warn(clazz, m, None, "Unexpected tense; probably meant 'enabled'")
+@verifier
def verify_icu(clazz):
"""Verifies that richer ICU replacements are used."""
better = {
@@ -1844,6 +1915,7 @@ def verify_icu(clazz):
warn(clazz, m, None, "Type %s should be replaced with richer ICU type %s" % (arg, better[arg]))
+@verifier
def verify_clone(clazz):
"""Verify that clone() isn't implemented; see EJ page 61."""
for m in clazz.methods:
@@ -1851,8 +1923,12 @@ def verify_clone(clazz):
error(clazz, m, None, "Provide an explicit copy constructor instead of implementing clone()")
+@verifier
def verify_pfd(clazz):
"""Verify that android APIs use PFD over FD."""
+ if clazz.fullname == "android.os.FileUtils" or clazz.fullname == "android.system.Os":
+ return
+
examine = clazz.ctors + clazz.methods
for m in examine:
if m.typ == "java.io.FileDescriptor":
@@ -1869,6 +1945,7 @@ def verify_pfd(clazz):
error(clazz, f, "FW11", "Must use ParcelFileDescriptor")
+@verifier
def verify_numbers(clazz):
"""Discourage small numbers types like short and byte."""
@@ -1890,8 +1967,10 @@ def verify_numbers(clazz):
if arg in discouraged:
warn(clazz, m, "FW12", "Should avoid odd sized primitives; use int instead")
+
PRIMITIVES = {"void", "int", "float", "boolean", "short", "char", "byte", "long", "double"}
+@verifier
def verify_nullability(clazz):
"""Catches missing nullability annotations"""
@@ -1920,6 +1999,18 @@ def verify_nullability_args(clazz, m):
def has_nullability(annotations):
return "@NonNull" in annotations or "@Nullable" in annotations
+
+@verifier
+def verify_intdef(clazz):
+ """intdefs must be @hide, because the constant names cannot be stored in
+ the stubs (only the values are, which is not useful)"""
+ if "@interface" not in clazz.split:
+ return
+ if "@IntDef" in clazz.annotations or "@LongDef" in clazz.annotations:
+ error(clazz, None, None, "@IntDef and @LongDef annotations must be @hide")
+
+
+@verifier
def verify_singleton(clazz):
"""Catch singleton objects with constructors."""
@@ -1954,60 +2045,10 @@ def examine_clazz(clazz):
if not is_interesting(clazz): return
- verify_constants(clazz)
- verify_enums(clazz)
- verify_class_names(clazz)
- verify_method_names(clazz)
- verify_callbacks(clazz)
- verify_listeners(clazz)
- verify_actions(clazz)
- verify_extras(clazz)
- verify_equals(clazz)
- verify_parcelable(clazz)
- verify_protected(clazz)
- verify_fields(clazz)
- verify_register(clazz)
- verify_sync(clazz)
- verify_intent_builder(clazz)
- verify_helper_classes(clazz)
- verify_builder(clazz)
- verify_aidl(clazz)
- verify_internal(clazz)
- verify_layering(clazz)
- verify_boolean(clazz)
- verify_collections(clazz)
- verify_flags(clazz)
- verify_exception(clazz)
+ for v in verifiers.itervalues():
+ v(clazz)
+
if not ALLOW_GOOGLE: verify_google(clazz)
- verify_bitset(clazz)
- verify_manager(clazz)
- verify_boxed(clazz)
- verify_static_utils(clazz)
- # verify_overload_args(clazz)
- verify_callback_handlers(clazz)
- verify_context_first(clazz)
- verify_listener_last(clazz)
- verify_resource_names(clazz)
- verify_files(clazz)
- verify_manager_list(clazz)
- verify_abstract_inner(clazz)
- verify_runtime_exceptions(clazz)
- verify_error(clazz)
- verify_units(clazz)
- verify_closable(clazz)
- verify_member_name_not_kotlin_keyword(clazz)
- verify_method_name_not_kotlin_operator(clazz)
- verify_collections_over_arrays(clazz)
- verify_user_handle(clazz)
- verify_params(clazz)
- verify_services(clazz)
- verify_tense(clazz)
- verify_icu(clazz)
- verify_clone(clazz)
- verify_pfd(clazz)
- verify_numbers(clazz)
- verify_singleton(clazz)
- verify_nullability(clazz)
def examine_stream(stream, base_stream=None, in_classes_with_base=[], out_classes_with_base=None):
diff --git a/tools/apilint/apilint_test.py b/tools/apilint/apilint_test.py
index f34492d644ce..5cb43db0b00d 100644
--- a/tools/apilint/apilint_test.py
+++ b/tools/apilint/apilint_test.py
@@ -242,6 +242,10 @@ class V2ParserTests(unittest.TestCase):
cls = self._cls("class Class {")
return apilint.Field(cls, 1, raw, '', sig_format=2)
+ def test_parse_package(self):
+ pkg = apilint.Package(999, "package wifi.p2p {", None)
+ self.assertEquals("wifi.p2p", pkg.name)
+
def test_class(self):
cls = self._cls("@Deprecated @IntRange(from=1, to=2) public static abstract class Some.Name extends Super<Class> implements Interface<Class> {")
self.assertTrue('deprecated' in cls.split)
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
index ee976287b467..1ad7ada95018 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectableClassModel.java
@@ -308,7 +308,10 @@ public final class InspectableClassModel {
* @see android.view.inspector.IntFlagMapping
* @see IntFlagEntry
*/
- INT_FLAG
+ INT_FLAG,
+
+ /** A resource ID */
+ RESOURCE_ID
}
}
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java
index 6305228cfa36..20de90d51482 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectablePropertyProcessor.java
@@ -78,6 +78,54 @@ public final class InspectablePropertyProcessor implements ModelProcessor {
"androidx.annotation.ColorLong"};
/**
+ * Set of android and androidx annotation qualified names of resource ID annotations.
+ */
+ private static final String[] RESOURCE_ID_ANNOTATION_NAMES = {
+ "android.annotation.AnimatorRes",
+ "android.annotation.AnimRes",
+ "android.annotation.AnyRes",
+ "android.annotation.ArrayRes",
+ "android.annotation.BoolRes",
+ "android.annotation.DimenRes",
+ "android.annotation.DrawableRes",
+ "android.annotation.FontRes",
+ "android.annotation.IdRes",
+ "android.annotation.IntegerRes",
+ "android.annotation.InterpolatorRes",
+ "android.annotation.LayoutRes",
+ "android.annotation.MenuRes",
+ "android.annotation.NavigationRes",
+ "android.annotation.PluralsRes",
+ "android.annotation.RawRes",
+ "android.annotation.StringRes",
+ "android.annotation.StyleableRes",
+ "android.annotation.StyleRes",
+ "android.annotation.TransitionRes",
+ "android.annotation.XmlRes",
+ "androidx.annotation.AnimatorRes",
+ "androidx.annotation.AnimRes",
+ "androidx.annotation.AnyRes",
+ "androidx.annotation.ArrayRes",
+ "androidx.annotation.BoolRes",
+ "androidx.annotation.DimenRes",
+ "androidx.annotation.DrawableRes",
+ "androidx.annotation.FontRes",
+ "androidx.annotation.IdRes",
+ "androidx.annotation.IntegerRes",
+ "androidx.annotation.InterpolatorRes",
+ "androidx.annotation.LayoutRes",
+ "androidx.annotation.MenuRes",
+ "androidx.annotation.NavigationRes",
+ "androidx.annotation.PluralsRes",
+ "androidx.annotation.RawRes",
+ "androidx.annotation.StringRes",
+ "androidx.annotation.StyleableRes",
+ "androidx.annotation.StyleRes",
+ "androidx.annotation.TransitionRes",
+ "androidx.annotation.XmlRes"
+ };
+
+ /**
* @param annotationQualifiedName The qualified name of the annotation to process
* @param processingEnv The processing environment from the parent processor
*/
@@ -264,7 +312,6 @@ public final class InspectablePropertyProcessor implements ModelProcessor {
final Property.Type accessorType =
convertTypeMirrorToPropertyType(extractReturnOrFieldType(accessor), accessor);
- final boolean hasColor = hasColorAnnotation(accessor);
final Optional<AnnotationValue> enumMapping =
mAnnotationUtils.valueByName("enumMapping", annotation);
final Optional<AnnotationValue> flagMapping =
@@ -291,8 +338,12 @@ public final class InspectablePropertyProcessor implements ModelProcessor {
});
}
+
switch (valueType) {
case "INFERRED":
+ final boolean hasColor = hasColorAnnotation(accessor);
+ final boolean hasResourceId = hasResourceIdAnnotation(accessor);
+
if (hasColor) {
enumMapping.ifPresent(value -> {
throw new ProcessingException(
@@ -308,7 +359,30 @@ public final class InspectablePropertyProcessor implements ModelProcessor {
annotation,
value);
});
+ if (hasResourceId) {
+ throw new ProcessingException(
+ "Cannot infer type, both color and resource ID annotations "
+ + "are present.",
+ accessor,
+ annotation);
+ }
return Property.Type.COLOR;
+ } else if (hasResourceId) {
+ enumMapping.ifPresent(value -> {
+ throw new ProcessingException(
+ "Cannot use enumMapping on a resource ID type.",
+ accessor,
+ annotation,
+ value);
+ });
+ flagMapping.ifPresent(value -> {
+ throw new ProcessingException(
+ "Cannot use flagMapping on a resource ID type.",
+ accessor,
+ annotation,
+ value);
+ });
+ return Property.Type.RESOURCE_ID;
} else if (enumMapping.isPresent()) {
flagMapping.ifPresent(value -> {
throw new ProcessingException(
@@ -346,6 +420,8 @@ public final class InspectablePropertyProcessor implements ModelProcessor {
case "INT_FLAG":
requirePackedIntToBeInt("IntFlag", accessorType, accessor, annotation);
return Property.Type.INT_FLAG;
+ case "RESOURCE_ID":
+ return Property.Type.RESOURCE_ID;
default:
throw new ProcessingException(
String.format("Unknown value type enumeration value: %s", valueType),
@@ -474,6 +550,24 @@ public final class InspectablePropertyProcessor implements ModelProcessor {
}
/**
+ * Determine if a getter or a field is annotated with a resource ID annotation.
+ *
+ * @param accessor The getter or field to query
+ * @return True if the accessor is an integer and has a resource ID annotation, false otherwise
+ */
+ private boolean hasResourceIdAnnotation(Element accessor) {
+ if (unboxType(extractReturnOrFieldType(accessor)) == TypeKind.INT) {
+ for (String name : RESOURCE_ID_ANNOTATION_NAMES) {
+ if (mAnnotationUtils.hasAnnotation(accessor, name)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
* Infer a property name from a getter method.
*
* If the method is prefixed with {@code get}, the prefix will be stripped, and the
diff --git a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
index 1ab9914d3aed..44d88bb4b73d 100644
--- a/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
+++ b/tools/processors/view_inspector/src/java/android/processor/view/inspector/InspectionCompanionGenerator.java
@@ -446,6 +446,8 @@ public final class InspectionCompanionGenerator {
return "IntEnum";
case INT_FLAG:
return "IntFlag";
+ case RESOURCE_ID:
+ return "ResourceId";
default:
throw new NoSuchElementException(String.format("No such property type, %s", type));
}
diff --git a/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java b/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
index 35f0fcf9bcae..4eed5040eb51 100644
--- a/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
+++ b/tools/processors/view_inspector/test/java/android/processor/view/inspector/InspectionCompanionGeneratorTest.java
@@ -82,6 +82,7 @@ public class InspectionCompanionGeneratorTest {
addProperty("object", "getObject", Property.Type.OBJECT);
addProperty("color", "getColor", Property.Type.COLOR);
addProperty("gravity", "getGravity", Property.Type.GRAVITY);
+ addProperty("resourceId", "getResourceId", Property.Type.RESOURCE_ID);
assertGeneratedFileEquals("SimpleProperties");
}
diff --git a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
index dfc1bce8afcc..556d8ddc5d5e 100644
--- a/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
+++ b/tools/processors/view_inspector/test/resources/android/processor/view/inspector/InspectionCompanionGeneratorTest/SimpleProperties.java.txt
@@ -69,6 +69,11 @@ public final class TestNode$$InspectionCompanion implements InspectionCompanion<
private int mObjectId;
/**
+ * Property ID of {@code resourceId}.
+ */
+ private int mResourceIdId;
+
+ /**
* Property ID of {@code short}.
*/
private int mShortId;
@@ -85,6 +90,7 @@ public final class TestNode$$InspectionCompanion implements InspectionCompanion<
mIntId = propertyMapper.mapInt("int", R.attr.int);
mLongId = propertyMapper.mapLong("long", R.attr.long);
mObjectId = propertyMapper.mapObject("object", R.attr.object);
+ mResourceIdId = propertyMapper.mapResourceId("resourceId", R.attr.resourceId);
mShortId = propertyMapper.mapShort("short", R.attr.short);
mPropertiesMapped = true;
}
@@ -104,6 +110,7 @@ public final class TestNode$$InspectionCompanion implements InspectionCompanion<
propertyReader.readInt(mIntId, node.getInt());
propertyReader.readLong(mLongId, node.getLong());
propertyReader.readObject(mObjectId, node.getObject());
+ propertyReader.readResourceId(mResourceIdId, node.getResourceId());
propertyReader.readShort(mShortId, node.getShort());
}
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 8ef976f0f9ae..6dd838cf4252 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -4346,7 +4346,9 @@ public class WifiManager {
/**
* Start subscription provisioning flow
+ *
* @param provider {@link OsuProvider} to provision with
+ * @param executor the Executor on which to run the callback.
* @param callback {@link ProvisioningCallback} for updates regarding provisioning flow
* @hide
*/
@@ -4355,45 +4357,48 @@ public class WifiManager {
android.Manifest.permission.NETWORK_SETTINGS,
android.Manifest.permission.NETWORK_SETUP_WIZARD
})
- public void startSubscriptionProvisioning(OsuProvider provider, ProvisioningCallback callback,
- @Nullable Handler handler) {
- Looper looper = (handler == null) ? Looper.getMainLooper() : handler.getLooper();
+ public void startSubscriptionProvisioning(@NonNull OsuProvider provider,
+ @NonNull @CallbackExecutor Executor executor, @NonNull ProvisioningCallback callback) {
+ // Verify arguments
+ if (executor == null) {
+ throw new IllegalArgumentException("executor must not be null");
+ }
+ if (callback == null) {
+ throw new IllegalArgumentException("callback must not be null");
+ }
try {
mService.startSubscriptionProvisioning(provider,
- new ProvisioningCallbackProxy(looper, callback));
+ new ProvisioningCallbackProxy(executor, callback));
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
+ /**
+ * Helper class to support OSU Provisioning callbacks
+ */
private static class ProvisioningCallbackProxy extends IProvisioningCallback.Stub {
- private final Handler mHandler;
+ private final Executor mExecutor;
private final ProvisioningCallback mCallback;
- ProvisioningCallbackProxy(Looper looper, ProvisioningCallback callback) {
- mHandler = new Handler(looper);
+ ProvisioningCallbackProxy(Executor executor, ProvisioningCallback callback) {
+ mExecutor = executor;
mCallback = callback;
}
@Override
public void onProvisioningStatus(int status) {
- mHandler.post(() -> {
- mCallback.onProvisioningStatus(status);
- });
+ mExecutor.execute(() -> mCallback.onProvisioningStatus(status));
}
@Override
public void onProvisioningFailure(int status) {
- mHandler.post(() -> {
- mCallback.onProvisioningFailure(status);
- });
+ mExecutor.execute(() -> mCallback.onProvisioningFailure(status));
}
@Override
public void onProvisioningComplete() {
- mHandler.post(() -> {
- mCallback.onProvisioningComplete();
- });
+ mExecutor.execute(() -> mCallback.onProvisioningComplete());
}
}
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
index 63f47e7a7fea..29a18d2edc21 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pManager.java
@@ -816,7 +816,7 @@ public class WifiP2pManager {
* The requested {@link android.net.wifi.p2p.WifiP2pDevice} is available.
* @param wifiP2pDevice Wi-Fi p2p {@link android.net.wifi.p2p.WifiP2pDevice}
*/
- void onDeviceInfoAvailable(WifiP2pDevice wifiP2pDevice);
+ void onDeviceInfoAvailable(@Nullable WifiP2pDevice wifiP2pDevice);
}
/**