summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp11
-rwxr-xr-xapi/current.txt180
-rw-r--r--api/system-current.txt96
-rw-r--r--cmds/statsd/Android.bp16
-rw-r--r--cmds/statsd/src/FieldValue.cpp20
-rw-r--r--cmds/statsd/src/FieldValue.h2
-rw-r--r--cmds/statsd/src/StatsLogProcessor.cpp41
-rw-r--r--cmds/statsd/src/StatsLogProcessor.h6
-rw-r--r--cmds/statsd/src/StatsService.cpp71
-rw-r--r--cmds/statsd/src/StatsService.h11
-rw-r--r--cmds/statsd/src/anomaly/AnomalyTracker.cpp3
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.cpp15
-rw-r--r--cmds/statsd/src/guardrail/StatsdStats.h6
-rw-r--r--cmds/statsd/src/main.cpp4
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.cpp5
-rw-r--r--cmds/statsd/src/metrics/CountMetricProducer.h1
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.cpp5
-rw-r--r--cmds/statsd/src/metrics/DurationMetricProducer.h1
-rw-r--r--cmds/statsd/src/metrics/EventMetricProducer.cpp5
-rw-r--r--cmds/statsd/src/metrics/EventMetricProducer.h1
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.cpp8
-rw-r--r--cmds/statsd/src/metrics/GaugeMetricProducer.h1
-rw-r--r--cmds/statsd/src/metrics/MetricProducer.h5
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.cpp9
-rw-r--r--cmds/statsd/src/metrics/MetricsManager.h1
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.cpp266
-rw-r--r--cmds/statsd/src/metrics/ValueMetricProducer.h58
-rw-r--r--cmds/statsd/src/metrics/metrics_manager_util.cpp4
-rw-r--r--cmds/statsd/src/stats_log.proto1
-rw-r--r--cmds/statsd/src/stats_log_util.cpp2
-rw-r--r--cmds/statsd/src/stats_log_util.h5
-rw-r--r--cmds/statsd/src/statsd_config.proto11
-rw-r--r--cmds/statsd/tests/StatsLogProcessor_test.cpp6
-rw-r--r--cmds/statsd/tests/e2e/Attribution_e2e_test.cpp8
-rw-r--r--cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp6
-rw-r--r--cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp16
-rw-r--r--cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp8
-rw-r--r--cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp12
-rw-r--r--cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp4
-rw-r--r--cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp4
-rw-r--r--cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp8
-rw-r--r--cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp2
-rw-r--r--cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp9
-rw-r--r--cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp24
-rw-r--r--cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp425
-rw-r--r--config/hiddenapi-light-greylist.txt3921
-rw-r--r--core/java/android/app/Activity.java77
-rw-r--r--core/java/android/app/AppOpsManager.java34
-rw-r--r--core/java/android/app/AutomaticZenRule.java33
-rw-r--r--core/java/android/app/IActivityManager.aidl11
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl10
-rw-r--r--core/java/android/app/SystemServiceRegistry.java27
-rw-r--r--core/java/android/app/assist/AssistStructure.java7
-rw-r--r--core/java/android/content/Context.java19
-rw-r--r--core/java/android/content/SharedPreferences.java3
-rw-r--r--core/java/android/content/pm/PackageManager.java8
-rw-r--r--core/java/android/content/pm/SharedLibraryInfo.java51
-rw-r--r--core/java/android/content/pm/SharedLibraryNames.java12
-rw-r--r--core/java/android/content/res/AssetManager.java14
-rw-r--r--core/java/android/content/res/FontResourcesParser.java6
-rw-r--r--core/java/android/content/res/ResourcesImpl.java5
-rw-r--r--core/java/android/hardware/camera2/CameraCharacteristics.java33
-rw-r--r--core/java/android/hardware/camera2/CameraDevice.java6
-rw-r--r--core/java/android/hardware/camera2/CameraMetadata.java14
-rw-r--r--core/java/android/hardware/camera2/CaptureRequest.java4
-rw-r--r--core/java/android/hardware/camera2/CaptureResult.java4
-rw-r--r--core/java/android/hardware/iris/IIrisService.aidl24
-rw-r--r--core/java/android/hardware/iris/IrisManager.java34
-rw-r--r--core/java/android/hardware/location/ContextHubBroadcastReceiver.java102
-rw-r--r--core/java/android/hardware/location/ContextHubClient.java8
-rw-r--r--core/java/android/hardware/location/ContextHubManager.java24
-rw-r--r--core/java/android/hardware/location/IContextHubService.aidl6
-rw-r--r--core/java/android/net/MacAddress.java15
-rw-r--r--core/java/android/os/UserManager.java15
-rw-r--r--core/java/android/provider/FontsContract.java44
-rw-r--r--core/java/android/provider/Settings.java52
-rw-r--r--core/java/android/service/intelligence/IIntelligenceService.aidl39
-rw-r--r--core/java/android/service/intelligence/IntelligenceService.java126
-rw-r--r--core/java/android/service/intelligence/InteractionContext.aidl19
-rw-r--r--core/java/android/service/intelligence/InteractionContext.java157
-rw-r--r--core/java/android/service/intelligence/InteractionSessionId.aidl19
-rw-r--r--core/java/android/service/intelligence/InteractionSessionId.java123
-rw-r--r--core/java/android/util/FeatureFlagUtils.java2
-rw-r--r--core/java/android/view/View.java12
-rw-r--r--core/java/android/view/ViewRootImpl.java2
-rw-r--r--core/java/android/view/WindowInsets.java406
-rw-r--r--core/java/android/view/intelligence/ContentCaptureEvent.aidl19
-rw-r--r--core/java/android/view/intelligence/ContentCaptureEvent.java226
-rw-r--r--core/java/android/view/intelligence/IIntelligenceManager.aidl48
-rw-r--r--core/java/android/view/intelligence/IntelligenceManager.java349
-rw-r--r--core/java/android/view/intelligence/ViewNode.java44
-rw-r--r--core/java/android/widget/Magnifier.java3
-rw-r--r--core/java/com/android/internal/app/procstats/ProcessStats.java23
-rw-r--r--core/java/com/android/internal/policy/DecorView.java2
-rw-r--r--core/java/com/android/internal/widget/ActionBarOverlayLayout.java3
-rw-r--r--core/java/com/android/internal/widget/LockPatternView.java2
-rw-r--r--core/jni/android/graphics/FontFamily.cpp3
-rw-r--r--core/jni/android/graphics/Paint.cpp7
-rw-r--r--core/jni/android/graphics/fonts/FontFamily.cpp7
-rw-r--r--core/jni/android_media_AudioFormat.h8
-rw-r--r--core/jni/android_util_AssetManager.cpp25
-rw-r--r--core/jni/android_view_RenderNode.cpp20
-rw-r--r--core/proto/android/os/incident.proto7
-rw-r--r--core/proto/android/os/statsdata.proto33
-rw-r--r--core/proto/android/providers/settings/global.proto4
-rw-r--r--core/res/AndroidManifest.xml9
-rw-r--r--core/res/res/values/strings.xml9
-rw-r--r--core/res/res/xml/sms_short_codes.xml2
-rw-r--r--core/tests/coretests/src/android/provider/SettingsBackupTest.java4
-rw-r--r--core/tests/coretests/src/android/view/ViewRootImplTest.java18
-rw-r--r--graphics/java/android/graphics/Canvas.java80
-rw-r--r--graphics/java/android/graphics/ImageFormat.java18
-rw-r--r--graphics/java/android/graphics/RecordingCanvas.java26
-rw-r--r--graphics/java/android/graphics/RenderNode.java473
-rw-r--r--graphics/java/android/graphics/Typeface.java404
-rw-r--r--graphics/java/android/graphics/fonts/Font.java37
-rw-r--r--graphics/java/android/graphics/fonts/FontFamily.java12
-rw-r--r--graphics/java/android/graphics/fonts/SystemFonts.java2
-rw-r--r--libs/androidfw/AssetManager2.cpp250
-rw-r--r--libs/androidfw/ResourceTypes.cpp32
-rw-r--r--libs/androidfw/include/androidfw/AssetManager2.h12
-rw-r--r--libs/androidfw/tests/DynamicRefTable_test.cpp58
-rw-r--r--libs/androidfw/tests/Theme_test.cpp39
-rw-r--r--libs/androidfw/tests/data/lib_two/R.h12
-rw-r--r--libs/androidfw/tests/data/lib_two/lib_two.apkbin1106 -> 1426 bytes
-rw-r--r--libs/androidfw/tests/data/lib_two/res/values/values.xml8
-rw-r--r--libs/hwui/hwui/Bitmap.cpp2
-rw-r--r--libs/hwui/hwui/MinikinSkia.cpp4
-rw-r--r--libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp10
-rw-r--r--libs/hwui/service/GraphicsStatsService.cpp6
-rw-r--r--libs/protoutil/include/android/util/ProtoOutputStream.h1
-rw-r--r--libs/protoutil/src/ProtoOutputStream.cpp28
-rw-r--r--media/java/android/media/AudioFormat.java193
-rw-r--r--media/java/android/media/MediaPlayer2.java206
-rw-r--r--media/java/android/media/MediaPlayer2Impl.java450
-rw-r--r--media/jni/android_media_MediaDrm.cpp10
-rw-r--r--media/jni/android_media_MediaPlayer2.cpp21
-rw-r--r--packages/CarSystemUI/Android.bp2
-rw-r--r--packages/ExtServices/src/android/ext/services/notification/Assistant.java12
-rw-r--r--packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java5
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java6
-rw-r--r--packages/SimAppDialog/res/drawable/illo_sim_app_dialog.xml18
-rw-r--r--packages/SimAppDialog/res/layout/install_carrier_app_activity.xml18
-rw-r--r--packages/SimAppDialog/res/values/bools.xml25
-rw-r--r--packages/SimAppDialog/res/values/strings.xml4
-rw-r--r--packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java5
-rw-r--r--packages/SystemUI/Android.bp8
-rw-r--r--packages/SystemUI/README.md2
-rw-r--r--packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/RecentsView.java2
-rw-r--r--packages/SystemUI/res-keyguard/values/styles.xml1
-rw-r--r--packages/SystemUI/res/values/strings.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java200
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java9
-rw-r--r--packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java34
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java26
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java43
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java13
-rw-r--r--packages/SystemUI/tests/Android.mk2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java29
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerService.java549
-rw-r--r--services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java201
-rw-r--r--services/autofill/java/com/android/server/autofill/Helper.java24
-rw-r--r--services/autofill/java/com/android/server/autofill/RemoteFillService.java409
-rw-r--r--services/autofill/java/com/android/server/autofill/Session.java21
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/FillUi.java12
-rw-r--r--services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java129
-rw-r--r--services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java142
-rw-r--r--services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java185
-rw-r--r--services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java170
-rw-r--r--services/core/java/com/android/server/AbstractMasterSystemService.java507
-rw-r--r--services/core/java/com/android/server/AbstractPerUserSystemService.java274
-rw-r--r--services/core/java/com/android/server/AbstractRemoteService.java443
-rw-r--r--services/core/java/com/android/server/VibratorService.java5
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java22
-rw-r--r--services/core/java/com/android/server/biometrics/face/FaceService.java2
-rw-r--r--services/core/java/com/android/server/biometrics/iris/IrisService.java131
-rw-r--r--services/core/java/com/android/server/location/ContextHubClientBroker.java69
-rw-r--r--services/core/java/com/android/server/location/ContextHubClientManager.java67
-rw-r--r--services/core/java/com/android/server/location/ContextHubService.java32
-rw-r--r--services/core/java/com/android/server/notification/ZenModeHelper.java20
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java23
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java93
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java95
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java8
-rw-r--r--services/core/java/com/android/server/pm/dex/DexManager.java21
-rw-r--r--services/core/java/com/android/server/pm/dex/PackageDexUsage.java44
-rw-r--r--services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java56
-rw-r--r--services/core/java/com/android/server/pm/permission/OWNERS3
-rw-r--r--services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java8
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLaunchObserver.java182
-rw-r--r--services/core/java/com/android/server/wm/ActivityMetricsLogger.java167
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java28
-rw-r--r--services/core/java/com/android/server/wm/ActivityStarter.java2
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java14
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java52
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java2
-rw-r--r--services/java/com/android/server/SystemServer.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java39
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java44
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java50
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java49
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java23
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java52
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java108
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DimmerTests.java55
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java89
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java66
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java41
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java31
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java22
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java30
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java33
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java67
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java42
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java33
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java94
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java45
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java18
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TestIWindow.java32
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java64
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java22
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java27
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java28
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java34
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java189
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java12
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java74
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java78
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java76
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java97
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java15
-rw-r--r--services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java103
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java3
-rw-r--r--services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java106
-rw-r--r--services/tests/wmtests/AndroidManifest.xml3
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java190
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java19
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java2
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java (renamed from services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java)71
-rw-r--r--telephony/java/android/provider/Telephony.java26
-rw-r--r--telephony/java/android/telephony/AccessNetworkConstants.java26
-rw-r--r--telephony/java/android/telephony/CarrierConfigManager.java47
-rw-r--r--telephony/java/android/telephony/CellSignalStrengthLte.java65
-rw-r--r--telephony/java/android/telephony/DisconnectCause.java8
-rw-r--r--telephony/java/android/telephony/TelephonyManager.java90
-rw-r--r--telephony/java/android/telephony/data/ApnSetting.java10
-rw-r--r--telephony/java/android/telephony/euicc/EuiccCardManager.java49
-rw-r--r--telephony/java/android/telephony/ims/ImsCallProfile.java52
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyPermissions.java74
-rw-r--r--tests/net/java/android/net/MacAddressTest.java35
-rw-r--r--tools/aapt2/Debug.cpp25
-rw-r--r--tools/aapt2/ResourceParser.cpp164
-rw-r--r--tools/aapt2/ResourceParser.h4
-rw-r--r--tools/aapt2/ResourceParser_test.cpp239
-rw-r--r--tools/aapt2/ResourceTable.cpp39
-rw-r--r--tools/aapt2/ResourceTable.h30
-rw-r--r--tools/aapt2/ResourceTable_test.cpp62
-rw-r--r--tools/aapt2/Resources.proto16
-rw-r--r--tools/aapt2/format/binary/BinaryResourceParser.cpp2
-rw-r--r--tools/aapt2/format/binary/TableFlattener.cpp2
-rw-r--r--tools/aapt2/format/binary/TableFlattener_test.cpp2
-rw-r--r--tools/aapt2/format/proto/ProtoDeserialize.cpp30
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize.cpp28
-rw-r--r--tools/aapt2/format/proto/ProtoSerialize_test.cpp62
-rw-r--r--tools/aapt2/link/TableMerger.cpp40
-rw-r--r--tools/aapt2/link/TableMerger_test.cpp93
-rw-r--r--tools/aapt2/test/Builders.cpp9
-rw-r--r--tools/aapt2/test/Builders.h2
-rw-r--r--wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl36
-rw-r--r--wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl31
-rw-r--r--wifi/java/android/net/wifi/IWifiManager.aidl5
-rw-r--r--wifi/java/android/net/wifi/ScanResult.java25
-rw-r--r--wifi/java/android/net/wifi/WifiConfiguration.java152
-rw-r--r--wifi/java/android/net/wifi/WifiManager.java453
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java187
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java511
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkSpecifier.java181
-rw-r--r--wifi/java/android/net/wifi/WifiNetworkSuggestion.java143
-rw-r--r--wifi/java/android/net/wifi/WifiScanner.java10
-rw-r--r--wifi/tests/src/android/net/wifi/WifiConfigurationTest.java5
-rw-r--r--wifi/tests/src/android/net/wifi/WifiManagerTest.java89
-rw-r--r--wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java453
-rw-r--r--wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java481
-rw-r--r--wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java212
-rw-r--r--wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java146
-rw-r--r--wifi/tests/src/android/net/wifi/WifiScannerTest.java85
313 files changed, 17213 insertions, 4927 deletions
diff --git a/Android.bp b/Android.bp
index b715b7336d23..8163ff82d4b7 100644
--- a/Android.bp
+++ b/Android.bp
@@ -181,6 +181,7 @@ java_defaults {
"core/java/android/hardware/input/IInputManager.aidl",
"core/java/android/hardware/input/IInputDevicesChangedListener.aidl",
"core/java/android/hardware/input/ITabletModeChangedListener.aidl",
+ "core/java/android/hardware/iris/IIrisService.aidl",
"core/java/android/hardware/location/IActivityRecognitionHardware.aidl",
"core/java/android/hardware/location/IActivityRecognitionHardwareClient.aidl",
"core/java/android/hardware/location/IActivityRecognitionHardwareSink.aidl",
@@ -286,6 +287,8 @@ java_defaults {
"core/java/android/service/euicc/ISwitchToSubscriptionCallback.aidl",
"core/java/android/service/euicc/IUpdateSubscriptionNicknameCallback.aidl",
"core/java/android/service/gatekeeper/IGateKeeperService.aidl",
+ "core/java/android/service/intelligence/IIntelligenceService.aidl",
+
"core/java/android/service/notification/INotificationListener.aidl",
"core/java/android/service/notification/IStatusBarNotificationHolder.aidl",
"core/java/android/service/notification/IConditionListener.aidl",
@@ -342,6 +345,7 @@ java_defaults {
"core/java/android/view/autofill/IAutoFillManager.aidl",
"core/java/android/view/autofill/IAutoFillManagerClient.aidl",
"core/java/android/view/autofill/IAutofillWindowPresenter.aidl",
+ "core/java/android/view/intelligence/IIntelligenceManager.aidl",
"core/java/android/view/IApplicationToken.aidl",
"core/java/android/view/IAppTransitionAnimationSpecsFuture.aidl",
"core/java/android/view/IDockedStackListener.aidl",
@@ -594,6 +598,8 @@ java_defaults {
"telephony/java/com/android/internal/telephony/euicc/ISetDefaultSmdpAddressCallback.aidl",
"telephony/java/com/android/internal/telephony/euicc/ISetNicknameCallback.aidl",
"telephony/java/com/android/internal/telephony/euicc/ISwitchToProfileCallback.aidl",
+ "wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl",
+ "wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl",
"wifi/java/android/net/wifi/ISoftApCallback.aidl",
"wifi/java/android/net/wifi/ITrafficStateCallback.aidl",
"wifi/java/android/net/wifi/IWifiManager.aidl",
@@ -692,6 +698,7 @@ java_defaults {
],
static_libs: [
+ "apex_aidl_interface-java",
"framework-protos",
"mediaplayer2-protos",
"android.hidl.base-V1.0-java",
@@ -1567,6 +1574,10 @@ droidstubs {
droidstubs {
name: "hiddenapi-mappings",
defaults: ["metalava-api-stubs-default"],
+ srcs: [
+ ":openjdk_java_files",
+ ":non_openjdk_java_files",
+ ],
arg_files: [
"core/res/AndroidManifest.xml",
],
diff --git a/api/current.txt b/api/current.txt
index 70d7fd29d55e..e53760a8e8d6 100755
--- a/api/current.txt
+++ b/api/current.txt
@@ -13434,6 +13434,7 @@ package android.graphics {
method public boolean clipRect(float, float, float, float);
method public boolean clipRect(int, int, int, int);
method public void concat(android.graphics.Matrix);
+ method public void disableZ();
method public void drawARGB(int, int, int, int);
method public void drawArc(android.graphics.RectF, float, float, boolean, android.graphics.Paint);
method public void drawArc(float, float, float, float, float, float, boolean, android.graphics.Paint);
@@ -13468,6 +13469,7 @@ package android.graphics {
method public void drawRect(android.graphics.RectF, android.graphics.Paint);
method public void drawRect(android.graphics.Rect, android.graphics.Paint);
method public void drawRect(float, float, float, float, android.graphics.Paint);
+ method public void drawRenderNode(android.graphics.RenderNode);
method public void drawRoundRect(android.graphics.RectF, float, float, android.graphics.Paint);
method public void drawRoundRect(float, float, float, float, float, float, android.graphics.Paint);
method public void drawText(char[], int, int, float, float, android.graphics.Paint);
@@ -13479,6 +13481,7 @@ package android.graphics {
method public void drawTextRun(char[], int, int, int, int, float, float, boolean, android.graphics.Paint);
method public void drawTextRun(java.lang.CharSequence, int, int, int, int, float, float, boolean, android.graphics.Paint);
method public void drawVertices(android.graphics.Canvas.VertexMode, int, float[], int, float[], int, int[], int, short[], int, int, android.graphics.Paint);
+ method public void enableZ();
method public boolean getClipBounds(android.graphics.Rect);
method public final android.graphics.Rect getClipBounds();
method public int getDensity();
@@ -13875,6 +13878,7 @@ package android.graphics {
field public static final int RAW_SENSOR = 32; // 0x20
field public static final int RGB_565 = 4; // 0x4
field public static final int UNKNOWN = 0; // 0x0
+ field public static final int Y8 = 538982489; // 0x20203859
field public static final int YUV_420_888 = 35; // 0x23
field public static final int YUV_422_888 = 39; // 0x27
field public static final int YUV_444_888 = 40; // 0x28
@@ -14468,6 +14472,9 @@ package android.graphics {
ctor public RadialGradient(float, float, float, int, int, android.graphics.Shader.TileMode);
}
+ public final class RecordingCanvas extends android.graphics.Canvas {
+ }
+
public final class Rect implements android.os.Parcelable {
ctor public Rect();
ctor public Rect(int, int, int, int);
@@ -14604,6 +14611,77 @@ package android.graphics {
method public final boolean next(android.graphics.Rect);
}
+ public class RenderNode {
+ method public int computeApproximateMemoryUsage();
+ method public static android.graphics.RenderNode create(java.lang.String);
+ method public void discardDisplayList();
+ method public void endRecording();
+ method public float getAlpha();
+ method public int getAmbientShadowColor();
+ method public int getBottom();
+ method public float getCameraDistance();
+ method public boolean getClipToOutline();
+ method public float getElevation();
+ method public int getHeight();
+ method public void getInverseMatrix(android.graphics.Matrix);
+ method public int getLeft();
+ method public void getMatrix(android.graphics.Matrix);
+ method public float getPivotX();
+ method public float getPivotY();
+ method public int getRight();
+ method public float getRotation();
+ method public float getRotationX();
+ method public float getRotationY();
+ method public float getScaleX();
+ method public float getScaleY();
+ method public int getSpotShadowColor();
+ method public int getTop();
+ method public float getTranslationX();
+ method public float getTranslationY();
+ method public float getTranslationZ();
+ method public int getWidth();
+ method public boolean hasDisplayList();
+ method public boolean hasIdentityMatrix();
+ method public boolean hasOverlappingRendering();
+ method public boolean hasShadow();
+ method public boolean isForceDarkAllowed();
+ method public boolean isPivotExplicitlySet();
+ method public boolean offsetLeftAndRight(int);
+ method public boolean offsetTopAndBottom(int);
+ method public boolean resetPivot();
+ method public boolean setAlpha(float);
+ method public boolean setAmbientShadowColor(int);
+ method public boolean setBottom(int);
+ method public boolean setCameraDistance(float);
+ method public boolean setClipBounds(android.graphics.Rect);
+ method public boolean setClipToBounds(boolean);
+ method public boolean setClipToOutline(boolean);
+ method public boolean setElevation(float);
+ method public boolean setForceDarkAllowed(boolean);
+ method public boolean setHasOverlappingRendering(boolean);
+ method public boolean setLeft(int);
+ method public boolean setLeftTopRightBottom(int, int, int, int);
+ method public boolean setOutline(android.graphics.Outline);
+ method public boolean setPivotX(float);
+ method public boolean setPivotY(float);
+ method public boolean setProjectBackwards(boolean);
+ method public boolean setProjectionReceiver(boolean);
+ method public boolean setRight(int);
+ method public boolean setRotation(float);
+ method public boolean setRotationX(float);
+ method public boolean setRotationY(float);
+ method public boolean setScaleX(float);
+ method public boolean setScaleY(float);
+ method public boolean setSpotShadowColor(int);
+ method public boolean setTop(int);
+ method public boolean setTranslationX(float);
+ method public boolean setTranslationY(float);
+ method public boolean setTranslationZ(float);
+ method public boolean setUseCompositingLayer(boolean, android.graphics.Paint);
+ method public android.graphics.RecordingCanvas startRecording(int, int);
+ method public android.graphics.RecordingCanvas startRecording();
+ }
+
public class Shader {
ctor public deprecated Shader();
method public boolean getLocalMatrix(android.graphics.Matrix);
@@ -14692,10 +14770,10 @@ package android.graphics {
public static class Typeface.CustomFallbackBuilder {
ctor public Typeface.CustomFallbackBuilder(android.graphics.fonts.FontFamily);
+ method public android.graphics.Typeface.CustomFallbackBuilder addCustomFallback(android.graphics.fonts.FontFamily);
method public android.graphics.Typeface build();
- method public android.graphics.Typeface.CustomFallbackBuilder setFallback(java.lang.String);
- method public android.graphics.Typeface.CustomFallbackBuilder setItalic(boolean);
- method public android.graphics.Typeface.CustomFallbackBuilder setWeight(int);
+ method public android.graphics.Typeface.CustomFallbackBuilder setStyle(android.graphics.fonts.FontStyle);
+ method public android.graphics.Typeface.CustomFallbackBuilder setSystemFallback(java.lang.String);
}
public class Xfermode {
@@ -15340,9 +15418,8 @@ package android.graphics.fonts {
method public java.nio.ByteBuffer getBuffer();
method public java.io.File getFile();
method public android.os.LocaleList getLocaleList();
- method public int getSlant();
+ method public android.graphics.fonts.FontStyle getStyle();
method public int getTtcIndex();
- method public int getWeight();
}
public static class Font.Builder {
@@ -22714,6 +22791,7 @@ package android.media {
field public static final int ENCODING_AC3 = 5; // 0x5
field public static final int ENCODING_AC4 = 17; // 0x11
field public static final int ENCODING_DEFAULT = 1; // 0x1
+ field public static final int ENCODING_DOLBY_MAT = 19; // 0x13
field public static final int ENCODING_DOLBY_TRUEHD = 14; // 0xe
field public static final int ENCODING_DTS = 7; // 0x7
field public static final int ENCODING_DTS_HD = 8; // 0x8
@@ -28614,7 +28692,7 @@ package android.net.wifi {
enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
}
- public class WifiConfiguration implements android.os.Parcelable {
+ public deprecated class WifiConfiguration implements android.os.Parcelable {
ctor public WifiConfiguration();
method public int describeContents();
method public android.net.ProxyInfo getHttpProxy();
@@ -28626,9 +28704,11 @@ package android.net.wifi {
field public java.lang.String SSID;
field public java.util.BitSet allowedAuthAlgorithms;
field public java.util.BitSet allowedGroupCiphers;
+ field public java.util.BitSet allowedGroupMgmtCiphers;
field public java.util.BitSet allowedKeyManagement;
field public java.util.BitSet allowedPairwiseCiphers;
field public java.util.BitSet allowedProtocols;
+ field public java.util.BitSet allowedSuiteBCiphers;
field public android.net.wifi.WifiEnterpriseConfig enterpriseConfig;
field public boolean hiddenSSID;
field public boolean isHomeProviderNetwork;
@@ -28652,6 +28732,7 @@ package android.net.wifi {
public static class WifiConfiguration.GroupCipher {
field public static final int CCMP = 3; // 0x3
+ field public static final int GCMP_256 = 5; // 0x5
field public static final int TKIP = 2; // 0x2
field public static final deprecated int WEP104 = 1; // 0x1
field public static final deprecated int WEP40 = 0; // 0x0
@@ -28659,9 +28740,18 @@ package android.net.wifi {
field public static final java.lang.String varName = "group";
}
+ public static class WifiConfiguration.GroupMgmtCipher {
+ field public static final int BIP_CMAC_256 = 0; // 0x0
+ field public static final int BIP_GMAC_128 = 1; // 0x1
+ field public static final int BIP_GMAC_256 = 2; // 0x2
+ }
+
public static class WifiConfiguration.KeyMgmt {
field public static final int IEEE8021X = 3; // 0x3
field public static final int NONE = 0; // 0x0
+ field public static final int OWE = 9; // 0x9
+ field public static final int SAE = 8; // 0x8
+ field public static final int SUITE_B_192 = 10; // 0xa
field public static final int WPA_EAP = 2; // 0x2
field public static final int WPA_PSK = 1; // 0x1
field public static final java.lang.String[] strings;
@@ -28670,6 +28760,7 @@ package android.net.wifi {
public static class WifiConfiguration.PairwiseCipher {
field public static final int CCMP = 2; // 0x2
+ field public static final int GCMP_256 = 3; // 0x3
field public static final int NONE = 0; // 0x0
field public static final deprecated int TKIP = 1; // 0x1
field public static final java.lang.String[] strings;
@@ -28768,7 +28859,8 @@ package android.net.wifi {
}
public class WifiManager {
- method public int addNetwork(android.net.wifi.WifiConfiguration);
+ method public deprecated int addNetwork(android.net.wifi.WifiConfiguration);
+ method public boolean addNetworkSuggestions(java.util.List<android.net.wifi.WifiNetworkSuggestion>, android.app.PendingIntent);
method public void addOrUpdatePasspointConfiguration(android.net.wifi.hotspot2.PasspointConfiguration);
method public static int calculateSignalLevel(int, int);
method public deprecated void cancelWps(android.net.wifi.WifiManager.WpsCallback);
@@ -28776,10 +28868,10 @@ package android.net.wifi {
method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String);
method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String);
method public android.net.wifi.WifiManager.WifiLock createWifiLock(java.lang.String);
- method public boolean disableNetwork(int);
- method public boolean disconnect();
- method public boolean enableNetwork(int, boolean);
- method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
+ method public deprecated boolean disableNetwork(int);
+ method public deprecated boolean disconnect();
+ method public deprecated boolean enableNetwork(int, boolean);
+ method public deprecated java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
method public android.net.wifi.WifiInfo getConnectionInfo();
method public android.net.DhcpInfo getDhcpInfo();
method public java.util.List<android.net.wifi.hotspot2.PasspointConfiguration> getPasspointConfigurations();
@@ -28790,22 +28882,23 @@ package android.net.wifi {
method public boolean isEnhancedPowerReportingSupported();
method public boolean isP2pSupported();
method public boolean isPreferredNetworkOffloadSupported();
- method public boolean isScanAlwaysAvailable();
+ method public deprecated boolean isScanAlwaysAvailable();
method public boolean isTdlsSupported();
method public boolean isWifiEnabled();
method public deprecated boolean pingSupplicant();
- method public boolean reassociate();
- method public boolean reconnect();
- method public boolean removeNetwork(int);
+ method public deprecated boolean reassociate();
+ method public deprecated boolean reconnect();
+ method public deprecated boolean removeNetwork(int);
+ method public boolean removeNetworkSuggestions(java.util.List<android.net.wifi.WifiNetworkSuggestion>);
method public void removePasspointConfiguration(java.lang.String);
method public deprecated boolean saveConfiguration();
method public void setTdlsEnabled(java.net.InetAddress, boolean);
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
- method public boolean setWifiEnabled(boolean);
+ method public deprecated boolean setWifiEnabled(boolean);
method public void startLocalOnlyHotspot(android.net.wifi.WifiManager.LocalOnlyHotspotCallback, android.os.Handler);
method public deprecated boolean startScan();
method public deprecated void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
- method public int updateNetwork(android.net.wifi.WifiConfiguration);
+ method public deprecated int updateNetwork(android.net.wifi.WifiConfiguration);
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
field public static final deprecated int ERROR_AUTHENTICATING = 1; // 0x1
@@ -28879,6 +28972,29 @@ package android.net.wifi {
method public abstract deprecated void onSucceeded();
}
+ public class WifiNetworkConfigBuilder {
+ ctor public WifiNetworkConfigBuilder();
+ method public android.net.NetworkSpecifier buildNetworkSpecifier();
+ method public android.net.wifi.WifiNetworkSuggestion buildNetworkSuggestion();
+ method public android.net.wifi.WifiNetworkConfigBuilder setBssid(android.net.MacAddress);
+ method public android.net.wifi.WifiNetworkConfigBuilder setBssidPattern(android.net.MacAddress, android.net.MacAddress);
+ method public android.net.wifi.WifiNetworkConfigBuilder setEnterpriseConfig(android.net.wifi.WifiEnterpriseConfig);
+ method public android.net.wifi.WifiNetworkConfigBuilder setIsAppInteractionRequired();
+ method public android.net.wifi.WifiNetworkConfigBuilder setIsHiddenSsid();
+ method public android.net.wifi.WifiNetworkConfigBuilder setIsMetered();
+ method public android.net.wifi.WifiNetworkConfigBuilder setIsUserInteractionRequired();
+ method public android.net.wifi.WifiNetworkConfigBuilder setPriority(int);
+ method public android.net.wifi.WifiNetworkConfigBuilder setPskPassphrase(java.lang.String);
+ method public android.net.wifi.WifiNetworkConfigBuilder setSsid(java.lang.String);
+ method public android.net.wifi.WifiNetworkConfigBuilder setSsidPattern(android.os.PatternMatcher);
+ }
+
+ public final class WifiNetworkSuggestion implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.net.wifi.WifiNetworkSuggestion> CREATOR;
+ }
+
public deprecated class WpsInfo implements android.os.Parcelable {
ctor public deprecated WpsInfo();
ctor public deprecated WpsInfo(android.net.wifi.WpsInfo);
@@ -34041,6 +34157,7 @@ package android.os {
field public static final java.lang.String DISALLOW_INSTALL_APPS = "no_install_apps";
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES = "no_install_unknown_sources";
field public static final java.lang.String DISALLOW_INSTALL_UNKNOWN_SOURCES_GLOBALLY = "no_install_unknown_sources_globally";
+ field public static final java.lang.String DISALLOW_INTELLIGENCE_CAPTURE = "no_intelligence_capture";
field public static final java.lang.String DISALLOW_MODIFY_ACCOUNTS = "no_modify_accounts";
field public static final java.lang.String DISALLOW_MOUNT_PHYSICAL_MEDIA = "no_physical_media";
field public static final java.lang.String DISALLOW_NETWORK_RESET = "no_network_reset";
@@ -37291,6 +37408,7 @@ package android.provider {
field public static final java.lang.String ACTION_APPLICATION_SETTINGS = "android.settings.APPLICATION_SETTINGS";
field public static final java.lang.String ACTION_APP_NOTIFICATION_SETTINGS = "android.settings.APP_NOTIFICATION_SETTINGS";
field public static final java.lang.String ACTION_APP_SEARCH_SETTINGS = "android.settings.APP_SEARCH_SETTINGS";
+ field public static final java.lang.String ACTION_APP_USAGE_SETTINGS = "android.settings.action.APP_USAGE_SETTINGS";
field public static final java.lang.String ACTION_BATTERY_SAVER_SETTINGS = "android.settings.BATTERY_SAVER_SETTINGS";
field public static final java.lang.String ACTION_BLUETOOTH_SETTINGS = "android.settings.BLUETOOTH_SETTINGS";
field public static final java.lang.String ACTION_CAPTIONING_SETTINGS = "android.settings.CAPTIONING_SETTINGS";
@@ -42847,7 +42965,6 @@ package android.telephony {
method public int getLevel();
method public int getRsrp();
method public int getRsrq();
- method public int getRssi();
method public int getRssnr();
method public int getTimingAdvance();
method public void writeToParcel(android.os.Parcel, int);
@@ -50041,17 +50158,29 @@ package android.view {
method public int getStableInsetLeft();
method public int getStableInsetRight();
method public int getStableInsetTop();
+ method public android.graphics.Insets getStableInsets();
method public int getSystemWindowInsetBottom();
method public int getSystemWindowInsetLeft();
method public int getSystemWindowInsetRight();
method public int getSystemWindowInsetTop();
+ method public android.graphics.Insets getSystemWindowInsets();
method public boolean hasInsets();
method public boolean hasStableInsets();
method public boolean hasSystemWindowInsets();
+ method public android.view.WindowInsets inset(int, int, int, int);
method public boolean isConsumed();
method public boolean isRound();
- method public android.view.WindowInsets replaceSystemWindowInsets(int, int, int, int);
- method public android.view.WindowInsets replaceSystemWindowInsets(android.graphics.Rect);
+ method public deprecated android.view.WindowInsets replaceSystemWindowInsets(int, int, int, int);
+ method public deprecated android.view.WindowInsets replaceSystemWindowInsets(android.graphics.Rect);
+ }
+
+ public static class WindowInsets.Builder {
+ ctor public WindowInsets.Builder();
+ ctor public WindowInsets.Builder(android.view.WindowInsets);
+ method public android.view.WindowInsets build();
+ method public android.view.WindowInsets.Builder setDisplayCutout(android.view.DisplayCutout);
+ method public android.view.WindowInsets.Builder setStableInsets(android.graphics.Insets);
+ method public android.view.WindowInsets.Builder setSystemWindowInsets(android.graphics.Insets);
}
public abstract interface WindowManager implements android.view.ViewManager {
@@ -51484,6 +51613,17 @@ package android.view.inputmethod {
}
+package android.view.intelligence {
+
+ public final class IntelligenceManager {
+ method public void disableContentCapture();
+ method public android.content.ComponentName getIntelligenceServiceComponentName();
+ method public boolean isContentCaptureEnabled();
+ field public static final int FLAG_USER_INPUT = 1; // 0x1
+ }
+
+}
+
package android.view.textclassifier {
public final class ConversationActions implements android.os.Parcelable {
diff --git a/api/system-current.txt b/api/system-current.txt
index a04a39867595..123ca5109696 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24,6 +24,7 @@ package android {
field public static final java.lang.String BIND_DIRECTORY_SEARCH = "android.permission.BIND_DIRECTORY_SEARCH";
field public static final java.lang.String BIND_EUICC_SERVICE = "android.permission.BIND_EUICC_SERVICE";
field public static final java.lang.String BIND_IMS_SERVICE = "android.permission.BIND_IMS_SERVICE";
+ field public static final java.lang.String BIND_INTELLIGENCE_SERVICE = "android.permission.BIND_INTELLIGENCE_SERVICE";
field public static final java.lang.String BIND_KEYGUARD_APPWIDGET = "android.permission.BIND_KEYGUARD_APPWIDGET";
field public static final java.lang.String BIND_NETWORK_RECOMMENDATION_SERVICE = "android.permission.BIND_NETWORK_RECOMMENDATION_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
@@ -299,8 +300,8 @@ package android.app {
method public static java.lang.String[] getOpStrs();
method public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, java.lang.String, int[]);
method public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOpStrs(java.lang.String[]);
+ method public static int opToDefaultMode(java.lang.String);
method public static java.lang.String opToPermission(java.lang.String);
- method public void resetUidMode(java.lang.String, int, boolean);
method public void setMode(java.lang.String, int, java.lang.String, int);
method public void setUidMode(java.lang.String, int, int);
field public static final java.lang.String OPSTR_ACCEPT_HANDOVER = "android:accept_handover";
@@ -614,6 +615,14 @@ package android.app.admin {
}
+package android.app.assist {
+
+ public static class AssistStructure.ViewNode {
+ ctor public AssistStructure.ViewNode();
+ }
+
+}
+
package android.app.backup {
public class BackupDataInput {
@@ -3606,7 +3615,7 @@ package android.net.wifi {
field public byte id;
}
- public class WifiConfiguration implements android.os.Parcelable {
+ public deprecated class WifiConfiguration implements android.os.Parcelable {
method public boolean hasNoInternetAccess();
method public boolean isEphemeral();
method public boolean isNoInternetAccessExpected();
@@ -3632,11 +3641,16 @@ package android.net.wifi {
method public int getWifiApState();
method public boolean isDeviceToApRttSupported();
method public boolean isDeviceToDeviceRttSupported();
+ method public boolean isOweSupported();
method public boolean isPortableHotspotSupported();
method public boolean isWifiApEnabled();
method public boolean isWifiScannerSupported();
+ method public void registerNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback, android.os.Handler);
+ method public boolean isWpa3SaeSupported();
+ method public boolean isWpa3SuiteBSupported();
method public boolean setWifiApConfiguration(android.net.wifi.WifiConfiguration);
method public boolean startScan(android.os.WorkSource);
+ method public void unregisterNetworkRequestMatchCallback(android.net.wifi.WifiManager.NetworkRequestMatchCallback);
field public static final int CHANGE_REASON_ADDED = 0; // 0x0
field public static final int CHANGE_REASON_CONFIG_CHANGE = 2; // 0x2
field public static final int CHANGE_REASON_REMOVED = 1; // 0x1
@@ -3664,6 +3678,18 @@ package android.net.wifi {
method public abstract void onSuccess();
}
+ public static abstract interface WifiManager.NetworkRequestMatchCallback {
+ method public abstract void onMatch(java.util.List<android.net.wifi.WifiConfiguration>);
+ method public abstract void onUserSelectionCallbackRegistration(android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback);
+ method public abstract void onUserSelectionConnectFailure(android.net.wifi.WifiConfiguration);
+ method public abstract void onUserSelectionConnectSuccess(android.net.wifi.WifiConfiguration);
+ }
+
+ public static abstract interface WifiManager.NetworkRequestUserSelectionCallback {
+ method public abstract void reject();
+ method public abstract void select(android.net.wifi.WifiConfiguration);
+ }
+
public class WifiNetworkConnectionStatistics implements android.os.Parcelable {
ctor public WifiNetworkConnectionStatistics(int, int);
ctor public WifiNetworkConnectionStatistics();
@@ -4861,6 +4887,36 @@ package android.service.euicc {
}
+package android.service.intelligence {
+
+ public abstract class IntelligenceService extends android.app.Service {
+ ctor public IntelligenceService();
+ method public abstract void onContentCaptureEvent(android.service.intelligence.InteractionSessionId, java.util.List<android.view.intelligence.ContentCaptureEvent>);
+ method public void onCreateInteractionSession(android.service.intelligence.InteractionContext, android.service.intelligence.InteractionSessionId);
+ method public void onDestroyInteractionSession(android.service.intelligence.InteractionSessionId);
+ field public static final java.lang.String SERVICE_INTERFACE = "android.service.intelligence.IntelligenceService";
+ }
+
+ public final class InteractionContext implements android.os.Parcelable {
+ method public int describeContents();
+ method public android.content.ComponentName getActivityComponent();
+ method public int getDisplayId();
+ method public int getFlags();
+ method public int getTaskId();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.intelligence.InteractionContext> CREATOR;
+ field public static final int FLAG_DISABLED_BY_APP = 1; // 0x1
+ field public static final int FLAG_DISABLED_BY_FLAG_SECURE = 2; // 0x2
+ }
+
+ public final class InteractionSessionId implements android.os.Parcelable {
+ method public int describeContents();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.service.intelligence.InteractionSessionId> CREATOR;
+ }
+
+}
+
package android.service.notification {
public final class Adjustment implements android.os.Parcelable {
@@ -5864,6 +5920,7 @@ package android.telephony.euicc {
field public static final int RESET_OPTION_DELETE_FIELD_LOADED_TEST_PROFILES = 2; // 0x2
field public static final int RESET_OPTION_DELETE_OPERATIONAL_PROFILES = 1; // 0x1
field public static final int RESET_OPTION_RESET_DEFAULT_SMDP_ADDRESS = 4; // 0x4
+ field public static final int RESULT_CALLER_NOT_ALLOWED = -3; // 0xfffffffd
field public static final int RESULT_EUICC_NOT_FOUND = -2; // 0xfffffffe
field public static final int RESULT_OK = 0; // 0x0
field public static final int RESULT_UNKNOWN_ERROR = -1; // 0xffffffff
@@ -5988,6 +6045,7 @@ package android.telephony.ims {
method public void setCallExtra(java.lang.String, java.lang.String);
method public void setCallExtraBoolean(java.lang.String, boolean);
method public void setCallExtraInt(java.lang.String, int);
+ method public void setCallRestrictCause(int);
method public void updateCallExtras(android.telephony.ims.ImsCallProfile);
method public void updateCallType(android.telephony.ims.ImsCallProfile);
method public void updateMediaProfile(android.telephony.ims.ImsCallProfile);
@@ -6898,6 +6956,40 @@ package android.view.accessibility {
}
+package android.view.intelligence {
+
+ public final class ContentCaptureEvent implements android.os.Parcelable {
+ method public int describeContents();
+ method public long getEventTime();
+ method public int getFlags();
+ method public android.view.autofill.AutofillId getId();
+ method public java.lang.CharSequence getText();
+ method public int getType();
+ method public android.view.intelligence.ViewNode getViewNode();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.view.intelligence.ContentCaptureEvent> CREATOR;
+ field public static final int TYPE_ACTIVITY_PAUSED = 3; // 0x3
+ field public static final int TYPE_ACTIVITY_RESUMED = 2; // 0x2
+ field public static final int TYPE_ACTIVITY_STARTED = 1; // 0x1
+ field public static final int TYPE_ACTIVITY_STOPPED = 4; // 0x4
+ field public static final int TYPE_VIEW_ADDED = 5; // 0x5
+ field public static final int TYPE_VIEW_REMOVED = 6; // 0x6
+ field public static final int TYPE_VIEW_TEXT_CHANGED = 7; // 0x7
+ }
+
+ public final class IntelligenceManager {
+ method public java.util.Set<android.content.ComponentName> getContentCaptureDisabledActivities();
+ method public java.util.Set<java.lang.String> getContentCaptureDisabledPackages();
+ method public void setActivityContentCaptureEnabled(android.content.ComponentName, boolean);
+ method public void setPackageContentCaptureEnabled(java.lang.String, boolean);
+ }
+
+ public final class ViewNode extends android.app.assist.AssistStructure.ViewNode {
+ method public android.view.autofill.AutofillId getParentAutofillId();
+ }
+
+}
+
package android.webkit {
public abstract class CookieManager {
diff --git a/cmds/statsd/Android.bp b/cmds/statsd/Android.bp
index 6547b3ad7ad5..a3cd8a3bb32b 100644
--- a/cmds/statsd/Android.bp
+++ b/cmds/statsd/Android.bp
@@ -205,10 +205,6 @@ cc_test {
],
srcs: [
- // atom_field_options.proto needs field_options.proto, but that is
- // not included in libprotobuf-cpp-lite, so compile it here.
- ":libprotobuf-internal-protos",
-
"src/atom_field_options.proto",
"src/atoms.proto",
"src/stats_log.proto",
@@ -263,11 +259,11 @@ cc_test {
],
proto: {
- type: "lite",
+ type: "full",
include_dirs: ["external/protobuf/src"],
},
- shared_libs: ["libprotobuf-cpp-lite"],
+ shared_libs: ["libprotobuf-cpp-full"],
}
@@ -280,10 +276,6 @@ cc_benchmark {
defaults: ["statsd_defaults"],
srcs: [
- // atom_field_options.proto needs field_options.proto, but that is
- // not included in libprotobuf-cpp-lite, so compile it here.
- ":libprotobuf-internal-protos",
-
"src/atom_field_options.proto",
"src/atoms.proto",
"src/stats_log.proto",
@@ -298,7 +290,7 @@ cc_benchmark {
],
proto: {
- type: "lite",
+ type: "full",
include_dirs: ["external/protobuf/src"],
},
@@ -320,7 +312,7 @@ cc_benchmark {
shared_libs: [
"libgtest_prod",
"libstatslog",
- "libprotobuf-cpp-lite",
+ "libprotobuf-cpp-full",
],
}
diff --git a/cmds/statsd/src/FieldValue.cpp b/cmds/statsd/src/FieldValue.cpp
index fc1a61cac558..80ed80776829 100644
--- a/cmds/statsd/src/FieldValue.cpp
+++ b/cmds/statsd/src/FieldValue.cpp
@@ -18,6 +18,7 @@
#include "Log.h"
#include "FieldValue.h"
#include "HashableDimensionKey.h"
+#include "math.h"
namespace android {
namespace os {
@@ -174,6 +175,25 @@ std::string Value::toString() const {
}
}
+bool Value::isZero() const {
+ switch (type) {
+ case INT:
+ return int_value == 0;
+ case LONG:
+ return long_value == 0;
+ case FLOAT:
+ return fabs(float_value) <= std::numeric_limits<float>::epsilon();
+ case DOUBLE:
+ return fabs(double_value) <= std::numeric_limits<double>::epsilon();
+ case STRING:
+ return str_value.size() == 0;
+ case STORAGE:
+ return storage_value.size() == 0;
+ default:
+ return false;
+ }
+}
+
bool Value::operator==(const Value& that) const {
if (type != that.getType()) return false;
diff --git a/cmds/statsd/src/FieldValue.h b/cmds/statsd/src/FieldValue.h
index 77163f9d8619..a5d00ac4e72b 100644
--- a/cmds/statsd/src/FieldValue.h
+++ b/cmds/statsd/src/FieldValue.h
@@ -331,6 +331,8 @@ struct Value {
std::string toString() const;
+ bool isZero() const;
+
Type getType() const {
return type;
}
diff --git a/cmds/statsd/src/StatsLogProcessor.cpp b/cmds/statsd/src/StatsLogProcessor.cpp
index 12e2560a43b5..f0f599317352 100644
--- a/cmds/statsd/src/StatsLogProcessor.cpp
+++ b/cmds/statsd/src/StatsLogProcessor.cpp
@@ -272,26 +272,25 @@ void StatsLogProcessor::dumpStates(int out, bool verbose) {
}
/*
- * onDumpReport dumps serialized ConfigMetricsReportList into outData.
+ * onDumpReport dumps serialized ConfigMetricsReportList into proto.
*/
void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
const DumpReportReason dumpReportReason,
- vector<uint8_t>* outData) {
+ ProtoOutputStream* proto) {
std::lock_guard<std::mutex> lock(mMetricsMutex);
- ProtoOutputStream proto;
-
// Start of ConfigKey.
- uint64_t configKeyToken = proto.start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
- proto.write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
- proto.write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
- proto.end(configKeyToken);
+ uint64_t configKeyToken = proto->start(FIELD_TYPE_MESSAGE | FIELD_ID_CONFIG_KEY);
+ proto->write(FIELD_TYPE_INT32 | FIELD_ID_UID, key.GetUid());
+ proto->write(FIELD_TYPE_INT64 | FIELD_ID_ID, (long long)key.GetId());
+ proto->end(configKeyToken);
// End of ConfigKey.
// Then, check stats-data directory to see there's any file containing
// ConfigMetricsReport from previous shutdowns to concatenate to reports.
- StorageManager::appendConfigMetricsReport(key, &proto);
+ StorageManager::appendConfigMetricsReport(key, proto);
auto it = mMetricsManagers.find(key);
if (it != mMetricsManagers.end()) {
@@ -301,14 +300,27 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim
// Start of ConfigMetricsReport (reports).
uint64_t reportsToken =
- proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS);
+ proto->start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS);
onConfigMetricsReportLocked(key, dumpTimeStampNs, include_current_partial_bucket,
- dumpReportReason, &proto);
- proto.end(reportsToken);
+ erase_data, dumpReportReason, proto);
+ proto->end(reportsToken);
// End of ConfigMetricsReport (reports).
} else {
ALOGW("Config source %s does not exist", key.ToString().c_str());
}
+}
+
+/*
+ * onDumpReport dumps serialized ConfigMetricsReportList into outData.
+ */
+void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTimeStampNs,
+ const bool include_current_partial_bucket,
+ const bool erase_data,
+ const DumpReportReason dumpReportReason,
+ vector<uint8_t>* outData) {
+ ProtoOutputStream proto;
+ onDumpReport(key, dumpTimeStampNs, include_current_partial_bucket, erase_data,
+ dumpReportReason, &proto);
if (outData != nullptr) {
outData->clear();
@@ -332,6 +344,7 @@ void StatsLogProcessor::onDumpReport(const ConfigKey& key, const int64_t dumpTim
void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key,
const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
const DumpReportReason dumpReportReason,
ProtoOutputStream* proto) {
// We already checked whether key exists in mMetricsManagers in
@@ -348,7 +361,7 @@ void StatsLogProcessor::onConfigMetricsReportLocked(const ConfigKey& key,
// First, fill in ConfigMetricsReport using current data on memory, which
// starts from filling in StatsLogReport's.
it->second->onDumpReport(dumpTimeStampNs, include_current_partial_bucket,
- &str_set, proto);
+ erase_data, &str_set, proto);
// Fill in UidMap if there is at least one metric to report.
// This skips the uid map if it's an empty config.
@@ -479,7 +492,7 @@ void StatsLogProcessor::WriteDataToDiskLocked(const ConfigKey& key,
}
ProtoOutputStream proto;
onConfigMetricsReportLocked(key, timestampNs, true /* include_current_partial_bucket*/,
- dumpReportReason, &proto);
+ true /* erase_data */, dumpReportReason, &proto);
string file_name = StringPrintf("%s/%ld_%d_%lld", STATS_DATA_DIR,
(long)getWallClockSec(), key.GetUid(), (long long)key.GetId());
android::base::unique_fd fd(open(file_name.c_str(),
diff --git a/cmds/statsd/src/StatsLogProcessor.h b/cmds/statsd/src/StatsLogProcessor.h
index 3e8b9b8d5df5..ecfd819a3399 100644
--- a/cmds/statsd/src/StatsLogProcessor.h
+++ b/cmds/statsd/src/StatsLogProcessor.h
@@ -61,8 +61,11 @@ public:
size_t GetMetricsSize(const ConfigKey& key) const;
void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
- const bool include_current_partial_bucket,
+ const bool include_current_partial_bucket, const bool erase_data,
const DumpReportReason dumpReportReason, vector<uint8_t>* outData);
+ void onDumpReport(const ConfigKey& key, const int64_t dumpTimeNs,
+ const bool include_current_partial_bucket, const bool erase_data,
+ const DumpReportReason dumpReportReason, ProtoOutputStream* proto);
/* Tells MetricsManager that the alarms in alarmSet have fired. Modifies anomaly alarmSet. */
void onAnomalyAlarmFired(
@@ -141,6 +144,7 @@ private:
void onConfigMetricsReportLocked(const ConfigKey& key, const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
const DumpReportReason dumpReportReason,
util::ProtoOutputStream* proto);
diff --git a/cmds/statsd/src/StatsService.cpp b/cmds/statsd/src/StatsService.cpp
index ce2877731882..27685fc108a0 100644
--- a/cmds/statsd/src/StatsService.cpp
+++ b/cmds/statsd/src/StatsService.cpp
@@ -46,6 +46,8 @@
using namespace android;
using android::base::StringPrintf;
+using android::util::FIELD_COUNT_REPEATED;
+using android::util::FIELD_TYPE_MESSAGE;
namespace android {
namespace os {
@@ -58,6 +60,9 @@ constexpr const char* kOpUsage = "android:get_usage_stats";
#define STATS_SERVICE_DIR "/data/misc/stats-service"
+// for StatsDataDumpProto
+const int FIELD_ID_REPORTS_LIST = 1;
+
static binder::Status ok() {
return binder::Status::ok();
}
@@ -224,31 +229,48 @@ status_t StatsService::onTransact(uint32_t code, const Parcel& data, Parcel* rep
}
/**
- * Write debugging data about statsd.
+ * Write data from statsd.
+ * Format for statsdStats: adb shell dumpsys stats --metadata [-v] [--proto]
+ * Format for data report: adb shell dumpsys stats [anything other than --metadata] [--proto]
+ * Anything ending in --proto will be in proto format.
+ * Anything without --metadata as the first argument will be report information.
+ * (bugreports call "adb shell dumpsys stats --dump-priority NORMAL -a --proto")
+ * TODO: Come up with a more robust method of enacting <serviceutils/PriorityDumper.h>.
*/
status_t StatsService::dump(int fd, const Vector<String16>& args) {
if (!checkCallingPermission(String16(kPermissionDump))) {
return PERMISSION_DENIED;
}
-
- bool verbose = false;
- bool proto = false;
- if (args.size() > 0 && !args[0].compare(String16("-v"))) {
- verbose = true;
+ int lastArg = args.size() - 1;
+ bool asProto = false;
+ if (lastArg >= 0 && !args[lastArg].compare(String16("--proto"))) { // last argument
+ asProto = true;
+ lastArg--;
}
- if (args.size() > 0 && !args[args.size()-1].compare(String16("--proto"))) {
- proto = true;
+ if (args.size() > 0 && !args[0].compare(String16("--metadata"))) { // first argument
+ // Request is to dump statsd stats.
+ bool verbose = false;
+ if (lastArg >= 0 && !args[lastArg].compare(String16("-v"))) {
+ verbose = true;
+ lastArg--;
+ }
+ dumpStatsdStats(fd, verbose, asProto);
+ } else {
+ // Request is to dump statsd report data.
+ if (asProto) {
+ dumpIncidentSection(fd);
+ } else {
+ dprintf(fd, "Non-proto format of stats data dump not available; see proto version.\n");
+ }
}
- dump_impl(fd, verbose, proto);
-
return NO_ERROR;
}
/**
* Write debugging data about statsd in text or proto format.
*/
-void StatsService::dump_impl(int out, bool verbose, bool proto) {
+void StatsService::dumpStatsdStats(int out, bool verbose, bool proto) {
if (proto) {
vector<uint8_t> data;
StatsdStats::getInstance().dumpStats(&data, false); // does not reset statsdStats.
@@ -262,6 +284,22 @@ void StatsService::dump_impl(int out, bool verbose, bool proto) {
}
/**
+ * Write stats report data in StatsDataDumpProto incident section format.
+ */
+void StatsService::dumpIncidentSection(int out) {
+ ProtoOutputStream proto;
+ for (const ConfigKey& configKey : mConfigManager->GetAllConfigKeys()) {
+ uint64_t reportsListToken =
+ proto.start(FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_REPORTS_LIST);
+ mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(),
+ true /* includeCurrentBucket */, false /* erase_data */,
+ ADB_DUMP, &proto);
+ proto.end(reportsListToken);
+ proto.flush(out);
+ }
+}
+
+/**
* Implementation of the adb shell cmd stats command.
*/
status_t StatsService::command(int in, int out, int err, Vector<String8>& args,
@@ -283,7 +321,7 @@ status_t StatsService::command(int in, int out, int err, Vector<String8>& args,
}
if (!args[0].compare(String8("dump-report"))) {
- return cmd_dump_report(out, err, args);
+ return cmd_dump_report(out, args);
}
if (!args[0].compare(String8("pull-source")) && args.size() > 1) {
@@ -546,7 +584,7 @@ status_t StatsService::cmd_config(int in, int out, int err, Vector<String8>& arg
return UNKNOWN_ERROR;
}
-status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>& args) {
+status_t StatsService::cmd_dump_report(int out, const Vector<String8>& args) {
if (mProcessor != nullptr) {
int argCount = args.size();
bool good = false;
@@ -589,14 +627,13 @@ status_t StatsService::cmd_dump_report(int out, int err, const Vector<String8>&
if (good) {
vector<uint8_t> data;
mProcessor->onDumpReport(ConfigKey(uid, StrToInt64(name)), getElapsedRealtimeNs(),
- includeCurrentBucket, ADB_DUMP, &data);
+ includeCurrentBucket, true /* erase_data */, ADB_DUMP, &data);
if (proto) {
for (size_t i = 0; i < data.size(); i ++) {
dprintf(out, "%c", data[i]);
}
} else {
- dprintf(out, "Dump report for Config [%d,%s]\n", uid, name.c_str());
- dprintf(out, "See the StatsLogReport in logcat...\n");
+ dprintf(out, "Non-proto stats data dump not currently supported.\n");
}
return android::OK;
} else {
@@ -888,7 +925,7 @@ Status StatsService::getData(int64_t key, const String16& packageName, vector<ui
VLOG("StatsService::getData with Pid %i, Uid %i", ipc->getCallingPid(), ipc->getCallingUid());
ConfigKey configKey(ipc->getCallingUid(), key);
mProcessor->onDumpReport(configKey, getElapsedRealtimeNs(), false /* include_current_bucket*/,
- GET_DATA_CALLED, output);
+ true /* erase_data */, GET_DATA_CALLED, output);
return Status::ok();
}
diff --git a/cmds/statsd/src/StatsService.h b/cmds/statsd/src/StatsService.h
index cbf34292c1d4..4a5f05fef034 100644
--- a/cmds/statsd/src/StatsService.h
+++ b/cmds/statsd/src/StatsService.h
@@ -213,9 +213,14 @@ private:
uint32_t serial);
/**
- * Text or proto output of dumpsys.
+ * Proto output of statsd report data dumpsys, wrapped in a StatsDataDumpProto.
*/
- void dump_impl(int outFd, bool verbose, bool proto);
+ void dumpIncidentSection(int outFd);
+
+ /**
+ * Text or proto output of statsdStats dumpsys.
+ */
+ void dumpStatsdStats(int outFd, bool verbose, bool proto);
/**
* Print usage information for the commands
@@ -240,7 +245,7 @@ private:
/**
* Print the event log.
*/
- status_t cmd_dump_report(int outFd, int err, const Vector<String8>& args);
+ status_t cmd_dump_report(int outFd, const Vector<String8>& args);
/**
* Print the mapping of uids to package names.
diff --git a/cmds/statsd/src/anomaly/AnomalyTracker.cpp b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
index 13ab844f5eeb..ee111cddcfd7 100644
--- a/cmds/statsd/src/anomaly/AnomalyTracker.cpp
+++ b/cmds/statsd/src/anomaly/AnomalyTracker.cpp
@@ -24,7 +24,6 @@
#include "subscriber/IncidentdReporter.h"
#include "subscriber/SubscriberReporter.h"
-#include <inttypes.h>
#include <statslog.h>
#include <time.h>
@@ -224,7 +223,7 @@ void AnomalyTracker::declareAnomaly(const int64_t& timestampNs, const MetricDime
}
if (!mSubscriptions.empty()) {
- ALOGI("An anomaly (%" PRId64 ") %s has occurred! Informing subscribers.",
+ ALOGI("An anomaly (%lld) %s has occurred! Informing subscribers.",
mAlert.id(), key.toString().c_str());
informSubscribers(key);
} else {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.cpp b/cmds/statsd/src/guardrail/StatsdStats.cpp
index d2919c51a65e..a0d77d6f922d 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.cpp
+++ b/cmds/statsd/src/guardrail/StatsdStats.cpp
@@ -362,11 +362,17 @@ void StatsdStats::notePullDelay(int pullAtomId, int64_t pullDelayNs) {
lock_guard<std::mutex> lock(mLock);
auto& pullStats = mPulledAtomStats[pullAtomId];
pullStats.maxPullDelayNs = std::max(pullStats.maxPullDelayNs, pullDelayNs);
- pullStats.avgPullDelayNs = (pullStats.avgPullDelayNs * pullStats.numPullDelay + pullDelayNs) /
- (pullStats.numPullDelay + 1);
+ pullStats.avgPullDelayNs =
+ (pullStats.avgPullDelayNs * pullStats.numPullDelay + pullDelayNs) /
+ (pullStats.numPullDelay + 1);
pullStats.numPullDelay += 1;
}
+void StatsdStats::notePullDataError(int pullAtomId) {
+ lock_guard<std::mutex> lock(mLock);
+ mPulledAtomStats[pullAtomId].dataError++;
+}
+
void StatsdStats::noteAtomLogged(int atomId, int32_t timeSec) {
lock_guard<std::mutex> lock(mLock);
@@ -422,6 +428,7 @@ void StatsdStats::resetInternalLocked() {
pullStats.second.avgPullDelayNs = 0;
pullStats.second.maxPullDelayNs = 0;
pullStats.second.numPullDelay = 0;
+ pullStats.second.dataError = 0;
}
}
@@ -530,11 +537,11 @@ void StatsdStats::dumpStats(int out) const {
dprintf(out,
"Atom %d->(total pull)%ld, (pull from cache)%ld, (min pull interval)%ld, (average "
"pull time nanos)%lld, (max pull time nanos)%lld, (average pull delay nanos)%lld, "
- "(max pull delay nanos)%lld\n",
+ "(max pull delay nanos)%lld, (data error)%ld\n",
(int)pair.first, (long)pair.second.totalPull, (long)pair.second.totalPullFromCache,
(long)pair.second.minPullIntervalSec, (long long)pair.second.avgPullTimeNs,
(long long)pair.second.maxPullTimeNs, (long long)pair.second.avgPullDelayNs,
- (long long)pair.second.maxPullDelayNs);
+ (long long)pair.second.maxPullDelayNs, pair.second.dataError);
}
if (mAnomalyAlarmRegisteredStats > 0) {
diff --git a/cmds/statsd/src/guardrail/StatsdStats.h b/cmds/statsd/src/guardrail/StatsdStats.h
index 777d8652d2b6..2008abdb2345 100644
--- a/cmds/statsd/src/guardrail/StatsdStats.h
+++ b/cmds/statsd/src/guardrail/StatsdStats.h
@@ -279,6 +279,11 @@ public:
void notePullFromCache(int pullAtomId);
/*
+ * Notify data error for pulled atom.
+ */
+ void notePullDataError(int pullAtomId);
+
+ /*
* Records time for actual pulling, not including those served from cache and not including
* statsd processing delays.
*/
@@ -329,6 +334,7 @@ public:
int64_t avgPullDelayNs = 0;
int64_t maxPullDelayNs = 0;
long numPullDelay = 0;
+ long dataError = 0;
} PulledAtomStats;
private:
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 6b8c12a893e8..eddc86eca798 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -82,7 +82,9 @@ int main(int /*argc*/, char** /*argv*/) {
// Create the service
gStatsService = new StatsService(looper);
- if (defaultServiceManager()->addService(String16("stats"), gStatsService) != 0) {
+ if (defaultServiceManager()->addService(String16("stats"), gStatsService, false,
+ IServiceManager::DUMP_FLAG_PRIORITY_NORMAL | IServiceManager::DUMP_FLAG_PROTO)
+ != 0) {
ALOGE("Failed to add service as AIDL service");
return -1;
}
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.cpp b/cmds/statsd/src/metrics/CountMetricProducer.cpp
index bd94800a327d..5ca88142f152 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/CountMetricProducer.cpp
@@ -143,6 +143,7 @@ void CountMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
if (include_current_partial_bucket) {
@@ -230,7 +231,9 @@ void CountMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
protoOutput->end(protoToken);
- mPastBuckets.clear();
+ if (erase_data) {
+ mPastBuckets.clear();
+ }
}
void CountMetricProducer::dropDataLocked(const int64_t dropTimeNs) {
diff --git a/cmds/statsd/src/metrics/CountMetricProducer.h b/cmds/statsd/src/metrics/CountMetricProducer.h
index 39d4ae2f36a5..1ac4426468d8 100644
--- a/cmds/statsd/src/metrics/CountMetricProducer.h
+++ b/cmds/statsd/src/metrics/CountMetricProducer.h
@@ -56,6 +56,7 @@ private:
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.cpp b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
index dd3402dae2f8..35deffe5db97 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.cpp
@@ -453,6 +453,7 @@ void DurationMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
if (include_current_partial_bucket) {
@@ -541,7 +542,9 @@ void DurationMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
}
protoOutput->end(protoToken);
- mPastBuckets.clear();
+ if (erase_data) {
+ mPastBuckets.clear();
+ }
}
void DurationMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
diff --git a/cmds/statsd/src/metrics/DurationMetricProducer.h b/cmds/statsd/src/metrics/DurationMetricProducer.h
index 12addb8727f1..1b830a3f69f5 100644
--- a/cmds/statsd/src/metrics/DurationMetricProducer.h
+++ b/cmds/statsd/src/metrics/DurationMetricProducer.h
@@ -63,6 +63,7 @@ private:
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.cpp b/cmds/statsd/src/metrics/EventMetricProducer.cpp
index afd8ec2212fe..a18e406b74ca 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/EventMetricProducer.cpp
@@ -105,6 +105,7 @@ void EventMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
if (mProto->size() <= 0) {
@@ -120,7 +121,9 @@ void EventMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
protoOutput->write(FIELD_TYPE_MESSAGE | FIELD_ID_EVENT_METRICS,
reinterpret_cast<char*>(buffer.get()->data()), buffer.get()->size());
- mProto->clear();
+ if (erase_data) {
+ mProto->clear();
+ }
}
void EventMetricProducer::onConditionChangedLocked(const bool conditionMet,
diff --git a/cmds/statsd/src/metrics/EventMetricProducer.h b/cmds/statsd/src/metrics/EventMetricProducer.h
index 7f7aa3711255..96adfdd48743 100644
--- a/cmds/statsd/src/metrics/EventMetricProducer.h
+++ b/cmds/statsd/src/metrics/EventMetricProducer.h
@@ -47,6 +47,7 @@ private:
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
index f5a16e96fdf5..05103a962c33 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.cpp
@@ -182,6 +182,7 @@ void GaugeMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
VLOG("Gauge metric %lld report now...", (long long)mMetricId);
@@ -226,7 +227,6 @@ void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
(long long)(NanoToMillis(pair.second)));
protoOutput->end(wrapperToken);
}
- mSkippedBuckets.clear();
for (const auto& pair : mPastBuckets) {
const MetricDimensionKey& dimensionKey = pair.first;
@@ -304,7 +304,11 @@ void GaugeMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
}
protoOutput->end(protoToken);
- mPastBuckets.clear();
+
+ if (erase_data) {
+ mPastBuckets.clear();
+ mSkippedBuckets.clear();
+ }
}
void GaugeMetricProducer::pullAndMatchEventsLocked(const int64_t timestampNs) {
diff --git a/cmds/statsd/src/metrics/GaugeMetricProducer.h b/cmds/statsd/src/metrics/GaugeMetricProducer.h
index 99827bb2ad2d..5866139047ae 100644
--- a/cmds/statsd/src/metrics/GaugeMetricProducer.h
+++ b/cmds/statsd/src/metrics/GaugeMetricProducer.h
@@ -94,6 +94,7 @@ protected:
private:
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
diff --git a/cmds/statsd/src/metrics/MetricProducer.h b/cmds/statsd/src/metrics/MetricProducer.h
index b21fd501c2d0..127cbbde1a3a 100644
--- a/cmds/statsd/src/metrics/MetricProducer.h
+++ b/cmds/statsd/src/metrics/MetricProducer.h
@@ -133,10 +133,12 @@ public:
// This method clears all the past buckets.
void onDumpReport(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) {
std::lock_guard<std::mutex> lock(mMutex);
- return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, str_set, protoOutput);
+ return onDumpReportLocked(dumpTimeNs, include_current_partial_bucket, erase_data,
+ str_set, protoOutput);
}
void clearPastBuckets(const int64_t dumpTimeNs) {
@@ -210,6 +212,7 @@ protected:
const int64_t eventTime) = 0;
virtual void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) = 0;
virtual void clearPastBucketsLocked(const int64_t dumpTimeNs) = 0;
diff --git a/cmds/statsd/src/metrics/MetricsManager.cpp b/cmds/statsd/src/metrics/MetricsManager.cpp
index f85ba1f93e8c..4244d5bed23b 100644
--- a/cmds/statsd/src/metrics/MetricsManager.cpp
+++ b/cmds/statsd/src/metrics/MetricsManager.cpp
@@ -197,6 +197,7 @@ void MetricsManager::dropData(const int64_t dropTimeNs) {
void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
VLOG("=========================Metric Reports Start==========================");
@@ -206,11 +207,11 @@ void MetricsManager::onDumpReport(const int64_t dumpTimeStampNs,
uint64_t token = protoOutput->start(
FIELD_TYPE_MESSAGE | FIELD_COUNT_REPEATED | FIELD_ID_METRICS);
if (mHashStringsInReport) {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, str_set,
- protoOutput);
+ producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
+ str_set, protoOutput);
} else {
- producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, nullptr,
- protoOutput);
+ producer->onDumpReport(dumpTimeStampNs, include_current_partial_bucket, erase_data,
+ nullptr, protoOutput);
}
protoOutput->end(token);
} else {
diff --git a/cmds/statsd/src/metrics/MetricsManager.h b/cmds/statsd/src/metrics/MetricsManager.h
index 649222ffef9d..a4672b68f2bc 100644
--- a/cmds/statsd/src/metrics/MetricsManager.h
+++ b/cmds/statsd/src/metrics/MetricsManager.h
@@ -107,6 +107,7 @@ public:
virtual void onDumpReport(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput);
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.cpp b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
index 192a54b7e0a3..c8b1cf07eb32 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.cpp
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.cpp
@@ -92,7 +92,9 @@ ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric
: StatsdStats::kDimensionKeySizeHardLimit),
mUseAbsoluteValueOnReset(metric.use_absolute_value_on_reset()),
mAggregationType(metric.aggregation_type()),
- mValueType(metric.aggregation_type() == ValueMetric::AVG ? DOUBLE : LONG) {
+ mUseDiff(metric.has_use_diff() ? metric.use_diff() : (mIsPulled ? true : false)),
+ mValueDirection(metric.value_direction()),
+ mSkipZeroDiffOutput(metric.skip_zero_diff_output()) {
int64_t bucketSizeMills = 0;
if (metric.has_bucket()) {
bucketSizeMills = TimeUnitToBucketSizeInMillisGuardrailed(key.GetUid(), metric.bucket());
@@ -125,24 +127,25 @@ ValueMetricProducer::ValueMetricProducer(const ConfigKey& key, const ValueMetric
}
mConditionSliced = (metric.links().size() > 0) || (mDimensionsInCondition.size() > 0);
mSliceByPositionALL = HasPositionALL(metric.dimensions_in_what()) ||
- HasPositionALL(metric.dimensions_in_condition());
+ HasPositionALL(metric.dimensions_in_condition());
flushIfNeededLocked(startTimeNs);
- // Kicks off the puller immediately.
+
if (mIsPulled) {
mPullerManager->RegisterReceiver(mPullTagId, this, getCurrentBucketEndTimeNs(),
mBucketSizeNs);
}
- // TODO: Only do this for partial buckets like first bucket. All other buckets should use
+ // Only do this for partial buckets like first bucket. All other buckets should use
// flushIfNeeded to adjust start and end to bucket boundaries.
// Adjust start for partial bucket
mCurrentBucketStartTimeNs = startTimeNs;
- if (mIsPulled) {
+ // Kicks off the puller immediately if condition is true and diff based.
+ if (mIsPulled && mCondition && mUseDiff) {
pullLocked(startTimeNs);
}
- VLOG("value metric %lld created. bucket size %lld start_time: %lld",
- (long long)metric.id(), (long long)mBucketSizeNs, (long long)mTimeBaseNs);
+ VLOG("value metric %lld created. bucket size %lld start_time: %lld", (long long)metric.id(),
+ (long long)mBucketSizeNs, (long long)mTimeBaseNs);
}
ValueMetricProducer::~ValueMetricProducer() {
@@ -170,6 +173,7 @@ void ValueMetricProducer::clearPastBucketsLocked(const int64_t dumpTimeNs) {
void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
ProtoOutputStream* protoOutput) {
VLOG("metric %lld dump report now...", (long long)mMetricId);
@@ -187,14 +191,14 @@ void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
// Fills the dimension path if not slicing by ALL.
if (!mSliceByPositionALL) {
if (!mDimensionsInWhat.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
+ uint64_t dimenPathToken =
+ protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_WHAT);
writeDimensionPathToProto(mDimensionsInWhat, protoOutput);
protoOutput->end(dimenPathToken);
}
if (!mDimensionsInCondition.empty()) {
- uint64_t dimenPathToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION);
+ uint64_t dimenPathToken =
+ protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_PATH_IN_CONDITION);
writeDimensionPathToProto(mDimensionsInCondition, protoOutput);
protoOutput->end(dimenPathToken);
}
@@ -211,7 +215,6 @@ void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
(long long)(NanoToMillis(pair.second)));
protoOutput->end(wrapperToken);
}
- mSkippedBuckets.clear();
for (const auto& pair : mPastBuckets) {
const MetricDimensionKey& dimensionKey = pair.first;
@@ -221,15 +224,15 @@ void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
// First fill dimension.
if (mSliceByPositionALL) {
- uint64_t dimensionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
+ uint64_t dimensionToken =
+ protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_WHAT);
writeDimensionToProto(dimensionKey.getDimensionKeyInWhat(), str_set, protoOutput);
protoOutput->end(dimensionToken);
if (dimensionKey.hasDimensionKeyInCondition()) {
- uint64_t dimensionInConditionToken = protoOutput->start(
- FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_CONDITION);
- writeDimensionToProto(dimensionKey.getDimensionKeyInCondition(),
- str_set, protoOutput);
+ uint64_t dimensionInConditionToken =
+ protoOutput->start(FIELD_TYPE_MESSAGE | FIELD_ID_DIMENSION_IN_CONDITION);
+ writeDimensionToProto(dimensionKey.getDimensionKeyInCondition(), str_set,
+ protoOutput);
protoOutput->end(dimensionInConditionToken);
}
} else {
@@ -237,8 +240,8 @@ void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
FIELD_ID_DIMENSION_LEAF_IN_WHAT, str_set, protoOutput);
if (dimensionKey.hasDimensionKeyInCondition()) {
writeDimensionLeafNodesToProto(dimensionKey.getDimensionKeyInCondition(),
- FIELD_ID_DIMENSION_LEAF_IN_CONDITION,
- str_set, protoOutput);
+ FIELD_ID_DIMENSION_LEAF_IN_CONDITION, str_set,
+ protoOutput);
}
}
@@ -256,28 +259,34 @@ void ValueMetricProducer::onDumpReportLocked(const int64_t dumpTimeNs,
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_BUCKET_NUM,
(long long)(getBucketNumFromEndTimeNs(bucket.mBucketEndNs)));
}
- if (mValueType == LONG) {
+ if (bucket.value.getType() == LONG) {
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_VALUE_LONG,
- (long long)bucket.mValueLong);
+ (long long)bucket.value.long_value);
+ VLOG("\t bucket [%lld - %lld] count: %lld", (long long)bucket.mBucketStartNs,
+ (long long)bucket.mBucketEndNs, (long long)bucket.value.long_value);
+ } else if (bucket.value.getType() == DOUBLE) {
+ protoOutput->write(FIELD_TYPE_DOUBLE | FIELD_ID_VALUE_DOUBLE,
+ bucket.value.double_value);
+ VLOG("\t bucket [%lld - %lld] count: %.2f", (long long)bucket.mBucketStartNs,
+ (long long)bucket.mBucketEndNs, bucket.value.double_value);
} else {
- protoOutput->write(FIELD_TYPE_DOUBLE | FIELD_ID_VALUE_DOUBLE, bucket.mValueDouble);
+ VLOG("Wrong value type for ValueMetric output: %d", bucket.value.getType());
}
protoOutput->end(bucketInfoToken);
- VLOG("\t bucket [%lld - %lld] count: %lld, %.2f", (long long)bucket.mBucketStartNs,
- (long long)bucket.mBucketEndNs, (long long)bucket.mValueLong, bucket.mValueDouble);
}
protoOutput->end(wrapperToken);
}
protoOutput->end(protoToken);
VLOG("metric %lld dump report now...", (long long)mMetricId);
- mPastBuckets.clear();
+ if (erase_data) {
+ mPastBuckets.clear();
+ mSkippedBuckets.clear();
+ }
}
void ValueMetricProducer::onConditionChangedLocked(const bool condition,
const int64_t eventTimeNs) {
- mCondition = condition;
-
if (eventTimeNs < mCurrentBucketStartTimeNs) {
VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
(long long)mCurrentBucketStartTimeNs);
@@ -286,9 +295,19 @@ void ValueMetricProducer::onConditionChangedLocked(const bool condition,
flushIfNeededLocked(eventTimeNs);
- if (mIsPulled) {
+ // Pull on condition changes.
+ if (mIsPulled && (mCondition != condition)) {
pullLocked(eventTimeNs);
}
+
+ // when condition change from true to false, clear diff base
+ if (mUseDiff && mCondition && !condition) {
+ for (auto& slice : mCurrentSlicedBucket) {
+ slice.second.hasBase = false;
+ }
+ }
+
+ mCondition = condition;
}
void ValueMetricProducer::pullLocked(const int64_t timestampNs) {
@@ -303,30 +322,33 @@ void ValueMetricProducer::pullLocked(const int64_t timestampNs) {
}
}
+int64_t ValueMetricProducer::calcPreviousBucketEndTime(const int64_t currentTimeNs) {
+ return mTimeBaseNs + ((currentTimeNs - mTimeBaseNs) / mBucketSizeNs) * mBucketSizeNs;
+}
+
void ValueMetricProducer::onDataPulled(const std::vector<std::shared_ptr<LogEvent>>& allData) {
std::lock_guard<std::mutex> lock(mMutex);
- if (mCondition == true || mConditionTrackerIndex < 0) {
+ if (mCondition) {
if (allData.size() == 0) {
return;
}
// For scheduled pulled data, the effective event time is snap to the nearest
- // bucket boundary to make bucket finalize.
+ // bucket end. In the case of waking up from a deep sleep state, we will
+ // attribute to the previous bucket end. If the sleep was long but not very long, we
+ // will be in the immediate next bucket. Previous bucket may get a larger number as
+ // we pull at a later time than real bucket end.
+ // If the sleep was very long, we skip more than one bucket before sleep. In this case,
+ // if the diff base will be cleared and this new data will serve as new diff base.
int64_t realEventTime = allData.at(0)->GetElapsedTimestampNs();
- int64_t eventTime = mTimeBaseNs +
- ((realEventTime - mTimeBaseNs) / mBucketSizeNs) * mBucketSizeNs;
-
- // close the end of the bucket
- mCondition = false;
- for (const auto& data : allData) {
- data->setElapsedTimestampNs(eventTime - 1);
- onMatchedLogEventLocked(0, *data);
+ int64_t bucketEndTime = calcPreviousBucketEndTime(realEventTime) - 1;
+ if (bucketEndTime < mCurrentBucketStartTimeNs) {
+ VLOG("Skip bucket end pull due to late arrival: %lld vs %lld", (long long)bucketEndTime,
+ (long long)mCurrentBucketStartTimeNs);
+ return;
}
-
- // start a new bucket
- mCondition = true;
for (const auto& data : allData) {
- data->setElapsedTimestampNs(eventTime);
+ data->setElapsedTimestampNs(bucketEndTime);
onMatchedLogEventLocked(0, *data);
}
}
@@ -360,8 +382,8 @@ bool ValueMetricProducer::hitGuardRailLocked(const MetricDimensionKey& newKey) {
StatsdStats::getInstance().noteMetricDimensionSize(mConfigKey, mMetricId, newTupleCount);
// 2. Don't add more tuples, we are above the allowed threshold. Drop the data.
if (newTupleCount > mDimensionHardLimit) {
- ALOGE("ValueMetric %lld dropping data for dimension key %s",
- (long long)mMetricId, newKey.toString().c_str());
+ ALOGE("ValueMetric %lld dropping data for dimension key %s", (long long)mMetricId,
+ newKey.toString().c_str());
return true;
}
}
@@ -390,10 +412,10 @@ const Value getDoubleOrLong(const Value& value) {
return v;
}
-void ValueMetricProducer::onMatchedLogEventInternalLocked(
- const size_t matcherIndex, const MetricDimensionKey& eventKey,
- const ConditionKey& conditionKey, bool condition,
- const LogEvent& event) {
+void ValueMetricProducer::onMatchedLogEventInternalLocked(const size_t matcherIndex,
+ const MetricDimensionKey& eventKey,
+ const ConditionKey& conditionKey,
+ bool condition, const LogEvent& event) {
int64_t eventTimeNs = event.GetElapsedTimestampNs();
if (eventTimeNs < mCurrentBucketStartTimeNs) {
VLOG("Skip event due to late arrival: %lld vs %lld", (long long)eventTimeNs,
@@ -403,6 +425,14 @@ void ValueMetricProducer::onMatchedLogEventInternalLocked(
flushIfNeededLocked(eventTimeNs);
+ // For pulled data, we already check condition when we decide to pull or
+ // in onDataPulled. So take all of them.
+ // For pushed data, just check condition.
+ if (!(mIsPulled || condition)) {
+ VLOG("ValueMetric skip event because condition is false");
+ return;
+ }
+
if (hitGuardRailLocked(eventKey)) {
return;
}
@@ -415,71 +445,70 @@ void ValueMetricProducer::onMatchedLogEventInternalLocked(
}
Value value = getDoubleOrLong(event.getValues()[mField - 1].mValue);
- Value diff;
- bool hasDiff = false;
- if (mIsPulled) {
- // Always require condition for pulled events. In the case of no condition, only pull
- // on bucket boundaries, in which we fake condition changes.
- if (mCondition == true) {
- if (!interval.startUpdated) {
- interval.start = value;
- interval.startUpdated = true;
- } else {
- // Skip it if there is already value recorded for the start. Happens when puller
- // takes too long to finish. In this case we take the previous value.
- VLOG("Already recorded value for this dimension %s", eventKey.toString().c_str());
- }
- } else {
- // Generally we expect value to be monotonically increasing.
- // If not, take absolute value or drop it, based on config.
- if (interval.startUpdated) {
- if (value >= interval.start) {
- diff = (value - interval.start);
- hasDiff = true;
+ if (mUseDiff) {
+ // no base. just update base and return.
+ if (!interval.hasBase) {
+ interval.base = value;
+ interval.hasBase = true;
+ return;
+ }
+ Value diff;
+ switch (mValueDirection) {
+ case ValueMetric::INCREASING:
+ if (value >= interval.base) {
+ diff = value - interval.base;
+ } else if (mUseAbsoluteValueOnReset) {
+ diff = value;
} else {
- if (mUseAbsoluteValueOnReset) {
- diff = value;
- hasDiff = true;
- } else {
- VLOG("Dropping data for atom %d, prev: %s, now: %s", mPullTagId,
- interval.start.toString().c_str(), value.toString().c_str());
- }
+ VLOG("Unexpected decreasing value");
+ StatsdStats::getInstance().notePullDataError(mPullTagId);
+ interval.base = value;
+ return;
}
- interval.startUpdated = false;
- } else {
- VLOG("No start for matching end %s", value.toString().c_str());
- }
- }
- } else {
- // for pushed events, only aggregate when sliced condition is true
- if (condition == true || mConditionTrackerIndex < 0) {
- diff = value;
- hasDiff = true;
+ break;
+ case ValueMetric::DECREASING:
+ if (interval.base >= value) {
+ diff = interval.base - value;
+ } else if (mUseAbsoluteValueOnReset) {
+ diff = value;
+ } else {
+ VLOG("Unexpected increasing value");
+ StatsdStats::getInstance().notePullDataError(mPullTagId);
+ interval.base = value;
+ return;
+ }
+ break;
+ case ValueMetric::ANY:
+ diff = value - interval.base;
+ break;
+ default:
+ break;
}
+ interval.base = value;
+ value = diff;
}
- if (hasDiff) {
- if (interval.hasValue) {
- switch (mAggregationType) {
- case ValueMetric::SUM:
+
+ if (interval.hasValue) {
+ switch (mAggregationType) {
+ case ValueMetric::SUM:
// for AVG, we add up and take average when flushing the bucket
- case ValueMetric::AVG:
- interval.value += diff;
- break;
- case ValueMetric::MIN:
- interval.value = diff < interval.value ? diff : interval.value;
- break;
- case ValueMetric::MAX:
- interval.value = diff > interval.value ? diff : interval.value;
- break;
- default:
- break;
- }
- } else {
- interval.value = diff;
- interval.hasValue = true;
+ case ValueMetric::AVG:
+ interval.value += value;
+ break;
+ case ValueMetric::MIN:
+ interval.value = std::min(value, interval.value);
+ break;
+ case ValueMetric::MAX:
+ interval.value = std::max(value, interval.value);
+ break;
+ default:
+ break;
}
- interval.sampleSize += 1;
+ } else {
+ interval.value = value;
+ interval.hasValue = true;
}
+ interval.sampleSize += 1;
// TODO: propgate proper values down stream when anomaly support doubles
long wholeBucketVal = interval.value.long_value;
@@ -509,6 +538,10 @@ void ValueMetricProducer::flushIfNeededLocked(const int64_t& eventTimeNs) {
if (numBucketsForward > 1) {
VLOG("Skipping forward %lld buckets", (long long)numBucketsForward);
+ // take base again in future good bucket.
+ for (auto& slice : mCurrentSlicedBucket) {
+ slice.second.hasBase = false;
+ }
}
VLOG("metric %lld: new bucket start time: %lld", (long long)mMetricId,
(long long)mCurrentBucketStartTimeNs);
@@ -531,8 +564,18 @@ void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs) {
// The current bucket is large enough to keep.
for (const auto& slice : mCurrentSlicedBucket) {
if (slice.second.hasValue) {
- info.mValueLong = slice.second.value.long_value;
- info.mValueDouble = (double)slice.second.value.long_value / slice.second.sampleSize;
+ // skip the output if the diff is zero
+ if (mSkipZeroDiffOutput && mUseDiff && slice.second.value.isZero()) {
+ continue;
+ }
+ if (mAggregationType != ValueMetric::AVG) {
+ info.value = slice.second.value;
+ } else {
+ double sum = slice.second.value.type == LONG
+ ? (double)slice.second.value.long_value
+ : slice.second.value.double_value;
+ info.value.setDouble(sum / slice.second.sampleSize);
+ }
// it will auto create new vector of ValuebucketInfo if the key is not found.
auto& bucketList = mPastBuckets[slice.first];
bucketList.push_back(info);
@@ -578,7 +621,10 @@ void ValueMetricProducer::flushCurrentBucketLocked(const int64_t& eventTimeNs) {
}
// Reset counters
- mCurrentSlicedBucket.clear();
+ for (auto& slice : mCurrentSlicedBucket) {
+ slice.second.hasValue = false;
+ slice.second.sampleSize = 0;
+ }
}
size_t ValueMetricProducer::byteSizeLocked() const {
diff --git a/cmds/statsd/src/metrics/ValueMetricProducer.h b/cmds/statsd/src/metrics/ValueMetricProducer.h
index b2f0b6ff4d78..3416afe06b81 100644
--- a/cmds/statsd/src/metrics/ValueMetricProducer.h
+++ b/cmds/statsd/src/metrics/ValueMetricProducer.h
@@ -34,8 +34,7 @@ namespace statsd {
struct ValueBucket {
int64_t mBucketStartNs;
int64_t mBucketEndNs;
- int64_t mValueLong;
- double mValueDouble;
+ Value value;
};
class ValueMetricProducer : public virtual MetricProducer, public virtual PullDataReceiver {
@@ -54,35 +53,11 @@ public:
void notifyAppUpgrade(const int64_t& eventTimeNs, const string& apk, const int uid,
const int64_t version) override {
std::lock_guard<std::mutex> lock(mMutex);
-
- if (mIsPulled && (mCondition == true || mConditionTrackerIndex < 0)) {
- vector<shared_ptr<LogEvent>> allData;
- mPullerManager->Pull(mPullTagId, eventTimeNs, &allData);
- if (allData.size() == 0) {
- // This shouldn't happen since this valuemetric is not useful now.
- }
-
- // Pretend the pulled data occurs right before the app upgrade event.
- mCondition = false;
- for (const auto& data : allData) {
- data->setElapsedTimestampNs(eventTimeNs - 1);
- onMatchedLogEventLocked(0, *data);
- }
-
- flushCurrentBucketLocked(eventTimeNs);
- mCurrentBucketStartTimeNs = eventTimeNs;
-
- mCondition = true;
- for (const auto& data : allData) {
- data->setElapsedTimestampNs(eventTimeNs);
- onMatchedLogEventLocked(0, *data);
- }
- } else {
- // For pushed value metric or pulled metric where condition is not true,
- // we simply flush and reset the current bucket start.
- flushCurrentBucketLocked(eventTimeNs);
- mCurrentBucketStartTimeNs = eventTimeNs;
+ if (mIsPulled && mCondition) {
+ pullLocked(eventTimeNs - 1);
}
+ flushCurrentBucketLocked(eventTimeNs);
+ mCurrentBucketStartTimeNs = eventTimeNs;
};
protected:
@@ -94,6 +69,7 @@ protected:
private:
void onDumpReportLocked(const int64_t dumpTimeNs,
const bool include_current_partial_bucket,
+ const bool erase_data,
std::set<string> *str_set,
android::util::ProtoOutputStream* protoOutput) override;
void clearPastBucketsLocked(const int64_t dumpTimeNs) override;
@@ -116,6 +92,9 @@ private:
void dropDataLocked(const int64_t dropTimeNs) override;
+ // Calculate previous bucket end time based on current time.
+ int64_t calcPreviousBucketEndTime(const int64_t currentTimeNs);
+
sp<StatsPullerManager> mPullerManager;
const FieldMatcher mValueField;
@@ -130,11 +109,10 @@ private:
// internal state of a bucket.
typedef struct {
- // Pulled data always come in pair of <start, end>. This holds the value
- // for start. The diff (end - start) is taken as the real value.
- Value start;
- // Whether the start data point is updated
- bool startUpdated;
+ // Holds current base value of the dimension. Take diff and update if necessary.
+ Value base;
+ // Whether there is a base to diff to.
+ bool hasBase;
// Current value, depending on the aggregation type.
Value value;
// Number of samples collected.
@@ -171,7 +149,11 @@ private:
const ValueMetric::AggregationType mAggregationType;
- const Type mValueType;
+ const bool mUseDiff;
+
+ const ValueMetric::ValueDirection mValueDirection;
+
+ const bool mSkipZeroDiffOutput;
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsNoCondition);
FRIEND_TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset);
@@ -186,13 +168,13 @@ private:
FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition);
FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition);
FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2);
- FRIEND_TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition3);
FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMin);
FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateMax);
FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateAvg);
FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSum);
- FRIEND_TEST(ValueMetricProducerTest, TestPushedAggregateSumSliced);
FRIEND_TEST(ValueMetricProducerTest, TestFirstBucket);
+ FRIEND_TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime);
+ FRIEND_TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput);
};
} // namespace statsd
diff --git a/cmds/statsd/src/metrics/metrics_manager_util.cpp b/cmds/statsd/src/metrics/metrics_manager_util.cpp
index 4a9b52127690..136ba074d589 100644
--- a/cmds/statsd/src/metrics/metrics_manager_util.cpp
+++ b/cmds/statsd/src/metrics/metrics_manager_util.cpp
@@ -35,8 +35,6 @@
#include "stats_util.h"
#include "statslog.h"
-#include <inttypes.h>
-
using std::set;
using std::string;
using std::unordered_map;
@@ -575,7 +573,7 @@ bool initMetrics(const ConfigKey& key, const StatsdConfig& config, const int64_t
for (int i = 0; i < config.no_report_metric_size(); ++i) {
const auto no_report_metric = config.no_report_metric(i);
if (metricMap.find(no_report_metric) == metricMap.end()) {
- ALOGW("no_report_metric %" PRId64 " not exist", no_report_metric);
+ ALOGW("no_report_metric %lld not exist", no_report_metric);
return false;
}
noReportMetricIds.insert(no_report_metric);
diff --git a/cmds/statsd/src/stats_log.proto b/cmds/statsd/src/stats_log.proto
index 8bfa36059e9a..4da3828ff88d 100644
--- a/cmds/statsd/src/stats_log.proto
+++ b/cmds/statsd/src/stats_log.proto
@@ -374,6 +374,7 @@ message StatsdStatsReport {
optional int64 max_pull_time_nanos = 6;
optional int64 average_pull_delay_nanos = 7;
optional int64 max_pull_delay_nanos = 8;
+ optional int64 data_error = 9;
}
repeated PulledAtomStats pulled_atom_stats = 10;
diff --git a/cmds/statsd/src/stats_log_util.cpp b/cmds/statsd/src/stats_log_util.cpp
index 44fa72e77a0d..504c5864f2ec 100644
--- a/cmds/statsd/src/stats_log_util.cpp
+++ b/cmds/statsd/src/stats_log_util.cpp
@@ -63,6 +63,7 @@ const int FIELD_ID_AVERAGE_PULL_TIME_NANOS = 5;
const int FIELD_ID_MAX_PULL_TIME_NANOS = 6;
const int FIELD_ID_AVERAGE_PULL_DELAY_NANOS = 7;
const int FIELD_ID_MAX_PULL_DELAY_NANOS = 8;
+const int FIELD_ID_DATA_ERROR = 9;
namespace {
@@ -446,6 +447,7 @@ void writePullerStatsToStream(const std::pair<int, StatsdStats::PulledAtomStats>
(long long)pair.second.avgPullDelayNs);
protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_MAX_PULL_DELAY_NANOS,
(long long)pair.second.maxPullDelayNs);
+ protoOutput->write(FIELD_TYPE_INT64 | FIELD_ID_DATA_ERROR, (long long)pair.second.dataError);
protoOutput->end(token);
}
diff --git a/cmds/statsd/src/stats_log_util.h b/cmds/statsd/src/stats_log_util.h
index b8f6850ddc29..61f31eb3fa17 100644
--- a/cmds/statsd/src/stats_log_util.h
+++ b/cmds/statsd/src/stats_log_util.h
@@ -21,6 +21,7 @@
#include "HashableDimensionKey.h"
#include "frameworks/base/cmds/statsd/src/statsd_config.pb.h"
#include "guardrail/StatsdStats.h"
+#include "statslog.h"
namespace android {
namespace os {
@@ -87,6 +88,10 @@ bool parseProtoOutputStream(util::ProtoOutputStream& protoOutput, T* message) {
// Returns the truncated timestamp.
int64_t truncateTimestampNsToFiveMinutes(int64_t timestampNs);
+inline bool isPushedAtom(int atomId) {
+ return atomId <= util::kMaxPushedAtomId && atomId > 1;
+}
+
} // namespace statsd
} // namespace os
} // namespace android
diff --git a/cmds/statsd/src/statsd_config.proto b/cmds/statsd/src/statsd_config.proto
index d5f81a593082..5c46a296b9bf 100644
--- a/cmds/statsd/src/statsd_config.proto
+++ b/cmds/statsd/src/statsd_config.proto
@@ -270,6 +270,17 @@ message ValueMetric {
optional int64 min_bucket_size_nanos = 10;
optional bool use_absolute_value_on_reset = 11 [default = false];
+
+ optional bool use_diff = 12;
+
+ enum ValueDirection {
+ INCREASING = 1;
+ DECREASING = 2;
+ ANY = 3;
+ }
+ optional ValueDirection value_direction = 13 [default = INCREASING];
+
+ optional bool skip_zero_diff_output = 14 [default = true];
}
message Alert {
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index b6f635c6a0cb..8864252bcf4b 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -168,7 +168,7 @@ TEST(StatsLogProcessorTest, TestUidMapHasSnapshot) {
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, ADB_DUMP, &bytes);
+ p.onDumpReport(key, 1, false, true, ADB_DUMP, &bytes);
ConfigMetricsReportList output;
output.ParseFromArray(bytes.data(), bytes.size());
@@ -197,7 +197,7 @@ TEST(StatsLogProcessorTest, TestEmptyConfigHasNoUidMap) {
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, ADB_DUMP, &bytes);
+ p.onDumpReport(key, 1, false, true, ADB_DUMP, &bytes);
ConfigMetricsReportList output;
output.ParseFromArray(bytes.data(), bytes.size());
@@ -227,7 +227,7 @@ TEST(StatsLogProcessorTest, TestReportIncludesSubConfig) {
// Expect to get no metrics, but snapshot specified above in uidmap.
vector<uint8_t> bytes;
- p.onDumpReport(key, 1, false, ADB_DUMP, &bytes);
+ p.onDumpReport(key, 1, false, true, ADB_DUMP, &bytes);
ConfigMetricsReportList output;
output.ParseFromArray(bytes.data(), bytes.size());
diff --git a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
index a8fcc8163656..5c47af797eea 100644
--- a/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/Attribution_e2e_test.cpp
@@ -144,8 +144,8 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSliceByFirstUid) {
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -290,8 +290,8 @@ TEST(AttributionE2eTest, TestAttributionMatchAndSliceByChain) {
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 4 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
index 75bd40f67946..a8914da4b7fe 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_AND_cond_test.cpp
@@ -212,7 +212,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_AND_CombinationCondi
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -548,7 +548,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_AND_CombinationConditi
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -798,7 +798,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_AND_Combination
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
index c5a8a2eba4ae..621b6ed6ddbf 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_combination_OR_cond_test.cpp
@@ -130,8 +130,8 @@ TEST(DimensionInConditionE2eTest, TestCreateCountMetric_NoLink_OR_CombinationCon
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -346,8 +346,8 @@ TEST(DimensionInConditionE2eTest, TestCreateCountMetric_Link_OR_CombinationCondi
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -530,8 +530,8 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_OR_CombinationCondit
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -732,8 +732,8 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_OR_CombinationConditio
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
index 5bcc9ee8513d..9f8acaf18422 100644
--- a/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
+++ b/cmds/statsd/tests/e2e/DimensionInCondition_e2e_simple_cond_test.cpp
@@ -143,7 +143,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_NoLink_SimpleCondition) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -438,7 +438,7 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_Link_SimpleCondition) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false,
- ADB_DUMP, &buffer);
+ true, ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -658,8 +658,8 @@ TEST(DimensionInConditionE2eTest, TestDurationMetric_PartialLink_SimpleCondition
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
index d7b9c119b71b..2d090e02a42a 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_pull_test.cpp
@@ -123,8 +123,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvents) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -246,8 +246,8 @@ TEST(GaugeMetricE2eTest, TestConditionChangeToTrueSamplePulledEvents) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 8 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -350,8 +350,8 @@ TEST(GaugeMetricE2eTest, TestRandomSamplePulledEvent_LateAlarm) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
index 5c1ef01dd576..71afedfa6c8f 100644
--- a/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
+++ b/cmds/statsd/tests/e2e/GaugeMetric_e2e_push_test.cpp
@@ -149,8 +149,8 @@ TEST(GaugeMetricE2eTest, TestMultipleFieldsForPushedEvent) {
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 3 * bucketSizeNs, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
index 0f13a4ac1254..29e86f3f9456 100644
--- a/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricActivation_e2e_test.cpp
@@ -167,8 +167,8 @@ TEST(MetricActivationE2eTest, TestCountMetric) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + NS_PER_SEC * 60 * 15 + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
index cc8894bdbca6..9349c857c5b3 100644
--- a/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/MetricConditionLink_e2e_test.cpp
@@ -199,8 +199,8 @@ TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks1) {
}
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -318,8 +318,8 @@ TEST(MetricConditionLinkE2eTest, TestMultiplePredicatesAndLinks2) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
index 67acd6154176..3cb553fd9a16 100644
--- a/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/PartialBucket_e2e_test.cpp
@@ -46,7 +46,7 @@ ConfigMetricsReport GetReports(sp<StatsLogProcessor> processor, int64_t timestam
IPCThreadState* ipc = IPCThreadState::self();
ConfigKey configKey(ipc->getCallingUid(), kConfigKey);
processor->onDumpReport(configKey, timestamp, include_current /* include_current_bucket*/,
- ADB_DUMP, &output);
+ true /* erase_data */, ADB_DUMP, &output);
ConfigMetricsReportList reports;
reports.ParseFromArray(output.data(), output.size());
EXPECT_EQ(1, reports.reports_size());
diff --git a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
index f2e8f58fe763..095b4017b440 100644
--- a/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/ValueMetric_pull_e2e_test.cpp
@@ -49,6 +49,7 @@ StatsdConfig CreateStatsdConfig() {
CreateDimensions(android::util::TEMPERATURE, {2/* sensor name field */ });
valueMetric->set_bucket(FIVE_MINUTES);
valueMetric->set_use_absolute_value_on_reset(true);
+ valueMetric->set_skip_zero_diff_output(false);
return config;
}
@@ -117,8 +118,8 @@ TEST(ValueMetricE2eTest, TestPulledEvents) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 7 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -224,8 +225,8 @@ TEST(ValueMetricE2eTest, TestPulledEvents_LateAlarm) {
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, configAddedTimeNs + 9 * bucketSizeNs + 10, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
index b9d0c62cf596..6d1317cb5dee 100644
--- a/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
+++ b/cmds/statsd/tests/e2e/WakelockDuration_e2e_test.cpp
@@ -127,8 +127,8 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration1)
FeedEvents(config, processor);
vector<uint8_t> buffer;
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -164,8 +164,8 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration2)
FeedEvents(config, processor);
vector<uint8_t> buffer;
ConfigMetricsReportList reports;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -215,8 +215,8 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForSumDuration3)
processor->OnLogEvent(event.get());
}
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -248,8 +248,8 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration1)
FeedEvents(config, processor);
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs - 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
@@ -277,8 +277,8 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration2)
FeedEvents(config, processor);
ConfigMetricsReportList reports;
vector<uint8_t> buffer;
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 2 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
@@ -323,8 +323,8 @@ TEST(WakelockDurationE2eTest, TestAggregatedPredicateDimensionsForMaxDuration3)
processor->OnLogEvent(event.get());
}
- processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, ADB_DUMP,
- &buffer);
+ processor->onDumpReport(cfgKey, bucketStartTimeNs + 6 * bucketSizeNs + 1, false, true,
+ ADB_DUMP, &buffer);
EXPECT_TRUE(buffer.size() > 0);
EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
backfillDimensionPath(&reports);
diff --git a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
index 57aab971eaaa..ffa07081c781 100644
--- a/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
+++ b/cmds/statsd/tests/metrics/ValueMetricProducer_test.cpp
@@ -47,7 +47,35 @@ const int64_t bucket3StartTimeNs = bucketStartTimeNs + 2 * bucketSizeNs;
const int64_t bucket4StartTimeNs = bucketStartTimeNs + 3 * bucketSizeNs;
const int64_t bucket5StartTimeNs = bucketStartTimeNs + 4 * bucketSizeNs;
const int64_t bucket6StartTimeNs = bucketStartTimeNs + 5 * bucketSizeNs;
-const int64_t eventUpgradeTimeNs = bucketStartTimeNs + 15 * NS_PER_SEC;
+double epsilon = 0.001;
+
+/*
+ * Tests that the first bucket works correctly
+ */
+TEST(ValueMetricProducerTest, TestCalcPreviousBucketEndTime) {
+ ValueMetric metric;
+ metric.set_id(metricId);
+ metric.set_bucket(ONE_MINUTE);
+ metric.mutable_value_field()->set_field(tagId);
+ metric.mutable_value_field()->add_child()->set_field(2);
+
+ int64_t startTimeBase = 11;
+
+ sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
+ sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
+
+ // statsd started long ago.
+ // The metric starts in the middle of the bucket
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
+ -1, startTimeBase, 22, pullerManager);
+
+ EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
+ EXPECT_EQ(startTimeBase, valueProducer.calcPreviousBucketEndTime(60 * NS_PER_SEC + 10));
+ EXPECT_EQ(60 * NS_PER_SEC + startTimeBase,
+ valueProducer.calcPreviousBucketEndTime(2 * 60 * NS_PER_SEC));
+ EXPECT_EQ(2 * 60 * NS_PER_SEC + startTimeBase,
+ valueProducer.calcPreviousBucketEndTime(3 * 60 * NS_PER_SEC));
+}
/*
* Tests that the first bucket works correctly
@@ -90,7 +118,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs);
event->write(tagId);
event->write(3);
event->init();
@@ -114,12 +142,11 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- // startUpdated:true sum:0 start:11
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(11, curInterval.start.long_value);
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(11, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(8, curInterval.value.long_value);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
allData.clear();
event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
@@ -131,12 +158,14 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- // tartUpdated:false sum:12
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
+
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(23, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(12, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(8, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
allData.clear();
event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -147,12 +176,14 @@ TEST(ValueMetricProducerTest, TestPulledEventsNoCondition) {
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- // startUpdated:false sum:12
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
+
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(36, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(13, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(3UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(13, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
/*
@@ -170,7 +201,7 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
@@ -188,9 +219,9 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(11, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(11, curInterval.start.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
allData.clear();
@@ -203,11 +234,11 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(10, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(10, curInterval.value.long_value);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
allData.clear();
event = make_shared<LogEvent>(tagId, bucket4StartTimeNs + 1);
@@ -218,11 +249,13 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeAbsoluteValueOnReset) {
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(36, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(26, curInterval.value.long_value);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(2UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
+ EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
/*
@@ -257,9 +290,9 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(11, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(11, curInterval.start.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
allData.clear();
@@ -272,7 +305,8 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(10, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
@@ -285,11 +319,11 @@ TEST(ValueMetricProducerTest, TestPulledEventsTakeZeroOnReset) {
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(26, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(36, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(26, curInterval.value.long_value);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
}
/*
@@ -309,21 +343,10 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
- // should not take effect
- .WillOnce(Invoke([](int tagId, int64_t timeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event->write(tagId);
- event->write(3);
- event->init();
- data->push_back(event);
- return true;
- }))
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
event->write(tagId);
event->write(100);
event->init();
@@ -333,7 +356,7 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
event->write(tagId);
event->write(120);
event->init();
@@ -349,8 +372,8 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
// startUpdated:false sum:0 start:100
- EXPECT_EQ(100, curInterval.start.long_value);
- EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(100, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
@@ -366,20 +389,20 @@ TEST(ValueMetricProducerTest, TestEventsWithNonSlicedCondition) {
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- // startUpdated:false sum:0 start:110
- EXPECT_EQ(110, curInterval.start.long_value);
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(110, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(10, curInterval.value.long_value);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- // startUpdated:false sum:0 start:110
+ EXPECT_EQ(true, curInterval.hasValue);
EXPECT_EQ(10, curInterval.value.long_value);
- EXPECT_EQ(false, curInterval.startUpdated);
+ EXPECT_EQ(false, curInterval.hasBase);
}
TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
@@ -401,9 +424,9 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- valueProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
+ valueProducer.notifyAppUpgrade(bucketStartTimeNs + 150, "ANY.APP", 1, 1);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(eventUpgradeTimeNs, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 59 * NS_PER_SEC);
event2->write(1);
@@ -411,7 +434,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithUpgrade) {
event2->init();
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(eventUpgradeTimeNs, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(bucketStartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
// Next value should create a new bucket.
shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 65 * NS_PER_SEC);
@@ -435,11 +458,11 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
- .WillOnce(Return(false))
+ .WillOnce(Return(true))
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 149);
event->write(tagId);
event->write(120);
event->init();
@@ -451,7 +474,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
vector<shared_ptr<LogEvent>> allData;
allData.clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
event->write(tagId);
event->write(100);
event->init();
@@ -460,21 +483,21 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgrade) {
valueProducer.onDataPulled(allData);
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- valueProducer.notifyAppUpgrade(eventUpgradeTimeNs, "ANY.APP", 1, 1);
+ valueProducer.notifyAppUpgrade(bucket2StartTimeNs + 150, "ANY.APP", 1, 1);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(eventUpgradeTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mValueLong);
+ EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].value.long_value);
allData.clear();
- event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
+ event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 1);
event->write(tagId);
event->write(150);
event->init();
allData.push_back(event);
valueProducer.onDataPulled(allData);
- EXPECT_EQ(2UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
- EXPECT_EQ(bucket2StartTimeNs, valueProducer.mCurrentBucketStartTimeNs);
- EXPECT_EQ(30L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][1].mValueLong);
+ EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
+ EXPECT_EQ(bucket2StartTimeNs + 150, valueProducer.mCurrentBucketStartTimeNs);
+ EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].value.long_value);
}
TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
@@ -490,11 +513,10 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
- .WillOnce(Return(false))
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 1);
event->write(tagId);
event->write(100);
event->init();
@@ -504,7 +526,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs - 100);
event->write(tagId);
event->write(120);
event->init();
@@ -523,7 +545,7 @@ TEST(ValueMetricProducerTest, TestPulledValueWithUpgradeWhileConditionFalse) {
EXPECT_EQ(bucket2StartTimeNs-50, valueProducer.mCurrentBucketStartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY].size());
EXPECT_EQ(bucketStartTimeNs, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mBucketStartNs);
- EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].mValueLong);
+ EXPECT_EQ(20L, valueProducer.mPastBuckets[DEFAULT_METRIC_DIMENSION_KEY][0].value.long_value);
EXPECT_FALSE(valueProducer.mCondition);
}
@@ -565,7 +587,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithoutCondition) {
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(30, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
@@ -587,9 +609,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
event1->init();
valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
// has 1 slice
- EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(0UL, valueProducer.mCurrentSlicedBucket.size());
valueProducer.onConditionChangedLocked(true, bucketStartTimeNs + 15);
shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 20);
@@ -600,6 +620,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
EXPECT_EQ(20, curInterval.value.long_value);
@@ -629,7 +650,7 @@ TEST(ValueMetricProducerTest, TestPushedEventsWithCondition) {
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(50, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
TEST(ValueMetricProducerTest, TestAnomalyDetection) {
@@ -727,7 +748,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(false));
+ EXPECT_CALL(*pullerManager, Pull(tagId, _, _)).WillOnce(Return(true));
ValueMetricProducer valueProducer(kConfigKey, metric, -1 /*-1 meaning no condition*/, wizard,
tagId, bucketStartTimeNs, bucketStartTimeNs, pullerManager);
@@ -747,9 +768,9 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
// startUpdated:true sum:0 start:11
- EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(11, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(11, curInterval.start.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
// pull 2 at correct time
@@ -764,11 +785,11 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
// tartUpdated:false sum:12
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
- EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(23, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(12, curInterval.value.long_value);
+ EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
// pull 3 come late.
// The previous bucket gets closed with error. (Has start value 23, no ending)
@@ -784,12 +805,12 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryNoCondition) {
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
// startUpdated:false sum:12
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(36, curInterval.start.long_value);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(36, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(12, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
/*
@@ -810,12 +831,11 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
- .WillOnce(Return(false))
// condition becomes true
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
event->write(tagId);
event->write(100);
event->init();
@@ -826,7 +846,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 20);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
event->write(tagId);
event->write(120);
event->init();
@@ -841,17 +861,17 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- // startUpdated:false sum:0 start:100
- EXPECT_EQ(100, curInterval.start.long_value);
- EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(100, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
// pull on bucket boundary come late, condition change happens before it
valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(false, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasBase);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(20, curInterval.value.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
// Now the alarm is delivered.
@@ -866,8 +886,9 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition) {
valueProducer.onDataPulled(allData);
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(false, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasBase);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(20, curInterval.value.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
}
@@ -889,12 +910,11 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
- .WillOnce(Return(false))
// condition becomes true
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 8);
event->write(tagId);
event->write(100);
event->init();
@@ -905,7 +925,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 20);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 1);
event->write(tagId);
event->write(120);
event->init();
@@ -916,7 +936,7 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
.WillOnce(Invoke([](int tagId, int64_t timeNs,
vector<std::shared_ptr<LogEvent>>* data) {
data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 30);
+ shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 25);
event->write(tagId);
event->write(130);
event->init();
@@ -932,24 +952,26 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
// startUpdated:false sum:0 start:100
- EXPECT_EQ(100, curInterval.start.long_value);
- EXPECT_EQ(true, curInterval.startUpdated);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(100, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
// pull on bucket boundary come late, condition change happens before it
valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(false, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(false, curInterval.hasBase);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(20, curInterval.value.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
// condition changed to true again, before the pull alarm is delivered
valueProducer.onConditionChanged(true, bucket2StartTimeNs + 25);
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(130, curInterval.start.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(130, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(20, curInterval.value.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
// Now the alarm is delivered, but it is considered late, it has no effect
@@ -963,89 +985,10 @@ TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition2) {
valueProducer.onDataPulled(allData);
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(130, curInterval.start.long_value);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
-}
-
-/*
- * Test pulled event with non sliced condition. The pull on boundary come late because the puller is
- * very slow.
- */
-TEST(ValueMetricProducerTest, TestBucketBoundaryWithCondition3) {
- ValueMetric metric;
- metric.set_id(metricId);
- metric.set_bucket(ONE_MINUTE);
- metric.mutable_value_field()->set_field(tagId);
- metric.mutable_value_field()->add_child()->set_field(2);
- metric.set_condition(StringToId("SCREEN_ON"));
-
- sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- EXPECT_CALL(*pullerManager, RegisterReceiver(tagId, _, _, _)).WillOnce(Return());
- EXPECT_CALL(*pullerManager, UnRegisterReceiver(tagId, _)).WillRepeatedly(Return());
-
- EXPECT_CALL(*pullerManager, Pull(tagId, _, _))
- .WillOnce(Return(false))
- // condition becomes true
- .WillOnce(Invoke([](int tagId, int64_t timeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
- event->write(tagId);
- event->write(100);
- event->init();
- data->push_back(event);
- return true;
- }))
- // condition becomes false
- .WillOnce(Invoke([](int tagId, int64_t timeNs,
- vector<std::shared_ptr<LogEvent>>* data) {
- data->clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 20);
- event->write(tagId);
- event->write(120);
- event->init();
- data->push_back(event);
- return true;
- }));
-
- ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, tagId, bucketStartTimeNs,
- bucketStartTimeNs, pullerManager);
- valueProducer.onConditionChanged(true, bucketStartTimeNs + 8);
-
- // has one slice
- EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
- ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- // startUpdated:false sum:0 start:100
- EXPECT_EQ(100, curInterval.start.long_value);
- EXPECT_EQ(true, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
-
- // pull on bucket boundary come late, condition change happens before it.
- // But puller is very slow in this one, so the data come after bucket finish
- valueProducer.onConditionChanged(false, bucket2StartTimeNs + 1);
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(false, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
- EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
-
- // Alarm is delivered in time, but the pull is very slow, and pullers are called in order,
- // so this one comes even later
- vector<shared_ptr<LogEvent>> allData;
- allData.clear();
- shared_ptr<LogEvent> event = make_shared<LogEvent>(tagId, bucket3StartTimeNs + 30);
- event->write(1);
- event->write(110);
- event->init();
- allData.push_back(event);
- valueProducer.onDataPulled(allData);
-
- curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(false, curInterval.startUpdated);
- EXPECT_EQ(false, curInterval.hasValue);
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(130, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(20, curInterval.value.long_value);
EXPECT_EQ(0UL, valueProducer.mPastBuckets.size());
}
@@ -1088,7 +1031,7 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMin) {
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(10, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
@@ -1130,7 +1073,7 @@ TEST(ValueMetricProducerTest, TestPushedAggregateMax) {
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(20, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
@@ -1175,7 +1118,7 @@ TEST(ValueMetricProducerTest, TestPushedAggregateAvg) {
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(12.5, valueProducer.mPastBuckets.begin()->second.back().mValueDouble);
+ EXPECT_TRUE(std::abs(valueProducer.mPastBuckets.begin()->second.back().value.double_value - 12.5) < epsilon);
}
TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
@@ -1217,67 +1160,75 @@ TEST(ValueMetricProducerTest, TestPushedAggregateSum) {
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(25, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(25, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
-TEST(ValueMetricProducerTest, TestPushedAggregateSumSliced) {
- string slicedConditionName = "UID";
- const int conditionTagId = 2;
+TEST(ValueMetricProducerTest, TestSkipZeroDiffOutput) {
ValueMetric metric;
metric.set_id(metricId);
metric.set_bucket(ONE_MINUTE);
metric.mutable_value_field()->set_field(tagId);
- metric.mutable_value_field()->add_child()->set_field(1);
- metric.set_aggregation_type(ValueMetric::SUM);
-
- metric.set_condition(StringToId(slicedConditionName));
- MetricConditionLink* link = metric.add_links();
- link->set_condition(StringToId(slicedConditionName));
- buildSimpleAtomFieldMatcher(tagId, 2, link->mutable_fields_in_what());
- buildSimpleAtomFieldMatcher(conditionTagId, 2, link->mutable_fields_in_condition());
-
- LogEvent event1(tagId, bucketStartTimeNs + 10);
- event1.write(10); // value
- event1.write("111"); // uid
- event1.init();
- ConditionKey key1;
- key1[StringToId(slicedConditionName)] =
- {getMockedDimensionKey(conditionTagId, 2, "111")};
-
- LogEvent event2(tagId, bucketStartTimeNs + 20);
- event2.write(15);
- event2.write("222");
- event2.init();
- ConditionKey key2;
- key2[StringToId(slicedConditionName)] =
- {getMockedDimensionKey(conditionTagId, 2, "222")};
+ metric.mutable_value_field()->add_child()->set_field(2);
+ metric.set_aggregation_type(ValueMetric::MIN);
+ metric.set_use_diff(true);
sp<MockConditionWizard> wizard = new NaggyMock<MockConditionWizard>();
- EXPECT_CALL(*wizard, query(_, key1, _, _, _, _)).WillOnce(Return(ConditionState::kFalse));
- EXPECT_CALL(*wizard, query(_, key2, _, _, _, _)).WillOnce(Return(ConditionState::kTrue));
-
sp<MockStatsPullerManager> pullerManager = new StrictMock<MockStatsPullerManager>();
- ValueMetricProducer valueProducer(kConfigKey, metric, 1, wizard, -1, bucketStartTimeNs,
+ ValueMetricProducer valueProducer(kConfigKey, metric, -1, wizard, -1, bucketStartTimeNs,
bucketStartTimeNs, pullerManager);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event1);
-
+ shared_ptr<LogEvent> event1 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 10);
+ event1->write(1);
+ event1->write(10);
+ event1->init();
+ shared_ptr<LogEvent> event2 = make_shared<LogEvent>(tagId, bucketStartTimeNs + 15);
+ event2->write(1);
+ event2->write(15);
+ event2->init();
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event1);
+ // has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
ValueMetricProducer::Interval curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(10, curInterval.base.long_value);
EXPECT_EQ(false, curInterval.hasValue);
- valueProducer.onMatchedLogEvent(1 /*log matcher index*/, event2);
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event2);
// has one slice
EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
- EXPECT_EQ(15, curInterval.value.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+ EXPECT_EQ(5, curInterval.value.long_value);
+
+ // no change in data.
+ shared_ptr<LogEvent> event3 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 10);
+ event3->write(1);
+ event3->write(15);
+ event3->init();
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event3);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(15, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
+
+ shared_ptr<LogEvent> event4 = make_shared<LogEvent>(tagId, bucket2StartTimeNs + 15);
+ event4->write(1);
+ event4->write(15);
+ event4->init();
+ valueProducer.onMatchedLogEvent(1 /*log matcher index*/, *event4);
+ EXPECT_EQ(1UL, valueProducer.mCurrentSlicedBucket.size());
+ curInterval = valueProducer.mCurrentSlicedBucket.begin()->second;
+ EXPECT_EQ(true, curInterval.hasBase);
+ EXPECT_EQ(15, curInterval.base.long_value);
+ EXPECT_EQ(true, curInterval.hasValue);
valueProducer.flushIfNeededLocked(bucket3StartTimeNs);
EXPECT_EQ(1UL, valueProducer.mPastBuckets.size());
EXPECT_EQ(1UL, valueProducer.mPastBuckets.begin()->second.size());
- EXPECT_EQ(15, valueProducer.mPastBuckets.begin()->second.back().mValueLong);
+ EXPECT_EQ(5, valueProducer.mPastBuckets.begin()->second.back().value.long_value);
}
} // namespace statsd
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 7382cd3f5ff1..e396a3d05517 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -1,4 +1,6 @@
Landroid/accessibilityservice/IAccessibilityServiceConnection$Stub;->asInterface(Landroid/os/IBinder;)Landroid/accessibilityservice/IAccessibilityServiceConnection;
+Landroid/accounts/AccountManager$AmsTask;-><init>(Landroid/accounts/AccountManager;Landroid/app/Activity;Landroid/os/Handler;Landroid/accounts/AccountManagerCallback;)V
+Landroid/accounts/AccountManager$Future2Task;-><init>(Landroid/accounts/AccountManager;Landroid/os/Handler;Landroid/accounts/AccountManagerCallback;)V
Landroid/accounts/IAccountAuthenticator$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/accounts/IAccountAuthenticator$Stub$Proxy;->mRemote:Landroid/os/IBinder;
Landroid/accounts/IAccountAuthenticator$Stub;-><init>()V
@@ -30,6 +32,7 @@ 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
+Landroid/app/ActivityThread$H;-><init>(Landroid/app/ActivityThread;)V
Landroid/app/admin/IDevicePolicyManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/app/admin/IDevicePolicyManager;
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_packageHasActiveAdmins:I
Landroid/app/admin/IDevicePolicyManager$Stub;->TRANSACTION_removeActiveAdmin:I
@@ -212,6 +215,7 @@ Landroid/app/job/IJobService;->startJob(Landroid/app/job/JobParameters;)V
Landroid/app/job/IJobService;->stopJob(Landroid/app/job/JobParameters;)V
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
@@ -262,6 +266,7 @@ Landroid/bluetooth/IBluetoothManager;->unregisterStateChangeCallback(Landroid/bl
Landroid/bluetooth/IBluetoothManagerCallback$Stub;-><init>()V
Landroid/bluetooth/IBluetoothPbap$Stub;->asInterface(Landroid/os/IBinder;)Landroid/bluetooth/IBluetoothPbap;
Landroid/bluetooth/IBluetoothStateChangeCallback$Stub;-><init>()V
+Landroid/content/ContentProviderProxy;->mRemote:Landroid/os/IBinder;
Landroid/content/IClipboard$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/content/IClipboard$Stub;->asInterface(Landroid/os/IBinder;)Landroid/content/IClipboard;
Landroid/content/IContentService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -415,9 +420,14 @@ Landroid/content/pm/IShortcutService$Stub;->asInterface(Landroid/os/IBinder;)Lan
Landroid/content/res/ConfigurationBoundResourceCache;-><init>()V
Landroid/content/res/DrawableCache;-><init>()V
Landroid/content/UndoManager;-><init>()V
+Landroid/database/BulkCursorProxy;->mRemote:Landroid/os/IBinder;
Landroid/database/IContentObserver$Stub;-><init>()V
Landroid/database/IContentObserver$Stub;->asInterface(Landroid/os/IBinder;)Landroid/database/IContentObserver;
Landroid/database/IContentObserver;->onChange(ZLandroid/net/Uri;I)V
+Landroid/database/sqlite/SQLiteConnectionPool;->$assertionsDisabled:Z
+Landroid/database/sqlite/SQLiteDatabase;->$assertionsDisabled:Z
+Landroid/filterfw/GraphEnvironment;->addReferences([Ljava/lang/Object;)V
+Landroid/hardware/camera2/utils/HashCodeHelpers;->hashCode([I)I
Landroid/hardware/display/IDisplayManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/display/IDisplayManager;
Landroid/hardware/display/IDisplayManager;->getDisplayInfo(I)Landroid/view/DisplayInfo;
Landroid/hardware/fingerprint/IFingerprintService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -432,6 +442,9 @@ Landroid/hardware/location/IContextHubService$Stub;->asInterface(Landroid/os/IBi
Landroid/hardware/usb/IUsbManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/hardware/usb/IUsbManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/hardware/usb/IUsbManager;
Landroid/icu/impl/CurrencyData;-><init>()V
+Landroid/icu/impl/ICUResourceBundle;->getULocale()Landroid/icu/util/ULocale;
+Landroid/icu/impl/ICUResourceBundle;->getWithFallback(Ljava/lang/String;)Landroid/icu/impl/ICUResourceBundle;
+Landroid/icu/impl/IllegalIcuArgumentException;-><init>(Ljava/lang/String;)V
Landroid/icu/text/ArabicShaping;-><init>(I)V
Landroid/icu/text/ArabicShaping;->isAlefMaksouraChar(C)Z
Landroid/icu/text/ArabicShaping;->isSeenTailFamilyChar(C)I
@@ -462,6 +475,8 @@ Landroid/icu/util/UResourceBundle;->getString()Ljava/lang/String;
Landroid/icu/util/UResourceBundle;->getType()I
Landroid/icu/util/UResourceBundleIterator;->hasNext()Z
Landroid/icu/util/UResourceBundleIterator;->next()Landroid/icu/util/UResourceBundle;
+Landroid/inputmethodservice/IInputMethodSessionWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller;
+Landroid/inputmethodservice/IInputMethodWrapper;->mCaller:Lcom/android/internal/os/HandlerCaller;
Landroid/location/ICountryDetector$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ICountryDetector;
Landroid/location/ICountryListener$Stub;-><init>()V
Landroid/location/IGeocodeProvider$Stub;-><init>()V
@@ -479,9 +494,11 @@ Landroid/location/ILocationManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/location/ILocationManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/location/ILocationManager;
Landroid/location/ILocationManager$Stub;->TRANSACTION_getAllProviders:I
Landroid/location/ILocationManager;->getAllProviders()Ljava/util/List;
+Landroid/location/LocationManager$ListenerTransport;-><init>(Landroid/location/LocationManager;Landroid/location/LocationListener;Landroid/os/Looper;)V
Landroid/Manifest$permission;->CAPTURE_SECURE_VIDEO_OUTPUT:Ljava/lang/String;
Landroid/Manifest$permission;->CAPTURE_VIDEO_OUTPUT:Ljava/lang/String;
Landroid/Manifest$permission;->READ_FRAME_BUFFER:Ljava/lang/String;
+Landroid/media/effect/SingleFilterEffect;-><init>(Landroid/media/effect/EffectContext;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
Landroid/media/IAudioFocusDispatcher;->dispatchAudioFocusChange(ILjava/lang/String;)V
Landroid/media/IAudioRoutesObserver$Stub;-><init>()V
Landroid/media/IAudioService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -500,6 +517,7 @@ Landroid/media/IRemoteDisplayCallback;->onStateChanged(Landroid/media/RemoteDisp
Landroid/media/IRingtonePlayer;->play(Landroid/os/IBinder;Landroid/net/Uri;Landroid/media/AudioAttributes;FZ)V
Landroid/media/IVolumeController$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/IVolumeController;
Landroid/media/MediaFile;-><init>()V
+Landroid/media/MediaScanner$MyMediaScannerClient;-><init>(Landroid/media/MediaScanner;)V
Landroid/media/projection/IMediaProjectionManager;->hasProjectionPermission(ILjava/lang/String;)Z
Landroid/media/session/ISessionManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/media/session/ISessionManager;
Landroid/net/IConnectivityManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
@@ -547,6 +565,7 @@ Landroid/net/INetworkStatsSession;->getSummaryForNetwork(Landroid/net/NetworkTem
Landroid/net/MobileLinkQualityInfo;-><init>()V
Landroid/net/nsd/INsdManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/nsd/INsdManager;
Landroid/net/nsd/INsdManager;->getMessenger()Landroid/os/Messenger;
+Landroid/net/sip/ISipSession$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/sip/ISipSession;
Landroid/net/SntpClient;-><init>()V
Landroid/net/wifi/IWifiManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Landroid/net/wifi/IWifiManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/net/wifi/IWifiManager;
@@ -637,6 +656,7 @@ Landroid/os/BatteryStats;->computeBatteryRealtime(JI)J
Landroid/os/BatteryStats;->computeBatteryTimeRemaining(J)J
Landroid/os/BatteryStats;->computeBatteryUptime(JI)J
Landroid/os/BatteryStats;->computeChargeTimeRemaining(J)J
+Landroid/os/BatteryStats;->dumpLine(Ljava/io/PrintWriter;ILjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
Landroid/os/BatteryStats;->getBatteryUptime(J)J
Landroid/os/BatteryStats;->getGlobalWifiRunningTime(JI)J
Landroid/os/BatteryStats;->getMobileRadioActiveTime(JI)J
@@ -725,6 +745,7 @@ Landroid/os/Environment;->buildExternalStorageAppDataDirs(Ljava/lang/String;)[Lj
Landroid/os/Environment;->buildExternalStorageAppFilesDirs(Ljava/lang/String;)[Ljava/io/File;
Landroid/os/Environment;->buildExternalStorageAppMediaDirs(Ljava/lang/String;)[Ljava/io/File;
Landroid/os/Environment;->buildExternalStorageAppObbDirs(Ljava/lang/String;)[Ljava/io/File;
+Landroid/os/Environment;->buildPaths([Ljava/io/File;[Ljava/lang/String;)[Ljava/io/File;
Landroid/os/Environment;->getDataSystemDirectory()Ljava/io/File;
Landroid/os/Environment;->getLegacyExternalStorageObbDirectory()Ljava/io/File;
Landroid/os/Environment;->initForCurrentUser()V
@@ -930,6 +951,8 @@ Landroid/os/ServiceManager;->listServices()[Ljava/lang/String;
Landroid/os/ServiceManager;->sCache:Ljava/util/Map;
Landroid/os/ServiceManager;->sServiceManager:Landroid/os/IServiceManager;
Landroid/os/ServiceManagerNative;->asInterface(Landroid/os/IBinder;)Landroid/os/IServiceManager;
+Landroid/os/ServiceManagerProxy;->getService(Ljava/lang/String;)Landroid/os/IBinder;
+Landroid/os/ServiceManagerProxy;->mRemote:Landroid/os/IBinder;
Landroid/os/ServiceSpecificException;-><init>(ILjava/lang/String;)V
Landroid/os/SharedMemory;->getFd()I
Landroid/os/ShellCommand;->peekNextArg()Ljava/lang/String;
@@ -1064,6 +1087,7 @@ Landroid/os/WorkSource;->sTmpWorkSource:Landroid/os/WorkSource;
Landroid/os/WorkSource;->updateLocked(Landroid/os/WorkSource;ZZ)Z
Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/String;)V
Landroid/os/ZygoteStartFailedEx;-><init>(Ljava/lang/Throwable;)V
+Landroid/preference/PreferenceGroupAdapter;->getItem(I)Landroid/preference/Preference;
Landroid/R$styleable;->ActionBar:[I
Landroid/R$styleable;->ActionBar_background:I
Landroid/R$styleable;->ActionBar_backgroundSplit:I
@@ -1346,6 +1370,17 @@ Landroid/security/IKeystoreService;->reset()I
Landroid/security/IKeystoreService;->sign(Ljava/lang/String;[B)[B
Landroid/security/IKeystoreService;->ungrant(Ljava/lang/String;I)I
Landroid/security/IKeystoreService;->verify(Ljava/lang/String;[B[B)I
+Landroid/security/keymaster/KeymasterBlobArgument;-><init>(ILandroid/os/Parcel;)V
+Landroid/security/keymaster/KeymasterBlobArgument;-><init>(I[B)V
+Landroid/security/keymaster/KeymasterBlobArgument;->blob:[B
+Landroid/security/keymaster/KeymasterBooleanArgument;-><init>(ILandroid/os/Parcel;)V
+Landroid/security/keymaster/KeymasterDateArgument;-><init>(ILandroid/os/Parcel;)V
+Landroid/security/keymaster/KeymasterIntArgument;-><init>(II)V
+Landroid/security/keymaster/KeymasterIntArgument;-><init>(ILandroid/os/Parcel;)V
+Landroid/security/keymaster/KeymasterIntArgument;->value:I
+Landroid/security/keymaster/KeymasterLongArgument;-><init>(IJ)V
+Landroid/security/keymaster/KeymasterLongArgument;-><init>(ILandroid/os/Parcel;)V
+Landroid/security/keymaster/KeymasterLongArgument;->value:J
Landroid/service/carrier/ICarrierMessagingCallback$Stub;-><init>()V
Landroid/service/carrier/ICarrierMessagingService;->filterSms(Landroid/service/carrier/MessagePdu;Ljava/lang/String;IILandroid/service/carrier/ICarrierMessagingCallback;)V
Landroid/service/dreams/IDreamManager$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/dreams/IDreamManager;
@@ -1383,9 +1418,42 @@ Landroid/service/wallpaper/IWallpaperEngine;->dispatchWallpaperCommand(Ljava/lan
Landroid/service/wallpaper/IWallpaperEngine;->setVisibility(Z)V
Landroid/service/wallpaper/IWallpaperService$Stub;->asInterface(Landroid/os/IBinder;)Landroid/service/wallpaper/IWallpaperService;
Landroid/speech/IRecognitionListener;->onEvent(ILandroid/os/Bundle;)V
+Landroid/telecom/Log;->i(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+Landroid/telecom/Log;->w(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
Landroid/telephony/CarrierMessagingServiceManager;-><init>()V
+Landroid/telephony/JapanesePhoneNumberFormatter;->format(Landroid/text/Editable;)V
+Landroid/telephony/SmsCbCmasInfo;->getCategory()I
+Landroid/telephony/SmsCbCmasInfo;->getCertainty()I
+Landroid/telephony/SmsCbCmasInfo;->getMessageClass()I
+Landroid/telephony/SmsCbCmasInfo;->getResponseType()I
+Landroid/telephony/SmsCbCmasInfo;->getSeverity()I
+Landroid/telephony/SmsCbCmasInfo;->getUrgency()I
+Landroid/telephony/SmsCbEtwsInfo;->getWarningType()I
+Landroid/telephony/SmsCbLocation;-><init>(Ljava/lang/String;)V
+Landroid/telephony/SmsCbLocation;-><init>(Ljava/lang/String;II)V
+Landroid/telephony/SmsCbLocation;->getCid()I
+Landroid/telephony/SmsCbLocation;->getLac()I
+Landroid/telephony/SmsCbLocation;->getPlmn()Ljava/lang/String;
+Landroid/telephony/SmsCbMessage;-><init>(Landroid/os/Parcel;)V
+Landroid/telephony/SmsCbMessage;->getCmasWarningInfo()Landroid/telephony/SmsCbCmasInfo;
+Landroid/telephony/SmsCbMessage;->getEtwsWarningInfo()Landroid/telephony/SmsCbEtwsInfo;
+Landroid/telephony/SmsCbMessage;->getGeographicalScope()I
+Landroid/telephony/SmsCbMessage;->getLanguageCode()Ljava/lang/String;
+Landroid/telephony/SmsCbMessage;->getLocation()Landroid/telephony/SmsCbLocation;
+Landroid/telephony/SmsCbMessage;->getMessageBody()Ljava/lang/String;
+Landroid/telephony/SmsCbMessage;->getMessageFormat()I
+Landroid/telephony/SmsCbMessage;->getSerialNumber()I
+Landroid/telephony/SmsCbMessage;->getServiceCategory()I
+Landroid/telephony/SmsCbMessage;->isCmasMessage()Z
+Landroid/telephony/SmsCbMessage;->isEmergencyMessage()Z
Landroid/telephony/TelephonyManager$MultiSimVariants;->values()[Landroid/telephony/TelephonyManager$MultiSimVariants;
+Landroid/test/AndroidTestCase;->getTestContext()Landroid/content/Context;
+Landroid/test/AndroidTestCase;->setTestContext(Landroid/content/Context;)V
+Landroid/test/InstrumentationTestCase;->runMethod(Ljava/lang/reflect/Method;I)V
+Landroid/test/RepetitiveTest;->numIterations()I
Landroid/util/Singleton;-><init>()V
+Landroid/util/XmlPullAttributes;-><init>(Lorg/xmlpull/v1/XmlPullParser;)V
+Landroid/util/XmlPullAttributes;->mParser:Lorg/xmlpull/v1/XmlPullParser;
Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setFindAccessibilityNodeInfoResult(Landroid/view/accessibility/AccessibilityNodeInfo;I)V
Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setFindAccessibilityNodeInfosResult(Ljava/util/List;I)V
Landroid/view/accessibility/IAccessibilityInteractionConnectionCallback;->setPerformAccessibilityActionResult(ZI)V
@@ -1443,7 +1511,9 @@ Landroid/view/IWindowSession;->setInTouchMode(Z)V
Landroid/view/IWindowSession;->setTransparentRegion(Landroid/view/IWindow;Landroid/graphics/Region;)V
Landroid/view/IWindowSession;->wallpaperCommandComplete(Landroid/os/IBinder;Landroid/os/Bundle;)V
Landroid/view/IWindowSession;->wallpaperOffsetsComplete(Landroid/os/IBinder;)V
+Landroid/view/RenderNodeAnimator;->setDuration(J)Landroid/view/RenderNodeAnimator;
Landroid/view/View$AttachInfo$InvalidateInfo;-><init>()V
+Landroid/view/View$CheckForLongPress;-><init>(Landroid/view/View;)V
Landroid/view/View$ListenerInfo;-><init>()V
Landroid/view/ViewTreeObserver$InternalInsetsInfo;-><init>()V
Landroid/webkit/CacheManager$CacheResult;-><init>()V
@@ -1453,9 +1523,102 @@ Landroid/webkit/IWebViewUpdateService$Stub;->asInterface(Landroid/os/IBinder;)La
Landroid/webkit/IWebViewUpdateService;->getCurrentWebViewPackageName()Ljava/lang/String;
Landroid/webkit/IWebViewUpdateService;->getValidWebViewPackages()[Landroid/webkit/WebViewProviderInfo;
Landroid/webkit/IWebViewUpdateService;->isFallbackPackage(Ljava/lang/String;)Z
+Landroid/widget/DigitalClock$FormatChangeObserver;-><init>(Landroid/widget/DigitalClock;)V
+Landroid/widget/QuickContactBadge$QueryHandler;-><init>(Landroid/widget/QuickContactBadge;Landroid/content/ContentResolver;)V
Landroid/widget/RelativeLayout$DependencyGraph$Node;-><init>()V
Landroid/widget/ScrollBarDrawable;-><init>()V
+Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;->clear()V
+Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;->getRememberedPosition()I
+Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;->inputDigit(C)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;->inputDigitAndRememberPosition(C)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder;->getDescriptionForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/util/Locale;)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder;->getInstance()Lcom/android/i18n/phonenumbers/geocoding/PhoneNumberOfflineGeocoder;
+Lcom/android/i18n/phonenumbers/NumberParseException;->getErrorType()Lcom/android/i18n/phonenumbers/NumberParseException$ErrorType;
+Lcom/android/i18n/phonenumbers/Phonemetadata$NumberFormat;->getDomesticCarrierCodeFormattingRule()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$NumberFormat;->getFormat()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$NumberFormat;->getLeadingDigitsPattern(I)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$NumberFormat;->getNationalPrefixFormattingRule()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$NumberFormat;->getPattern()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$NumberFormat;->leadingDigitsPatternSize()I
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->getCountryCode()I
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->getGeneralDesc()Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->getNationalPrefixForParsing()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->getNationalPrefixTransformRule()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->getPreferredExtnPrefix()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->hasNationalPrefix()Z
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->hasPreferredExtnPrefix()Z
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->intlNumberFormats()Ljava/util/List;
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadata;->numberFormats()Ljava/util/List;
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadataCollection;-><init>()V
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneMetadataCollection;->getMetadataList()Ljava/util/List;
+Lcom/android/i18n/phonenumbers/Phonemetadata$PhoneNumberDesc;->getNationalNumberPattern()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;->FROM_DEFAULT_COUNTRY:Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;->FROM_NUMBER_WITHOUT_PLUS_SIGN:Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;->FROM_NUMBER_WITH_IDD:Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;->FROM_NUMBER_WITH_PLUS_SIGN:Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;->values()[Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->clearCountryCode()Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->getCountryCode()I
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->getCountryCodeSource()Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber$CountryCodeSource;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->getExtension()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->getNationalNumber()J
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->hasCountryCode()Z
+Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;->hasExtension()Z
+Lcom/android/i18n/phonenumbers/PhoneNumberMatch;->end()I
+Lcom/android/i18n/phonenumbers/PhoneNumberMatch;->number()Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;
+Lcom/android/i18n/phonenumbers/PhoneNumberMatch;->rawString()Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/PhoneNumberMatch;->start()I
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$Leniency;->POSSIBLE:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$Leniency;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->EXACT_MATCH:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->NOT_A_NUMBER:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->NO_MATCH:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->NSN_MATCH:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->SHORT_NSN_MATCH:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;->E164:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;->INTERNATIONAL:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;->NATIONAL:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;->RFC3966:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->FIXED_LINE:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->FIXED_LINE_OR_MOBILE:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->MOBILE:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->PAGER:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->PERSONAL_NUMBER:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->PREMIUM_RATE:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->SHARED_COST:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->TOLL_FREE:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->UAN:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->values()[Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->VOICEMAIL:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;->VOIP:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$ValidationResult;->IS_POSSIBLE:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$ValidationResult;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil$ValidationResult;->TOO_LONG:Lcom/android/i18n/phonenumbers/PhoneNumberUtil$ValidationResult;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->findNumbers(Ljava/lang/CharSequence;Ljava/lang/String;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$Leniency;J)Ljava/lang/Iterable;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->format(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberFormat;)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->formatInOriginalFormat(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->getAsYouTypeFormatter(Ljava/lang/String;)Lcom/android/i18n/phonenumbers/AsYouTypeFormatter;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->getCountryCodeForRegion(Ljava/lang/String;)I
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->getInstance()Lcom/android/i18n/phonenumbers/PhoneNumberUtil;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNationalSignificantNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->getNumberType(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$PhoneNumberType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->getRegionCodeForNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Ljava/lang/String;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->isNumberMatch(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$MatchType;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->isPossibleNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->isPossibleNumberWithReason(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Lcom/android/i18n/phonenumbers/PhoneNumberUtil$ValidationResult;
+Lcom/android/i18n/phonenumbers/PhoneNumberUtil;->isValidNumber(Lcom/android/i18n/phonenumbers/Phonenumber$PhoneNumber;)Z
+Lcom/android/ims/ImsCall;->deflect(Ljava/lang/String;)V
+Lcom/android/ims/ImsCall;->isMultiparty()Z
+Lcom/android/ims/ImsCall;->reject(I)V
+Lcom/android/ims/ImsCall;->terminate(I)V
Lcom/android/ims/ImsConfigListener$Stub;-><init>()V
+Lcom/android/ims/ImsEcbm;->exitEmergencyCallbackMode()V
+Lcom/android/ims/ImsManager;->getConfigInterface()Lcom/android/ims/ImsConfig;
+Lcom/android/ims/ImsManager;->getInstance(Landroid/content/Context;I)Lcom/android/ims/ImsManager;
+Lcom/android/ims/ImsManager;->isEnhanced4gLteModeSettingEnabledByUser(Landroid/content/Context;)Z
+Lcom/android/ims/ImsManager;->isNonTtyOrTtyOnVolteEnabled(Landroid/content/Context;)Z
+Lcom/android/ims/ImsManager;->isVolteEnabledByPlatform(Landroid/content/Context;)Z
+Lcom/android/ims/ImsUtInterface;->queryCallForward(ILjava/lang/String;Landroid/os/Message;)V
Lcom/android/ims/internal/IImsCallSession$Stub;-><init>()V
Lcom/android/ims/internal/IImsCallSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/ims/internal/IImsCallSession;
Lcom/android/ims/internal/IImsConfig$Stub;-><init>()V
@@ -1473,7 +1636,15 @@ Lcom/android/ims/internal/IImsVideoCallCallback;->receiveSessionModifyRequest(La
Lcom/android/ims/internal/IImsVideoCallCallback;->receiveSessionModifyResponse(ILandroid/telecom/VideoProfile;Landroid/telecom/VideoProfile;)V
Lcom/android/ims/internal/IImsVideoCallProvider$Stub;-><init>()V
Lcom/android/ims/internal/IImsVideoCallProvider;->setCallback(Lcom/android/ims/internal/IImsVideoCallCallback;)V
+Lcom/android/ims/internal/ImsVideoCallProviderWrapper;-><init>(Lcom/android/ims/internal/IImsVideoCallProvider;)V
Lcom/android/ims/internal/uce/uceservice/IUceListener$Stub;-><init>()V
+Lcom/android/internal/app/AlertActivity;-><init>()V
+Lcom/android/internal/app/AlertActivity;->mAlert:Lcom/android/internal/app/AlertController;
+Lcom/android/internal/app/AlertActivity;->mAlertParams:Lcom/android/internal/app/AlertController$AlertParams;
+Lcom/android/internal/app/AlertActivity;->setupAlert()V
+Lcom/android/internal/app/AssistUtils;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/app/AssistUtils;->getAssistComponentForUser(I)Landroid/content/ComponentName;
+Lcom/android/internal/app/ChooserActivity;-><init>()V
Lcom/android/internal/app/IAppOpsCallback$Stub;-><init>()V
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/app/IAppOpsService$Stub$Proxy;->checkOperation(IILjava/lang/String;)I
@@ -1508,9 +1679,35 @@ Lcom/android/internal/app/IBatteryStats;->getAwakeTimeBattery()J
Lcom/android/internal/app/IBatteryStats;->getStatistics()[B
Lcom/android/internal/app/IBatteryStats;->isCharging()Z
Lcom/android/internal/app/IMediaContainerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IMediaContainerService;
+Lcom/android/internal/app/IntentForwarderActivity;->TAG:Ljava/lang/String;
Lcom/android/internal/app/IVoiceInteractionManagerService$Stub$Proxy;->showSessionFromSession(Landroid/os/IBinder;Landroid/os/Bundle;I)Z
Lcom/android/internal/app/IVoiceInteractionManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/app/IVoiceInteractionManagerService;
Lcom/android/internal/app/IVoiceInteractionManagerService;->getKeyphraseSoundModel(ILjava/lang/String;)Landroid/hardware/soundtrigger/SoundTrigger$KeyphraseSoundModel;
+Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;-><init>(Ljava/util/Locale;Z)V
+Lcom/android/internal/app/LocaleHelper$LocaleInfoComparator;->compare(Lcom/android/internal/app/LocaleStore$LocaleInfo;Lcom/android/internal/app/LocaleStore$LocaleInfo;)I
+Lcom/android/internal/app/LocaleHelper;->getDisplayCountry(Ljava/util/Locale;Ljava/util/Locale;)Ljava/lang/String;
+Lcom/android/internal/app/LocaleHelper;->getDisplayName(Ljava/util/Locale;Ljava/util/Locale;Z)Ljava/lang/String;
+Lcom/android/internal/app/LocaleHelper;->normalizeForSearch(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String;
+Lcom/android/internal/app/LocalePicker$LocaleInfo;->getLocale()Ljava/util/Locale;
+Lcom/android/internal/app/LocalePicker;->getLocales()Landroid/os/LocaleList;
+Lcom/android/internal/app/LocalePicker;->updateLocale(Ljava/util/Locale;)V
+Lcom/android/internal/app/LocalePicker;->updateLocales(Landroid/os/LocaleList;)V
+Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameInUiLanguage()Ljava/lang/String;
+Lcom/android/internal/app/LocaleStore$LocaleInfo;->getFullNameNative()Ljava/lang/String;
+Lcom/android/internal/app/LocaleStore$LocaleInfo;->getId()Ljava/lang/String;
+Lcom/android/internal/app/LocaleStore$LocaleInfo;->getLocale()Ljava/util/Locale;
+Lcom/android/internal/app/LocaleStore$LocaleInfo;->getParent()Ljava/util/Locale;
+Lcom/android/internal/app/LocaleStore;->fillCache(Landroid/content/Context;)V
+Lcom/android/internal/app/LocaleStore;->getLevelLocales(Landroid/content/Context;Ljava/util/Set;Lcom/android/internal/app/LocaleStore$LocaleInfo;Z)Ljava/util/Set;
+Lcom/android/internal/app/LocaleStore;->getLocaleInfo(Ljava/util/Locale;)Lcom/android/internal/app/LocaleStore$LocaleInfo;
+Lcom/android/internal/app/NetInitiatedActivity;->handleNIVerify(Landroid/content/Intent;)V
+Lcom/android/internal/app/ResolverActivity;-><init>()V
+Lcom/android/internal/app/ResolverActivity;->mAdapter:Lcom/android/internal/app/ResolverActivity$ResolveListAdapter;
+Lcom/android/internal/app/ResolverActivity;->mPm:Landroid/content/pm/PackageManager;
+Lcom/android/internal/app/ResolverActivity;->onCreate(Landroid/os/Bundle;Landroid/content/Intent;Ljava/lang/CharSequence;[Landroid/content/Intent;Ljava/util/List;Z)V
+Lcom/android/internal/app/WindowDecorActionBar$TabImpl;->mCallback:Landroid/app/ActionBar$TabListener;
+Lcom/android/internal/app/WindowDecorActionBar;->mTabScrollView:Lcom/android/internal/widget/ScrollingTabContainerView;
+Lcom/android/internal/app/WindowDecorActionBar;->setShowHideAnimationEnabled(Z)V
Lcom/android/internal/appwidget/IAppWidgetService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/appwidget/IAppWidgetService;
Lcom/android/internal/appwidget/IAppWidgetService$Stub;->TRANSACTION_bindAppWidgetId:I
Lcom/android/internal/appwidget/IAppWidgetService;->bindAppWidgetId(Ljava/lang/String;IILandroid/content/ComponentName;Landroid/os/Bundle;)Z
@@ -1518,17 +1715,80 @@ Lcom/android/internal/appwidget/IAppWidgetService;->bindRemoteViewsService(Ljava
Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetIds(Landroid/content/ComponentName;)[I
Lcom/android/internal/appwidget/IAppWidgetService;->getAppWidgetViews(Ljava/lang/String;I)Landroid/widget/RemoteViews;
Lcom/android/internal/backup/IBackupTransport$Stub;-><init>()V
+Lcom/android/internal/database/SortCursor;-><init>([Landroid/database/Cursor;Ljava/lang/String;)V
+Lcom/android/internal/database/SortCursor;->mCursor:Landroid/database/Cursor;
+Lcom/android/internal/database/SortCursor;->mCursors:[Landroid/database/Cursor;
+Lcom/android/internal/http/HttpDateTime;->parse(Ljava/lang/String;)J
+Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;-><init>()V
+Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorId:Ljava/lang/String;
+Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->requestorIdEncoding:I
+Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->text:Ljava/lang/String;
+Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;->textEncoding:I
+Lcom/android/internal/location/GpsNetInitiatedHandler;->decodeString(Ljava/lang/String;ZI)Ljava/lang/String;
+Lcom/android/internal/location/GpsNetInitiatedHandler;->handleNiNotification(Lcom/android/internal/location/GpsNetInitiatedHandler$GpsNiNotification;)V
+Lcom/android/internal/location/GpsNetInitiatedHandler;->mIsHexInput:Z
Lcom/android/internal/location/ILocationProvider$Stub;-><init>()V
Lcom/android/internal/logging/MetricsLogger;-><init>()V
Lcom/android/internal/net/LegacyVpnInfo;-><init>()V
Lcom/android/internal/net/VpnConfig;-><init>()V
+Lcom/android/internal/os/AndroidPrintStream;-><init>(ILjava/lang/String;)V
+Lcom/android/internal/os/BaseCommand;-><init>()V
+Lcom/android/internal/os/BaseCommand;->mArgs:Landroid/os/ShellCommand;
Lcom/android/internal/os/BatterySipper$DrainType;->values()[Lcom/android/internal/os/BatterySipper$DrainType;
+Lcom/android/internal/os/BinderInternal;->getContextObject()Landroid/os/IBinder;
+Lcom/android/internal/os/BinderInternal;->handleGc()V
+Lcom/android/internal/os/ClassLoaderFactory;->createClassloaderNamespace(Ljava/lang/ClassLoader;ILjava/lang/String;Ljava/lang/String;ZZ)Ljava/lang/String;
Lcom/android/internal/os/IDropBoxManagerService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/os/IDropBoxManagerService;
Lcom/android/internal/os/IDropBoxManagerService;->getNextEntry(Ljava/lang/String;JLjava/lang/String;)Landroid/os/DropBoxManager$Entry;
+Lcom/android/internal/os/ProcessCpuTracker$Stats;->name:Ljava/lang/String;
+Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_stime:I
+Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_uptime:J
+Lcom/android/internal/os/ProcessCpuTracker$Stats;->rel_utime:I
+Lcom/android/internal/os/ProcessCpuTracker;-><init>(Z)V
+Lcom/android/internal/os/ProcessCpuTracker;->countWorkingStats()I
+Lcom/android/internal/os/ProcessCpuTracker;->getWorkingStats(I)Lcom/android/internal/os/ProcessCpuTracker$Stats;
+Lcom/android/internal/os/ProcessCpuTracker;->update()V
+Lcom/android/internal/os/RuntimeInit;->commonInit()V
+Lcom/android/internal/os/RuntimeInit;->getApplicationObject()Landroid/os/IBinder;
+Lcom/android/internal/os/RuntimeInit;->initialized:Z
+Lcom/android/internal/os/RuntimeInit;->main([Ljava/lang/String;)V
+Lcom/android/internal/os/RuntimeInit;->mApplicationObject:Landroid/os/IBinder;
+Lcom/android/internal/os/ZygoteConnection$Arguments;-><init>([Ljava/lang/String;)V
+Lcom/android/internal/os/ZygoteConnection$Arguments;->effectiveCapabilities:J
+Lcom/android/internal/os/ZygoteConnection$Arguments;->gid:I
+Lcom/android/internal/os/ZygoteConnection$Arguments;->gids:[I
+Lcom/android/internal/os/ZygoteConnection$Arguments;->permittedCapabilities:J
+Lcom/android/internal/os/ZygoteConnection$Arguments;->remainingArgs:[Ljava/lang/String;
+Lcom/android/internal/os/ZygoteConnection$Arguments;->rlimits:Ljava/util/ArrayList;
+Lcom/android/internal/os/ZygoteConnection$Arguments;->uid:I
+Lcom/android/internal/os/ZygoteConnection;->applyUidSecurityPolicy(Lcom/android/internal/os/ZygoteConnection$Arguments;Landroid/net/Credentials;)V
+Lcom/android/internal/os/ZygoteConnection;->closeSocket()V
+Lcom/android/internal/os/ZygoteConnection;->getFileDesciptor()Ljava/io/FileDescriptor;
+Lcom/android/internal/os/ZygoteConnection;->intArray2d:[[I
+Lcom/android/internal/os/ZygoteConnection;->mSocket:Landroid/net/LocalSocket;
+Lcom/android/internal/os/ZygoteConnection;->mSocketOutStream:Ljava/io/DataOutputStream;
+Lcom/android/internal/os/ZygoteConnection;->peer:Landroid/net/Credentials;
+Lcom/android/internal/os/ZygoteConnection;->readArgumentList()[Ljava/lang/String;
+Lcom/android/internal/os/ZygoteInit;->main([Ljava/lang/String;)V
+Lcom/android/internal/os/ZygoteInit;->mResources:Landroid/content/res/Resources;
+Lcom/android/internal/os/ZygoteSecurityException;-><init>(Ljava/lang/String;)V
+Lcom/android/internal/policy/DecorView;->mLastBottomInset:I
+Lcom/android/internal/policy/DecorView;->mLastLeftInset:I
+Lcom/android/internal/policy/DecorView;->mLastRightInset:I
+Lcom/android/internal/policy/DecorView;->mWindow:Lcom/android/internal/policy/PhoneWindow;
Lcom/android/internal/policy/IKeyguardService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardService;
Lcom/android/internal/policy/IKeyguardService;->doKeyguardTimeout(Landroid/os/Bundle;)V
Lcom/android/internal/policy/IKeyguardService;->setKeyguardEnabled(Z)V
Lcom/android/internal/policy/IKeyguardStateCallback$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/policy/IKeyguardStateCallback;
+Lcom/android/internal/policy/PhoneFallbackEventHandler;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/policy/PhoneFallbackEventHandler;->mContext:Landroid/content/Context;
+Lcom/android/internal/policy/PhoneFallbackEventHandler;->mView:Landroid/view/View;
+Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyDown(ILandroid/view/KeyEvent;)Z
+Lcom/android/internal/policy/PhoneFallbackEventHandler;->onKeyUp(ILandroid/view/KeyEvent;)Z
+Lcom/android/internal/policy/PhoneFallbackEventHandler;->startCallActivity()V
+Lcom/android/internal/policy/PhoneWindow;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/policy/PhoneWindow;->mTitle:Ljava/lang/CharSequence;
+Lcom/android/internal/preference/YesNoPreference;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
Lcom/android/internal/R$anim;->fade_in:I
Lcom/android/internal/R$array;->config_autoBrightnessLcdBacklightValues:I
Lcom/android/internal/R$array;->config_autoBrightnessLevels:I
@@ -1996,9 +2256,961 @@ Lcom/android/internal/statusbar/IStatusBarService;->removeIcon(Ljava/lang/String
Lcom/android/internal/statusbar/IStatusBarService;->setIconVisibility(Ljava/lang/String;Z)V
Lcom/android/internal/telecom/ITelecomService$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telecom/ITelecomService;
Lcom/android/internal/telecom/ITelecomService;->getCallState()I
+Lcom/android/internal/telephony/BaseCommands;->mCallStateRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mCallWaitingInfoRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mCatCallSetUpRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mCatCcAlphaRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mCatEventRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mCatProCmdRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mCatSessionEndRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mCdmaPrlChangedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mCdmaSmsRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mCdmaSubscriptionChangedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/BaseCommands;->mEmergencyCallbackModeRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mExitEmergencyCallbackModeRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mGsmBroadcastSmsRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mGsmSmsRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mHardwareConfigChangeRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mIccRefreshRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mIccSmsFullRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mIccStatusChangedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mImsNetworkStateChangedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mNITZTimeRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mOtaProvisionRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mPhoneRadioCapabilityChangedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mPhoneType:I
+Lcom/android/internal/telephony/BaseCommands;->mPreferredNetworkType:I
+Lcom/android/internal/telephony/BaseCommands;->mResendIncallMuteRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mRestrictedStateRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mRilCellInfoListRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mRingbackToneRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mRingRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mSignalStrengthRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mSmsOnSimRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mSmsStatusRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mSrvccStateRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mSsnRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mSsRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mStateMonitor:Ljava/lang/Object;
+Lcom/android/internal/telephony/BaseCommands;->mSubscriptionStatusRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/BaseCommands;->mUnsolOemHookRawRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mUSSDRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/BaseCommands;->mVoiceRadioTechChangedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/Call$State;->ACTIVE:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->ALERTING:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->DIALING:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->DISCONNECTED:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->DISCONNECTING:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->HOLDING:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->IDLE:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->INCOMING:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->isAlive()Z
+Lcom/android/internal/telephony/Call$State;->isRinging()Z
+Lcom/android/internal/telephony/Call$State;->values()[Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call$State;->WAITING:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call;-><init>()V
+Lcom/android/internal/telephony/Call;->getConnections()Ljava/util/List;
+Lcom/android/internal/telephony/Call;->getEarliestConnection()Lcom/android/internal/telephony/Connection;
+Lcom/android/internal/telephony/Call;->getLatestConnection()Lcom/android/internal/telephony/Connection;
+Lcom/android/internal/telephony/Call;->getPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/Call;->getState()Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Call;->hangup()V
+Lcom/android/internal/telephony/Call;->isIdle()Z
+Lcom/android/internal/telephony/Call;->isMultiparty()Z
+Lcom/android/internal/telephony/Call;->mConnections:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/Call;->mState:Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/CallerInfoAsyncQuery$CallerInfoAsyncQueryHandler;-><init>(Lcom/android/internal/telephony/CallerInfoAsyncQuery;Landroid/content/Context;)V
+Lcom/android/internal/telephony/CallerInfoAsyncQuery$CookieWrapper;-><init>()V
+Lcom/android/internal/telephony/CallerInfoAsyncQuery;->release()V
+Lcom/android/internal/telephony/CallForwardInfo;-><init>()V
+Lcom/android/internal/telephony/CallForwardInfo;->number:Ljava/lang/String;
+Lcom/android/internal/telephony/CallForwardInfo;->reason:I
+Lcom/android/internal/telephony/CallForwardInfo;->serviceClass:I
+Lcom/android/internal/telephony/CallForwardInfo;->status:I
+Lcom/android/internal/telephony/CallForwardInfo;->timeSeconds:I
+Lcom/android/internal/telephony/CallForwardInfo;->toa:I
+Lcom/android/internal/telephony/CallManager;->canConference(Lcom/android/internal/telephony/Call;I)Z
+Lcom/android/internal/telephony/CallManager;->canDial(Lcom/android/internal/telephony/Phone;)Z
+Lcom/android/internal/telephony/CallManager;->conference(Lcom/android/internal/telephony/Call;)V
+Lcom/android/internal/telephony/CallManager;->getActiveFgCall(I)Lcom/android/internal/telephony/Call;
+Lcom/android/internal/telephony/CallManager;->getActiveFgCallState(I)Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/CallManager;->getBackgroundCalls()Ljava/util/List;
+Lcom/android/internal/telephony/CallManager;->getBgCallConnections()Ljava/util/List;
+Lcom/android/internal/telephony/CallManager;->getBgPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/CallManager;->getContext()Landroid/content/Context;
+Lcom/android/internal/telephony/CallManager;->getDefaultPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/CallManager;->getFgCallConnections()Ljava/util/List;
+Lcom/android/internal/telephony/CallManager;->getFgPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/CallManager;->getFgPhone(I)Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/CallManager;->getFirstActiveBgCall()Lcom/android/internal/telephony/Call;
+Lcom/android/internal/telephony/CallManager;->getFirstActiveBgCall(I)Lcom/android/internal/telephony/Call;
+Lcom/android/internal/telephony/CallManager;->getFirstActiveRingingCall()Lcom/android/internal/telephony/Call;
+Lcom/android/internal/telephony/CallManager;->getFirstActiveRingingCall(I)Lcom/android/internal/telephony/Call;
+Lcom/android/internal/telephony/CallManager;->getInstance()Lcom/android/internal/telephony/CallManager;
+Lcom/android/internal/telephony/CallManager;->getPhoneInCall()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/CallManager;->getRingingCalls()Ljava/util/List;
+Lcom/android/internal/telephony/CallManager;->getRingingPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/CallManager;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/CallManager;->getState(I)Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/CallManager;->hasActiveBgCall()Z
+Lcom/android/internal/telephony/CallManager;->hasActiveBgCall(I)Z
+Lcom/android/internal/telephony/CallManager;->hasActiveFgCall()Z
+Lcom/android/internal/telephony/CallManager;->hasActiveFgCall(I)Z
+Lcom/android/internal/telephony/CallManager;->hasActiveRingingCall(I)Z
+Lcom/android/internal/telephony/CallManager;->hasMoreThanOneRingingCall()Z
+Lcom/android/internal/telephony/CallManager;->hasMoreThanOneRingingCall(I)Z
+Lcom/android/internal/telephony/CallManager;->mBackgroundCalls:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/CallManager;->mEmptyConnections:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/CallManager;->mForegroundCalls:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/CallManager;->mPhones:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/CallManager;->mRingingCalls:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/CallManager;->registerForDisconnect(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CallManager;->registerForNewRingingConnection(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CallManager;->registerForPreciseCallStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CallManager;->registerPhone(Lcom/android/internal/telephony/Phone;)Z
+Lcom/android/internal/telephony/CallManager;->unregisterForDisconnect(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CallManager;->unregisterForNewRingingConnection(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CallManager;->unregisterForPreciseCallStateChanged(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CallManager;->unregisterPhone(Lcom/android/internal/telephony/Phone;)V
+Lcom/android/internal/telephony/CallStateException;-><init>(Ljava/lang/String;)V
+Lcom/android/internal/telephony/CallTracker;-><init>()V
+Lcom/android/internal/telephony/CallTracker;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/CallTracker;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/CallTracker;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/CallTracker;->mNeedsPoll:Z
+Lcom/android/internal/telephony/CallTracker;->mNumberConverted:Z
+Lcom/android/internal/telephony/CallTracker;->mPendingOperations:I
+Lcom/android/internal/telephony/CallTracker;->registerForVoiceCallEnded(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CarrierServiceBindHelper;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/CarrierServiceBindHelper;->mHandler:Landroid/os/Handler;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->CLOSE_CHANNEL:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->DISPLAY_TEXT:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->fromInt(I)Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->GET_CHANNEL_STATUS:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->GET_INKEY:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->GET_INPUT:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->LANGUAGE_NOTIFICATION:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->LAUNCH_BROWSER:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->OPEN_CHANNEL:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->PLAY_TONE:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->PROVIDE_LOCAL_INFORMATION:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->RECEIVE_DATA:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->REFRESH:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SELECT_ITEM:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_DATA:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_DTMF:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_SMS:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_SS:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SEND_USSD:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_CALL:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_EVENT_LIST:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_IDLE_MODE_TEXT:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->SET_UP_MENU:Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/AppInterface$CommandType;->values()[Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;->callMsg:Lcom/android/internal/telephony/cat/TextMessage;
+Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;->confirmMsg:Lcom/android/internal/telephony/cat/TextMessage;
+Lcom/android/internal/telephony/cat/CatCmdMessage$SetupEventListSettings;->eventList:[I
+Lcom/android/internal/telephony/cat/CatCmdMessage;->getCallSettings()Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->getCmdType()Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->geTextMessage()Lcom/android/internal/telephony/cat/TextMessage;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->getSetEventList()Lcom/android/internal/telephony/cat/CatCmdMessage$SetupEventListSettings;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->hasIconLoadFailed()Z
+Lcom/android/internal/telephony/cat/CatCmdMessage;->mCallSettings:Lcom/android/internal/telephony/cat/CatCmdMessage$CallSettings;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->mCmdDet:Lcom/android/internal/telephony/cat/CommandDetails;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->mInput:Lcom/android/internal/telephony/cat/Input;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->mMenu:Lcom/android/internal/telephony/cat/Menu;
+Lcom/android/internal/telephony/cat/CatCmdMessage;->mTextMsg:Lcom/android/internal/telephony/cat/TextMessage;
+Lcom/android/internal/telephony/cat/CatLog;->d(Ljava/lang/Object;Ljava/lang/String;)V
+Lcom/android/internal/telephony/cat/CatLog;->d(Ljava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/cat/CatLog;->e(Ljava/lang/Object;Ljava/lang/String;)V
+Lcom/android/internal/telephony/cat/CatResponseMessage;->setEventDownload(I[B)V
+Lcom/android/internal/telephony/cat/CatService;->dispose()V
+Lcom/android/internal/telephony/cat/CatService;->isStkAppInstalled()Z
+Lcom/android/internal/telephony/cat/CatService;->mCmdIf:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/cat/CatService;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/cat/CatService;->mCurrntCmd:Lcom/android/internal/telephony/cat/CatCmdMessage;
+Lcom/android/internal/telephony/cat/CatService;->mHandlerThread:Landroid/os/HandlerThread;
+Lcom/android/internal/telephony/cat/CatService;->mMenuCmd:Lcom/android/internal/telephony/cat/CatCmdMessage;
+Lcom/android/internal/telephony/cat/CatService;->mMsgDecoder:Lcom/android/internal/telephony/cat/RilMessageDecoder;
+Lcom/android/internal/telephony/cat/CatService;->mSlotId:I
+Lcom/android/internal/telephony/cat/CatService;->mStkAppInstalled:Z
+Lcom/android/internal/telephony/cat/CatService;->mUiccController:Lcom/android/internal/telephony/uicc/UiccController;
+Lcom/android/internal/telephony/cat/CatService;->sendTerminalResponse(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/ResultCode;ZILcom/android/internal/telephony/cat/ResponseData;)V
+Lcom/android/internal/telephony/cat/CatService;->sInstance:[Lcom/android/internal/telephony/cat/CatService;
+Lcom/android/internal/telephony/cat/CatService;->sInstanceLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/cat/CommandDetails;->commandNumber:I
+Lcom/android/internal/telephony/cat/CommandDetails;->commandQualifier:I
+Lcom/android/internal/telephony/cat/CommandDetails;->compRequired:Z
+Lcom/android/internal/telephony/cat/CommandDetails;->typeOfCommand:I
+Lcom/android/internal/telephony/cat/CommandParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;)V
+Lcom/android/internal/telephony/cat/CommandParams;->getCommandType()Lcom/android/internal/telephony/cat/AppInterface$CommandType;
+Lcom/android/internal/telephony/cat/CommandParams;->mCmdDet:Lcom/android/internal/telephony/cat/CommandDetails;
+Lcom/android/internal/telephony/cat/CommandParamsFactory;->dispose()V
+Lcom/android/internal/telephony/cat/CommandParamsFactory;->mIconLoader:Lcom/android/internal/telephony/cat/IconLoader;
+Lcom/android/internal/telephony/cat/CommandParamsFactory;->searchForNextTag(Lcom/android/internal/telephony/cat/ComprehensionTlvTag;Ljava/util/Iterator;)Lcom/android/internal/telephony/cat/ComprehensionTlv;
+Lcom/android/internal/telephony/cat/CommandParamsFactory;->searchForTag(Lcom/android/internal/telephony/cat/ComprehensionTlvTag;Ljava/util/List;)Lcom/android/internal/telephony/cat/ComprehensionTlv;
+Lcom/android/internal/telephony/cat/ComprehensionTlv;->getLength()I
+Lcom/android/internal/telephony/cat/ComprehensionTlv;->getRawValue()[B
+Lcom/android/internal/telephony/cat/ComprehensionTlv;->getTag()I
+Lcom/android/internal/telephony/cat/ComprehensionTlv;->getValueIndex()I
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->ADDRESS:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->ALPHA_ID:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->COMMAND_DETAILS:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->DEVICE_IDENTITIES:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->ICON_ID:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->RESULT:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->SMS_TPDU:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->TEXT_ATTRIBUTE:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->TEXT_STRING:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->USSD_STRING:Lcom/android/internal/telephony/cat/ComprehensionTlvTag;
+Lcom/android/internal/telephony/cat/ComprehensionTlvTag;->value()I
+Lcom/android/internal/telephony/cat/DeviceIdentities;->destinationId:I
+Lcom/android/internal/telephony/cat/DisplayTextParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/TextMessage;)V
+Lcom/android/internal/telephony/cat/DisplayTextParams;->mTextMsg:Lcom/android/internal/telephony/cat/TextMessage;
+Lcom/android/internal/telephony/cat/Duration$TimeUnit;->value()I
+Lcom/android/internal/telephony/cat/Duration;->timeInterval:I
+Lcom/android/internal/telephony/cat/Duration;->timeUnit:Lcom/android/internal/telephony/cat/Duration$TimeUnit;
+Lcom/android/internal/telephony/cat/GetInputParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/Input;)V
+Lcom/android/internal/telephony/cat/IconId;->recordNumber:I
+Lcom/android/internal/telephony/cat/IconLoader;->loadIcon(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/cat/Menu;->titleAttrs:Ljava/util/List;
+Lcom/android/internal/telephony/cat/PlayToneParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/TextMessage;Lcom/android/internal/telephony/cat/Tone;Lcom/android/internal/telephony/cat/Duration;Z)V
+Lcom/android/internal/telephony/cat/ResponseData;-><init>()V
+Lcom/android/internal/telephony/cat/ResponseData;->format(Ljava/io/ByteArrayOutputStream;)V
+Lcom/android/internal/telephony/cat/ResultCode;->BACKWARD_MOVE_BY_USER:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->BEYOND_TERMINAL_CAPABILITY:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->BIP_ERROR:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->CMD_DATA_NOT_UNDERSTOOD:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->HELP_INFO_REQUIRED:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->LAUNCH_BROWSER_ERROR:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->NETWORK_CRNTLY_UNABLE_TO_PROCESS:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->NO_RESPONSE_FROM_USER:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->OK:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_ICON_NOT_DISPLAYED:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_LIMITED_SERVICE:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_MODIFIED_BY_NAA:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_NAA_NOT_ACTIVE:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_TONE_NOT_PLAYED:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_ADDITIONAL_EFS_READ:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_MISSING_INFO:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_MODIFICATION:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->PRFRMD_WITH_PARTIAL_COMPREHENSION:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->REQUIRED_VALUES_MISSING:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->TERMINAL_CRNTLY_UNABLE_TO_PROCESS:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->UICC_SESSION_TERM_BY_USER:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->USER_NOT_ACCEPT:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->USIM_CALL_CONTROL_PERMANENT:Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultCode;->value()I
+Lcom/android/internal/telephony/cat/ResultCode;->values()[Lcom/android/internal/telephony/cat/ResultCode;
+Lcom/android/internal/telephony/cat/ResultException;-><init>(Lcom/android/internal/telephony/cat/ResultCode;)V
+Lcom/android/internal/telephony/cat/RilMessage;-><init>(ILjava/lang/String;)V
+Lcom/android/internal/telephony/cat/RilMessage;->mData:Ljava/lang/Object;
+Lcom/android/internal/telephony/cat/RilMessage;->mId:I
+Lcom/android/internal/telephony/cat/RilMessageDecoder;->getInstance(Landroid/os/Handler;Lcom/android/internal/telephony/uicc/IccFileHandler;I)Lcom/android/internal/telephony/cat/RilMessageDecoder;
+Lcom/android/internal/telephony/cat/RilMessageDecoder;->mCmdParamsFactory:Lcom/android/internal/telephony/cat/CommandParamsFactory;
+Lcom/android/internal/telephony/cat/RilMessageDecoder;->mCurrentRilMessage:Lcom/android/internal/telephony/cat/RilMessage;
+Lcom/android/internal/telephony/cat/RilMessageDecoder;->mInstance:[Lcom/android/internal/telephony/cat/RilMessageDecoder;
+Lcom/android/internal/telephony/cat/RilMessageDecoder;->mStateStart:Lcom/android/internal/telephony/cat/RilMessageDecoder$StateStart;
+Lcom/android/internal/telephony/cat/RilMessageDecoder;->sendCmdForExecution(Lcom/android/internal/telephony/cat/RilMessage;)V
+Lcom/android/internal/telephony/cat/RilMessageDecoder;->sendStartDecodingMessageParams(Lcom/android/internal/telephony/cat/RilMessage;)V
+Lcom/android/internal/telephony/cat/SelectItemParams;-><init>(Lcom/android/internal/telephony/cat/CommandDetails;Lcom/android/internal/telephony/cat/Menu;Z)V
+Lcom/android/internal/telephony/cat/TextMessage;-><init>()V
+Lcom/android/internal/telephony/cat/TextMessage;->iconSelfExplanatory:Z
+Lcom/android/internal/telephony/cat/TextMessage;->text:Ljava/lang/String;
+Lcom/android/internal/telephony/cat/ValueObject;-><init>()V
+Lcom/android/internal/telephony/cat/ValueParser;->retrieveAlphaId(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Ljava/lang/String;
+Lcom/android/internal/telephony/cat/ValueParser;->retrieveDeviceIdentities(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Lcom/android/internal/telephony/cat/DeviceIdentities;
+Lcom/android/internal/telephony/cat/ValueParser;->retrieveTextAttribute(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Ljava/util/List;
+Lcom/android/internal/telephony/cat/ValueParser;->retrieveTextString(Lcom/android/internal/telephony/cat/ComprehensionTlv;)Ljava/lang/String;
+Lcom/android/internal/telephony/cdma/CdmaCallWaitingNotification;->number:Ljava/lang/String;
+Lcom/android/internal/telephony/cdma/CdmaMmiCode;->makeEmptyNull(Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/cdma/CdmaMmiCode;->mSc:Ljava/lang/String;
+Lcom/android/internal/telephony/cdma/CdmaSMSDispatcher;->getFormat()Ljava/lang/String;
+Lcom/android/internal/telephony/cdma/CdmaSMSDispatcher;->handleCdmaStatusReport(Lcom/android/internal/telephony/cdma/SmsMessage;)V
+Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;->getCdmaSubscriptionSource()I
+Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;->getInstance(Landroid/content/Context;Lcom/android/internal/telephony/CommandsInterface;Landroid/os/Handler;ILjava/lang/Object;)Lcom/android/internal/telephony/cdma/CdmaSubscriptionSourceManager;
+Lcom/android/internal/telephony/cdma/EriManager$EriDisplayInformation;->mEriIconText:Ljava/lang/String;
+Lcom/android/internal/telephony/cdma/EriManager;->getEriDisplayInformation(II)Lcom/android/internal/telephony/cdma/EriManager$EriDisplayInformation;
+Lcom/android/internal/telephony/cdma/sms/BearerData$CodingException;-><init>(Ljava/lang/String;)V
+Lcom/android/internal/telephony/cdma/sms/BearerData$TimeStamp;-><init>()V
+Lcom/android/internal/telephony/cdma/sms/BearerData;-><init>()V
+Lcom/android/internal/telephony/cdma/sms/BearerData;->countAsciiSeptets(Ljava/lang/CharSequence;Z)I
+Lcom/android/internal/telephony/cdma/sms/BearerData;->decodeUserDataPayload(Lcom/android/internal/telephony/cdma/sms/UserData;Z)V
+Lcom/android/internal/telephony/cdma/sms/BearerData;->displayMode:I
+Lcom/android/internal/telephony/cdma/sms/BearerData;->encode(Lcom/android/internal/telephony/cdma/sms/BearerData;)[B
+Lcom/android/internal/telephony/cdma/sms/BearerData;->encode7bitAscii(Ljava/lang/String;Z)[B
+Lcom/android/internal/telephony/cdma/sms/BearerData;->getBitsForNumFields(II)I
+Lcom/android/internal/telephony/cdma/sms/BearerData;->hasUserDataHeader:Z
+Lcom/android/internal/telephony/cdma/sms/BearerData;->messageId:I
+Lcom/android/internal/telephony/cdma/sms/BearerData;->msgCenterTimeStamp:Lcom/android/internal/telephony/cdma/sms/BearerData$TimeStamp;
+Lcom/android/internal/telephony/cdma/sms/BearerData;->priority:I
+Lcom/android/internal/telephony/cdma/sms/BearerData;->priorityIndicatorSet:Z
+Lcom/android/internal/telephony/cdma/sms/BearerData;->userData:Lcom/android/internal/telephony/cdma/sms/UserData;
+Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;-><init>()V
+Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;->digitMode:I
+Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;->numberMode:I
+Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;->numberOfDigits:I
+Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;->numberPlan:I
+Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;->parse(Ljava/lang/String;)Lcom/android/internal/telephony/cdma/sms/CdmaSmsAddress;
+Lcom/android/internal/telephony/cdma/sms/SmsEnvelope;-><init>()V
+Lcom/android/internal/telephony/cdma/sms/SmsEnvelope;->bearerData:[B
+Lcom/android/internal/telephony/cdma/sms/SmsEnvelope;->serviceCategory:I
+Lcom/android/internal/telephony/cdma/sms/SmsEnvelope;->teleService:I
+Lcom/android/internal/telephony/cdma/sms/UserData;-><init>()V
+Lcom/android/internal/telephony/cdma/sms/UserData;->charToAscii:Landroid/util/SparseIntArray;
+Lcom/android/internal/telephony/cdma/sms/UserData;->msgEncoding:I
+Lcom/android/internal/telephony/cdma/sms/UserData;->msgEncodingSet:Z
+Lcom/android/internal/telephony/cdma/sms/UserData;->numFields:I
+Lcom/android/internal/telephony/cdma/sms/UserData;->payload:[B
+Lcom/android/internal/telephony/cdma/sms/UserData;->payloadStr:Ljava/lang/String;
+Lcom/android/internal/telephony/cdma/sms/UserData;->userDataHeader:Lcom/android/internal/telephony/SmsHeader;
+Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;-><init>()V
+Lcom/android/internal/telephony/cdma/SmsMessage;-><init>()V
+Lcom/android/internal/telephony/cdma/SmsMessage;->calculateLength(Ljava/lang/CharSequence;ZZ)Lcom/android/internal/telephony/GsmAlphabet$TextEncodingDetails;
+Lcom/android/internal/telephony/cdma/SmsMessage;->createFromEfRecord(I[B)Lcom/android/internal/telephony/cdma/SmsMessage;
+Lcom/android/internal/telephony/cdma/SmsMessage;->createFromPdu([B)Lcom/android/internal/telephony/cdma/SmsMessage;
+Lcom/android/internal/telephony/cdma/SmsMessage;->getIncomingSmsFingerprint()[B
+Lcom/android/internal/telephony/cdma/SmsMessage;->getMessageType()I
+Lcom/android/internal/telephony/cdma/SmsMessage;->getNextMessageId()I
+Lcom/android/internal/telephony/cdma/SmsMessage;->getNumOfVoicemails()I
+Lcom/android/internal/telephony/cdma/SmsMessage;->getSubmitPdu(Ljava/lang/String;Lcom/android/internal/telephony/cdma/sms/UserData;Z)Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/cdma/SmsMessage;->getSubmitPdu(Ljava/lang/String;Lcom/android/internal/telephony/cdma/sms/UserData;ZI)Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/cdma/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;I[BZ)Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/cdma/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLcom/android/internal/telephony/SmsHeader;)Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/cdma/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLcom/android/internal/telephony/SmsHeader;I)Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/cdma/SmsMessage;->getTeleService()I
+Lcom/android/internal/telephony/cdma/SmsMessage;->isStatusReportMessage()Z
+Lcom/android/internal/telephony/cdma/SmsMessage;->mBearerData:Lcom/android/internal/telephony/cdma/sms/BearerData;
+Lcom/android/internal/telephony/cdma/SmsMessage;->mEnvelope:Lcom/android/internal/telephony/cdma/sms/SmsEnvelope;
+Lcom/android/internal/telephony/cdma/SmsMessage;->parseSms()V
+Lcom/android/internal/telephony/cdma/SmsMessage;->privateGetSubmitPdu(Ljava/lang/String;ZLcom/android/internal/telephony/cdma/sms/UserData;)Lcom/android/internal/telephony/cdma/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/CommandException$Error;->GENERIC_FAILURE:Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandException$Error;->PASSWORD_INCORRECT:Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandException$Error;->RADIO_NOT_AVAILABLE:Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandException$Error;->REQUEST_NOT_SUPPORTED:Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandException$Error;->SIM_PUK2:Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandException$Error;->SMS_FAIL_RETRY:Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandException;-><init>(Lcom/android/internal/telephony/CommandException$Error;)V
+Lcom/android/internal/telephony/CommandException;->fromRilErrno(I)Lcom/android/internal/telephony/CommandException;
+Lcom/android/internal/telephony/CommandException;->getCommandError()Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandException;->mError:Lcom/android/internal/telephony/CommandException$Error;
+Lcom/android/internal/telephony/CommandsInterface;->acceptCall(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->acknowledgeLastIncomingCdmaSms(ZILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->acknowledgeLastIncomingGsmSms(ZILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->changeBarringPassword(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->deleteSmsOnRuim(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->deleteSmsOnSim(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->dial(Ljava/lang/String;ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->dial(Ljava/lang/String;ILcom/android/internal/telephony/UUSInfo;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->exitEmergencyCallbackMode(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getBasebandVersion(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getCdmaBroadcastConfig(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getCDMASubscription(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getDataCallList(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getIccCardStatus(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getIMEISV(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getIMSI(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getLastDataCallFailCause(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getLastPdpFailCause(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getNetworkSelectionMode(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getOperator(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getPDPContextList(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getPreferredNetworkType(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getSignalStrength(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getSmscAddress(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->getVoiceRegistrationState(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->handleCallSetupRequestFromSim(ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->iccIO(IILjava/lang/String;IIILjava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->iccIOForApp(IILjava/lang/String;IIILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->invokeOemRilRequestRaw([BLandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->queryCallForwardStatus(IILjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->queryCallWaiting(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->queryFacilityLock(Ljava/lang/String;Ljava/lang/String;ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->queryTTYMode(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForAvailable(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForCdmaOtaProvision(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForCellInfoList(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForIccRefresh(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForImsNetworkStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForNotAvailable(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForOffOrNotAvailable(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForOn(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForRadioStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->registerForRilConnected(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->reportSmsMemoryStatus(ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->reportStkServiceIsRunning(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->requestIccSimAuthentication(ILjava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->requestShutdown(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->sendDtmf(CLandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->sendEnvelope(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->sendTerminalResponse(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setCallForward(IIILjava/lang/String;ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setCallWaiting(ZILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setCdmaBroadcastActivation(ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setDataAllowed(ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setEmergencyCallbackMode(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setFacilityLock(Ljava/lang/String;ZLjava/lang/String;ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setNetworkSelectionModeAutomatic(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setNetworkSelectionModeManual(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnCallRing(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnCatCallSetUp(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnCatCcAlphaNotify(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnCatEvent(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnCatProactiveCmd(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnCatSessionEnd(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnIccRefresh(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnIccSmsFull(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnNewGsmBroadcastSms(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnNITZTime(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnSignalStrengthUpdate(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnSmsOnSim(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnSmsStatus(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setOnSuppServiceNotification(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/CommandsInterface;->setPhoneType(I)V
+Lcom/android/internal/telephony/CommandsInterface;->setPreferredNetworkType(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setRadioPower(ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setSmscAddress(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setTTYMode(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->setUiccSubscription(IIIILandroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->supplyIccPin(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->switchWaitingOrHoldingAndActive(Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->unregisterForAvailable(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CommandsInterface;->unregisterForCdmaOtaProvision(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CommandsInterface;->unregisterForOffOrNotAvailable(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CommandsInterface;->unregisterForOn(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CommandsInterface;->unregisterForRilConnected(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CommandsInterface;->unregisterForVoiceRadioTechChanged(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/CommandsInterface;->writeSmsToRuim(ILjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/CommandsInterface;->writeSmsToSim(ILjava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/Connection$PostDialState;->CANCELLED:Lcom/android/internal/telephony/Connection$PostDialState;
+Lcom/android/internal/telephony/Connection$PostDialState;->COMPLETE:Lcom/android/internal/telephony/Connection$PostDialState;
+Lcom/android/internal/telephony/Connection$PostDialState;->NOT_STARTED:Lcom/android/internal/telephony/Connection$PostDialState;
+Lcom/android/internal/telephony/Connection$PostDialState;->STARTED:Lcom/android/internal/telephony/Connection$PostDialState;
+Lcom/android/internal/telephony/Connection$PostDialState;->WAIT:Lcom/android/internal/telephony/Connection$PostDialState;
+Lcom/android/internal/telephony/Connection$PostDialState;->WILD:Lcom/android/internal/telephony/Connection$PostDialState;
+Lcom/android/internal/telephony/Connection;-><init>(I)V
+Lcom/android/internal/telephony/Connection;->getAddress()Ljava/lang/String;
+Lcom/android/internal/telephony/Connection;->getCall()Lcom/android/internal/telephony/Call;
+Lcom/android/internal/telephony/Connection;->getConnectTime()J
+Lcom/android/internal/telephony/Connection;->getCreateTime()J
+Lcom/android/internal/telephony/Connection;->getDisconnectCause()I
+Lcom/android/internal/telephony/Connection;->getDisconnectTime()J
+Lcom/android/internal/telephony/Connection;->getDurationMillis()J
+Lcom/android/internal/telephony/Connection;->getState()Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/Connection;->getUserData()Ljava/lang/Object;
+Lcom/android/internal/telephony/Connection;->hangup()V
+Lcom/android/internal/telephony/Connection;->isAlive()Z
+Lcom/android/internal/telephony/Connection;->isIncoming()Z
+Lcom/android/internal/telephony/Connection;->LOG_TAG:Ljava/lang/String;
+Lcom/android/internal/telephony/Connection;->mAddress:Ljava/lang/String;
+Lcom/android/internal/telephony/Connection;->mCnapName:Ljava/lang/String;
+Lcom/android/internal/telephony/Connection;->mCnapNamePresentation:I
+Lcom/android/internal/telephony/Connection;->mDialString:Ljava/lang/String;
+Lcom/android/internal/telephony/Connection;->mDuration:J
+Lcom/android/internal/telephony/Connection;->mIsIncoming:Z
+Lcom/android/internal/telephony/Connection;->mNumberPresentation:I
+Lcom/android/internal/telephony/Connection;->setVideoState(I)V
+Lcom/android/internal/telephony/dataconnection/ApnContext;->getApnType()Ljava/lang/String;
+Lcom/android/internal/telephony/dataconnection/ApnContext;->getReason()Ljava/lang/String;
+Lcom/android/internal/telephony/dataconnection/ApnContext;->getState()Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/dataconnection/ApnContext;->isConnectable()Z
+Lcom/android/internal/telephony/dataconnection/ApnContext;->isDisconnected()Z
+Lcom/android/internal/telephony/dataconnection/ApnContext;->isEnabled()Z
+Lcom/android/internal/telephony/dataconnection/ApnContext;->isReady()Z
+Lcom/android/internal/telephony/dataconnection/ApnContext;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/ApnContext;->mApnType:Ljava/lang/String;
+Lcom/android/internal/telephony/dataconnection/ApnContext;->mRefCount:I
+Lcom/android/internal/telephony/dataconnection/ApnContext;->mRefCountLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/dataconnection/ApnContext;->setState(Lcom/android/internal/telephony/DctConstants$State;)V
+Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;->mApnContext:Lcom/android/internal/telephony/dataconnection/ApnContext;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->clearSettings()V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->dumpToLog()V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->initConnection(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)Z
+Lcom/android/internal/telephony/dataconnection/DataConnection;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mActivatingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActivatingState;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mActiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcActiveState;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mApnContexts:Ljava/util/HashMap;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mConnectionParams:Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mDataRegState:I
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mDcFailCause:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingErrorCreatingConnection:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectionErrorCreatingConnection;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectingState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcDisconnectingState;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mDisconnectParams:Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mId:I
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mInactiveState:Lcom/android/internal/telephony/dataconnection/DataConnection$DcInactiveState;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mLinkProperties:Landroid/net/LinkProperties;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mNetworkInfo:Landroid/net/NetworkInfo;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/dataconnection/DataConnection;->mRilRat:I
+Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DcFailCause;)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfConnected(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyAllOfDisconnectDcRetrying(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyConnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;Lcom/android/internal/telephony/dataconnection/DcFailCause;Z)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->notifyDisconnectCompleted(Lcom/android/internal/telephony/dataconnection/DataConnection$DisconnectParams;Z)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->onConnect(Lcom/android/internal/telephony/dataconnection/DataConnection$ConnectionParams;)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->tearDownData(Ljava/lang/Object;)V
+Lcom/android/internal/telephony/dataconnection/DataConnection;->updateTcpBufferSizes(I)V
+Lcom/android/internal/telephony/dataconnection/DcController;->lr(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcController;->mDcListActiveByCid:Ljava/util/HashMap;
+Lcom/android/internal/telephony/dataconnection/DcController;->mDct:Lcom/android/internal/telephony/dataconnection/DcTracker;
+Lcom/android/internal/telephony/dataconnection/DcController;->mDcTesterDeactivateAll:Lcom/android/internal/telephony/dataconnection/DcTesterDeactivateAll;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_GGSN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->ACTIVATION_REJECT_UNSPECIFIED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->APN_TYPE_CONFLICT:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->INSUFFICIENT_RESOURCES:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->MISSING_UNKNOWN_APN:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->NSAPI_IN_USE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV4_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_IPV6_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->ONLY_SINGLE_BEARER_ALLOWED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->OPERATOR_BARRED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->PROTOCOL_ERRORS:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUBSCRIBED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_NOT_SUPPORTED:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->SERVICE_OPTION_OUT_OF_ORDER:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->UNKNOWN_PDP_ADDRESS_TYPE:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcFailCause;->USER_AUTHENTICATION:Lcom/android/internal/telephony/dataconnection/DcFailCause;
+Lcom/android/internal/telephony/dataconnection/DcTracker$RecoveryAction;->isAggressiveRecovery(I)Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->cancelReconnectAlarm(Lcom/android/internal/telephony/dataconnection/ApnContext;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpAllConnections(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpAllConnections(ZLjava/lang/String;)Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->cleanUpConnection(ZLcom/android/internal/telephony/dataconnection/ApnContext;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->createAllApnList()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->getActiveApnTypes()[Ljava/lang/String;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->getOverallState()Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->getUiccRecords(I)Lcom/android/internal/telephony/uicc/IccRecords;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->isConnected()Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->isDisconnected()Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->isOnlySingleDcAllowed(I)Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mAllApnSettings:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mApnContexts:Ljava/util/concurrent/ConcurrentHashMap;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mAttached:Ljava/util/concurrent/atomic/AtomicBoolean;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mAutoAttachOnCreation:Ljava/util/concurrent/atomic/AtomicBoolean;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mDataConnectionTracker:Landroid/os/Handler;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mDisconnectPendingCount:I
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mIccRecords:Ljava/util/concurrent/atomic/AtomicReference;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mIsPsRestricted:Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mIsScreenOn:Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mNetStatPollEnabled:Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mNetStatPollPeriod:I
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mPrioritySortedApnContexts:Ljava/util/PriorityQueue;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mProvisioningSpinner:Landroid/app/ProgressDialog;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mResolver:Landroid/content/ContentResolver;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mState:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->mSubscriptionManager:Landroid/telephony/SubscriptionManager;
+Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyDataConnection(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->notifyOffApnsOfAvailability(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentDataStallAlarm(Landroid/content/Intent;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->onActionIntentProvisioningApnAlarm(Landroid/content/Intent;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->onCleanUpAllConnections(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->onRecordsLoadedOrSubIdChanged()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->onSetUserDataEnabled(Z)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Lcom/android/internal/telephony/dataconnection/ApnContext;)Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->onTrySetupData(Ljava/lang/String;)Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->registerForAllDataDisconnected(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->registerSettingsObserver()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->resetPollStats()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->restartDataStallAlarm()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->setInitialAttachApn()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->setInternalDataEnabled(ZLandroid/os/Message;)Z
+Lcom/android/internal/telephony/dataconnection/DcTracker;->setPreferredApn(I)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->setRadio(Z)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->setupDataOnConnectableApns(Ljava/lang/String;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->startDataStallAlarm(Z)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->startNetStatPoll()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->stopDataStallAlarm()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->stopNetStatPoll()V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->unregisterForAllDataDisconnected(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/dataconnection/DcTracker;->updateRecords()V
+Lcom/android/internal/telephony/DctConstants$Activity;->DATAIN:Lcom/android/internal/telephony/DctConstants$Activity;
+Lcom/android/internal/telephony/DctConstants$Activity;->DATAINANDOUT:Lcom/android/internal/telephony/DctConstants$Activity;
+Lcom/android/internal/telephony/DctConstants$Activity;->DATAOUT:Lcom/android/internal/telephony/DctConstants$Activity;
+Lcom/android/internal/telephony/DctConstants$Activity;->DORMANT:Lcom/android/internal/telephony/DctConstants$Activity;
+Lcom/android/internal/telephony/DctConstants$Activity;->values()[Lcom/android/internal/telephony/DctConstants$Activity;
+Lcom/android/internal/telephony/DctConstants$State;->CONNECTED:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DctConstants$State;->CONNECTING:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DctConstants$State;->DISCONNECTING:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DctConstants$State;->FAILED:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DctConstants$State;->IDLE:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DctConstants$State;->RETRYING:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DctConstants$State;->SCANNING:Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DctConstants$State;->values()[Lcom/android/internal/telephony/DctConstants$State;
+Lcom/android/internal/telephony/DefaultPhoneNotifier;->mRegistry:Lcom/android/internal/telephony/ITelephonyRegistry;
+Lcom/android/internal/telephony/DriverCall$State;->ACTIVE:Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/DriverCall$State;->ALERTING:Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/DriverCall$State;->DIALING:Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/DriverCall$State;->HOLDING:Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/DriverCall$State;->INCOMING:Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/DriverCall$State;->values()[Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/DriverCall$State;->WAITING:Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/DriverCall;-><init>()V
+Lcom/android/internal/telephony/DriverCall;->index:I
+Lcom/android/internal/telephony/DriverCall;->isMT:Z
+Lcom/android/internal/telephony/DriverCall;->isVoice:Z
+Lcom/android/internal/telephony/DriverCall;->name:Ljava/lang/String;
+Lcom/android/internal/telephony/DriverCall;->number:Ljava/lang/String;
+Lcom/android/internal/telephony/DriverCall;->numberPresentation:I
+Lcom/android/internal/telephony/DriverCall;->state:Lcom/android/internal/telephony/DriverCall$State;
+Lcom/android/internal/telephony/gsm/GsmCellBroadcastHandler$SmsCbConcatInfo;-><init>(Lcom/android/internal/telephony/gsm/SmsCbHeader;Landroid/telephony/SmsCbLocation;)V
+Lcom/android/internal/telephony/gsm/GsmCellBroadcastHandler$SmsCbConcatInfo;->matchesLocation(Ljava/lang/String;II)Z
+Lcom/android/internal/telephony/gsm/GsmCellBroadcastHandler;->mSmsCbPageMap:Ljava/util/HashMap;
+Lcom/android/internal/telephony/gsm/GsmInboundSmsHandler;->acknowledgeLastIncomingSms(ZILandroid/os/Message;)V
+Lcom/android/internal/telephony/gsm/GsmMmiCode;-><init>(Lcom/android/internal/telephony/GsmCdmaPhone;Lcom/android/internal/telephony/uicc/UiccCardApplication;)V
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->getCLIRMode()I
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->getScString()Ljava/lang/CharSequence;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isActivate()Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isDeactivate()Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isErasure()Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isInterrogate()Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isRegister()Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isServiceCodeCallBarring(Ljava/lang/String;)Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isServiceCodeCallForwarding(Ljava/lang/String;)Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->isTemporaryModeCLIR()Z
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->makeEmptyNull(Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mDialingNumber:Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mIccRecords:Lcom/android/internal/telephony/uicc/IccRecords;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mPhone:Lcom/android/internal/telephony/GsmCdmaPhone;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mSc:Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mSia:Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mSib:Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->mSic:Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->newFromDialString(Ljava/lang/String;Lcom/android/internal/telephony/GsmCdmaPhone;Lcom/android/internal/telephony/uicc/UiccCardApplication;)Lcom/android/internal/telephony/gsm/GsmMmiCode;
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->processCode()V
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->siToServiceClass(Ljava/lang/String;)I
+Lcom/android/internal/telephony/gsm/GsmMmiCode;->sPatternSuppService:Ljava/util/regex/Pattern;
+Lcom/android/internal/telephony/gsm/GsmSmsAddress;-><init>([BII)V
+Lcom/android/internal/telephony/gsm/GsmSmsAddress;->isCphsVoiceMessageClear()Z
+Lcom/android/internal/telephony/gsm/GsmSmsAddress;->isCphsVoiceMessageSet()Z
+Lcom/android/internal/telephony/gsm/GsmSMSDispatcher;->getFormat()Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/GsmSMSDispatcher;->mGsmInboundSmsHandler:Lcom/android/internal/telephony/gsm/GsmInboundSmsHandler;
+Lcom/android/internal/telephony/gsm/GsmSMSDispatcher;->sendSms(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+Lcom/android/internal/telephony/gsm/SimTlv;-><init>([BII)V
+Lcom/android/internal/telephony/gsm/SimTlv;->getData()[B
+Lcom/android/internal/telephony/gsm/SimTlv;->getTag()I
+Lcom/android/internal/telephony/gsm/SimTlv;->isValidObject()Z
+Lcom/android/internal/telephony/gsm/SimTlv;->mHasValidTlvObject:Z
+Lcom/android/internal/telephony/gsm/SimTlv;->nextObject()Z
+Lcom/android/internal/telephony/gsm/SmsCbHeader;-><init>([B)V
+Lcom/android/internal/telephony/gsm/SmsCbHeader;->getGeographicalScope()I
+Lcom/android/internal/telephony/gsm/SmsCbHeader;->getNumberOfPages()I
+Lcom/android/internal/telephony/gsm/SmsCbHeader;->getPageIndex()I
+Lcom/android/internal/telephony/gsm/SmsCbHeader;->getSerialNumber()I
+Lcom/android/internal/telephony/gsm/SmsCbHeader;->getServiceCategory()I
+Lcom/android/internal/telephony/gsm/SmsCbHeader;->mMessageIdentifier:I
+Lcom/android/internal/telephony/gsm/SmsMessage$PduParser;-><init>([B)V
+Lcom/android/internal/telephony/gsm/SmsMessage$PduParser;->getByte()I
+Lcom/android/internal/telephony/gsm/SmsMessage$PduParser;->getUserData()[B
+Lcom/android/internal/telephony/gsm/SmsMessage$PduParser;->getUserDataUCS2(I)Ljava/lang/String;
+Lcom/android/internal/telephony/gsm/SmsMessage$PduParser;->mCur:I
+Lcom/android/internal/telephony/gsm/SmsMessage$PduParser;->mPdu:[B
+Lcom/android/internal/telephony/gsm/SmsMessage$PduParser;->mUserDataSeptetPadding:I
+Lcom/android/internal/telephony/gsm/SmsMessage$SubmitPdu;-><init>()V
+Lcom/android/internal/telephony/gsm/SmsMessage;-><init>()V
+Lcom/android/internal/telephony/gsm/SmsMessage;->calculateLength(Ljava/lang/CharSequence;Z)Lcom/android/internal/telephony/GsmAlphabet$TextEncodingDetails;
+Lcom/android/internal/telephony/gsm/SmsMessage;->createFromEfRecord(I[B)Lcom/android/internal/telephony/gsm/SmsMessage;
+Lcom/android/internal/telephony/gsm/SmsMessage;->createFromPdu([B)Lcom/android/internal/telephony/gsm/SmsMessage;
+Lcom/android/internal/telephony/gsm/SmsMessage;->encodeUCS2(Ljava/lang/String;[B)[B
+Lcom/android/internal/telephony/gsm/SmsMessage;->getStatus()I
+Lcom/android/internal/telephony/gsm/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)Lcom/android/internal/telephony/gsm/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/gsm/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZI)Lcom/android/internal/telephony/gsm/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/gsm/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z[B)Lcom/android/internal/telephony/gsm/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/gsm/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z[BIII)Lcom/android/internal/telephony/gsm/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/gsm/SmsMessage;->getSubmitPdu(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z[BIIII)Lcom/android/internal/telephony/gsm/SmsMessage$SubmitPdu;
+Lcom/android/internal/telephony/gsm/SmsMessage;->getSubmitPduHead(Ljava/lang/String;Ljava/lang/String;BZLcom/android/internal/telephony/gsm/SmsMessage$SubmitPdu;)Ljava/io/ByteArrayOutputStream;
+Lcom/android/internal/telephony/gsm/SmsMessage;->isMWIClearMessage()Z
+Lcom/android/internal/telephony/gsm/SmsMessage;->isMwiDontStore()Z
+Lcom/android/internal/telephony/gsm/SmsMessage;->isMWISetMessage()Z
+Lcom/android/internal/telephony/gsm/SmsMessage;->isStatusReportMessage()Z
+Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->loadEfFilesFromUsim()Ljava/util/ArrayList;
+Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->mFh:Lcom/android/internal/telephony/uicc/IccFileHandler;
+Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->mPhoneBookRecords:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;->reset()V
Lcom/android/internal/telephony/GsmAlphabet$TextEncodingDetails;-><init>()V
+Lcom/android/internal/telephony/GsmCdmaCall;->attachFake(Lcom/android/internal/telephony/Connection;Lcom/android/internal/telephony/Call$State;)V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->clearDisconnected()V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->dialThreeWay(Ljava/lang/String;)Lcom/android/internal/telephony/Connection;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->disableDataCallInEmergencyCall(Ljava/lang/String;)V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->fakeHoldForegroundBeforeDial()V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->getPhone()Lcom/android/internal/telephony/GsmCdmaPhone;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->handleEcmTimer(I)V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->isPhoneTypeGsm()Z
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->mBackgroundCall:Lcom/android/internal/telephony/GsmCdmaCall;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->mForegroundCall:Lcom/android/internal/telephony/GsmCdmaCall;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->mPendingMO:Lcom/android/internal/telephony/GsmCdmaConnection;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->mPhone:Lcom/android/internal/telephony/GsmCdmaPhone;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->mRingingCall:Lcom/android/internal/telephony/GsmCdmaCall;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->mState:Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->obtainCompleteMessage()Landroid/os/Message;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->obtainCompleteMessage(I)Landroid/os/Message;
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->setMute(Z)V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->switchWaitingOrHoldingAndActive()V
+Lcom/android/internal/telephony/GsmCdmaCallTracker;->updatePhoneState()V
+Lcom/android/internal/telephony/GsmCdmaConnection$MyHandler;-><init>(Lcom/android/internal/telephony/GsmCdmaConnection;Landroid/os/Looper;)V
+Lcom/android/internal/telephony/GsmCdmaConnection;->acquireWakeLock()V
+Lcom/android/internal/telephony/GsmCdmaConnection;->createWakeLock(Landroid/content/Context;)V
+Lcom/android/internal/telephony/GsmCdmaConnection;->disconnectCauseFromCode(I)I
+Lcom/android/internal/telephony/GsmCdmaConnection;->fetchDtmfToneDelay(Lcom/android/internal/telephony/GsmCdmaPhone;)V
+Lcom/android/internal/telephony/GsmCdmaConnection;->findNextPCharOrNonPOrNonWCharIndex(Ljava/lang/String;I)I
+Lcom/android/internal/telephony/GsmCdmaConnection;->findPOrWCharToAppend(Ljava/lang/String;II)C
+Lcom/android/internal/telephony/GsmCdmaConnection;->formatDialString(Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/GsmCdmaConnection;->getState()Lcom/android/internal/telephony/Call$State;
+Lcom/android/internal/telephony/GsmCdmaConnection;->isPause(C)Z
+Lcom/android/internal/telephony/GsmCdmaConnection;->isPhoneTypeGsm()Z
+Lcom/android/internal/telephony/GsmCdmaConnection;->isWait(C)Z
+Lcom/android/internal/telephony/GsmCdmaConnection;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/GsmCdmaConnection;->maskDialString(Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/GsmCdmaConnection;->mIndex:I
+Lcom/android/internal/telephony/GsmCdmaConnection;->mOwner:Lcom/android/internal/telephony/GsmCdmaCallTracker;
+Lcom/android/internal/telephony/GsmCdmaConnection;->onConnectedInOrOut()V
+Lcom/android/internal/telephony/GsmCdmaConnection;->updateParent(Lcom/android/internal/telephony/GsmCdmaCall;Lcom/android/internal/telephony/GsmCdmaCall;)V
+Lcom/android/internal/telephony/GsmCdmaPhone$Cfu;-><init>(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/GsmCdmaPhone;->exitEmergencyCallbackMode()V
+Lcom/android/internal/telephony/GsmCdmaPhone;->getCallTracker()Lcom/android/internal/telephony/CallTracker;
+Lcom/android/internal/telephony/GsmCdmaPhone;->getCdmaEriText()Ljava/lang/String;
+Lcom/android/internal/telephony/GsmCdmaPhone;->getEsn()Ljava/lang/String;
+Lcom/android/internal/telephony/GsmCdmaPhone;->getLine1Number()Ljava/lang/String;
+Lcom/android/internal/telephony/GsmCdmaPhone;->getPhoneType()I
+Lcom/android/internal/telephony/GsmCdmaPhone;->getServiceState()Landroid/telephony/ServiceState;
+Lcom/android/internal/telephony/GsmCdmaPhone;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/GsmCdmaPhone;->getSystemProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/GsmCdmaPhone;->handleInCallMmiCommands(Ljava/lang/String;)Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->isCfEnable(I)Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->isEriFileLoaded()Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->isInCall()Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->isManualSelProhibitedInGlobalMode()Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->isPhoneTypeGsm()Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->isValidCommandInterfaceCFAction(I)Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->isValidCommandInterfaceCFReason(I)Z
+Lcom/android/internal/telephony/GsmCdmaPhone;->logd(Ljava/lang/String;)V
+Lcom/android/internal/telephony/GsmCdmaPhone;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/GsmCdmaPhone;->mCT:Lcom/android/internal/telephony/GsmCdmaCallTracker;
+Lcom/android/internal/telephony/GsmCdmaPhone;->mEcmExitRespRegistrant:Landroid/os/Registrant;
+Lcom/android/internal/telephony/GsmCdmaPhone;->mEriManager:Lcom/android/internal/telephony/cdma/EriManager;
+Lcom/android/internal/telephony/GsmCdmaPhone;->mIccSmsInterfaceManager:Lcom/android/internal/telephony/IccSmsInterfaceManager;
+Lcom/android/internal/telephony/GsmCdmaPhone;->mIsimUiccRecords:Lcom/android/internal/telephony/uicc/IsimUiccRecords;
+Lcom/android/internal/telephony/GsmCdmaPhone;->mPendingMMIs:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/GsmCdmaPhone;->mSST:Lcom/android/internal/telephony/ServiceStateTracker;
+Lcom/android/internal/telephony/GsmCdmaPhone;->notifyPreciseCallStateChanged()V
+Lcom/android/internal/telephony/GsmCdmaPhone;->notifyServiceStateChanged(Landroid/telephony/ServiceState;)V
+Lcom/android/internal/telephony/GsmCdmaPhone;->setOnEcbModeExitResponse(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/GsmCdmaPhone;->syncClirSetting()V
Lcom/android/internal/telephony/ICarrierConfigLoader;->getConfigForSubId(ILjava/lang/String;)Landroid/os/PersistableBundle;
+Lcom/android/internal/telephony/IccCard;->getState()Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCard;->registerForNetworkLocked(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/IccCard;->supplyNetworkDepersonalization(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/IccCard;->supplyPin(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/IccCard;->supplyPuk(Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/IccCardConstants$State;->ABSENT:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->CARD_IO_ERROR:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->NETWORK_LOCKED:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->NOT_READY:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->PERM_DISABLED:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->PIN_REQUIRED:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->PUK_REQUIRED:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->READY:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->UNKNOWN:Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccCardConstants$State;->values()[Lcom/android/internal/telephony/IccCardConstants$State;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->checkThread()V
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->DBG:Z
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->logd(Ljava/lang/String;)V
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mAdnCache:Lcom/android/internal/telephony/uicc/AdnRecordCache;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mBaseHandler:Landroid/os/Handler;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mCurrentApp:Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mIs3gCard:Z
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mRecords:Ljava/util/List;
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mRecordSize:[I
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->mSuccess:Z
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->updateEfForIccType(I)I
+Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;->waitForResult(Ljava/util/concurrent/atomic/AtomicBoolean;)V
+Lcom/android/internal/telephony/IccProvider;-><init>()V
+Lcom/android/internal/telephony/IccProvider;->ADDRESS_BOOK_COLUMN_NAMES:[Ljava/lang/String;
+Lcom/android/internal/telephony/IccProvider;->DBG:Z
+Lcom/android/internal/telephony/IccProvider;->loadRecord(Lcom/android/internal/telephony/uicc/AdnRecord;Landroid/database/MatrixCursor;I)V
+Lcom/android/internal/telephony/IccProvider;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->copyMessageToIccEf(Ljava/lang/String;I[B[B)Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->disableCdmaBroadcastRange(II)Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->disableGsmBroadcastRange(II)Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->enableCdmaBroadcastRange(II)Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->enableGsmBroadcastRange(II)Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->enforceReceiveAndSend(Ljava/lang/String;)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->filterDestAddress(Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->getAllMessagesFromIccEf(Ljava/lang/String;)Ljava/util/List;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->getImsSmsFormat()Ljava/lang/String;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->getPremiumSmsPermission(Ljava/lang/String;)I
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->injectSmsPdu([BLjava/lang/String;Landroid/app/PendingIntent;)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->isImsSmsSupported()Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mAppOps:Landroid/app/AppOpsManager;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mCellBroadcastRangeManager:Lcom/android/internal/telephony/IccSmsInterfaceManager$CellBroadcastRangeManager;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mHandler:Landroid/os/Handler;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mSms:Ljava/util/List;
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->mSuccess:Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->sendData(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->sendStoredMultipartText(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;Ljava/util/List;Ljava/util/List;)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->sendStoredText(Ljava/lang/String;Landroid/net/Uri;Ljava/lang/String;Landroid/app/PendingIntent;Landroid/app/PendingIntent;)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->setCdmaBroadcastConfig([Lcom/android/internal/telephony/cdma/CdmaSmsBroadcastConfigInfo;)Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->setCellBroadcastConfig([Lcom/android/internal/telephony/gsm/SmsBroadcastConfigInfo;)Z
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->setPremiumSmsPermission(Ljava/lang/String;I)V
+Lcom/android/internal/telephony/IccSmsInterfaceManager;->updateMessageOnIccEf(Ljava/lang/String;II[B)Z
+Lcom/android/internal/telephony/IIccPhoneBook$Stub$Proxy;->mRemote:Landroid/os/IBinder;
+Lcom/android/internal/telephony/IIccPhoneBook$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IIccPhoneBook;
+Lcom/android/internal/telephony/IIccPhoneBook;->getAdnRecordsInEf(I)Ljava/util/List;
+Lcom/android/internal/telephony/IIccPhoneBook;->getAdnRecordsInEfForSubscriber(II)Ljava/util/List;
+Lcom/android/internal/telephony/IIccPhoneBook;->getAdnRecordsSize(I)[I
+Lcom/android/internal/telephony/IIccPhoneBook;->getAdnRecordsSizeForSubscriber(II)[I
+Lcom/android/internal/telephony/IIccPhoneBook;->updateAdnRecordsInEfBySearch(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
Lcom/android/internal/telephony/IMms$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IMms;
+Lcom/android/internal/telephony/imsphone/ImsExternalCall;-><init>(Lcom/android/internal/telephony/Phone;Lcom/android/internal/telephony/imsphone/ImsExternalConnection;)V
+Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker$ExternalCallStateListener;-><init>(Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker;)V
+Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker$ExternalConnectionListener;-><init>(Lcom/android/internal/telephony/imsphone/ImsExternalCallTracker;)V
+Lcom/android/internal/telephony/imsphone/ImsExternalConnection;->rebuildCapabilities()V
+Lcom/android/internal/telephony/imsphone/ImsExternalConnection;->setActive()V
+Lcom/android/internal/telephony/imsphone/ImsPhone$Cf;-><init>(Ljava/lang/String;ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getActionFromCFAction(I)I
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getBackgroundCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getCallForwardingOption(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getCallWaiting(Landroid/os/Message;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getConditionFromCFReason(I)I
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getForegroundCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getRingingCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getServiceState()Landroid/telephony/ServiceState;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->handleEnterEmergencyCallbackMode()V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->handleExitEmergencyCallbackMode()V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->handleInCallMmiCommands(Ljava/lang/String;)Z
+Lcom/android/internal/telephony/imsphone/ImsPhone;->isCfEnable(I)Z
+Lcom/android/internal/telephony/imsphone/ImsPhone;->isUtEnabled()Z
+Lcom/android/internal/telephony/imsphone/ImsPhone;->isValidCommandInterfaceCFAction(I)Z
+Lcom/android/internal/telephony/imsphone/ImsPhone;->isValidCommandInterfaceCFReason(I)Z
+Lcom/android/internal/telephony/imsphone/ImsPhone;->isVolteEnabled()Z
+Lcom/android/internal/telephony/imsphone/ImsPhone;->mCT:Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->mPendingMMIs:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->mSS:Landroid/telephony/ServiceState;
+Lcom/android/internal/telephony/imsphone/ImsPhone;->notifyCallForwardingIndicator()V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->notifyPreciseCallStateChanged()V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->notifyUnknownConnection(Lcom/android/internal/telephony/Connection;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->onMMIDone(Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->sendErrorResponse(Landroid/os/Message;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->sendErrorResponse(Landroid/os/Message;Ljava/lang/Throwable;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->setCallForwardingOption(IILjava/lang/String;IILandroid/os/Message;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->setCallWaiting(ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->setImsRegistered(Z)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->setOnEcbModeExitResponse(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/imsphone/ImsPhone;->setServiceState(I)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->attach(Lcom/android/internal/telephony/Connection;Lcom/android/internal/telephony/Call$State;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->attachFake(Lcom/android/internal/telephony/Connection;Lcom/android/internal/telephony/Call$State;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->getConnections()Ljava/util/List;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->getImsCall()Lcom/android/ims/ImsCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->hangup()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->merge(Lcom/android/internal/telephony/imsphone/ImsPhoneCall;Lcom/android/internal/telephony/Call$State;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCall;->onHangupLocal()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->addConnection(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->clearDisconnected()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->dial(Ljava/lang/String;ILandroid/os/Bundle;)Lcom/android/internal/telephony/Connection;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->dialPendingMO()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->findConnection(Lcom/android/ims/ImsCall;)Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getEcbmInterface()Lcom/android/ims/ImsEcbm;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->getUtInterface()Lcom/android/ims/ImsUtInterface;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->handleEcmTimer(I)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mAllowEmergencyVideoCalls:Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mBackgroundCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mCallExpectedToResume:Lcom/android/ims/ImsCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mConnections:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mForegroundCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mHandoverCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mImsCallListener:Lcom/android/ims/ImsCall$Listener;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mImsManager:Lcom/android/ims/ImsManager;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mOnHoldToneId:I
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mOnHoldToneStarted:Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mPendingMO:Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mPendingUssd:Landroid/os/Message;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mPhone:Lcom/android/internal/telephony/imsphone/ImsPhone;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mRingingCall:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mSwitchingFgAndBgCalls:Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mSyncHold:Ljava/lang/Object;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->mUssdSession:Lcom/android/ims/ImsCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->processCallStateChange(Lcom/android/ims/ImsCall;Lcom/android/internal/telephony/Call$State;I)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->processCallStateChange(Lcom/android/ims/ImsCall;Lcom/android/internal/telephony/Call$State;IZ)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->removeConnection(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->setVideoCallProvider(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;Lcom/android/ims/ImsCall;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->switchAfterConferenceSuccess()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;->updatePhoneState()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection$MyHandler;-><init>(Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;Landroid/os/Looper;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->acquireWakeLock()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->createWakeLock(Landroid/content/Context;)V
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->getCall()Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->getOwner()Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->isMultiparty()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mDisconnected:Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mImsCall:Lcom/android/ims/ImsCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mOwner:Lcom/android/internal/telephony/imsphone/ImsPhoneCallTracker;
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->mParent:Lcom/android/internal/telephony/imsphone/ImsPhoneCall;
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->onDisconnect()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneConnection;->update(Lcom/android/ims/ImsCall;Lcom/android/internal/telephony/Call$State;)Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getCLIRMode()I
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getDialingNumber()Ljava/lang/String;
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getErrorMessage(Landroid/os/AsyncResult;)Ljava/lang/CharSequence;
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->getScString()Ljava/lang/CharSequence;
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isActivate()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isDeactivate()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isEmptyOrNull(Ljava/lang/CharSequence;)Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isErasure()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isRegister()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isSupportedOverImsPhone()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->isTemporaryModeCLIR()Z
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->mPhone:Lcom/android/internal/telephony/imsphone/ImsPhone;
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->newFromDialString(Ljava/lang/String;Lcom/android/internal/telephony/imsphone/ImsPhone;)Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->processCode()V
+Lcom/android/internal/telephony/imsphone/ImsPhoneMmiCode;->serviceClassToCFString(I)Ljava/lang/CharSequence;
+Lcom/android/internal/telephony/InboundSmsHandler$SmsBroadcastReceiver;-><init>(Lcom/android/internal/telephony/InboundSmsHandler;Lcom/android/internal/telephony/InboundSmsTracker;)V
+Lcom/android/internal/telephony/InboundSmsHandler$SmsBroadcastReceiver;->mDeleteWhere:Ljava/lang/String;
+Lcom/android/internal/telephony/InboundSmsHandler$SmsBroadcastReceiver;->mDeleteWhereArgs:[Ljava/lang/String;
+Lcom/android/internal/telephony/InboundSmsHandler;->acknowledgeLastIncomingSms(ZILandroid/os/Message;)V
+Lcom/android/internal/telephony/InboundSmsHandler;->deleteFromRawTable(Ljava/lang/String;[Ljava/lang/String;I)V
+Lcom/android/internal/telephony/InboundSmsHandler;->dispatchIntent(Landroid/content/Intent;Ljava/lang/String;ILandroid/os/Bundle;Landroid/content/BroadcastReceiver;Landroid/os/UserHandle;)V
+Lcom/android/internal/telephony/InboundSmsHandler;->dispatchNormalMessage(Lcom/android/internal/telephony/SmsMessageBase;)I
+Lcom/android/internal/telephony/InboundSmsHandler;->getPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/InboundSmsHandler;->handleInjectSms(Landroid/os/AsyncResult;)V
+Lcom/android/internal/telephony/InboundSmsHandler;->handleNewSms(Landroid/os/AsyncResult;)V
+Lcom/android/internal/telephony/InboundSmsHandler;->handleSmsWhitelisting(Landroid/content/ComponentName;)Landroid/os/Bundle;
+Lcom/android/internal/telephony/InboundSmsHandler;->isSkipNotifyFlagSet(I)Z
+Lcom/android/internal/telephony/InboundSmsHandler;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/InboundSmsHandler;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/InboundSmsHandler;->mCellBroadcastHandler:Lcom/android/internal/telephony/CellBroadcastHandler;
+Lcom/android/internal/telephony/InboundSmsHandler;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/InboundSmsHandler;->mDeliveringState:Lcom/android/internal/telephony/InboundSmsHandler$DeliveringState;
+Lcom/android/internal/telephony/InboundSmsHandler;->mDeviceIdleController:Landroid/os/IDeviceIdleController;
+Lcom/android/internal/telephony/InboundSmsHandler;->mIdleState:Lcom/android/internal/telephony/InboundSmsHandler$IdleState;
+Lcom/android/internal/telephony/InboundSmsHandler;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/InboundSmsHandler;->mResolver:Landroid/content/ContentResolver;
+Lcom/android/internal/telephony/InboundSmsHandler;->mUserManager:Landroid/os/UserManager;
+Lcom/android/internal/telephony/InboundSmsHandler;->mWaitingState:Lcom/android/internal/telephony/InboundSmsHandler$WaitingState;
+Lcom/android/internal/telephony/InboundSmsHandler;->mWakeLock:Landroid/os/PowerManager$WakeLock;
+Lcom/android/internal/telephony/InboundSmsHandler;->mWapPush:Lcom/android/internal/telephony/WapPushOverSms;
+Lcom/android/internal/telephony/InboundSmsHandler;->processMessagePart(Lcom/android/internal/telephony/InboundSmsTracker;)Z
+Lcom/android/internal/telephony/InboundSmsHandler;->showNewMessageNotification()V
+Lcom/android/internal/telephony/InboundSmsHandler;->writeInboxMessage(Landroid/content/Intent;)Landroid/net/Uri;
+Lcom/android/internal/telephony/InboundSmsTracker;->getFormat()Ljava/lang/String;
+Lcom/android/internal/telephony/InboundSmsTracker;->getIndexOffset()I
+Lcom/android/internal/telephony/IntRangeManager;->mRanges:Ljava/util/ArrayList;
Lcom/android/internal/telephony/IPhoneStateListener$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/telephony/IPhoneStateListener;
Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/telephony/IPhoneSubInfo$Stub$Proxy;->getDeviceId(Ljava/lang/String;)Ljava/lang/String;
@@ -2060,16 +3272,808 @@ Lcom/android/internal/telephony/IWapPushManager$Stub;->asInterface(Landroid/os/I
Lcom/android/internal/telephony/IWapPushManager;->addPackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z
Lcom/android/internal/telephony/IWapPushManager;->deletePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
Lcom/android/internal/telephony/IWapPushManager;->updatePackage(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;IZZ)Z
+Lcom/android/internal/telephony/MccTable$MccEntry;->mIso:Ljava/lang/String;
+Lcom/android/internal/telephony/MccTable;->countryCodeForMcc(I)Ljava/lang/String;
+Lcom/android/internal/telephony/MccTable;->defaultLanguageForMcc(I)Ljava/lang/String;
+Lcom/android/internal/telephony/MccTable;->defaultTimeZoneForMcc(I)Ljava/lang/String;
+Lcom/android/internal/telephony/MccTable;->entryForMcc(I)Lcom/android/internal/telephony/MccTable$MccEntry;
+Lcom/android/internal/telephony/MccTable;->getLocaleForLanguageCountry(Landroid/content/Context;Ljava/lang/String;Ljava/lang/String;)Ljava/util/Locale;
+Lcom/android/internal/telephony/MccTable;->smallestDigitsMccForMnc(I)I
+Lcom/android/internal/telephony/MmiCode$State;->CANCELLED:Lcom/android/internal/telephony/MmiCode$State;
+Lcom/android/internal/telephony/MmiCode$State;->COMPLETE:Lcom/android/internal/telephony/MmiCode$State;
+Lcom/android/internal/telephony/MmiCode$State;->FAILED:Lcom/android/internal/telephony/MmiCode$State;
+Lcom/android/internal/telephony/MmiCode$State;->PENDING:Lcom/android/internal/telephony/MmiCode$State;
+Lcom/android/internal/telephony/MmiCode;->getPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/Phone;->dispose()V
+Lcom/android/internal/telephony/Phone;->exitEmergencyCallbackMode()V
+Lcom/android/internal/telephony/Phone;->getActiveApnTypes()[Ljava/lang/String;
+Lcom/android/internal/telephony/Phone;->getCallTracker()Lcom/android/internal/telephony/CallTracker;
+Lcom/android/internal/telephony/Phone;->getCellLocation()Landroid/telephony/CellLocation;
+Lcom/android/internal/telephony/Phone;->getContext()Landroid/content/Context;
+Lcom/android/internal/telephony/Phone;->getDataConnectionState()Lcom/android/internal/telephony/PhoneConstants$DataState;
+Lcom/android/internal/telephony/Phone;->getIccCard()Lcom/android/internal/telephony/IccCard;
+Lcom/android/internal/telephony/Phone;->getIccFileHandler()Lcom/android/internal/telephony/uicc/IccFileHandler;
+Lcom/android/internal/telephony/Phone;->getIccSerialNumber()Ljava/lang/String;
+Lcom/android/internal/telephony/Phone;->getIccSmsInterfaceManager()Lcom/android/internal/telephony/IccSmsInterfaceManager;
+Lcom/android/internal/telephony/Phone;->getImsPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/Phone;->getIsimRecords()Lcom/android/internal/telephony/uicc/IsimRecords;
+Lcom/android/internal/telephony/Phone;->getMsisdn()Ljava/lang/String;
+Lcom/android/internal/telephony/Phone;->getNai()Ljava/lang/String;
+Lcom/android/internal/telephony/Phone;->getPhoneId()I
+Lcom/android/internal/telephony/Phone;->getPhoneName()Ljava/lang/String;
+Lcom/android/internal/telephony/Phone;->getPhoneType()I
+Lcom/android/internal/telephony/Phone;->getServiceStateTracker()Lcom/android/internal/telephony/ServiceStateTracker;
+Lcom/android/internal/telephony/Phone;->getSmscAddress(Landroid/os/Message;)V
+Lcom/android/internal/telephony/Phone;->getState()Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/Phone;->getSubId()I
+Lcom/android/internal/telephony/Phone;->getSystemProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/Phone;->getUiccCard()Lcom/android/internal/telephony/uicc/UiccCard;
+Lcom/android/internal/telephony/Phone;->getVideoState(Lcom/android/internal/telephony/Call;)I
+Lcom/android/internal/telephony/Phone;->invokeOemRilRequestRaw([BLandroid/os/Message;)V
+Lcom/android/internal/telephony/Phone;->invokeOemRilRequestStrings([Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/Phone;->isCspPlmnEnabled()Z
+Lcom/android/internal/telephony/Phone;->isUtEnabled()Z
+Lcom/android/internal/telephony/Phone;->isVideoEnabled()Z
+Lcom/android/internal/telephony/Phone;->isVolteEnabled()Z
+Lcom/android/internal/telephony/Phone;->isWifiCallingEnabled()Z
+Lcom/android/internal/telephony/Phone;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/Phone;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/Phone;->mDcTracker:Lcom/android/internal/telephony/dataconnection/DcTracker;
+Lcom/android/internal/telephony/Phone;->mIccRecords:Ljava/util/concurrent/atomic/AtomicReference;
+Lcom/android/internal/telephony/Phone;->mImsPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/Phone;->mMmiRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/Phone;->mNotifier:Lcom/android/internal/telephony/PhoneNotifier;
+Lcom/android/internal/telephony/Phone;->mPhoneId:I
+Lcom/android/internal/telephony/Phone;->mSmsStorageMonitor:Lcom/android/internal/telephony/SmsStorageMonitor;
+Lcom/android/internal/telephony/Phone;->mUiccApplication:Ljava/util/concurrent/atomic/AtomicReference;
+Lcom/android/internal/telephony/Phone;->mUiccController:Lcom/android/internal/telephony/uicc/UiccController;
+Lcom/android/internal/telephony/Phone;->needsOtaServiceProvisioning()Z
+Lcom/android/internal/telephony/Phone;->notifyOtaspChanged(I)V
+Lcom/android/internal/telephony/Phone;->registerForDisconnect(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForEcmTimerReset(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForIncomingRing(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForMmiComplete(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForMmiInitiate(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForNewRingingConnection(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForPreciseCallStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForRingbackTone(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForServiceStateChanged(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForSimRecordsLoaded(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->registerForUnknownConnection(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->selectNetworkManually(Lcom/android/internal/telephony/OperatorInfo;ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/Phone;->setNetworkSelectionModeAutomatic(Landroid/os/Message;)V
+Lcom/android/internal/telephony/Phone;->setOnEcbModeExitResponse(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->setOnPostDialCharacter(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/Phone;->setPreferredNetworkType(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/Phone;->setSmscAddress(Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/Phone;->unregisterForDisconnect(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForEcmTimerReset(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForIncomingRing(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForMmiComplete(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForMmiInitiate(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForNewRingingConnection(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForPreciseCallStateChanged(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForRingbackTone(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForServiceStateChanged(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForSimRecordsLoaded(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unregisterForUnknownConnection(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/Phone;->unsetOnEcbModeExitResponse(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/PhoneConstants$DataState;->CONNECTED:Lcom/android/internal/telephony/PhoneConstants$DataState;
+Lcom/android/internal/telephony/PhoneConstants$DataState;->CONNECTING:Lcom/android/internal/telephony/PhoneConstants$DataState;
+Lcom/android/internal/telephony/PhoneConstants$DataState;->DISCONNECTED:Lcom/android/internal/telephony/PhoneConstants$DataState;
+Lcom/android/internal/telephony/PhoneConstants$DataState;->SUSPENDED:Lcom/android/internal/telephony/PhoneConstants$DataState;
+Lcom/android/internal/telephony/PhoneConstants$DataState;->values()[Lcom/android/internal/telephony/PhoneConstants$DataState;
+Lcom/android/internal/telephony/PhoneConstants$State;->IDLE:Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/PhoneConstants$State;->OFFHOOK:Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/PhoneConstants$State;->RINGING:Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/PhoneConstants$State;->values()[Lcom/android/internal/telephony/PhoneConstants$State;
+Lcom/android/internal/telephony/PhoneConstants;->PRESENTATION_ALLOWED:I
+Lcom/android/internal/telephony/PhoneConstants;->PRESENTATION_PAYPHONE:I
+Lcom/android/internal/telephony/PhoneConstants;->PRESENTATION_RESTRICTED:I
+Lcom/android/internal/telephony/PhoneConstants;->PRESENTATION_UNKNOWN:I
+Lcom/android/internal/telephony/PhoneFactory;->calculatePreferredNetworkType(Landroid/content/Context;I)I
+Lcom/android/internal/telephony/PhoneFactory;->getDefaultPhone()Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/PhoneFactory;->getDefaultSubscription()I
+Lcom/android/internal/telephony/PhoneFactory;->getPhone(I)Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/PhoneFactory;->getPhones()[Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/PhoneFactory;->makeDefaultPhone(Landroid/content/Context;)V
+Lcom/android/internal/telephony/PhoneFactory;->sCommandsInterface:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/PhoneFactory;->sContext:Landroid/content/Context;
+Lcom/android/internal/telephony/PhoneFactory;->sMadeDefaults:Z
+Lcom/android/internal/telephony/PhoneFactory;->sPhoneNotifier:Lcom/android/internal/telephony/PhoneNotifier;
+Lcom/android/internal/telephony/PhoneInternalInterface$DataActivityState;->NONE:Lcom/android/internal/telephony/PhoneInternalInterface$DataActivityState;
+Lcom/android/internal/telephony/PhoneInternalInterface;->PREFERRED_NT_MODE:I
+Lcom/android/internal/telephony/PhoneNotifier;->notifyMessageWaitingChanged(Lcom/android/internal/telephony/Phone;)V
+Lcom/android/internal/telephony/PhoneNotifier;->notifySignalStrength(Lcom/android/internal/telephony/Phone;)V
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;-><init>(Landroid/content/Context;Landroid/os/Handler;)V
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;->getSignalStrengthDbm()I
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;->mSignalStrength:Landroid/telephony/SignalStrength;
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;->mWants:I
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;->notifyServiceState(I)V
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;->notifySignalStrength(I)V
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;->registerIntent()V
+Lcom/android/internal/telephony/PhoneStateIntentReceiver;->unregisterIntent()V
+Lcom/android/internal/telephony/PhoneSubInfoController;->getDefaultSubscription()I
+Lcom/android/internal/telephony/PhoneSubInfoController;->getPhone(I)Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/PhoneSubInfoController;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/PhoneSubInfoController;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/PhoneSubInfoController;->mPhone:[Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/PhoneSwitcher;->activate(I)V
+Lcom/android/internal/telephony/PhoneSwitcher;->deactivate(I)V
+Lcom/android/internal/telephony/PhoneSwitcher;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/PhoneSwitcher;->mMaxActivePhones:I
+Lcom/android/internal/telephony/PhoneSwitcher;->mNumPhones:I
+Lcom/android/internal/telephony/PhoneSwitcher;->mPhones:[Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/ProxyController;->completeRadioCapabilityTransaction()V
+Lcom/android/internal/telephony/ProxyController;->getInstance()Lcom/android/internal/telephony/ProxyController;
+Lcom/android/internal/telephony/ProxyController;->logd(Ljava/lang/String;)V
+Lcom/android/internal/telephony/ProxyController;->mOldRadioAccessFamily:[I
+Lcom/android/internal/telephony/ProxyController;->mRadioCapabilitySessionId:I
+Lcom/android/internal/telephony/ProxyController;->mSetRadioAccessFamilyStatus:[I
+Lcom/android/internal/telephony/ProxyController;->mUniqueIdGenerator:Ljava/util/concurrent/atomic/AtomicInteger;
+Lcom/android/internal/telephony/ProxyController;->registerForAllDataDisconnected(ILandroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/ProxyController;->sendRadioCapabilityRequest(IIIILjava/lang/String;II)V
+Lcom/android/internal/telephony/ProxyController;->sProxyController:Lcom/android/internal/telephony/ProxyController;
+Lcom/android/internal/telephony/RadioCapability;->getRadioAccessFamily()I
+Lcom/android/internal/telephony/RetryManager;->configure(Ljava/lang/String;)Z
+Lcom/android/internal/telephony/RetryManager;->getRetryTimer()I
+Lcom/android/internal/telephony/RetryManager;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/RetryManager;->mApnType:Ljava/lang/String;
+Lcom/android/internal/telephony/RetryManager;->mFailFastInterApnDelay:J
+Lcom/android/internal/telephony/RetryManager;->mInterApnDelay:J
+Lcom/android/internal/telephony/RetryManager;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/RIL;-><init>(Landroid/content/Context;II)V
+Lcom/android/internal/telephony/RIL;-><init>(Landroid/content/Context;IILjava/lang/Integer;)V
+Lcom/android/internal/telephony/RIL;->acquireWakeLock(Lcom/android/internal/telephony/RILRequest;I)V
+Lcom/android/internal/telephony/RIL;->clearRequestList(IZ)V
+Lcom/android/internal/telephony/RIL;->clearWakeLock(I)Z
+Lcom/android/internal/telephony/RIL;->decrementWakeLock(Lcom/android/internal/telephony/RILRequest;)V
+Lcom/android/internal/telephony/RIL;->findAndRemoveRequestFromList(I)Lcom/android/internal/telephony/RILRequest;
+Lcom/android/internal/telephony/RIL;->getResponseForTimedOutRILRequest(Lcom/android/internal/telephony/RILRequest;)Ljava/lang/Object;
+Lcom/android/internal/telephony/RIL;->hangupForegroundResumeBackground(Landroid/os/Message;)V
+Lcom/android/internal/telephony/RIL;->hangupWaitingOrBackground(Landroid/os/Message;)V
+Lcom/android/internal/telephony/RIL;->invokeOemRilRequestRaw([BLandroid/os/Message;)V
+Lcom/android/internal/telephony/RIL;->makeStaticRadioCapability()Lcom/android/internal/telephony/RadioCapability;
+Lcom/android/internal/telephony/RIL;->mRequestList:Landroid/util/SparseArray;
+Lcom/android/internal/telephony/RIL;->mTestingEmergencyCall:Ljava/util/concurrent/atomic/AtomicBoolean;
+Lcom/android/internal/telephony/RIL;->mWakeLock:Landroid/os/PowerManager$WakeLock;
+Lcom/android/internal/telephony/RIL;->notifyRegistrantsCdmaInfoRec(Lcom/android/internal/telephony/cdma/CdmaInformationRecords;)V
+Lcom/android/internal/telephony/RIL;->notifyRegistrantsRilConnectionChanged(I)V
+Lcom/android/internal/telephony/RIL;->requestToString(I)Ljava/lang/String;
+Lcom/android/internal/telephony/RIL;->responseToString(I)Ljava/lang/String;
+Lcom/android/internal/telephony/RIL;->retToString(ILjava/lang/Object;)Ljava/lang/String;
+Lcom/android/internal/telephony/RIL;->riljLog(Ljava/lang/String;)V
+Lcom/android/internal/telephony/RIL;->setRadioPower(ZLandroid/os/Message;)V
+Lcom/android/internal/telephony/RIL;->unsljLog(I)V
+Lcom/android/internal/telephony/RIL;->unsljLogMore(ILjava/lang/String;)V
+Lcom/android/internal/telephony/RIL;->unsljLogRet(ILjava/lang/Object;)V
+Lcom/android/internal/telephony/RIL;->unsljLogvRet(ILjava/lang/Object;)V
+Lcom/android/internal/telephony/RILConstants;->PREFERRED_NETWORK_MODE:I
+Lcom/android/internal/telephony/RILRequest;->mRequest:I
+Lcom/android/internal/telephony/RILRequest;->mResult:Landroid/os/Message;
+Lcom/android/internal/telephony/RILRequest;->mSerial:I
+Lcom/android/internal/telephony/RILRequest;->obtain(ILandroid/os/Message;)Lcom/android/internal/telephony/RILRequest;
+Lcom/android/internal/telephony/RILRequest;->onError(ILjava/lang/Object;)V
+Lcom/android/internal/telephony/RILRequest;->release()V
+Lcom/android/internal/telephony/RILRequest;->serialString()Ljava/lang/String;
+Lcom/android/internal/telephony/ServiceStateTracker;->fixUnknownMcc(Ljava/lang/String;I)Ljava/lang/String;
+Lcom/android/internal/telephony/ServiceStateTracker;->getCurrentDataConnectionState()I
+Lcom/android/internal/telephony/ServiceStateTracker;->getDesiredPowerState()Z
+Lcom/android/internal/telephony/ServiceStateTracker;->getPhoneId()I
+Lcom/android/internal/telephony/ServiceStateTracker;->getSystemProperty(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/ServiceStateTracker;->isConcurrentVoiceAndDataAllowed()Z
+Lcom/android/internal/telephony/ServiceStateTracker;->isGprsConsistent(II)Z
+Lcom/android/internal/telephony/ServiceStateTracker;->isImsRegistered()Z
+Lcom/android/internal/telephony/ServiceStateTracker;->isInHomeSidNid(II)Z
+Lcom/android/internal/telephony/ServiceStateTracker;->isInvalidOperatorNumeric(Ljava/lang/String;)Z
+Lcom/android/internal/telephony/ServiceStateTracker;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/ServiceStateTracker;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/ServiceStateTracker;->mAttachedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/ServiceStateTracker;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/ServiceStateTracker;->mCr:Landroid/content/ContentResolver;
+Lcom/android/internal/telephony/ServiceStateTracker;->mCurDataSpn:Ljava/lang/String;
+Lcom/android/internal/telephony/ServiceStateTracker;->mCurPlmn:Ljava/lang/String;
+Lcom/android/internal/telephony/ServiceStateTracker;->mCurShowPlmn:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mCurShowSpn:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mCurSpn:Ljava/lang/String;
+Lcom/android/internal/telephony/ServiceStateTracker;->mDataRoamingOffRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/ServiceStateTracker;->mDataRoamingOnRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/ServiceStateTracker;->mDefaultRoamingIndicator:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mDesiredPowerState:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mDetachedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/ServiceStateTracker;->mDeviceShuttingDown:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mEmergencyOnly:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mIccRecords:Lcom/android/internal/telephony/uicc/IccRecords;
+Lcom/android/internal/telephony/ServiceStateTracker;->mIntentReceiver:Landroid/content/BroadcastReceiver;
+Lcom/android/internal/telephony/ServiceStateTracker;->mIsSubscriptionFromRuim:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mMaxDataCalls:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mNetworkAttachedRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/ServiceStateTracker;->mNewMaxDataCalls:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mNewReasonDataDenied:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mNewSS:Landroid/telephony/ServiceState;
+Lcom/android/internal/telephony/ServiceStateTracker;->mOnSubscriptionsChangedListener:Lcom/android/internal/telephony/ServiceStateTracker$SstSubscriptionsChangedListener;
+Lcom/android/internal/telephony/ServiceStateTracker;->mPhone:Lcom/android/internal/telephony/GsmCdmaPhone;
+Lcom/android/internal/telephony/ServiceStateTracker;->mPreferredNetworkType:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mReasonDataDenied:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mReportedGprsNoReg:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mRoamingIndicator:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mSignalStrength:Landroid/telephony/SignalStrength;
+Lcom/android/internal/telephony/ServiceStateTracker;->mSpnUpdatePending:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mSS:Landroid/telephony/ServiceState;
+Lcom/android/internal/telephony/ServiceStateTracker;->mStartedGprsRegCheck:Z
+Lcom/android/internal/telephony/ServiceStateTracker;->mSubId:I
+Lcom/android/internal/telephony/ServiceStateTracker;->mSubscriptionController:Lcom/android/internal/telephony/SubscriptionController;
+Lcom/android/internal/telephony/ServiceStateTracker;->mSubscriptionManager:Landroid/telephony/SubscriptionManager;
+Lcom/android/internal/telephony/ServiceStateTracker;->mUiccApplcation:Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/ServiceStateTracker;->mUiccController:Lcom/android/internal/telephony/uicc/UiccController;
+Lcom/android/internal/telephony/ServiceStateTracker;->mVoiceRoamingOffRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/ServiceStateTracker;->mVoiceRoamingOnRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/ServiceStateTracker;->notifyDataRegStateRilRadioTechnologyChanged()V
+Lcom/android/internal/telephony/ServiceStateTracker;->notifySignalStrength()Z
+Lcom/android/internal/telephony/ServiceStateTracker;->pollState()V
+Lcom/android/internal/telephony/ServiceStateTracker;->powerOffRadioSafely(Lcom/android/internal/telephony/dataconnection/DcTracker;)V
+Lcom/android/internal/telephony/ServiceStateTracker;->reRegisterNetwork(Landroid/os/Message;)V
+Lcom/android/internal/telephony/ServiceStateTracker;->resetServiceStateInIwlanMode()V
+Lcom/android/internal/telephony/ServiceStateTracker;->setOperatorIdd(Ljava/lang/String;)V
+Lcom/android/internal/telephony/ServiceStateTracker;->setRoamingType(Landroid/telephony/ServiceState;)V
+Lcom/android/internal/telephony/ServiceStateTracker;->setSignalStrengthDefaultValues()V
+Lcom/android/internal/telephony/ServiceStateTracker;->updateOtaspState()V
+Lcom/android/internal/telephony/ServiceStateTracker;->updatePhoneObject()V
+Lcom/android/internal/telephony/ServiceStateTracker;->updateRoamingState()V
+Lcom/android/internal/telephony/ServiceStateTracker;->updateSpnDisplay()V
+Lcom/android/internal/telephony/ServiceStateTracker;->useDataRegStateForDataOnlyDevices()V
+Lcom/android/internal/telephony/sip/SipPhone$SipCall;->hold()V
+Lcom/android/internal/telephony/sip/SipPhone$SipCall;->switchWith(Lcom/android/internal/telephony/sip/SipPhone$SipCall;)V
+Lcom/android/internal/telephony/sip/SipPhone$SipCall;->unhold()V
+Lcom/android/internal/telephony/sip/SipPhone;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/sip/SipPhone;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/sip/SipPhone;->mBackgroundCall:Lcom/android/internal/telephony/sip/SipPhone$SipCall;
+Lcom/android/internal/telephony/sip/SipPhone;->mForegroundCall:Lcom/android/internal/telephony/sip/SipPhone$SipCall;
+Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->DBG:Z
+Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableCDMA:Landroid/util/SparseIntArray;
+Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableCommon:Landroid/util/SparseIntArray;
+Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->mTranslationTableGSM:Landroid/util/SparseIntArray;
+Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->translate(Ljava/lang/CharSequence;)Ljava/lang/String;
+Lcom/android/internal/telephony/Sms7BitEncodingTranslator;->useCdmaFormatForMoSms()Z
+Lcom/android/internal/telephony/SmsApplication$SmsApplicationData;->mApplicationName:Ljava/lang/String;
+Lcom/android/internal/telephony/SmsApplication;->configurePreferredActivity(Landroid/content/pm/PackageManager;Landroid/content/ComponentName;I)V
+Lcom/android/internal/telephony/SmsApplication;->getApplicationCollection(Landroid/content/Context;)Ljava/util/Collection;
+Lcom/android/internal/telephony/SmsApplication;->getDefaultMmsApplication(Landroid/content/Context;Z)Landroid/content/ComponentName;
+Lcom/android/internal/telephony/SmsApplication;->getDefaultRespondViaMessageApplication(Landroid/content/Context;Z)Landroid/content/ComponentName;
+Lcom/android/internal/telephony/SmsApplication;->getDefaultSmsApplication(Landroid/content/Context;Z)Landroid/content/ComponentName;
+Lcom/android/internal/telephony/SmsApplication;->getSmsApplicationData(Ljava/lang/String;Landroid/content/Context;)Lcom/android/internal/telephony/SmsApplication$SmsApplicationData;
+Lcom/android/internal/telephony/SmsApplication;->isDefaultSmsApplication(Landroid/content/Context;Ljava/lang/String;)Z
+Lcom/android/internal/telephony/SmsApplication;->setDefaultApplication(Ljava/lang/String;Landroid/content/Context;)V
+Lcom/android/internal/telephony/SmsApplication;->shouldWriteMessageForPackage(Ljava/lang/String;Landroid/content/Context;)Z
+Lcom/android/internal/telephony/SmsBroadcastUndelivered;-><init>(Landroid/content/Context;Lcom/android/internal/telephony/gsm/GsmInboundSmsHandler;Lcom/android/internal/telephony/cdma/CdmaInboundSmsHandler;)V
+Lcom/android/internal/telephony/SMSDispatcher$ConfirmDialogListener;->mNegativeButton:Landroid/widget/Button;
+Lcom/android/internal/telephony/SMSDispatcher$ConfirmDialogListener;->mPositiveButton:Landroid/widget/Button;
+Lcom/android/internal/telephony/SMSDispatcher$ConfirmDialogListener;->mRememberUndoInstruction:Landroid/widget/TextView;
+Lcom/android/internal/telephony/SMSDispatcher$DataSmsSender;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSender;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Ljava/util/ArrayList;[Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSender;->sendSmsByCarrierApp(Ljava/lang/String;Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSenderCallback;)V
+Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSenderCallback;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$MultipartSmsSender;)V
+Lcom/android/internal/telephony/SMSDispatcher$SmsSenderCallback;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$SmsSender;)V
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->isMultipart()Z
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mAppInfo:Landroid/content/pm/PackageInfo;
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mData:Ljava/util/HashMap;
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mDeliveryIntent:Landroid/app/PendingIntent;
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mDestAddress:Ljava/lang/String;
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mMessageRef:I
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mMessageUri:Landroid/net/Uri;
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mPersistMessage:Z
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mSentIntent:Landroid/app/PendingIntent;
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->mTimestamp:J
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->onFailed(Landroid/content/Context;II)V
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->onSent(Landroid/content/Context;)V
+Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;->updateSentMessageStatus(Landroid/content/Context;I)V
+Lcom/android/internal/telephony/SMSDispatcher$TextSmsSender;-><init>(Lcom/android/internal/telephony/SMSDispatcher;Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+Lcom/android/internal/telephony/SMSDispatcher;->calculateLength(Ljava/lang/CharSequence;Z)Lcom/android/internal/telephony/GsmAlphabet$TextEncodingDetails;
+Lcom/android/internal/telephony/SMSDispatcher;->checkCallerIsPhoneOrCarrierApp()V
+Lcom/android/internal/telephony/SMSDispatcher;->deliveryPendingList:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/SMSDispatcher;->dispose()V
+Lcom/android/internal/telephony/SMSDispatcher;->getCarrierAppPackageName()Ljava/lang/String;
+Lcom/android/internal/telephony/SMSDispatcher;->getMultipartMessageText(Ljava/util/ArrayList;)Ljava/lang/String;
+Lcom/android/internal/telephony/SMSDispatcher;->getNextConcatenatedRef()I
+Lcom/android/internal/telephony/SMSDispatcher;->getSubId()I
+Lcom/android/internal/telephony/SMSDispatcher;->handleConfirmShortCode(ZLcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+Lcom/android/internal/telephony/SMSDispatcher;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/SMSDispatcher;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/SMSDispatcher;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/SMSDispatcher;->mResolver:Landroid/content/ContentResolver;
+Lcom/android/internal/telephony/SMSDispatcher;->mTelephonyManager:Landroid/telephony/TelephonyManager;
+Lcom/android/internal/telephony/SMSDispatcher;->processSendSmsResponse(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;II)V
+Lcom/android/internal/telephony/SMSDispatcher;->sendData(Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;)V
+Lcom/android/internal/telephony/SMSDispatcher;->sendMultipartSms(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+Lcom/android/internal/telephony/SMSDispatcher;->sendSms(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
+Lcom/android/internal/telephony/SMSDispatcher;->sendSubmitPdu(Lcom/android/internal/telephony/SMSDispatcher$SmsTracker;)V
Lcom/android/internal/telephony/SmsHeader$ConcatRef;-><init>()V
Lcom/android/internal/telephony/SmsHeader$PortAddrs;-><init>()V
Lcom/android/internal/telephony/SmsMessageBase;-><init>()V
+Lcom/android/internal/telephony/SmsResponse;-><init>(ILjava/lang/String;I)V
+Lcom/android/internal/telephony/SmsResponse;->mAckPdu:Ljava/lang/String;
+Lcom/android/internal/telephony/SmsResponse;->mErrorCode:I
+Lcom/android/internal/telephony/SmsResponse;->mMessageRef:I
+Lcom/android/internal/telephony/SmsStorageMonitor;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/SmsUsageMonitor;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/telephony/SmsUsageMonitor;->check(Ljava/lang/String;I)Z
+Lcom/android/internal/telephony/SubscriptionController;->broadcastDefaultDataSubIdChanged(I)V
+Lcom/android/internal/telephony/SubscriptionController;->colorArr:[I
+Lcom/android/internal/telephony/SubscriptionController;->enforceModifyPhoneState(Ljava/lang/String;)V
+Lcom/android/internal/telephony/SubscriptionController;->getActiveSubInfoCount(Ljava/lang/String;)I
+Lcom/android/internal/telephony/SubscriptionController;->getActiveSubscriptionInfo(ILjava/lang/String;)Landroid/telephony/SubscriptionInfo;
+Lcom/android/internal/telephony/SubscriptionController;->getActiveSubscriptionInfoList(Ljava/lang/String;)Ljava/util/List;
+Lcom/android/internal/telephony/SubscriptionController;->getDefaultDataSubId()I
+Lcom/android/internal/telephony/SubscriptionController;->getDefaultSmsSubId()I
+Lcom/android/internal/telephony/SubscriptionController;->getDefaultSubId()I
+Lcom/android/internal/telephony/SubscriptionController;->getDefaultVoiceSubId()I
+Lcom/android/internal/telephony/SubscriptionController;->getDummySubIds(I)[I
+Lcom/android/internal/telephony/SubscriptionController;->getInstance()Lcom/android/internal/telephony/SubscriptionController;
+Lcom/android/internal/telephony/SubscriptionController;->getPhoneId(I)I
+Lcom/android/internal/telephony/SubscriptionController;->getSubId(I)[I
+Lcom/android/internal/telephony/SubscriptionController;->getSubIdUsingPhoneId(I)I
+Lcom/android/internal/telephony/SubscriptionController;->getSubInfo(Ljava/lang/String;Ljava/lang/Object;)Ljava/util/List;
+Lcom/android/internal/telephony/SubscriptionController;->getSubInfoRecord(Landroid/database/Cursor;)Landroid/telephony/SubscriptionInfo;
+Lcom/android/internal/telephony/SubscriptionController;->isActiveSubId(I)Z
+Lcom/android/internal/telephony/SubscriptionController;->isSubInfoReady()Z
+Lcom/android/internal/telephony/SubscriptionController;->logd(Ljava/lang/String;)V
+Lcom/android/internal/telephony/SubscriptionController;->logdl(Ljava/lang/String;)V
+Lcom/android/internal/telephony/SubscriptionController;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/SubscriptionController;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/SubscriptionController;->mDefaultPhoneId:I
+Lcom/android/internal/telephony/SubscriptionController;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/SubscriptionController;->notifySubscriptionInfoChanged()V
+Lcom/android/internal/telephony/SubscriptionController;->setDefaultDataSubId(I)V
+Lcom/android/internal/telephony/SubscriptionController;->setDefaultFallbackSubId(I)V
+Lcom/android/internal/telephony/SubscriptionController;->setDefaultSmsSubId(I)V
+Lcom/android/internal/telephony/SubscriptionController;->setDefaultVoiceSubId(I)V
+Lcom/android/internal/telephony/SubscriptionController;->setPlmnSpn(IZLjava/lang/String;ZLjava/lang/String;)Z
+Lcom/android/internal/telephony/SubscriptionController;->updateAllDataConnectionTrackers()V
+Lcom/android/internal/telephony/SubscriptionController;->validateSubId(I)V
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->broadcastSimStateChanged(ILjava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->isAllIccIdQueryDone()Z
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->logd(Ljava/lang/String;)V
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mCurrentlyActiveUserId:I
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mIccId:[Ljava/lang/String;
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mInsertSimState:[I
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mPackageManager:Landroid/content/pm/IPackageManager;
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->mPhone:[Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->PROJECT_SIM_NUM:I
+Lcom/android/internal/telephony/SubscriptionInfoUpdater;->updateSubscriptionInfoByIccId()V
+Lcom/android/internal/telephony/TelephonyCapabilities;->supportsAdn(I)Z
+Lcom/android/internal/telephony/TelephonyProperties;->PROPERTY_ICC_OPERATOR_NUMERIC:Ljava/lang/String;
+Lcom/android/internal/telephony/test/InterpreterEx;-><init>(Ljava/lang/String;)V
+Lcom/android/internal/telephony/test/SimulatedCommands;->acceptCall(Landroid/os/Message;)V
+Lcom/android/internal/telephony/test/SimulatedCommands;->dial(Ljava/lang/String;ILandroid/os/Message;)V
+Lcom/android/internal/telephony/test/SimulatedCommands;->dial(Ljava/lang/String;ILcom/android/internal/telephony/UUSInfo;Landroid/os/Message;)V
+Lcom/android/internal/telephony/test/SimulatedCommands;->mDcSuccess:Z
+Lcom/android/internal/telephony/test/SimulatedCommands;->resultFail(Landroid/os/Message;Ljava/lang/Object;Ljava/lang/Throwable;)V
+Lcom/android/internal/telephony/test/SimulatedCommands;->resultSuccess(Landroid/os/Message;Ljava/lang/Object;)V
+Lcom/android/internal/telephony/test/SimulatedCommands;->simulatedCallState:Lcom/android/internal/telephony/test/SimulatedGsmCallState;
+Lcom/android/internal/telephony/test/SimulatedCommands;->unimplemented(Landroid/os/Message;)V
+Lcom/android/internal/telephony/test/SimulatedCommandsVerifier;->getInstance()Lcom/android/internal/telephony/test/SimulatedCommandsVerifier;
+Lcom/android/internal/telephony/test/SimulatedCommandsVerifier;->setCallForward(IIILjava/lang/String;ILandroid/os/Message;)V
+Lcom/android/internal/telephony/test/SimulatedGsmCallState;->conference()Z
+Lcom/android/internal/telephony/test/SimulatedGsmCallState;->onChld(CC)Z
+Lcom/android/internal/telephony/test/SimulatedGsmCallState;->releaseActiveAcceptHeldOrWaiting()Z
+Lcom/android/internal/telephony/test/SimulatedGsmCallState;->releaseHeldOrUDUB()Z
+Lcom/android/internal/telephony/test/SimulatedGsmCallState;->separateCall(I)Z
+Lcom/android/internal/telephony/test/SimulatedGsmCallState;->switchActiveAndHeldOrWaiting()Z
+Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(IILjava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(IILjava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(II[B)V
+Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/AdnRecord;-><init>(Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/AdnRecord;-><init>([B)V
+Lcom/android/internal/telephony/uicc/AdnRecord;->buildAdnString(I)[B
+Lcom/android/internal/telephony/uicc/AdnRecord;->CREATOR:Landroid/os/Parcelable$Creator;
+Lcom/android/internal/telephony/uicc/AdnRecord;->getEmails()[Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/AdnRecord;->getNumber()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/AdnRecord;->isEmpty()Z
+Lcom/android/internal/telephony/uicc/AdnRecord;->mAlphaTag:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/AdnRecord;->mEfid:I
+Lcom/android/internal/telephony/uicc/AdnRecord;->mEmails:[Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/AdnRecord;->mExtRecord:I
+Lcom/android/internal/telephony/uicc/AdnRecord;->mNumber:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/AdnRecord;->mRecordNumber:I
+Lcom/android/internal/telephony/uicc/AdnRecord;->setEmails([Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->extensionEfForEf(I)I
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->getRecordsIfLoaded(I)Ljava/util/ArrayList;
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->mAdnLikeWaiters:Landroid/util/SparseArray;
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->mFh:Lcom/android/internal/telephony/uicc/IccFileHandler;
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->mUserWriteResponse:Landroid/util/SparseArray;
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->mUsimPhoneBookManager:Lcom/android/internal/telephony/gsm/UsimPhoneBookManager;
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->reset()V
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->sendErrorResponse(Landroid/os/Message;Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/AdnRecordCache;->updateAdnByIndex(ILcom/android/internal/telephony/uicc/AdnRecord;ILjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/AdnRecordLoader;-><init>(Lcom/android/internal/telephony/uicc/IccFileHandler;)V
+Lcom/android/internal/telephony/uicc/AdnRecordLoader;->getEFPath(I)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/AdnRecordLoader;->loadFromEF(IIILandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/AdnRecordLoader;->mFh:Lcom/android/internal/telephony/uicc/IccFileHandler;
+Lcom/android/internal/telephony/uicc/AdnRecordLoader;->updateEF(Lcom/android/internal/telephony/uicc/AdnRecord;IIILjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_DETECTED:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_PIN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_PUK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_READY:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_SUBSCRIPTION_PERSO:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->APPSTATE_UNKNOWN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;->values()[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_CSIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_ISIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_RUIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_SIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_UNKNOWN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->APPTYPE_USIM:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;->values()[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_NETWORK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_NETWORK_SUBSET:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_NETWORK_SUBSET_PUK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_SERVICE_PROVIDER:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_SIM_SERVICE_PROVIDER_PUK:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->PERSOSUBSTATE_UNKNOWN:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;->values()[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;-><init>()V
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;->AppTypeFromRILInt(I)Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;->app_type:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->CARDSTATE_ABSENT:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
+Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->CARDSTATE_ERROR:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
+Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->CARDSTATE_PRESENT:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
+Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;->isCardPresent()Z
+Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;->PINSTATE_DISABLED:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
+Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;->PINSTATE_ENABLED_BLOCKED:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
+Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;->PINSTATE_ENABLED_PERM_BLOCKED:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
+Lcom/android/internal/telephony/uicc/IccCardStatus;->mApplications:[Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;
+Lcom/android/internal/telephony/uicc/IccCardStatus;->mCardState:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
+Lcom/android/internal/telephony/uicc/IccCardStatus;->mCdmaSubscriptionAppIndex:I
+Lcom/android/internal/telephony/uicc/IccCardStatus;->mGsmUmtsSubscriptionAppIndex:I
+Lcom/android/internal/telephony/uicc/IccCardStatus;->mImsSubscriptionAppIndex:I
+Lcom/android/internal/telephony/uicc/IccCardStatus;->mUniversalPinState:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
+Lcom/android/internal/telephony/uicc/IccFileHandler$LoadLinearFixedContext;-><init>(IILandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler$LoadLinearFixedContext;->mRecordSize:I
+Lcom/android/internal/telephony/uicc/IccFileHandler$LoadLinearFixedContext;->results:Ljava/util/ArrayList;
+Lcom/android/internal/telephony/uicc/IccFileHandler;->getEFLinearRecordSize(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->getEFLinearRecordSize(ILjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->getEFPath(I)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixed(IILandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixed(ILjava/lang/String;ILandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixedAll(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFLinearFixedAll(ILjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->loadEFTransparent(ILandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->mAid:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccFileHandler;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/uicc/IccFileHandler;->mParentApp:Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/uicc/IccFileHandler;->updateEFLinearFixed(II[BLjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->updateEFLinearFixed(ILjava/lang/String;I[BLjava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccFileHandler;->updateEFTransparent(I[BLandroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccIoResult;-><init>(IILjava/lang/String;)V
+Lcom/android/internal/telephony/uicc/IccIoResult;-><init>(II[B)V
+Lcom/android/internal/telephony/uicc/IccIoResult;->payload:[B
+Lcom/android/internal/telephony/uicc/IccIoResult;->success()Z
+Lcom/android/internal/telephony/uicc/IccIoResult;->sw1:I
+Lcom/android/internal/telephony/uicc/IccIoResult;->sw2:I
+Lcom/android/internal/telephony/uicc/IccRecords;->auth_rsp:Lcom/android/internal/telephony/uicc/IccIoResult;
+Lcom/android/internal/telephony/uicc/IccRecords;->getGid1()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->getIccId()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->getIccSimChallengeResponse(ILjava/lang/String;)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->getIMSI()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->getMsisdnNumber()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->getOperatorNumeric()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->getRecordsLoaded()Z
+Lcom/android/internal/telephony/uicc/IccRecords;->getServiceProviderName()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->getUsimServiceTable()Lcom/android/internal/telephony/uicc/UsimServiceTable;
+Lcom/android/internal/telephony/uicc/IccRecords;->handleRefresh(Lcom/android/internal/telephony/uicc/IccRefreshResponse;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->mAdnCache:Lcom/android/internal/telephony/uicc/AdnRecordCache;
+Lcom/android/internal/telephony/uicc/IccRecords;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/uicc/IccRecords;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/uicc/IccRecords;->mDestroyed:Ljava/util/concurrent/atomic/AtomicBoolean;
+Lcom/android/internal/telephony/uicc/IccRecords;->mFh:Lcom/android/internal/telephony/uicc/IccFileHandler;
+Lcom/android/internal/telephony/uicc/IccRecords;->mGid1:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->mIccId:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->mImsi:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->mIsVoiceMailFixed:Z
+Lcom/android/internal/telephony/uicc/IccRecords;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/uicc/IccRecords;->mMncLength:I
+Lcom/android/internal/telephony/uicc/IccRecords;->mParentApp:Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/uicc/IccRecords;->mRecordsEventsRegistrants:Landroid/os/RegistrantList;
+Lcom/android/internal/telephony/uicc/IccRecords;->mRecordsToLoad:I
+Lcom/android/internal/telephony/uicc/IccRecords;->mSpn:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->mTelephonyManager:Landroid/telephony/TelephonyManager;
+Lcom/android/internal/telephony/uicc/IccRecords;->mVoiceMailNum:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRecords;->registerForNetworkSelectionModeAutomatic(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->registerForNewSms(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->registerForRecordsEvents(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->registerForRecordsLoaded(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->setMsisdnNumber(Ljava/lang/String;Ljava/lang/String;Landroid/os/Message;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->setVoiceCallForwardingFlag(IZLjava/lang/String;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForNetworkSelectionModeAutomatic(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForNewSms(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForRecordsEvents(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/uicc/IccRecords;->unregisterForRecordsLoaded(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/uicc/IccRefreshResponse;-><init>()V
+Lcom/android/internal/telephony/uicc/IccRefreshResponse;->aid:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccRefreshResponse;->efId:I
+Lcom/android/internal/telephony/uicc/IccRefreshResponse;->refreshResult:I
+Lcom/android/internal/telephony/uicc/IccServiceTable;->getTag()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccServiceTable;->mServiceTable:[B
+Lcom/android/internal/telephony/uicc/IccUtils;->adnStringFieldToString([BII)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccUtils;->bcdToString([BII)Ljava/lang/String;
Lcom/android/internal/telephony/uicc/IccUtils;->bytesToHexString([B)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccUtils;->cdmaBcdByteToInt(B)I
+Lcom/android/internal/telephony/uicc/IccUtils;->cdmaBcdToString([BII)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccUtils;->gsmBcdByteToInt(B)I
+Lcom/android/internal/telephony/uicc/IccUtils;->hexCharToInt(C)I
+Lcom/android/internal/telephony/uicc/IccUtils;->hexStringToBytes(Ljava/lang/String;)[B
+Lcom/android/internal/telephony/uicc/IccUtils;->networkNameToString([BII)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IccUtils;->parseToBnW([BI)Landroid/graphics/Bitmap;
+Lcom/android/internal/telephony/uicc/IccUtils;->parseToRGB([BIZ)Landroid/graphics/Bitmap;
+Lcom/android/internal/telephony/uicc/IsimRecords;->getIsimDomain()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimRecords;->getIsimImpi()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimRecords;->getIsimImpu()[Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->auth_rsp:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->fetchIsimRecords()V
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->isimTlvToString([B)Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimDomain:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimImpi:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimImpu:[Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimIst:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mIsimPcscf:[Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/IsimUiccRecords;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/uicc/RuimRecords;->adjstMinDigits(I)I
+Lcom/android/internal/telephony/uicc/RuimRecords;->fetchRuimRecords()V
+Lcom/android/internal/telephony/uicc/RuimRecords;->getAssetLanguages(Landroid/content/Context;)[Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/RuimRecords;->getCsimSpnDisplayCondition()Z
+Lcom/android/internal/telephony/uicc/RuimRecords;->getMdn()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/RuimRecords;->getMdnNumber()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/RuimRecords;->getRUIMOperatorNumeric()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/RuimRecords;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/RuimRecords;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/RuimRecords;->mEFli:[B
+Lcom/android/internal/telephony/uicc/RuimRecords;->mEFpl:[B
+Lcom/android/internal/telephony/uicc/RuimRecords;->mMin:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/RuimRecords;->mNai:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/RuimRecords;->onGetCSimEprlDone(Landroid/os/AsyncResult;)V
+Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->INIT:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
+Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->READ_SPN_3GPP:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
+Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->READ_SPN_CPHS:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
+Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->READ_SPN_SHORT_CPHS:Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
+Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;->values()[Lcom/android/internal/telephony/uicc/SIMRecords$GetSpnFsmState;
+Lcom/android/internal/telephony/uicc/SIMRecords;->fetchSimRecords()V
+Lcom/android/internal/telephony/uicc/SIMRecords;->getExtFromEf(I)I
+Lcom/android/internal/telephony/uicc/SIMRecords;->getMsisdnNumber()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/SIMRecords;->getOperatorNumeric()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/SIMRecords;->getSpnFsm(ZLandroid/os/AsyncResult;)V
+Lcom/android/internal/telephony/uicc/SIMRecords;->getVoiceMailNumber()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/SIMRecords;->isCphsMailboxEnabled()Z
+Lcom/android/internal/telephony/uicc/SIMRecords;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/SIMRecords;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/SIMRecords;->logv(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/SIMRecords;->mEfCff:[B
+Lcom/android/internal/telephony/uicc/SIMRecords;->mEfCfis:[B
+Lcom/android/internal/telephony/uicc/SIMRecords;->mEfCPHS_MWI:[B
+Lcom/android/internal/telephony/uicc/SIMRecords;->mEfLi:[B
+Lcom/android/internal/telephony/uicc/SIMRecords;->mEfMWIS:[B
+Lcom/android/internal/telephony/uicc/SIMRecords;->mEfPl:[B
+Lcom/android/internal/telephony/uicc/SIMRecords;->mSpnDisplayCondition:I
+Lcom/android/internal/telephony/uicc/SIMRecords;->mUsimServiceTable:Lcom/android/internal/telephony/uicc/UsimServiceTable;
+Lcom/android/internal/telephony/uicc/SIMRecords;->mVmConfig:Lcom/android/internal/telephony/uicc/VoiceMailConstants;
+Lcom/android/internal/telephony/uicc/SIMRecords;->setVoiceCallForwardingFlag(IZLjava/lang/String;)V
+Lcom/android/internal/telephony/uicc/UiccCard;->getApplication(I)Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/uicc/UiccCard;->getApplicationByType(I)Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/uicc/UiccCard;->getApplicationIndex(I)Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/uicc/UiccCard;->getCardState()Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
+Lcom/android/internal/telephony/uicc/UiccCard;->getCarrierPackageNamesForIntent(Landroid/content/pm/PackageManager;Landroid/content/Intent;)Ljava/util/List;
+Lcom/android/internal/telephony/uicc/UiccCard;->getIccId()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/UiccCard;->getNumApplications()I
+Lcom/android/internal/telephony/uicc/UiccCard;->getOperatorBrandOverride()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/UiccCard;->isApplicationOnIcc(Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;)Z
+Lcom/android/internal/telephony/uicc/UiccCard;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/UiccCard;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/UiccCard;->mCardState:Lcom/android/internal/telephony/uicc/IccCardStatus$CardState;
+Lcom/android/internal/telephony/uicc/UiccCard;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/uicc/UiccCard;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/uicc/UiccCard;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/uicc/UiccCard;->mPhoneId:I
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->dispose()V
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getAid()Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getAuthContext()I
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getIccFileHandler()Lcom/android/internal/telephony/uicc/IccFileHandler;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getIccRecords()Lcom/android/internal/telephony/uicc/IccRecords;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getPersoSubState()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getPhoneId()I
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getPin1State()Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getState()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->getType()Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->loge(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mAid:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mAppState:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppState;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mAppType:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$AppType;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mCi:Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mDestroyed:Z
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mPersoSubState:Lcom/android/internal/telephony/uicc/IccCardApplicationStatus$PersoSubState;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->mPin1State:Lcom/android/internal/telephony/uicc/IccCardStatus$PinState;
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->registerForReady(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->unregisterForReady(Landroid/os/Handler;)V
+Lcom/android/internal/telephony/uicc/UiccCardApplication;->update(Lcom/android/internal/telephony/uicc/IccCardApplicationStatus;Landroid/content/Context;Lcom/android/internal/telephony/CommandsInterface;)V
+Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules$TLV;->length:Ljava/lang/Integer;
+Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules$TLV;->value:Ljava/lang/String;
+Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules;->mLoadedCallback:Landroid/os/Message;
+Lcom/android/internal/telephony/uicc/UiccCarrierPrivilegeRules;->mState:Ljava/util/concurrent/atomic/AtomicInteger;
+Lcom/android/internal/telephony/uicc/UiccController;->getIccFileHandler(II)Lcom/android/internal/telephony/uicc/IccFileHandler;
+Lcom/android/internal/telephony/uicc/UiccController;->getIccRecords(II)Lcom/android/internal/telephony/uicc/IccRecords;
+Lcom/android/internal/telephony/uicc/UiccController;->getInstance()Lcom/android/internal/telephony/uicc/UiccController;
+Lcom/android/internal/telephony/uicc/UiccController;->getUiccCard(I)Lcom/android/internal/telephony/uicc/UiccCard;
+Lcom/android/internal/telephony/uicc/UiccController;->getUiccCardApplication(II)Lcom/android/internal/telephony/uicc/UiccCardApplication;
+Lcom/android/internal/telephony/uicc/UiccController;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/uicc/UiccController;->mCis:[Lcom/android/internal/telephony/CommandsInterface;
+Lcom/android/internal/telephony/uicc/UiccController;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/uicc/UiccController;->mInstance:Lcom/android/internal/telephony/uicc/UiccController;
+Lcom/android/internal/telephony/uicc/UiccController;->mLock:Ljava/lang/Object;
+Lcom/android/internal/telephony/uicc/UiccController;->registerForIccChanged(Landroid/os/Handler;ILjava/lang/Object;)V
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->ALLOWED_CSG_LISTS_AND_INDICATIONS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->CFI_STATUS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->CSG_DISPLAY_CONTROL:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->FDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->MBDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->MSISDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->MWI_STATUS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->OPERATOR_CSG_LISTS_AND_INDICATIONS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->OPERATOR_PLMN_LIST:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->PLMN_NETWORK_NAME:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SDN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SM_OVER_IP:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SM_SERVICE_PARAMS:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SM_STORAGE:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;->SPN:Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;
+Lcom/android/internal/telephony/uicc/UsimServiceTable;->isAvailable(Lcom/android/internal/telephony/uicc/UsimServiceTable$UsimService;)Z
+Lcom/android/internal/telephony/uicc/VoiceMailConstants;-><init>()V
+Lcom/android/internal/telephony/UiccPhoneBookController;-><init>([Lcom/android/internal/telephony/Phone;)V
+Lcom/android/internal/telephony/UiccPhoneBookController;->getDefaultSubscription()I
+Lcom/android/internal/telephony/UiccPhoneBookController;->getIccPhoneBookInterfaceManager(I)Lcom/android/internal/telephony/IccPhoneBookInterfaceManager;
+Lcom/android/internal/telephony/UiccPhoneBookController;->mPhone:[Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/UiccSmsController;->copyMessageToIccEfForSubscriber(ILjava/lang/String;I[B[B)Z
+Lcom/android/internal/telephony/UiccSmsController;->disableCellBroadcastForSubscriber(III)Z
+Lcom/android/internal/telephony/UiccSmsController;->disableCellBroadcastRangeForSubscriber(IIII)Z
+Lcom/android/internal/telephony/UiccSmsController;->enableCellBroadcastForSubscriber(III)Z
+Lcom/android/internal/telephony/UiccSmsController;->enableCellBroadcastRangeForSubscriber(IIII)Z
+Lcom/android/internal/telephony/UiccSmsController;->getAllMessagesFromIccEfForSubscriber(ILjava/lang/String;)Ljava/util/List;
+Lcom/android/internal/telephony/UiccSmsController;->getIccSmsInterfaceManager(I)Lcom/android/internal/telephony/IccSmsInterfaceManager;
+Lcom/android/internal/telephony/UiccSmsController;->getImsSmsFormatForSubscriber(I)Ljava/lang/String;
+Lcom/android/internal/telephony/UiccSmsController;->getPreferredSmsSubscription()I
+Lcom/android/internal/telephony/UiccSmsController;->isImsSmsSupportedForSubscriber(I)Z
+Lcom/android/internal/telephony/UiccSmsController;->sendDataForSubscriber(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;I[BLandroid/app/PendingIntent;Landroid/app/PendingIntent;)V
+Lcom/android/internal/telephony/UiccSmsController;->sendErrorInPendingIntent(Landroid/app/PendingIntent;I)V
+Lcom/android/internal/telephony/UiccSmsController;->sendErrorInPendingIntents(Ljava/util/List;I)V
+Lcom/android/internal/telephony/UiccSmsController;->updateMessageOnIccEfForSubscriber(ILjava/lang/String;II[B)Z
+Lcom/android/internal/telephony/UUSInfo;->getDcs()I
+Lcom/android/internal/telephony/UUSInfo;->getType()I
+Lcom/android/internal/telephony/UUSInfo;->getUserData()[B
+Lcom/android/internal/telephony/WakeLockStateMachine;->log(Ljava/lang/String;)V
+Lcom/android/internal/telephony/WakeLockStateMachine;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/WakeLockStateMachine;->mIdleState:Lcom/android/internal/telephony/WakeLockStateMachine$IdleState;
+Lcom/android/internal/telephony/WakeLockStateMachine;->mPhone:Lcom/android/internal/telephony/Phone;
+Lcom/android/internal/telephony/WapPushOverSms;->dispatchWapPdu([BLandroid/content/BroadcastReceiver;Lcom/android/internal/telephony/InboundSmsHandler;)I
+Lcom/android/internal/telephony/WapPushOverSms;->getDeliveryOrReadReportThreadId(Landroid/content/Context;Lcom/google/android/mms/pdu/GenericPdu;)J
+Lcom/android/internal/telephony/WapPushOverSms;->isDuplicateNotification(Landroid/content/Context;Lcom/google/android/mms/pdu/NotificationInd;)Z
+Lcom/android/internal/telephony/WapPushOverSms;->isWapPushForMms([BLcom/android/internal/telephony/InboundSmsHandler;)Z
+Lcom/android/internal/telephony/WapPushOverSms;->mContext:Landroid/content/Context;
+Lcom/android/internal/telephony/WapPushOverSms;->mDeviceIdleController:Landroid/os/IDeviceIdleController;
+Lcom/android/internal/telephony/WapPushOverSms;->mWapPushManager:Lcom/android/internal/telephony/IWapPushManager;
+Lcom/android/internal/telephony/WspTypeDecoder;-><init>([B)V
+Lcom/android/internal/telephony/WspTypeDecoder;->decodeContentType(I)Z
+Lcom/android/internal/telephony/WspTypeDecoder;->decodeIntegerValue(I)Z
+Lcom/android/internal/telephony/WspTypeDecoder;->decodeShortInteger(I)Z
+Lcom/android/internal/telephony/WspTypeDecoder;->decodeTextString(I)Z
+Lcom/android/internal/telephony/WspTypeDecoder;->decodeUintvarInteger(I)Z
+Lcom/android/internal/telephony/WspTypeDecoder;->decodeValueLength(I)Z
+Lcom/android/internal/telephony/WspTypeDecoder;->decodeXWapApplicationId(I)Z
+Lcom/android/internal/telephony/WspTypeDecoder;->getContentParameters()Ljava/util/HashMap;
+Lcom/android/internal/telephony/WspTypeDecoder;->getDecodedDataLength()I
+Lcom/android/internal/telephony/WspTypeDecoder;->getValue32()J
+Lcom/android/internal/telephony/WspTypeDecoder;->getValueString()Ljava/lang/String;
+Lcom/android/internal/telephony/WspTypeDecoder;->mWspData:[B
+Lcom/android/internal/telephony/WspTypeDecoder;->seekXWapApplicationId(II)Z
Lcom/android/internal/textservice/ITextServicesManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
+Lcom/android/internal/util/ArrayUtils;->appendElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
+Lcom/android/internal/util/ArrayUtils;->appendInt([II)[I
+Lcom/android/internal/util/ArrayUtils;->contains([II)Z
+Lcom/android/internal/util/ArrayUtils;->contains([Ljava/lang/Object;Ljava/lang/Object;)Z
+Lcom/android/internal/util/ArrayUtils;->emptyArray(Ljava/lang/Class;)[Ljava/lang/Object;
+Lcom/android/internal/util/ArrayUtils;->indexOf([Ljava/lang/Object;Ljava/lang/Object;)I
+Lcom/android/internal/util/ArrayUtils;->isEmpty([Ljava/lang/Object;)Z
+Lcom/android/internal/util/ArrayUtils;->newUnpaddedArray(Ljava/lang/Class;I)[Ljava/lang/Object;
+Lcom/android/internal/util/ArrayUtils;->newUnpaddedIntArray(I)[I
+Lcom/android/internal/util/ArrayUtils;->removeElement(Ljava/lang/Class;[Ljava/lang/Object;Ljava/lang/Object;)[Ljava/lang/Object;
+Lcom/android/internal/util/BitwiseInputStream;-><init>([B)V
+Lcom/android/internal/util/BitwiseInputStream;->available()I
+Lcom/android/internal/util/BitwiseInputStream;->read(I)I
+Lcom/android/internal/util/BitwiseInputStream;->readByteArray(I)[B
+Lcom/android/internal/util/BitwiseInputStream;->skip(I)V
+Lcom/android/internal/util/BitwiseOutputStream;-><init>(I)V
+Lcom/android/internal/util/BitwiseOutputStream;->toByteArray()[B
+Lcom/android/internal/util/BitwiseOutputStream;->write(II)V
+Lcom/android/internal/util/BitwiseOutputStream;->writeByteArray(I[B)V
+Lcom/android/internal/util/CharSequences;->compareToIgnoreCase(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)I
+Lcom/android/internal/util/CharSequences;->equals(Ljava/lang/CharSequence;Ljava/lang/CharSequence;)Z
+Lcom/android/internal/util/FastMath;->round(F)I
+Lcom/android/internal/util/FastXmlSerializer;-><init>()V
+Lcom/android/internal/util/GrowingArrayUtils;->append([III)[I
+Lcom/android/internal/util/GrowingArrayUtils;->append([Ljava/lang/Object;ILjava/lang/Object;)[Ljava/lang/Object;
+Lcom/android/internal/util/HexDump;->hexStringToByteArray(Ljava/lang/String;)[B
+Lcom/android/internal/util/HexDump;->toHexString(I)Ljava/lang/String;
+Lcom/android/internal/util/HexDump;->toHexString([B)Ljava/lang/String;
+Lcom/android/internal/util/HexDump;->toHexString([BII)Ljava/lang/String;
Lcom/android/internal/util/HexDump;->toHexString([BZ)Ljava/lang/String;
+Lcom/android/internal/util/IState;->getName()Ljava/lang/String;
+Lcom/android/internal/util/MemInfoReader;-><init>()V
+Lcom/android/internal/util/MemInfoReader;->getCachedSize()J
+Lcom/android/internal/util/MemInfoReader;->getFreeSize()J
+Lcom/android/internal/util/MemInfoReader;->getRawInfo()[J
+Lcom/android/internal/util/MemInfoReader;->getTotalSize()J
+Lcom/android/internal/util/MemInfoReader;->readMemInfo()V
+Lcom/android/internal/util/Preconditions;->checkArgument(Z)V
+Lcom/android/internal/util/Preconditions;->checkArgument(ZLjava/lang/Object;)V
+Lcom/android/internal/util/Preconditions;->checkArgumentInRange(IIILjava/lang/String;)I
+Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;)Ljava/lang/Object;
+Lcom/android/internal/util/Preconditions;->checkNotNull(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+Lcom/android/internal/util/Preconditions;->checkState(Z)V
+Lcom/android/internal/util/Preconditions;->checkState(ZLjava/lang/String;)V
+Lcom/android/internal/util/State;-><init>()V
+Lcom/android/internal/util/State;->enter()V
+Lcom/android/internal/util/State;->exit()V
+Lcom/android/internal/util/State;->getName()Ljava/lang/String;
+Lcom/android/internal/util/State;->processMessage(Landroid/os/Message;)Z
+Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;)V
+Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Handler;)V
+Lcom/android/internal/util/StateMachine;-><init>(Ljava/lang/String;Landroid/os/Looper;)V
+Lcom/android/internal/util/StateMachine;->dump(Ljava/io/FileDescriptor;Ljava/io/PrintWriter;[Ljava/lang/String;)V
+Lcom/android/internal/util/StateMachine;->obtainMessage(III)Landroid/os/Message;
+Lcom/android/internal/util/StateMachine;->obtainMessage(IIILjava/lang/Object;)Landroid/os/Message;
+Lcom/android/internal/util/StateMachine;->sendMessage(I)V
+Lcom/android/internal/util/StateMachine;->sendMessage(II)V
+Lcom/android/internal/util/StateMachine;->sendMessage(IIILjava/lang/Object;)V
+Lcom/android/internal/util/StateMachine;->sendMessage(ILjava/lang/Object;)V
+Lcom/android/internal/util/StateMachine;->sendMessage(Landroid/os/Message;)V
+Lcom/android/internal/view/ActionBarPolicy;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/view/ActionBarPolicy;->get(Landroid/content/Context;)Lcom/android/internal/view/ActionBarPolicy;
+Lcom/android/internal/view/ActionBarPolicy;->getEmbeddedMenuWidthLimit()I
+Lcom/android/internal/view/ActionBarPolicy;->getMaxActionButtons()I
+Lcom/android/internal/view/ActionBarPolicy;->getStackedTabMaxWidth()I
+Lcom/android/internal/view/ActionBarPolicy;->getTabContainerHeight()I
+Lcom/android/internal/view/ActionBarPolicy;->hasEmbeddedTabs()Z
+Lcom/android/internal/view/ActionBarPolicy;->mContext:Landroid/content/Context;
+Lcom/android/internal/view/ActionBarPolicy;->showsOverflowMenuButton()Z
Lcom/android/internal/view/BaseIWindow;-><init>()V
Lcom/android/internal/view/IInputMethodManager$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
Lcom/android/internal/view/IInputMethodManager$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodManager;
Lcom/android/internal/view/IInputMethodSession$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/view/IInputMethodSession;
+Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->dispose()V
+Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;->getInstance()Lcom/android/internal/view/InputConnectionWrapper$InputContextCallback;
+Lcom/android/internal/view/menu/ActionMenu;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/view/menu/ActionMenuItem;-><init>(Landroid/content/Context;IIIILjava/lang/CharSequence;)V
+Lcom/android/internal/view/menu/ContextMenuBuilder;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/view/menu/IconMenuItemView;->getTextAppropriateLayoutParams()Lcom/android/internal/view/menu/IconMenuView$LayoutParams;
+Lcom/android/internal/view/menu/IconMenuItemView;->setIconMenuView(Lcom/android/internal/view/menu/IconMenuView;)V
+Lcom/android/internal/view/menu/IconMenuItemView;->setItemInvoker(Lcom/android/internal/view/menu/MenuBuilder$ItemInvoker;)V
+Lcom/android/internal/view/menu/IconMenuView$SavedState;-><init>(Landroid/os/Parcel;)V
+Lcom/android/internal/view/menu/IconMenuView;->createMoreItemView()Lcom/android/internal/view/menu/IconMenuItemView;
+Lcom/android/internal/view/menu/IconMenuView;->getNumActualItemsShown()I
+Lcom/android/internal/view/menu/IconMenuView;->mItemBackground:Landroid/graphics/drawable/Drawable;
+Lcom/android/internal/view/menu/IconMenuView;->mMaxItems:I
+Lcom/android/internal/view/menu/IconMenuView;->mMenu:Lcom/android/internal/view/menu/MenuBuilder;
+Lcom/android/internal/view/menu/MenuDialogHelper;-><init>(Lcom/android/internal/view/menu/MenuBuilder;)V
+Lcom/android/internal/view/menu/MenuDialogHelper;->dismiss()V
+Lcom/android/internal/view/menu/MenuDialogHelper;->show(Landroid/os/IBinder;)V
+Lcom/android/internal/view/WindowManagerPolicyThread;->getLooper()Landroid/os/Looper;
+Lcom/android/internal/widget/AbsActionBarView;->dismissPopupMenus()V
+Lcom/android/internal/widget/ActionBarContextView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+Lcom/android/internal/widget/ActionBarOverlayLayout;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+Lcom/android/internal/widget/ActionBarOverlayLayout;->setWindowCallback(Landroid/view/Window$Callback;)V
+Lcom/android/internal/widget/EditableInputConnection;-><init>(Landroid/widget/TextView;)V
Lcom/android/internal/widget/ILockSettings$Stub;->asInterface(Landroid/os/IBinder;)Lcom/android/internal/widget/ILockSettings;
Lcom/android/internal/widget/ILockSettings;->getBoolean(Ljava/lang/String;ZI)Z
Lcom/android/internal/widget/ILockSettings;->getLong(Ljava/lang/String;JI)J
@@ -2088,17 +4092,109 @@ Lcom/android/internal/widget/IRemoteViewsFactory;->getViewTypeCount()I
Lcom/android/internal/widget/IRemoteViewsFactory;->hasStableIds()Z
Lcom/android/internal/widget/IRemoteViewsFactory;->isCreated()Z
Lcom/android/internal/widget/IRemoteViewsFactory;->onDataSetChanged()V
+Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/widget/LinearLayoutWithDefaultTouchRecepient;->setDefaultTouchRecepient(Landroid/view/View;)V
+Lcom/android/internal/widget/LockPatternChecker;->checkPassword(Lcom/android/internal/widget/LockPatternUtils;Ljava/lang/String;ILcom/android/internal/widget/LockPatternChecker$OnCheckCallback;)Landroid/os/AsyncTask;
+Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;-><init>(I)V
+Lcom/android/internal/widget/LockPatternUtils$RequestThrottledException;->getTimeoutMs()I
+Lcom/android/internal/widget/LockPatternUtils;-><init>(Landroid/content/Context;)V
+Lcom/android/internal/widget/LockPatternUtils;->checkPassword(Ljava/lang/String;I)Z
+Lcom/android/internal/widget/LockPatternUtils;->getActivePasswordQuality(I)I
+Lcom/android/internal/widget/LockPatternUtils;->getDevicePolicyManager()Landroid/app/admin/DevicePolicyManager;
+Lcom/android/internal/widget/LockPatternUtils;->getKeyguardStoredPasswordQuality(I)I
+Lcom/android/internal/widget/LockPatternUtils;->getLockSettings()Lcom/android/internal/widget/ILockSettings;
+Lcom/android/internal/widget/LockPatternUtils;->getOwnerInfo(I)Ljava/lang/String;
+Lcom/android/internal/widget/LockPatternUtils;->getPowerButtonInstantlyLocks(I)Z
+Lcom/android/internal/widget/LockPatternUtils;->getString(Ljava/lang/String;I)Ljava/lang/String;
+Lcom/android/internal/widget/LockPatternUtils;->isDeviceEncryptionEnabled()Z
+Lcom/android/internal/widget/LockPatternUtils;->isLockPasswordEnabled(I)Z
+Lcom/android/internal/widget/LockPatternUtils;->isLockPatternEnabled(I)Z
+Lcom/android/internal/widget/LockPatternUtils;->isLockScreenDisabled(I)Z
+Lcom/android/internal/widget/LockPatternUtils;->isSecure(I)Z
+Lcom/android/internal/widget/LockPatternUtils;->isTactileFeedbackEnabled()Z
+Lcom/android/internal/widget/LockPatternUtils;->isVisiblePatternEnabled(I)Z
+Lcom/android/internal/widget/LockPatternUtils;->mContentResolver:Landroid/content/ContentResolver;
+Lcom/android/internal/widget/LockPatternUtils;->mContext:Landroid/content/Context;
+Lcom/android/internal/widget/LockPatternUtils;->patternToHash(Ljava/util/List;)[B
+Lcom/android/internal/widget/LockPatternUtils;->patternToString(Ljava/util/List;)Ljava/lang/String;
+Lcom/android/internal/widget/LockPatternUtils;->reportFailedPasswordAttempt(I)V
+Lcom/android/internal/widget/LockPatternUtils;->reportSuccessfulPasswordAttempt(I)V
+Lcom/android/internal/widget/LockPatternUtils;->saveLockPassword(Ljava/lang/String;Ljava/lang/String;II)V
+Lcom/android/internal/widget/LockPatternUtils;->setLockoutAttemptDeadline(II)J
+Lcom/android/internal/widget/LockPatternUtils;->setLong(Ljava/lang/String;JI)V
+Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfo(Ljava/lang/String;I)V
+Lcom/android/internal/widget/LockPatternUtils;->setOwnerInfoEnabled(ZI)V
+Lcom/android/internal/widget/LockPatternUtils;->setString(Ljava/lang/String;Ljava/lang/String;I)V
+Lcom/android/internal/widget/LockPatternView$Cell;->column:I
+Lcom/android/internal/widget/LockPatternView$Cell;->row:I
+Lcom/android/internal/widget/LockPatternView$DisplayMode;->Animate:Lcom/android/internal/widget/LockPatternView$DisplayMode;
+Lcom/android/internal/widget/LockPatternView$DisplayMode;->Correct:Lcom/android/internal/widget/LockPatternView$DisplayMode;
+Lcom/android/internal/widget/LockPatternView$DisplayMode;->Wrong:Lcom/android/internal/widget/LockPatternView$DisplayMode;
+Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcel;)V
+Lcom/android/internal/widget/LockPatternView$SavedState;-><init>(Landroid/os/Parcelable;Ljava/lang/String;IZZZ)V
+Lcom/android/internal/widget/LockPatternView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+Lcom/android/internal/widget/LockPatternView;->clearPattern()V
+Lcom/android/internal/widget/LockPatternView;->disableInput()V
+Lcom/android/internal/widget/LockPatternView;->enableInput()V
+Lcom/android/internal/widget/LockPatternView;->getCellStates()[[Lcom/android/internal/widget/LockPatternView$CellState;
+Lcom/android/internal/widget/LockPatternView;->mInStealthMode:Z
+Lcom/android/internal/widget/LockPatternView;->mPaint:Landroid/graphics/Paint;
+Lcom/android/internal/widget/LockPatternView;->mPathPaint:Landroid/graphics/Paint;
+Lcom/android/internal/widget/LockPatternView;->mPattern:Ljava/util/ArrayList;
+Lcom/android/internal/widget/LockPatternView;->mPatternDisplayMode:Lcom/android/internal/widget/LockPatternView$DisplayMode;
+Lcom/android/internal/widget/LockPatternView;->mPatternInProgress:Z
+Lcom/android/internal/widget/LockPatternView;->mSquareHeight:F
+Lcom/android/internal/widget/LockPatternView;->mSquareWidth:F
+Lcom/android/internal/widget/LockPatternView;->notifyPatternDetected()V
+Lcom/android/internal/widget/LockPatternView;->setDisplayMode(Lcom/android/internal/widget/LockPatternView$DisplayMode;)V
+Lcom/android/internal/widget/LockPatternView;->setInStealthMode(Z)V
+Lcom/android/internal/widget/LockPatternView;->setOnPatternListener(Lcom/android/internal/widget/LockPatternView$OnPatternListener;)V
+Lcom/android/internal/widget/LockPatternView;->setTactileFeedbackEnabled(Z)V
+Lcom/android/internal/widget/PointerLocationView$PointerState;-><init>()V
+Lcom/android/internal/widget/PointerLocationView$PointerState;->mCurDown:Z
+Lcom/android/internal/widget/PointerLocationView;->mCurDown:Z
+Lcom/android/internal/widget/PointerLocationView;->mCurNumPointers:I
+Lcom/android/internal/widget/PointerLocationView;->mMaxNumPointers:I
+Lcom/android/internal/widget/PointerLocationView;->mPointers:Ljava/util/ArrayList;
+Lcom/android/internal/widget/PointerLocationView;->mPrintCoords:Z
+Lcom/android/internal/widget/PreferenceImageView;-><init>(Landroid/content/Context;Landroid/util/AttributeSet;)V
+Lcom/android/internal/widget/RecyclerView$RecycledViewPool$ScrapData;->mScrapHeap:Ljava/util/ArrayList;
Lcom/android/internal/widget/ScrollBarUtils;->getThumbLength(IIII)I
+Lcom/android/internal/widget/SlidingTab$Slider;->tab:Landroid/widget/ImageView;
+Lcom/android/internal/widget/SlidingTab$Slider;->text:Landroid/widget/TextView;
+Lcom/android/internal/widget/SlidingTab;->mAnimationDoneListener:Landroid/view/animation/Animation$AnimationListener;
+Lcom/android/internal/widget/SlidingTab;->mLeftSlider:Lcom/android/internal/widget/SlidingTab$Slider;
+Lcom/android/internal/widget/SlidingTab;->mRightSlider:Lcom/android/internal/widget/SlidingTab$Slider;
+Lcom/android/internal/widget/SlidingTab;->onAnimationDone()V
+Lcom/android/internal/widget/SlidingTab;->resetView()V
+Lcom/android/internal/widget/SlidingTab;->setHoldAfterTrigger(ZZ)V
+Lcom/android/internal/widget/SlidingTab;->setLeftHintText(I)V
+Lcom/android/internal/widget/SlidingTab;->setLeftTabResources(IIII)V
+Lcom/android/internal/widget/SlidingTab;->setOnTriggerListener(Lcom/android/internal/widget/SlidingTab$OnTriggerListener;)V
+Lcom/android/internal/widget/SlidingTab;->setRightHintText(I)V
+Lcom/android/internal/widget/SlidingTab;->setRightTabResources(IIII)V
+Lcom/android/internal/widget/TextViewInputDisabler;-><init>(Landroid/widget/TextView;)V
+Lcom/android/internal/widget/TextViewInputDisabler;->setInputEnabled(Z)V
+Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrolled(IFI)V
+Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageScrollStateChanged(I)V
+Lcom/android/internal/widget/ViewPager$OnPageChangeListener;->onPageSelected(I)V
+Lcom/android/internal/widget/ViewPager;->getCurrentItem()I
Lcom/android/okhttp/Connection;->getSocket()Ljava/net/Socket;
Lcom/android/okhttp/ConnectionPool;->connections:Ljava/util/Deque;
Lcom/android/okhttp/ConnectionPool;->keepAliveDurationNs:J
Lcom/android/okhttp/ConnectionPool;->maxIdleConnections:I
Lcom/android/okhttp/ConnectionPool;->systemDefault:Lcom/android/okhttp/ConnectionPool;
+Lcom/android/okhttp/HttpHandler;-><init>()V
+Lcom/android/okhttp/HttpsHandler;-><init>()V
Lcom/android/okhttp/HttpUrl$Builder;->build()Lcom/android/okhttp/HttpUrl;
Lcom/android/okhttp/HttpUrl;->encodedPath()Ljava/lang/String;
Lcom/android/okhttp/HttpUrl;->newBuilder()Lcom/android/okhttp/HttpUrl$Builder;
Lcom/android/okhttp/HttpUrl;->parse(Ljava/lang/String;)Lcom/android/okhttp/HttpUrl;
Lcom/android/okhttp/HttpUrl;->query()Ljava/lang/String;
+Lcom/android/okhttp/internal/http/HeaderParser;->skipUntil(Ljava/lang/String;ILjava/lang/String;)I
+Lcom/android/okhttp/internal/http/HeaderParser;->skipWhitespace(Ljava/lang/String;I)I
+Lcom/android/okhttp/internal/http/HttpDate;->format(Ljava/util/Date;)Ljava/lang/String;
+Lcom/android/okhttp/internal/http/HttpDate;->parse(Ljava/lang/String;)Ljava/util/Date;
Lcom/android/okhttp/internal/http/HttpEngine;->getConnection()Lcom/android/okhttp/Connection;
Lcom/android/okhttp/internal/http/HttpEngine;->hasResponse()Z
Lcom/android/okhttp/internal/http/HttpEngine;->httpStream:Lcom/android/okhttp/internal/http/HttpStream;
@@ -2111,6 +4207,29 @@ Lcom/android/okhttp/internal/http/HttpEngine;->sentRequestMillis:J
Lcom/android/okhttp/internal/http/HttpEngine;->userResponse:Lcom/android/okhttp/Response;
Lcom/android/okhttp/internal/http/HttpEngine;->writingRequestHeaders()V
Lcom/android/okhttp/internal/http/RouteSelector;->hasNext()Z
+Lcom/android/okhttp/internal/huc/HttpsURLConnectionImpl;->delegate:Lcom/android/okhttp/internal/huc/HttpURLConnectionImpl;
+Lcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->client:Lcom/android/okhttp/OkHttpClient;
+Lcom/android/okhttp/internal/huc/HttpURLConnectionImpl;->httpEngine:Lcom/android/okhttp/internal/http/HttpEngine;
+Lcom/android/okhttp/internal/Internal;-><init>()V
+Lcom/android/okhttp/internal/Internal;->addLenient(Lcom/android/okhttp/Headers$Builder;Ljava/lang/String;)V
+Lcom/android/okhttp/internal/Internal;->addLenient(Lcom/android/okhttp/Headers$Builder;Ljava/lang/String;Ljava/lang/String;)V
+Lcom/android/okhttp/internal/Internal;->apply(Lcom/android/okhttp/ConnectionSpec;Ljavax/net/ssl/SSLSocket;Z)V
+Lcom/android/okhttp/internal/Internal;->callEngineGetStreamAllocation(Lcom/android/okhttp/Call;)Lcom/android/okhttp/internal/http/StreamAllocation;
+Lcom/android/okhttp/internal/Internal;->callEnqueue(Lcom/android/okhttp/Call;Lcom/android/okhttp/Callback;Z)V
+Lcom/android/okhttp/internal/Internal;->connectionBecameIdle(Lcom/android/okhttp/ConnectionPool;Lcom/android/okhttp/internal/io/RealConnection;)Z
+Lcom/android/okhttp/internal/Internal;->get(Lcom/android/okhttp/ConnectionPool;Lcom/android/okhttp/Address;Lcom/android/okhttp/internal/http/StreamAllocation;)Lcom/android/okhttp/internal/io/RealConnection;
+Lcom/android/okhttp/internal/Internal;->getHttpUrlChecked(Ljava/lang/String;)Lcom/android/okhttp/HttpUrl;
+Lcom/android/okhttp/internal/Internal;->instance:Lcom/android/okhttp/internal/Internal;
+Lcom/android/okhttp/internal/Internal;->internalCache(Lcom/android/okhttp/OkHttpClient;)Lcom/android/okhttp/internal/InternalCache;
+Lcom/android/okhttp/internal/Internal;->put(Lcom/android/okhttp/ConnectionPool;Lcom/android/okhttp/internal/io/RealConnection;)V
+Lcom/android/okhttp/internal/Internal;->routeDatabase(Lcom/android/okhttp/ConnectionPool;)Lcom/android/okhttp/internal/RouteDatabase;
+Lcom/android/okhttp/internal/Internal;->setCache(Lcom/android/okhttp/OkHttpClient;Lcom/android/okhttp/internal/InternalCache;)V
+Lcom/android/okhttp/internal/Platform;->get()Lcom/android/okhttp/internal/Platform;
+Lcom/android/okhttp/internal/Platform;->logW(Ljava/lang/String;)V
+Lcom/android/okhttp/internal/Util;->closeAll(Ljava/io/Closeable;Ljava/io/Closeable;)V
+Lcom/android/okhttp/internal/Util;->closeQuietly(Ljava/io/Closeable;)V
+Lcom/android/okhttp/internal/Util;->EMPTY_BYTE_ARRAY:[B
+Lcom/android/okhttp/internal/Util;->UTF_8:Ljava/nio/charset/Charset;
Lcom/android/okhttp/OkHttpClient;-><init>()V
Lcom/android/okhttp/OkHttpClient;->connectionPool:Lcom/android/okhttp/ConnectionPool;
Lcom/android/okhttp/OkHttpClient;->DEFAULT_PROTOCOLS:Ljava/util/List;
@@ -2131,6 +4250,59 @@ Lcom/android/okhttp/Response;->headers:Lcom/android/okhttp/Headers;
Lcom/android/okhttp/Response;->message:Ljava/lang/String;
Lcom/android/okhttp/Response;->networkResponse:Lcom/android/okhttp/Response;
Lcom/android/okhttp/Response;->protocol:Lcom/android/okhttp/Protocol;
+Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;-><init>()V
+Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;->add(Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V
+Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>(Ljava/io/InputStream;)V
+Lcom/android/org/bouncycastle/asn1/ASN1InputStream;-><init>([B)V
+Lcom/android/org/bouncycastle/asn1/ASN1InputStream;->readObject()Lcom/android/org/bouncycastle/asn1/ASN1Primitive;
+Lcom/android/org/bouncycastle/asn1/ASN1Integer;-><init>(Ljava/math/BigInteger;)V
+Lcom/android/org/bouncycastle/asn1/DERBitString;-><init>([B)V
+Lcom/android/org/bouncycastle/asn1/DEREncodableVector;-><init>()V
+Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(J)V
+Lcom/android/org/bouncycastle/asn1/DERInteger;-><init>(Ljava/math/BigInteger;)V
+Lcom/android/org/bouncycastle/asn1/DERNull;->INSTANCE:Lcom/android/org/bouncycastle/asn1/DERNull;
+Lcom/android/org/bouncycastle/asn1/DERObjectIdentifier;-><init>(Ljava/lang/String;)V
+Lcom/android/org/bouncycastle/asn1/DEROctetString;-><init>([B)V
+Lcom/android/org/bouncycastle/asn1/DEROutputStream;-><init>(Ljava/io/OutputStream;)V
+Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>()V
+Lcom/android/org/bouncycastle/asn1/DERSequence;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V
+Lcom/android/org/bouncycastle/asn1/DERSet;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1EncodableVector;)V
+Lcom/android/org/bouncycastle/asn1/pkcs/PKCSObjectIdentifiers;->sha256WithRSAEncryption:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;
+Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;)V
+Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;Lcom/android/org/bouncycastle/asn1/ASN1Encodable;)V
+Lcom/android/org/bouncycastle/asn1/x509/Certificate;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/Certificate;
+Lcom/android/org/bouncycastle/asn1/x509/DigestInfo;-><init>(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;[B)V
+Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;->getInstance(Ljava/lang/Object;)Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;
+Lcom/android/org/bouncycastle/asn1/x509/Time;-><init>(Ljava/util/Date;)V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;-><init>()V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->generateTBSCertificate()Lcom/android/org/bouncycastle/asn1/x509/TBSCertificate;
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setEndDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setIssuer(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSerialNumber(Lcom/android/org/bouncycastle/asn1/ASN1Integer;)V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSignature(Lcom/android/org/bouncycastle/asn1/x509/AlgorithmIdentifier;)V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setStartDate(Lcom/android/org/bouncycastle/asn1/x509/Time;)V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubject(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
+Lcom/android/org/bouncycastle/asn1/x509/V3TBSCertificateGenerator;->setSubjectPublicKeyInfo(Lcom/android/org/bouncycastle/asn1/x509/SubjectPublicKeyInfo;)V
+Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Lcom/android/org/bouncycastle/asn1/ASN1Sequence;)V
+Lcom/android/org/bouncycastle/asn1/x509/X509Name;-><init>(Ljava/lang/String;)V
+Lcom/android/org/bouncycastle/asn1/x509/X509Name;->CN:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;
+Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getOIDs()Ljava/util/Vector;
+Lcom/android/org/bouncycastle/asn1/x509/X509Name;->getValues()Ljava/util/Vector;
+Lcom/android/org/bouncycastle/asn1/x9/X9ObjectIdentifiers;->ecdsa_with_SHA256:Lcom/android/org/bouncycastle/asn1/ASN1ObjectIdentifier;
+Lcom/android/org/bouncycastle/jce/provider/BouncyCastleProvider;-><init>()V
+Lcom/android/org/bouncycastle/jce/provider/X509CertificateObject;-><init>(Lcom/android/org/bouncycastle/asn1/x509/Certificate;)V
+Lcom/android/org/bouncycastle/jce/X509Principal;-><init>([B)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;-><init>()V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->generate(Ljava/security/PrivateKey;)Ljava/security/cert/X509Certificate;
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setIssuerDN(Ljavax/security/auth/x500/X500Principal;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotAfter(Ljava/util/Date;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setNotBefore(Ljava/util/Date;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setPublicKey(Ljava/security/PublicKey;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSerialNumber(Ljava/math/BigInteger;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSignatureAlgorithm(Ljava/lang/String;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Lcom/android/org/bouncycastle/asn1/x509/X509Name;)V
+Lcom/android/org/bouncycastle/x509/X509V3CertificateGenerator;->setSubjectDN(Ljavax/security/auth/x500/X500Principal;)V
Lcom/android/org/conscrypt/AbstractConscryptSocket;->getAlpnSelectedProtocol()[B
Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocol()Ljava/lang/String;
Lcom/android/org/conscrypt/AbstractConscryptSocket;->getApplicationProtocols()[Ljava/lang/String;
@@ -2150,14 +4322,73 @@ Lcom/android/org/conscrypt/AbstractConscryptSocket;->setHostname(Ljava/lang/Stri
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setNpnProtocols([B)V
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setSoWriteTimeout(I)V
Lcom/android/org/conscrypt/AbstractConscryptSocket;->setUseSessionTickets(Z)V
+Lcom/android/org/conscrypt/ClientSessionContext;->getSession(Ljava/lang/String;I)Lcom/android/org/conscrypt/NativeSslSession;
+Lcom/android/org/conscrypt/ClientSessionContext;->setPersistentCache(Lcom/android/org/conscrypt/SSLClientSessionCache;)V
Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setHostname(Ljava/lang/String;)V
Lcom/android/org/conscrypt/ConscryptFileDescriptorSocket;->setUseSessionTickets(Z)V
+Lcom/android/org/conscrypt/FileClientSessionCache$Impl;->getSessionData(Ljava/lang/String;I)[B
+Lcom/android/org/conscrypt/FileClientSessionCache;->usingDirectory(Ljava/io/File;)Lcom/android/org/conscrypt/SSLClientSessionCache;
+Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_pack_X509([J)[B
+Lcom/android/org/conscrypt/NativeCrypto;->ASN1_seq_unpack_X509_bio(J)[J
+Lcom/android/org/conscrypt/NativeCrypto;->ASN1_TIME_to_Calendar(JLjava/util/Calendar;)V
+Lcom/android/org/conscrypt/NativeCrypto;->BIO_free_all(J)V
+Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_InputStream(Lcom/android/org/conscrypt/OpenSSLBIOInputStream;Z)J
+Lcom/android/org/conscrypt/NativeCrypto;->create_BIO_OutputStream(Ljava/io/OutputStream;)J
+Lcom/android/org/conscrypt/NativeCrypto;->d2i_PKCS7_bio(JI)[J
+Lcom/android/org/conscrypt/NativeCrypto;->d2i_SSL_SESSION([B)J
+Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509([B)J
+Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_bio(J)J
+Lcom/android/org/conscrypt/NativeCrypto;->d2i_X509_CRL_bio(J)J
+Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_clear_free(J)V
+Lcom/android/org/conscrypt/NativeCrypto;->EC_GROUP_new_by_curve_name(Ljava/lang/String;)J
+Lcom/android/org/conscrypt/NativeCrypto;->EC_POINT_clear_free(J)V
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_CTX_new()J
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_CIPHER_iv_length(J)I
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_cipherbyname(Ljava/lang/String;)J
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_get_digestbyname(Ljava/lang/String;)J
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_create()J
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_CTX_destroy(J)V
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_MD_size(J)I
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_free(J)V
+Lcom/android/org/conscrypt/NativeCrypto;->EVP_PKEY_new_RSA([B[B[B[B[B[B[B[B)J
+Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_ext_oids(JI)[Ljava/lang/String;
+Lcom/android/org/conscrypt/NativeCrypto;->get_X509_REVOKED_revocationDate(J)J
+Lcom/android/org/conscrypt/NativeCrypto;->i2d_PKCS7([J)[B
+Lcom/android/org/conscrypt/NativeCrypto;->i2d_SSL_SESSION(J)[B
+Lcom/android/org/conscrypt/NativeCrypto;->i2d_X509_REVOKED(J)[B
+Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_PKCS7(JI)[J
+Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509(J)J
+Lcom/android/org/conscrypt/NativeCrypto;->PEM_read_bio_X509_CRL(J)J
+Lcom/android/org/conscrypt/NativeCrypto;->RAND_bytes([B)V
+Lcom/android/org/conscrypt/NativeCrypto;->RSA_generate_key_ex(I[B)J
+Lcom/android/org/conscrypt/NativeCrypto;->SSL_CTX_new()J
+Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_cipher(J)Ljava/lang/String;
+Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_free(J)V
+Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_time(J)J
+Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_get_version(J)Ljava/lang/String;
+Lcom/android/org/conscrypt/NativeCrypto;->SSL_SESSION_session_id(J)[B
+Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_dup(J)J
+Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext(JLjava/lang/String;)J
+Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_ext_oid(JLjava/lang/String;)[B
+Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_get_serialNumber(J)[B
+Lcom/android/org/conscrypt/NativeCrypto;->X509_REVOKED_print(JJ)V
+Lcom/android/org/conscrypt/NativeCrypto;->X509_supported_extension(J)I
+Lcom/android/org/conscrypt/OpenSSLBIOInputStream;-><init>(Ljava/io/InputStream;Z)V
+Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->getBioContext()J
+Lcom/android/org/conscrypt/OpenSSLBIOInputStream;->release()V
+Lcom/android/org/conscrypt/OpenSSLContextImpl$TLSv12;-><init>()V
+Lcom/android/org/conscrypt/OpenSSLContextImpl;-><init>()V
+Lcom/android/org/conscrypt/OpenSSLContextImpl;->engineGetClientSessionContext()Lcom/android/org/conscrypt/ClientSessionContext;
+Lcom/android/org/conscrypt/OpenSSLContextImpl;->getPreferred()Lcom/android/org/conscrypt/OpenSSLContextImpl;
Lcom/android/org/conscrypt/OpenSSLKey;-><init>(J)V
Lcom/android/org/conscrypt/OpenSSLKey;->fromPrivateKey(Ljava/security/PrivateKey;)Lcom/android/org/conscrypt/OpenSSLKey;
Lcom/android/org/conscrypt/OpenSSLKey;->getNativeRef()Lcom/android/org/conscrypt/NativeRef$EVP_PKEY;
Lcom/android/org/conscrypt/OpenSSLKey;->getPublicKey()Ljava/security/PublicKey;
+Lcom/android/org/conscrypt/OpenSSLKeyHolder;->getOpenSSLKey()Lcom/android/org/conscrypt/OpenSSLKey;
Lcom/android/org/conscrypt/OpenSSLProvider;-><init>()V
Lcom/android/org/conscrypt/OpenSSLRandom;-><init>()V
+Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;-><init>()V
+Lcom/android/org/conscrypt/OpenSSLSocketFactoryImpl;->sslParameters:Lcom/android/org/conscrypt/SSLParametersImpl;
Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getAlpnSelectedProtocol()[B
Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getChannelId()[B
Lcom/android/org/conscrypt/OpenSSLSocketImpl;->getHostname()Ljava/lang/String;
@@ -2175,32 +4406,83 @@ Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setSoWriteTimeout(I)V
Lcom/android/org/conscrypt/OpenSSLSocketImpl;->setUseSessionTickets(Z)V
Lcom/android/org/conscrypt/OpenSSLX509Certificate;->fromX509PemInputStream(Ljava/io/InputStream;)Lcom/android/org/conscrypt/OpenSSLX509Certificate;
Lcom/android/org/conscrypt/OpenSSLX509Certificate;->mContext:J
+Lcom/android/org/conscrypt/SSLParametersImpl;->getDefault()Lcom/android/org/conscrypt/SSLParametersImpl;
+Lcom/android/org/conscrypt/SSLParametersImpl;->getDefaultX509TrustManager()Ljavax/net/ssl/X509TrustManager;
+Lcom/android/org/conscrypt/SSLParametersImpl;->getX509TrustManager()Ljavax/net/ssl/X509TrustManager;
+Lcom/android/org/conscrypt/SSLParametersImpl;->setEnabledProtocols([Ljava/lang/String;)V
+Lcom/android/org/conscrypt/SSLParametersImpl;->x509TrustManager:Ljavax/net/ssl/X509TrustManager;
Lcom/android/org/conscrypt/TrustedCertificateStore;-><init>()V
Lcom/android/org/conscrypt/TrustedCertificateStore;->getCertificateChain(Ljava/security/cert/X509Certificate;)Ljava/util/List;
Lcom/android/org/conscrypt/TrustManagerImpl;-><init>(Ljava/security/KeyStore;)V
Lcom/android/org/conscrypt/TrustManagerImpl;->checkServerTrusted([Ljava/security/cert/X509Certificate;Ljava/lang/String;Ljava/lang/String;)Ljava/util/List;
+Lcom/android/org/conscrypt/X509PublicKey;-><init>(Ljava/lang/String;[B)V
+Lcom/android/server/net/BaseNetworkObserver;-><init>()V
+Lcom/android/server/net/NetlinkTracker;-><init>(Ljava/lang/String;Lcom/android/server/net/NetlinkTracker$Callback;)V
+Lcom/android/server/net/NetlinkTracker;->clearLinkProperties()V
+Lcom/android/server/net/NetlinkTracker;->getLinkProperties()Landroid/net/LinkProperties;
+Lcom/android/server/ResettableTimeout$T;-><init>(Lcom/android/server/ResettableTimeout;)V
+Lcom/android/server/ResettableTimeout;->mLock:Landroid/os/ConditionVariable;
+Lcom/android/server/ResettableTimeout;->mOffAt:J
+Lcom/google/android/collect/Lists;->newArrayList([Ljava/lang/Object;)Ljava/util/ArrayList;
+Lcom/google/android/collect/Sets;->newArraySet()Landroid/util/ArraySet;
+Lcom/google/android/collect/Sets;->newArraySet([Ljava/lang/Object;)Landroid/util/ArraySet;
+Lcom/google/android/collect/Sets;->newHashSet()Ljava/util/HashSet;
+Lcom/google/android/collect/Sets;->newHashSet([Ljava/lang/Object;)Ljava/util/HashSet;
+Lcom/google/android/collect/Sets;->newSortedSet()Ljava/util/SortedSet;
+Lcom/google/android/gles_jni/EGLImpl;-><init>()V
+Lcom/google/android/gles_jni/GLImpl;-><init>()V
Lcom/google/android/mms/ContentType;->getAudioTypes()Ljava/util/ArrayList;
Lcom/google/android/mms/ContentType;->getImageTypes()Ljava/util/ArrayList;
Lcom/google/android/mms/ContentType;->getVideoTypes()Ljava/util/ArrayList;
Lcom/google/android/mms/ContentType;->isAudioType(Ljava/lang/String;)Z
Lcom/google/android/mms/ContentType;->isDrmType(Ljava/lang/String;)Z
Lcom/google/android/mms/ContentType;->isImageType(Ljava/lang/String;)Z
+Lcom/google/android/mms/ContentType;->isSupportedAudioType(Ljava/lang/String;)Z
+Lcom/google/android/mms/ContentType;->isSupportedImageType(Ljava/lang/String;)Z
+Lcom/google/android/mms/ContentType;->isSupportedType(Ljava/lang/String;)Z
+Lcom/google/android/mms/ContentType;->isSupportedVideoType(Ljava/lang/String;)Z
Lcom/google/android/mms/ContentType;->isTextType(Ljava/lang/String;)Z
Lcom/google/android/mms/ContentType;->isVideoType(Ljava/lang/String;)Z
+Lcom/google/android/mms/InvalidHeaderValueException;-><init>(Ljava/lang/String;)V
Lcom/google/android/mms/MmsException;-><init>()V
Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/String;)V
+Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/String;Ljava/lang/Throwable;)V
Lcom/google/android/mms/MmsException;-><init>(Ljava/lang/Throwable;)V
Lcom/google/android/mms/pdu/AcknowledgeInd;-><init>(I[B)V
+Lcom/google/android/mms/pdu/AcknowledgeInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
+Lcom/google/android/mms/pdu/AcknowledgeInd;->setReportAllowed(I)V
+Lcom/google/android/mms/pdu/AcknowledgeInd;->setTransactionId([B)V
+Lcom/google/android/mms/pdu/Base64;->decodeBase64([B)[B
+Lcom/google/android/mms/pdu/CharacterSets;->getMibEnumValue(Ljava/lang/String;)I
Lcom/google/android/mms/pdu/CharacterSets;->getMimeName(I)Ljava/lang/String;
+Lcom/google/android/mms/pdu/DeliveryInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
+Lcom/google/android/mms/pdu/DeliveryInd;->getDate()J
Lcom/google/android/mms/pdu/DeliveryInd;->getMessageId()[B
+Lcom/google/android/mms/pdu/DeliveryInd;->getStatus()I
+Lcom/google/android/mms/pdu/DeliveryInd;->getTo()[Lcom/google/android/mms/pdu/EncodedStringValue;
Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(I[B)V
Lcom/google/android/mms/pdu/EncodedStringValue;-><init>(Ljava/lang/String;)V
Lcom/google/android/mms/pdu/EncodedStringValue;-><init>([B)V
+Lcom/google/android/mms/pdu/EncodedStringValue;->appendTextString([B)V
Lcom/google/android/mms/pdu/EncodedStringValue;->concat([Lcom/google/android/mms/pdu/EncodedStringValue;)Ljava/lang/String;
+Lcom/google/android/mms/pdu/EncodedStringValue;->copy(Lcom/google/android/mms/pdu/EncodedStringValue;)Lcom/google/android/mms/pdu/EncodedStringValue;
Lcom/google/android/mms/pdu/EncodedStringValue;->encodeStrings([Ljava/lang/String;)[Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/EncodedStringValue;->extract(Ljava/lang/String;)[Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/EncodedStringValue;->getCharacterSet()I
Lcom/google/android/mms/pdu/EncodedStringValue;->getString()Ljava/lang/String;
+Lcom/google/android/mms/pdu/EncodedStringValue;->getTextString()[B
+Lcom/google/android/mms/pdu/EncodedStringValue;->setCharacterSet(I)V
+Lcom/google/android/mms/pdu/EncodedStringValue;->setTextString([B)V
+Lcom/google/android/mms/pdu/GenericPdu;-><init>()V
+Lcom/google/android/mms/pdu/GenericPdu;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue;
Lcom/google/android/mms/pdu/GenericPdu;->getMessageType()I
+Lcom/google/android/mms/pdu/GenericPdu;->getPduHeaders()Lcom/google/android/mms/pdu/PduHeaders;
+Lcom/google/android/mms/pdu/GenericPdu;->mPduHeaders:Lcom/google/android/mms/pdu/PduHeaders;
Lcom/google/android/mms/pdu/GenericPdu;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/GenericPdu;->setMessageType(I)V
+Lcom/google/android/mms/pdu/MultimediaMessagePdu;-><init>()V
+Lcom/google/android/mms/pdu/MultimediaMessagePdu;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V
+Lcom/google/android/mms/pdu/MultimediaMessagePdu;->addTo(Lcom/google/android/mms/pdu/EncodedStringValue;)V
Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getBody()Lcom/google/android/mms/pdu/PduBody;
Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getDate()J
Lcom/google/android/mms/pdu/MultimediaMessagePdu;->getPriority()I
@@ -2210,15 +4492,31 @@ Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setBody(Lcom/google/android/m
Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setDate(J)V
Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setPriority(I)V
Lcom/google/android/mms/pdu/MultimediaMessagePdu;->setSubject(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/NotificationInd;-><init>()V
+Lcom/google/android/mms/pdu/NotificationInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
+Lcom/google/android/mms/pdu/NotificationInd;->getContentClass()I
Lcom/google/android/mms/pdu/NotificationInd;->getContentLocation()[B
+Lcom/google/android/mms/pdu/NotificationInd;->getDeliveryReport()I
Lcom/google/android/mms/pdu/NotificationInd;->getExpiry()J
Lcom/google/android/mms/pdu/NotificationInd;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue;
Lcom/google/android/mms/pdu/NotificationInd;->getMessageClass()[B
Lcom/google/android/mms/pdu/NotificationInd;->getMessageSize()J
Lcom/google/android/mms/pdu/NotificationInd;->getSubject()Lcom/google/android/mms/pdu/EncodedStringValue;
Lcom/google/android/mms/pdu/NotificationInd;->getTransactionId()[B
+Lcom/google/android/mms/pdu/NotificationInd;->setContentClass(I)V
Lcom/google/android/mms/pdu/NotificationInd;->setContentLocation([B)V
+Lcom/google/android/mms/pdu/NotificationInd;->setDeliveryReport(I)V
+Lcom/google/android/mms/pdu/NotificationInd;->setExpiry(J)V
+Lcom/google/android/mms/pdu/NotificationInd;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/NotificationInd;->setMessageClass([B)V
+Lcom/google/android/mms/pdu/NotificationInd;->setMessageSize(J)V
+Lcom/google/android/mms/pdu/NotificationInd;->setSubject(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/NotificationInd;->setTransactionId([B)V
Lcom/google/android/mms/pdu/NotifyRespInd;-><init>(I[BI)V
+Lcom/google/android/mms/pdu/NotifyRespInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
+Lcom/google/android/mms/pdu/NotifyRespInd;->setReportAllowed(I)V
+Lcom/google/android/mms/pdu/NotifyRespInd;->setStatus(I)V
+Lcom/google/android/mms/pdu/NotifyRespInd;->setTransactionId([B)V
Lcom/google/android/mms/pdu/PduBody;-><init>()V
Lcom/google/android/mms/pdu/PduBody;->addPart(ILcom/google/android/mms/pdu/PduPart;)V
Lcom/google/android/mms/pdu/PduBody;->addPart(Lcom/google/android/mms/pdu/PduPart;)Z
@@ -2227,62 +4525,1114 @@ Lcom/google/android/mms/pdu/PduBody;->getPartByContentId(Ljava/lang/String;)Lcom
Lcom/google/android/mms/pdu/PduBody;->getPartByContentLocation(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart;
Lcom/google/android/mms/pdu/PduBody;->getPartByFileName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart;
Lcom/google/android/mms/pdu/PduBody;->getPartByName(Ljava/lang/String;)Lcom/google/android/mms/pdu/PduPart;
+Lcom/google/android/mms/pdu/PduBody;->getPartIndex(Lcom/google/android/mms/pdu/PduPart;)I
Lcom/google/android/mms/pdu/PduBody;->getPartsNum()I
+Lcom/google/android/mms/pdu/PduBody;->removePart(I)Lcom/google/android/mms/pdu/PduPart;
+Lcom/google/android/mms/pdu/PduComposer$BufferStack;->copy()V
+Lcom/google/android/mms/pdu/PduComposer$BufferStack;->mark()Lcom/google/android/mms/pdu/PduComposer$PositionMarker;
+Lcom/google/android/mms/pdu/PduComposer$BufferStack;->newbuf()V
+Lcom/google/android/mms/pdu/PduComposer$BufferStack;->pop()V
+Lcom/google/android/mms/pdu/PduComposer$PositionMarker;->getLength()I
Lcom/google/android/mms/pdu/PduComposer;-><init>(Landroid/content/Context;Lcom/google/android/mms/pdu/GenericPdu;)V
+Lcom/google/android/mms/pdu/PduComposer;->appendEncodedString(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/PduComposer;->appendHeader(I)I
+Lcom/google/android/mms/pdu/PduComposer;->appendLongInteger(J)V
+Lcom/google/android/mms/pdu/PduComposer;->appendOctet(I)V
+Lcom/google/android/mms/pdu/PduComposer;->appendQuotedString(Ljava/lang/String;)V
+Lcom/google/android/mms/pdu/PduComposer;->appendQuotedString([B)V
+Lcom/google/android/mms/pdu/PduComposer;->appendShortInteger(I)V
+Lcom/google/android/mms/pdu/PduComposer;->appendTextString(Ljava/lang/String;)V
+Lcom/google/android/mms/pdu/PduComposer;->appendTextString([B)V
+Lcom/google/android/mms/pdu/PduComposer;->appendUintvarInteger(J)V
+Lcom/google/android/mms/pdu/PduComposer;->appendValueLength(J)V
+Lcom/google/android/mms/pdu/PduComposer;->arraycopy([BII)V
Lcom/google/android/mms/pdu/PduComposer;->make()[B
+Lcom/google/android/mms/pdu/PduComposer;->mContentTypeMap:Ljava/util/HashMap;
+Lcom/google/android/mms/pdu/PduComposer;->mMessage:Ljava/io/ByteArrayOutputStream;
+Lcom/google/android/mms/pdu/PduComposer;->mPdu:Lcom/google/android/mms/pdu/GenericPdu;
+Lcom/google/android/mms/pdu/PduComposer;->mPduHeader:Lcom/google/android/mms/pdu/PduHeaders;
+Lcom/google/android/mms/pdu/PduComposer;->mPosition:I
+Lcom/google/android/mms/pdu/PduComposer;->mResolver:Landroid/content/ContentResolver;
+Lcom/google/android/mms/pdu/PduComposer;->mStack:Lcom/google/android/mms/pdu/PduComposer$BufferStack;
+Lcom/google/android/mms/pdu/PduContentTypes;->contentTypes:[Ljava/lang/String;
+Lcom/google/android/mms/pdu/PduHeaders;-><init>()V
+Lcom/google/android/mms/pdu/PduHeaders;->appendEncodedStringValue(Lcom/google/android/mms/pdu/EncodedStringValue;I)V
+Lcom/google/android/mms/pdu/PduHeaders;->getEncodedStringValue(I)Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/PduHeaders;->getEncodedStringValues(I)[Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/PduHeaders;->getLongInteger(I)J
+Lcom/google/android/mms/pdu/PduHeaders;->getOctet(I)I
+Lcom/google/android/mms/pdu/PduHeaders;->getTextString(I)[B
+Lcom/google/android/mms/pdu/PduHeaders;->setEncodedStringValue(Lcom/google/android/mms/pdu/EncodedStringValue;I)V
+Lcom/google/android/mms/pdu/PduHeaders;->setLongInteger(JI)V
+Lcom/google/android/mms/pdu/PduHeaders;->setOctet(II)V
+Lcom/google/android/mms/pdu/PduParser;->$assertionsDisabled:Z
+Lcom/google/android/mms/pdu/PduParser;-><init>([BZ)V
+Lcom/google/android/mms/pdu/PduParser;->checkPartPosition(Lcom/google/android/mms/pdu/PduPart;)I
+Lcom/google/android/mms/pdu/PduParser;->log(Ljava/lang/String;)V
Lcom/google/android/mms/pdu/PduParser;->parse()Lcom/google/android/mms/pdu/GenericPdu;
+Lcom/google/android/mms/pdu/PduParser;->parseContentType(Ljava/io/ByteArrayInputStream;Ljava/util/HashMap;)[B
+Lcom/google/android/mms/pdu/PduParser;->parsePartHeaders(Ljava/io/ByteArrayInputStream;Lcom/google/android/mms/pdu/PduPart;I)Z
+Lcom/google/android/mms/pdu/PduParser;->parseShortInteger(Ljava/io/ByteArrayInputStream;)I
+Lcom/google/android/mms/pdu/PduParser;->parseUnsignedInt(Ljava/io/ByteArrayInputStream;)I
+Lcom/google/android/mms/pdu/PduParser;->parseValueLength(Ljava/io/ByteArrayInputStream;)I
+Lcom/google/android/mms/pdu/PduParser;->parseWapString(Ljava/io/ByteArrayInputStream;I)[B
Lcom/google/android/mms/pdu/PduPart;-><init>()V
Lcom/google/android/mms/pdu/PduPart;->generateLocation()Ljava/lang/String;
Lcom/google/android/mms/pdu/PduPart;->getCharset()I
+Lcom/google/android/mms/pdu/PduPart;->getContentDisposition()[B
+Lcom/google/android/mms/pdu/PduPart;->getContentId()[B
Lcom/google/android/mms/pdu/PduPart;->getContentLocation()[B
+Lcom/google/android/mms/pdu/PduPart;->getContentTransferEncoding()[B
Lcom/google/android/mms/pdu/PduPart;->getContentType()[B
Lcom/google/android/mms/pdu/PduPart;->getData()[B
+Lcom/google/android/mms/pdu/PduPart;->getDataLength()I
Lcom/google/android/mms/pdu/PduPart;->getDataUri()Landroid/net/Uri;
Lcom/google/android/mms/pdu/PduPart;->getFilename()[B
Lcom/google/android/mms/pdu/PduPart;->getName()[B
Lcom/google/android/mms/pdu/PduPart;->setCharset(I)V
+Lcom/google/android/mms/pdu/PduPart;->setContentDisposition([B)V
Lcom/google/android/mms/pdu/PduPart;->setContentId([B)V
Lcom/google/android/mms/pdu/PduPart;->setContentLocation([B)V
+Lcom/google/android/mms/pdu/PduPart;->setContentTransferEncoding([B)V
Lcom/google/android/mms/pdu/PduPart;->setContentType([B)V
Lcom/google/android/mms/pdu/PduPart;->setData([B)V
Lcom/google/android/mms/pdu/PduPart;->setDataUri(Landroid/net/Uri;)V
+Lcom/google/android/mms/pdu/PduPart;->setFilename([B)V
+Lcom/google/android/mms/pdu/PduPart;->setName([B)V
+Lcom/google/android/mms/pdu/PduPersister;->ADDRESS_FIELDS:[I
+Lcom/google/android/mms/pdu/PduPersister;->CHARSET_COLUMN_NAME_MAP:Ljava/util/HashMap;
+Lcom/google/android/mms/pdu/PduPersister;->ENCODED_STRING_COLUMN_NAME_MAP:Ljava/util/HashMap;
+Lcom/google/android/mms/pdu/PduPersister;->getByteArrayFromPartColumn(Landroid/database/Cursor;I)[B
Lcom/google/android/mms/pdu/PduPersister;->getBytes(Ljava/lang/String;)[B
+Lcom/google/android/mms/pdu/PduPersister;->getIntegerFromPartColumn(Landroid/database/Cursor;I)Ljava/lang/Integer;
+Lcom/google/android/mms/pdu/PduPersister;->getPartContentType(Lcom/google/android/mms/pdu/PduPart;)Ljava/lang/String;
Lcom/google/android/mms/pdu/PduPersister;->getPduPersister(Landroid/content/Context;)Lcom/google/android/mms/pdu/PduPersister;
Lcom/google/android/mms/pdu/PduPersister;->getPendingMessages(J)Landroid/database/Cursor;
Lcom/google/android/mms/pdu/PduPersister;->load(Landroid/net/Uri;)Lcom/google/android/mms/pdu/GenericPdu;
+Lcom/google/android/mms/pdu/PduPersister;->loadRecipients(ILjava/util/HashSet;Ljava/util/HashMap;Z)V
+Lcom/google/android/mms/pdu/PduPersister;->LONG_COLUMN_NAME_MAP:Ljava/util/HashMap;
+Lcom/google/android/mms/pdu/PduPersister;->mContentResolver:Landroid/content/ContentResolver;
+Lcom/google/android/mms/pdu/PduPersister;->mContext:Landroid/content/Context;
+Lcom/google/android/mms/pdu/PduPersister;->MESSAGE_BOX_MAP:Ljava/util/HashMap;
Lcom/google/android/mms/pdu/PduPersister;->move(Landroid/net/Uri;Landroid/net/Uri;)Landroid/net/Uri;
+Lcom/google/android/mms/pdu/PduPersister;->mTelephonyManager:Landroid/telephony/TelephonyManager;
+Lcom/google/android/mms/pdu/PduPersister;->OCTET_COLUMN_NAME_MAP:Ljava/util/HashMap;
+Lcom/google/android/mms/pdu/PduPersister;->PART_PROJECTION:[Ljava/lang/String;
+Lcom/google/android/mms/pdu/PduPersister;->PDU_CACHE_INSTANCE:Lcom/google/android/mms/util/PduCache;
Lcom/google/android/mms/pdu/PduPersister;->persist(Lcom/google/android/mms/pdu/GenericPdu;Landroid/net/Uri;ZZLjava/util/HashMap;)Landroid/net/Uri;
+Lcom/google/android/mms/pdu/PduPersister;->persistAddress(JI[Lcom/google/android/mms/pdu/EncodedStringValue;)V
Lcom/google/android/mms/pdu/PduPersister;->persistPart(Lcom/google/android/mms/pdu/PduPart;JLjava/util/HashMap;)Landroid/net/Uri;
+Lcom/google/android/mms/pdu/PduPersister;->TEXT_STRING_COLUMN_NAME_MAP:Ljava/util/HashMap;
Lcom/google/android/mms/pdu/PduPersister;->toIsoString([B)Ljava/lang/String;
+Lcom/google/android/mms/pdu/PduPersister;->updateAddress(JI[Lcom/google/android/mms/pdu/EncodedStringValue;)V
Lcom/google/android/mms/pdu/PduPersister;->updateHeaders(Landroid/net/Uri;Lcom/google/android/mms/pdu/SendReq;)V
Lcom/google/android/mms/pdu/PduPersister;->updateParts(Landroid/net/Uri;Lcom/google/android/mms/pdu/PduBody;Ljava/util/HashMap;)V
+Lcom/google/android/mms/pdu/QuotedPrintable;->decodeQuotedPrintable([B)[B
+Lcom/google/android/mms/pdu/ReadOrigInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
Lcom/google/android/mms/pdu/ReadOrigInd;->getMessageId()[B
+Lcom/google/android/mms/pdu/ReadOrigInd;->getReadStatus()I
Lcom/google/android/mms/pdu/ReadRecInd;-><init>(Lcom/google/android/mms/pdu/EncodedStringValue;[BII[Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/ReadRecInd;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
+Lcom/google/android/mms/pdu/ReadRecInd;->getMessageId()[B
Lcom/google/android/mms/pdu/ReadRecInd;->setDate(J)V
+Lcom/google/android/mms/pdu/RetrieveConf;-><init>()V
+Lcom/google/android/mms/pdu/RetrieveConf;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V
+Lcom/google/android/mms/pdu/RetrieveConf;->addCc(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/RetrieveConf;->getCc()[Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/RetrieveConf;->getContentType()[B
+Lcom/google/android/mms/pdu/RetrieveConf;->getDeliveryReport()I
Lcom/google/android/mms/pdu/RetrieveConf;->getFrom()Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/RetrieveConf;->getMessageClass()[B
Lcom/google/android/mms/pdu/RetrieveConf;->getMessageId()[B
+Lcom/google/android/mms/pdu/RetrieveConf;->getReadReport()I
+Lcom/google/android/mms/pdu/RetrieveConf;->getRetrieveStatus()I
+Lcom/google/android/mms/pdu/RetrieveConf;->getRetrieveText()Lcom/google/android/mms/pdu/EncodedStringValue;
Lcom/google/android/mms/pdu/RetrieveConf;->getTransactionId()[B
+Lcom/google/android/mms/pdu/RetrieveConf;->setContentType([B)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setDeliveryReport(I)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setFrom(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setMessageClass([B)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setMessageId([B)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setReadReport(I)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setRetrieveStatus(I)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setRetrieveText(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/RetrieveConf;->setTransactionId([B)V
+Lcom/google/android/mms/pdu/SendConf;-><init>()V
+Lcom/google/android/mms/pdu/SendConf;-><init>(Lcom/google/android/mms/pdu/PduHeaders;)V
Lcom/google/android/mms/pdu/SendConf;->getMessageId()[B
Lcom/google/android/mms/pdu/SendConf;->getResponseStatus()I
Lcom/google/android/mms/pdu/SendConf;->getTransactionId()[B
Lcom/google/android/mms/pdu/SendReq;-><init>()V
+Lcom/google/android/mms/pdu/SendReq;-><init>(Lcom/google/android/mms/pdu/PduHeaders;Lcom/google/android/mms/pdu/PduBody;)V
+Lcom/google/android/mms/pdu/SendReq;->addBcc(Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/SendReq;->addCc(Lcom/google/android/mms/pdu/EncodedStringValue;)V
Lcom/google/android/mms/pdu/SendReq;->getBcc()[Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/SendReq;->getCc()[Lcom/google/android/mms/pdu/EncodedStringValue;
+Lcom/google/android/mms/pdu/SendReq;->getContentType()[B
+Lcom/google/android/mms/pdu/SendReq;->getDeliveryReport()I
+Lcom/google/android/mms/pdu/SendReq;->getExpiry()J
+Lcom/google/android/mms/pdu/SendReq;->getMessageClass()[B
+Lcom/google/android/mms/pdu/SendReq;->getMessageSize()J
+Lcom/google/android/mms/pdu/SendReq;->getReadReport()I
Lcom/google/android/mms/pdu/SendReq;->getTransactionId()[B
+Lcom/google/android/mms/pdu/SendReq;->setBcc([Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/SendReq;->setCc([Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/SendReq;->setContentType([B)V
Lcom/google/android/mms/pdu/SendReq;->setDeliveryReport(I)V
Lcom/google/android/mms/pdu/SendReq;->setExpiry(J)V
Lcom/google/android/mms/pdu/SendReq;->setMessageClass([B)V
Lcom/google/android/mms/pdu/SendReq;->setMessageSize(J)V
Lcom/google/android/mms/pdu/SendReq;->setReadReport(I)V
Lcom/google/android/mms/pdu/SendReq;->setTo([Lcom/google/android/mms/pdu/EncodedStringValue;)V
+Lcom/google/android/mms/pdu/SendReq;->setTransactionId([B)V
+Lcom/google/android/mms/util/AbstractCache;-><init>()V
Lcom/google/android/mms/util/AbstractCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+Lcom/google/android/mms/util/AbstractCache;->purge(Ljava/lang/Object;)Ljava/lang/Object;
+Lcom/google/android/mms/util/AbstractCache;->purgeAll()V
+Lcom/google/android/mms/util/AbstractCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Z
+Lcom/google/android/mms/util/DownloadDrmHelper;->isDrmConvertNeeded(Ljava/lang/String;)Z
+Lcom/google/android/mms/util/DownloadDrmHelper;->modifyDrmFwLockFileExtension(Ljava/lang/String;)Ljava/lang/String;
+Lcom/google/android/mms/util/DrmConvertSession;->close(Ljava/lang/String;)I
+Lcom/google/android/mms/util/DrmConvertSession;->convert([BI)[B
+Lcom/google/android/mms/util/DrmConvertSession;->open(Landroid/content/Context;Ljava/lang/String;)Lcom/google/android/mms/util/DrmConvertSession;
+Lcom/google/android/mms/util/PduCache;-><init>()V
Lcom/google/android/mms/util/PduCache;->getInstance()Lcom/google/android/mms/util/PduCache;
Lcom/google/android/mms/util/PduCache;->isUpdating(Landroid/net/Uri;)Z
Lcom/google/android/mms/util/PduCache;->purge(Landroid/net/Uri;)Lcom/google/android/mms/util/PduCacheEntry;
Lcom/google/android/mms/util/PduCache;->purgeAll()V
+Lcom/google/android/mms/util/PduCacheEntry;-><init>(Lcom/google/android/mms/pdu/GenericPdu;IJ)V
+Lcom/google/android/mms/util/PduCacheEntry;->getMessageBox()I
Lcom/google/android/mms/util/PduCacheEntry;->getPdu()Lcom/google/android/mms/pdu/GenericPdu;
+Lcom/google/android/mms/util/PduCacheEntry;->getThreadId()J
+Lcom/google/android/mms/util/SqliteWrapper;->checkSQLiteException(Landroid/content/Context;Landroid/database/sqlite/SQLiteException;)V
+Lcom/google/android/mms/util/SqliteWrapper;->delete(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Ljava/lang/String;[Ljava/lang/String;)I
Lcom/google/android/mms/util/SqliteWrapper;->insert(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;)Landroid/net/Uri;
+Lcom/google/android/mms/util/SqliteWrapper;->query(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;[Ljava/lang/String;Ljava/lang/String;[Ljava/lang/String;Ljava/lang/String;)Landroid/database/Cursor;
+Lcom/google/android/mms/util/SqliteWrapper;->requery(Landroid/content/Context;Landroid/database/Cursor;)Z
+Lcom/google/android/mms/util/SqliteWrapper;->update(Landroid/content/Context;Landroid/content/ContentResolver;Landroid/net/Uri;Landroid/content/ContentValues;Ljava/lang/String;[Ljava/lang/String;)I
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->ACRONYM:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->FLICKR:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->FORMAT:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->GOOGLE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->HTML:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->LINK:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->MUSIC:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->PHOTO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->SMILEY:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->values()[Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/google/android/util/AbstractMessageParser$Token$Type;->YOUTUBE_VIDEO:Lcom/google/android/util/AbstractMessageParser$Token$Type;
+Lcom/sun/nio/file/ExtendedWatchEventModifier;->FILE_TREE:Lcom/sun/nio/file/ExtendedWatchEventModifier;
+Lgov/nist/core/Debug;->printStackTrace(Ljava/lang/Exception;)V
+Lgov/nist/core/GenericObject;-><init>()V
+Lgov/nist/core/GenericObject;->dbgPrint()V
+Lgov/nist/core/GenericObject;->debugDump(I)Ljava/lang/String;
+Lgov/nist/core/GenericObject;->encode()Ljava/lang/String;
+Lgov/nist/core/GenericObject;->getMatcher()Lgov/nist/core/Match;
+Lgov/nist/core/GenericObject;->indentation:I
+Lgov/nist/core/GenericObject;->isMySubclass(Ljava/lang/Class;)Z
+Lgov/nist/core/GenericObject;->match(Ljava/lang/Object;)Z
+Lgov/nist/core/GenericObject;->matchExpression:Lgov/nist/core/Match;
+Lgov/nist/core/GenericObject;->merge(Ljava/lang/Object;)V
+Lgov/nist/core/GenericObject;->sprint(Ljava/lang/String;)V
+Lgov/nist/core/GenericObject;->stringRepresentation:Ljava/lang/String;
+Lgov/nist/core/GenericObjectList;-><init>()V
+Lgov/nist/core/GenericObjectList;-><init>(Ljava/lang/String;)V
+Lgov/nist/core/GenericObjectList;-><init>(Ljava/lang/String;Ljava/lang/Class;)V
+Lgov/nist/core/GenericObjectList;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Lgov/nist/core/GenericObjectList;->concatenate(Lgov/nist/core/GenericObjectList;)V
+Lgov/nist/core/GenericObjectList;->concatenate(Lgov/nist/core/GenericObjectList;Z)V
+Lgov/nist/core/GenericObjectList;->debugDump(I)Ljava/lang/String;
+Lgov/nist/core/GenericObjectList;->first()Lgov/nist/core/GenericObject;
+Lgov/nist/core/GenericObjectList;->getIndentation()Ljava/lang/String;
+Lgov/nist/core/GenericObjectList;->indentation:I
+Lgov/nist/core/GenericObjectList;->isMySubclass(Ljava/lang/Class;)Z
+Lgov/nist/core/GenericObjectList;->match(Ljava/lang/Object;)Z
+Lgov/nist/core/GenericObjectList;->myClass:Ljava/lang/Class;
+Lgov/nist/core/GenericObjectList;->next()Lgov/nist/core/GenericObject;
+Lgov/nist/core/GenericObjectList;->next(Ljava/util/ListIterator;)Lgov/nist/core/GenericObject;
+Lgov/nist/core/GenericObjectList;->setMyClass(Ljava/lang/Class;)V
+Lgov/nist/core/GenericObjectList;->stringRep:Ljava/lang/String;
+Lgov/nist/core/Host;-><init>()V
+Lgov/nist/core/Host;-><init>(Ljava/lang/String;)V
+Lgov/nist/core/Host;->encode()Ljava/lang/String;
+Lgov/nist/core/Host;->getAddress()Ljava/lang/String;
+Lgov/nist/core/Host;->getHostname()Ljava/lang/String;
+Lgov/nist/core/Host;->isIPv6Reference(Ljava/lang/String;)Z
+Lgov/nist/core/Host;->setAddress(Ljava/lang/String;)V
+Lgov/nist/core/Host;->setHostname(Ljava/lang/String;)V
+Lgov/nist/core/HostNameParser;-><init>(Lgov/nist/core/LexerCore;)V
+Lgov/nist/core/HostNameParser;-><init>(Ljava/lang/String;)V
+Lgov/nist/core/HostNameParser;->host()Lgov/nist/core/Host;
+Lgov/nist/core/HostNameParser;->hostPort(Z)Lgov/nist/core/HostPort;
+Lgov/nist/core/HostPort;-><init>()V
+Lgov/nist/core/HostPort;->encode()Ljava/lang/String;
+Lgov/nist/core/HostPort;->encode(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;
+Lgov/nist/core/HostPort;->getHost()Lgov/nist/core/Host;
+Lgov/nist/core/HostPort;->getInetAddress()Ljava/net/InetAddress;
+Lgov/nist/core/HostPort;->getPort()I
+Lgov/nist/core/HostPort;->hasPort()Z
+Lgov/nist/core/HostPort;->removePort()V
+Lgov/nist/core/HostPort;->setHost(Lgov/nist/core/Host;)V
+Lgov/nist/core/HostPort;->setPort(I)V
+Lgov/nist/core/InternalErrorHandler;->handleException(Ljava/lang/Exception;)V
+Lgov/nist/core/InternalErrorHandler;->handleException(Ljava/lang/String;)V
+Lgov/nist/core/LexerCore;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Lgov/nist/core/LexerCore;->byteStringNoSemicolon()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->byteStringNoSlash()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->charAsString(I)Ljava/lang/String;
+Lgov/nist/core/LexerCore;->comment()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->createParseException()Ljava/text/ParseException;
+Lgov/nist/core/LexerCore;->currentLexer:Ljava/util/Hashtable;
+Lgov/nist/core/LexerCore;->getBuffer()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->getNextId()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->getNextToken()Lgov/nist/core/Token;
+Lgov/nist/core/LexerCore;->getPtr()I
+Lgov/nist/core/LexerCore;->getRest()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->getString(C)Ljava/lang/String;
+Lgov/nist/core/LexerCore;->isTokenChar(C)Z
+Lgov/nist/core/LexerCore;->lexerTables:Ljava/util/Hashtable;
+Lgov/nist/core/LexerCore;->markInputPosition()I
+Lgov/nist/core/LexerCore;->match(I)Lgov/nist/core/Token;
+Lgov/nist/core/LexerCore;->number()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->peekNextToken()Lgov/nist/core/Token;
+Lgov/nist/core/LexerCore;->peekNextToken(I)[Lgov/nist/core/Token;
+Lgov/nist/core/LexerCore;->quotedString()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->rewindInputPosition(I)V
+Lgov/nist/core/LexerCore;->selectLexer(Ljava/lang/String;)V
+Lgov/nist/core/LexerCore;->SPorHT()V
+Lgov/nist/core/LexerCore;->startsId()Z
+Lgov/nist/core/LexerCore;->ttoken()Ljava/lang/String;
+Lgov/nist/core/LexerCore;->ttokenSafe()Ljava/lang/String;
+Lgov/nist/core/Match;->match(Ljava/lang/String;)Z
+Lgov/nist/core/NameValue;-><init>()V
+Lgov/nist/core/NameValue;-><init>(Ljava/lang/String;Ljava/lang/Object;)V
+Lgov/nist/core/NameValue;-><init>(Ljava/lang/String;Ljava/lang/Object;Z)V
+Lgov/nist/core/NameValue;->encode()Ljava/lang/String;
+Lgov/nist/core/NameValue;->encode(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;
+Lgov/nist/core/NameValue;->getName()Ljava/lang/String;
+Lgov/nist/core/NameValue;->getValueAsObject()Ljava/lang/Object;
+Lgov/nist/core/NameValue;->setName(Ljava/lang/String;)V
+Lgov/nist/core/NameValue;->setQuotedValue()V
+Lgov/nist/core/NameValue;->setSeparator(Ljava/lang/String;)V
+Lgov/nist/core/NameValue;->setValueAsObject(Ljava/lang/Object;)V
+Lgov/nist/core/NameValueList;-><init>()V
+Lgov/nist/core/NameValueList;-><init>(Z)V
+Lgov/nist/core/NameValueList;->delete(Ljava/lang/String;)Z
+Lgov/nist/core/NameValueList;->encode()Ljava/lang/String;
+Lgov/nist/core/NameValueList;->encode(Ljava/lang/StringBuffer;)Ljava/lang/StringBuffer;
+Lgov/nist/core/NameValueList;->getNames()Ljava/util/Iterator;
+Lgov/nist/core/NameValueList;->getNameValue(Ljava/lang/String;)Lgov/nist/core/NameValue;
+Lgov/nist/core/NameValueList;->getParameter(Ljava/lang/String;)Ljava/lang/String;
+Lgov/nist/core/NameValueList;->getValue(Ljava/lang/String;)Ljava/lang/Object;
+Lgov/nist/core/NameValueList;->hasNameValue(Ljava/lang/String;)Z
+Lgov/nist/core/NameValueList;->iterator()Ljava/util/Iterator;
+Lgov/nist/core/NameValueList;->set(Lgov/nist/core/NameValue;)V
+Lgov/nist/core/NameValueList;->set(Ljava/lang/String;Ljava/lang/Object;)V
+Lgov/nist/core/NameValueList;->setSeparator(Ljava/lang/String;)V
+Lgov/nist/core/net/DefaultNetworkLayer;->SINGLETON:Lgov/nist/core/net/DefaultNetworkLayer;
+Lgov/nist/core/net/NetworkLayer;->createDatagramSocket()Ljava/net/DatagramSocket;
+Lgov/nist/core/net/NetworkLayer;->createDatagramSocket(ILjava/net/InetAddress;)Ljava/net/DatagramSocket;
+Lgov/nist/core/net/NetworkLayer;->createServerSocket(IILjava/net/InetAddress;)Ljava/net/ServerSocket;
+Lgov/nist/core/net/NetworkLayer;->createSocket(Ljava/net/InetAddress;I)Ljava/net/Socket;
+Lgov/nist/core/net/NetworkLayer;->createSSLServerSocket(IILjava/net/InetAddress;)Ljavax/net/ssl/SSLServerSocket;
+Lgov/nist/core/net/NetworkLayer;->createSSLSocket(Ljava/net/InetAddress;I)Ljavax/net/ssl/SSLSocket;
+Lgov/nist/core/ParserCore;-><init>()V
+Lgov/nist/core/ParserCore;->lexer:Lgov/nist/core/LexerCore;
+Lgov/nist/core/StringTokenizer;->ptr:I
+Lgov/nist/core/ThreadAuditor$ThreadHandle;->getPingIntervalInMillisecs()J
+Lgov/nist/core/ThreadAuditor$ThreadHandle;->ping()V
+Lgov/nist/core/ThreadAuditor;-><init>()V
+Lgov/nist/core/ThreadAuditor;->addCurrentThread()Lgov/nist/core/ThreadAuditor$ThreadHandle;
+Lgov/nist/core/ThreadAuditor;->getPingIntervalInMillisecs()J
+Lgov/nist/core/ThreadAuditor;->isEnabled()Z
+Lgov/nist/core/ThreadAuditor;->setPingIntervalInMillisecs(J)V
+Lgov/nist/core/Token;-><init>()V
+Lgov/nist/core/Token;->getTokenType()I
+Lgov/nist/core/Token;->getTokenValue()Ljava/lang/String;
+Lgov/nist/javax/sip/address/GenericURI;-><init>()V
+Lgov/nist/javax/sip/address/GenericURI;->encode()Ljava/lang/String;
+Lgov/nist/javax/sip/address/GenericURI;->getScheme()Ljava/lang/String;
+Lgov/nist/javax/sip/address/SipUri;->getHost()Ljava/lang/String;
+Lgov/nist/javax/sip/address/SipUri;->getParameter(Ljava/lang/String;)Ljava/lang/String;
+Lgov/nist/javax/sip/address/SipUri;->getPort()I
+Lgov/nist/javax/sip/address/SipUri;->getUser()Ljava/lang/String;
+Lgov/nist/javax/sip/address/SipUri;->removeParameter(Ljava/lang/String;)V
+Lgov/nist/javax/sip/address/SipUri;->setParameter(Ljava/lang/String;Ljava/lang/String;)V
+Lgov/nist/javax/sip/address/SipUri;->setUserParam(Ljava/lang/String;)V
+Lgov/nist/javax/sip/parser/URLParser;-><init>(Ljava/lang/String;)V
+Lgov/nist/javax/sip/parser/URLParser;->sipURL(Z)Lgov/nist/javax/sip/address/SipUri;
+Ljava/lang/DexCache;->dexFile:J
+Ljava/lang/invoke/SerializedLambda;-><init>(Ljava/lang/Class;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V
+Ljava/lang/invoke/SerializedLambda;->getCapturedArg(I)Ljava/lang/Object;
+Ljava/lang/invoke/SerializedLambda;->getCapturedArgCount()I
+Ljava/lang/invoke/SerializedLambda;->getCapturingClass()Ljava/lang/String;
+Ljava/lang/invoke/SerializedLambda;->getFunctionalInterfaceClass()Ljava/lang/String;
+Ljava/lang/invoke/SerializedLambda;->getFunctionalInterfaceMethodName()Ljava/lang/String;
+Ljava/lang/invoke/SerializedLambda;->getFunctionalInterfaceMethodSignature()Ljava/lang/String;
+Ljava/lang/invoke/SerializedLambda;->getImplClass()Ljava/lang/String;
+Ljava/lang/invoke/SerializedLambda;->getImplMethodKind()I
+Ljava/lang/invoke/SerializedLambda;->getImplMethodName()Ljava/lang/String;
+Ljava/lang/invoke/SerializedLambda;->getImplMethodSignature()Ljava/lang/String;
+Ljava/lang/invoke/SerializedLambda;->getInstantiatedMethodType()Ljava/lang/String;
+Ljava/lang/UNIXProcess;->pid:I
+Ljava/net/AddressCache$AddressCacheEntry;-><init>(Ljava/lang/Object;)V
+Ljava/net/AddressCache$AddressCacheEntry;->expiryNanos:J
+Ljava/net/AddressCache$AddressCacheEntry;->value:Ljava/lang/Object;
+Ljava/net/AddressCache$AddressCacheKey;->mHostname:Ljava/lang/String;
+Ljava/net/AddressCache;->cache:Llibcore/util/BasicLruCache;
+Ljava/net/Inet6AddressImpl;->addressCache:Ljava/net/AddressCache;
+Ljava/net/PlainSocketImpl;-><init>()V
+Ljava/nio/DirectByteBuffer;->cleaner()Lsun/misc/Cleaner;
+Ljava/nio/file/FileTreeWalker;->followLinks:Z
+Ljava/nio/file/FileTreeWalker;->linkOptions:[Ljava/nio/file/LinkOption;
+Ljava/nio/file/FileTreeWalker;->maxDepth:I
+Ljava/util/zip/ZipFile$ZipEntryIterator;->nextElement()Ljava/util/zip/ZipEntry;
+Ljunit/framework/TestCase;->fName:Ljava/lang/String;
+Ljunit/framework/TestSuite;->isPublicTestMethod(Ljava/lang/reflect/Method;)Z
+Ljunit/framework/TestSuite;->isTestMethod(Ljava/lang/reflect/Method;)Z
+Llibcore/icu/DateIntervalFormat;->formatDateRange(JJILjava/lang/String;)Ljava/lang/String;
+Llibcore/icu/ICU;->CACHED_PATTERNS:Llibcore/util/BasicLruCache;
+Llibcore/icu/ICU;->getBestDateTimePattern(Ljava/lang/String;Ljava/util/Locale;)Ljava/lang/String;
+Llibcore/icu/ICU;->getBestDateTimePatternNative(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+Llibcore/icu/ICU;->getDateFormatOrder(Ljava/lang/String;)[C
+Llibcore/icu/LocaleData;->firstDayOfWeek:Ljava/lang/Integer;
+Llibcore/icu/LocaleData;->get(Ljava/util/Locale;)Llibcore/icu/LocaleData;
+Llibcore/icu/LocaleData;->longStandAloneWeekdayNames:[Ljava/lang/String;
+Llibcore/icu/LocaleData;->mapInvalidAndNullLocales(Ljava/util/Locale;)Ljava/util/Locale;
+Llibcore/icu/LocaleData;->minimalDaysInFirstWeek:Ljava/lang/Integer;
+Llibcore/icu/LocaleData;->shortMonthNames:[Ljava/lang/String;
+Llibcore/icu/LocaleData;->shortStandAloneMonthNames:[Ljava/lang/String;
+Llibcore/icu/LocaleData;->shortStandAloneWeekdayNames:[Ljava/lang/String;
+Llibcore/icu/LocaleData;->timeFormat_Hm:Ljava/lang/String;
+Llibcore/icu/LocaleData;->timeFormat_hm:Ljava/lang/String;
+Llibcore/icu/LocaleData;->today:Ljava/lang/String;
+Llibcore/icu/LocaleData;->tomorrow:Ljava/lang/String;
+Llibcore/icu/LocaleData;->zeroDigit:C
+Llibcore/icu/TimeZoneNames;->forLocale(Ljava/util/Locale;)[Ljava/lang/String;
+Llibcore/io/AsynchronousCloseMonitor;->signalBlockedThreads(Ljava/io/FileDescriptor;)V
+Llibcore/io/BlockGuardOs;-><init>(Llibcore/io/Os;)V
+Llibcore/io/BlockGuardOs;->chmod(Ljava/lang/String;I)V
+Llibcore/io/BlockGuardOs;->chown(Ljava/lang/String;II)V
+Llibcore/io/BlockGuardOs;->close(Ljava/io/FileDescriptor;)V
+Llibcore/io/BlockGuardOs;->fchmod(Ljava/io/FileDescriptor;I)V
+Llibcore/io/BlockGuardOs;->fchown(Ljava/io/FileDescriptor;II)V
+Llibcore/io/BlockGuardOs;->fdatasync(Ljava/io/FileDescriptor;)V
+Llibcore/io/BlockGuardOs;->fstat(Ljava/io/FileDescriptor;)Landroid/system/StructStat;
+Llibcore/io/BlockGuardOs;->fstatvfs(Ljava/io/FileDescriptor;)Landroid/system/StructStatVfs;
+Llibcore/io/BlockGuardOs;->lchown(Ljava/lang/String;II)V
+Llibcore/io/BlockGuardOs;->link(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/BlockGuardOs;->lseek(Ljava/io/FileDescriptor;JI)J
+Llibcore/io/BlockGuardOs;->lstat(Ljava/lang/String;)Landroid/system/StructStat;
+Llibcore/io/BlockGuardOs;->mkdir(Ljava/lang/String;I)V
+Llibcore/io/BlockGuardOs;->mkfifo(Ljava/lang/String;I)V
+Llibcore/io/BlockGuardOs;->open(Ljava/lang/String;II)Ljava/io/FileDescriptor;
+Llibcore/io/BlockGuardOs;->posix_fallocate(Ljava/io/FileDescriptor;JJ)V
+Llibcore/io/BlockGuardOs;->pread(Ljava/io/FileDescriptor;Ljava/nio/ByteBuffer;J)I
+Llibcore/io/BlockGuardOs;->pread(Ljava/io/FileDescriptor;[BIIJ)I
+Llibcore/io/BlockGuardOs;->pwrite(Ljava/io/FileDescriptor;Ljava/nio/ByteBuffer;J)I
+Llibcore/io/BlockGuardOs;->pwrite(Ljava/io/FileDescriptor;[BIIJ)I
+Llibcore/io/BlockGuardOs;->read(Ljava/io/FileDescriptor;Ljava/nio/ByteBuffer;)I
+Llibcore/io/BlockGuardOs;->read(Ljava/io/FileDescriptor;[BII)I
+Llibcore/io/BlockGuardOs;->readlink(Ljava/lang/String;)Ljava/lang/String;
+Llibcore/io/BlockGuardOs;->readv(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I
+Llibcore/io/BlockGuardOs;->realpath(Ljava/lang/String;)Ljava/lang/String;
+Llibcore/io/BlockGuardOs;->remove(Ljava/lang/String;)V
+Llibcore/io/BlockGuardOs;->rename(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/BlockGuardOs;->stat(Ljava/lang/String;)Landroid/system/StructStat;
+Llibcore/io/BlockGuardOs;->statvfs(Ljava/lang/String;)Landroid/system/StructStatVfs;
+Llibcore/io/BlockGuardOs;->symlink(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/BlockGuardOs;->write(Ljava/io/FileDescriptor;Ljava/nio/ByteBuffer;)I
+Llibcore/io/BlockGuardOs;->write(Ljava/io/FileDescriptor;[BII)I
+Llibcore/io/BlockGuardOs;->writev(Ljava/io/FileDescriptor;[Ljava/lang/Object;[I[I)I
+Llibcore/io/BufferIterator;->readByte()B
+Llibcore/io/BufferIterator;->readByteArray([BII)V
+Llibcore/io/BufferIterator;->readInt()I
+Llibcore/io/BufferIterator;->readIntArray([III)V
+Llibcore/io/BufferIterator;->seek(I)V
+Llibcore/io/BufferIterator;->skip(I)V
+Llibcore/io/DropBox;->addText(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/ForwardingOs;-><init>(Llibcore/io/Os;)V
+Llibcore/io/ForwardingOs;->access(Ljava/lang/String;I)Z
+Llibcore/io/ForwardingOs;->chmod(Ljava/lang/String;I)V
+Llibcore/io/ForwardingOs;->chown(Ljava/lang/String;II)V
+Llibcore/io/ForwardingOs;->getenv(Ljava/lang/String;)Ljava/lang/String;
+Llibcore/io/ForwardingOs;->lchown(Ljava/lang/String;II)V
+Llibcore/io/ForwardingOs;->link(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/ForwardingOs;->lstat(Ljava/lang/String;)Landroid/system/StructStat;
+Llibcore/io/ForwardingOs;->mkdir(Ljava/lang/String;I)V
+Llibcore/io/ForwardingOs;->mkfifo(Ljava/lang/String;I)V
+Llibcore/io/ForwardingOs;->open(Ljava/lang/String;II)Ljava/io/FileDescriptor;
+Llibcore/io/ForwardingOs;->os:Llibcore/io/Os;
+Llibcore/io/ForwardingOs;->readlink(Ljava/lang/String;)Ljava/lang/String;
+Llibcore/io/ForwardingOs;->remove(Ljava/lang/String;)V
+Llibcore/io/ForwardingOs;->removexattr(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/ForwardingOs;->rename(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/ForwardingOs;->setenv(Ljava/lang/String;Ljava/lang/String;Z)V
+Llibcore/io/ForwardingOs;->setsockoptTimeval(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V
+Llibcore/io/ForwardingOs;->setxattr(Ljava/lang/String;Ljava/lang/String;[BI)V
+Llibcore/io/ForwardingOs;->stat(Ljava/lang/String;)Landroid/system/StructStat;
+Llibcore/io/ForwardingOs;->statvfs(Ljava/lang/String;)Landroid/system/StructStatVfs;
+Llibcore/io/ForwardingOs;->symlink(Ljava/lang/String;Ljava/lang/String;)V
+Llibcore/io/ForwardingOs;->sysconf(I)J
+Llibcore/io/ForwardingOs;->unlink(Ljava/lang/String;)V
+Llibcore/io/IoBridge;->isConnected(Ljava/io/FileDescriptor;Ljava/net/InetAddress;III)Z
+Llibcore/io/IoUtils;->closeQuietly(Ljava/io/FileDescriptor;)V
+Llibcore/io/IoUtils;->closeQuietly(Ljava/lang/AutoCloseable;)V
+Llibcore/io/IoUtils;->closeQuietly(Ljava/net/Socket;)V
+Llibcore/io/IoUtils;->readFileAsByteArray(Ljava/lang/String;)[B
+Llibcore/io/IoUtils;->readFileAsString(Ljava/lang/String;)Ljava/lang/String;
+Llibcore/io/IoUtils;->setBlocking(Ljava/io/FileDescriptor;Z)V
+Llibcore/io/MemoryMappedFile;->bigEndianIterator()Llibcore/io/BufferIterator;
+Llibcore/io/MemoryMappedFile;->mmapRO(Ljava/lang/String;)Llibcore/io/MemoryMappedFile;
+Llibcore/io/Os;->chmod(Ljava/lang/String;I)V
+Llibcore/io/Os;->close(Ljava/io/FileDescriptor;)V
+Llibcore/io/Os;->connect(Ljava/io/FileDescriptor;Ljava/net/InetAddress;I)V
+Llibcore/io/Os;->gai_strerror(I)Ljava/lang/String;
+Llibcore/io/Os;->remove(Ljava/lang/String;)V
+Llibcore/io/Os;->setenv(Ljava/lang/String;Ljava/lang/String;Z)V
+Llibcore/io/Os;->setsockoptTimeval(Ljava/io/FileDescriptor;IILandroid/system/StructTimeval;)V
+Llibcore/io/Os;->stat(Ljava/lang/String;)Landroid/system/StructStat;
+Llibcore/io/Os;->strerror(I)Ljava/lang/String;
+Llibcore/io/Os;->sysconf(I)J
+Llibcore/io/Streams;->readAsciiLine(Ljava/io/InputStream;)Ljava/lang/String;
+Llibcore/io/Streams;->readFully(Ljava/io/InputStream;)[B
+Llibcore/io/Streams;->readFully(Ljava/io/InputStream;[B)V
+Llibcore/io/Streams;->readSingleByte(Ljava/io/InputStream;)I
+Llibcore/io/Streams;->skipAll(Ljava/io/InputStream;)V
+Llibcore/io/Streams;->writeSingleByte(Ljava/io/OutputStream;I)V
+Llibcore/net/event/NetworkEventDispatcher;->addListener(Llibcore/net/event/NetworkEventListener;)V
+Llibcore/net/event/NetworkEventDispatcher;->getInstance()Llibcore/net/event/NetworkEventDispatcher;
+Llibcore/net/event/NetworkEventListener;-><init>()V
+Llibcore/net/http/HttpDate;->format(Ljava/util/Date;)Ljava/lang/String;
+Llibcore/net/http/HttpDate;->parse(Ljava/lang/String;)Ljava/util/Date;
+Llibcore/net/MimeUtils;->guessExtensionFromMimeType(Ljava/lang/String;)Ljava/lang/String;
+Llibcore/net/MimeUtils;->guessMimeTypeFromExtension(Ljava/lang/String;)Ljava/lang/String;
+Llibcore/net/NetworkSecurityPolicy;->isCleartextTrafficPermitted()Z
+Llibcore/util/BasicLruCache;-><init>(I)V
+Llibcore/util/BasicLruCache;->evictAll()V
+Llibcore/util/BasicLruCache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+Llibcore/util/BasicLruCache;->put(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
+Llibcore/util/EmptyArray;->BYTE:[B
+Llibcore/util/EmptyArray;->INT:[I
+Llibcore/util/EmptyArray;->OBJECT:[Ljava/lang/Object;
+Llibcore/util/ZoneInfoDB$TzData;-><init>()V
+Lorg/apache/harmony/dalvik/ddmc/Chunk;-><init>(ILjava/nio/ByteBuffer;)V
+Lorg/apache/harmony/dalvik/ddmc/ChunkHandler;->CHUNK_ORDER:Ljava/nio/ByteOrder;
+Lorg/apache/harmony/dalvik/ddmc/DdmServer;->broadcast(I)V
+Lorg/apache/harmony/dalvik/ddmc/DdmServer;->sendChunk(Lorg/apache/harmony/dalvik/ddmc/Chunk;)V
+Lorg/apache/harmony/dalvik/ddmc/DdmVmInternal;->getThreadStats()[B
+Lorg/apache/harmony/xml/dom/ElementImpl;->localName:Ljava/lang/String;
+Lorg/apache/harmony/xml/ExpatAttributes;-><init>()V
+Lorg/apache/harmony/xml/ExpatParser$EntityParser;->depth:I
+Lorg/apache/harmony/xml/ExpatParser;-><init>(Ljava/lang/String;Lorg/apache/harmony/xml/ExpatReader;ZLjava/lang/String;Ljava/lang/String;)V
+Lorg/apache/harmony/xml/ExpatParser;->append([BII)V
+Lorg/apache/harmony/xml/ExpatParser;->append([CII)V
+Lorg/apache/harmony/xml/ExpatParser;->attributes:Lorg/apache/harmony/xml/ExpatAttributes;
+Lorg/apache/harmony/xml/ExpatParser;->cloneAttributes()Lorg/xml/sax/Attributes;
+Lorg/apache/harmony/xml/ExpatParser;->finish()V
+Lorg/apache/harmony/xml/ExpatParser;->xmlReader:Lorg/apache/harmony/xml/ExpatReader;
+Lorg/apache/harmony/xml/ExpatReader;-><init>()V
+Lorg/apache/harmony/xml/ExpatReader;->contentHandler:Lorg/xml/sax/ContentHandler;
+Lorg/apache/xalan/extensions/ExpressionContext;->getContextNode()Lorg/w3c/dom/Node;
+Lorg/apache/xalan/extensions/ExpressionContext;->getErrorListener()Ljavax/xml/transform/ErrorListener;
+Lorg/apache/xalan/extensions/ExpressionContext;->getVariableOrParam(Lorg/apache/xml/utils/QName;)Lorg/apache/xpath/objects/XObject;
+Lorg/apache/xalan/extensions/ExpressionContext;->getXPathContext()Lorg/apache/xpath/XPathContext;
+Lorg/apache/xalan/extensions/ExtensionHandler;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Lorg/apache/xalan/extensions/ExtensionHandler;->callFunction(Ljava/lang/String;Ljava/util/Vector;Ljava/lang/Object;Lorg/apache/xalan/extensions/ExpressionContext;)Ljava/lang/Object;
+Lorg/apache/xalan/extensions/ExtensionHandler;->getClassForName(Ljava/lang/String;)Ljava/lang/Class;
+Lorg/apache/xalan/extensions/ObjectFactory$ConfigurationError;-><init>(Ljava/lang/String;Ljava/lang/Exception;)V
+Lorg/apache/xalan/extensions/ObjectFactory;->findClassLoader()Ljava/lang/ClassLoader;
+Lorg/apache/xalan/extensions/ObjectFactory;->findProviderClass(Ljava/lang/String;Ljava/lang/ClassLoader;Z)Ljava/lang/Class;
+Lorg/apache/xalan/processor/TransformerFactoryImpl;-><init>()V
+Lorg/apache/xalan/res/XSLMessages;->createMessage(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
+Lorg/apache/xalan/res/XSLTErrorResources;-><init>()V
+Lorg/apache/xalan/serialize/SerializerUtils;->outputResultTreeFragment(Lorg/apache/xml/serializer/SerializationHandler;Lorg/apache/xpath/objects/XObject;Lorg/apache/xpath/XPathContext;)V
+Lorg/apache/xalan/templates/AVT;->evaluate(Lorg/apache/xpath/XPathContext;ILorg/apache/xml/utils/PrefixResolver;)Ljava/lang/String;
+Lorg/apache/xalan/templates/ElemElement;->execute(Lorg/apache/xalan/transformer/TransformerImpl;)V
+Lorg/apache/xalan/templates/ElemExsltFunction;->execute(Lorg/apache/xalan/transformer/TransformerImpl;[Lorg/apache/xpath/objects/XObject;)V
+Lorg/apache/xalan/templates/ElemExtensionCall;->getAttribute(Ljava/lang/String;Lorg/w3c/dom/Node;Lorg/apache/xalan/transformer/TransformerImpl;)Ljava/lang/String;
+Lorg/apache/xalan/templates/ElemLiteralResult;->getLiteralResultAttribute(Ljava/lang/String;)Lorg/apache/xalan/templates/AVT;
+Lorg/apache/xalan/templates/ElemTemplate;->getMatch()Lorg/apache/xpath/XPath;
+Lorg/apache/xalan/templates/ElemTemplate;->getName()Lorg/apache/xml/utils/QName;
+Lorg/apache/xalan/templates/ElemTemplateElement;->getFirstChildElem()Lorg/apache/xalan/templates/ElemTemplateElement;
+Lorg/apache/xalan/templates/ElemTemplateElement;->getNextSiblingElem()Lorg/apache/xalan/templates/ElemTemplateElement;
+Lorg/apache/xalan/templates/ElemTemplateElement;->getParentElem()Lorg/apache/xalan/templates/ElemTemplateElement;
+Lorg/apache/xalan/templates/ElemTemplateElement;->getStylesheetRoot()Lorg/apache/xalan/templates/StylesheetRoot;
+Lorg/apache/xalan/templates/ElemTemplateElement;->getXSLToken()I
+Lorg/apache/xalan/templates/ElemTextLiteral;->getChars()[C
+Lorg/apache/xalan/templates/KeyDeclaration;->getName()Lorg/apache/xml/utils/QName;
+Lorg/apache/xalan/templates/KeyDeclaration;->getUse()Lorg/apache/xpath/XPath;
+Lorg/apache/xalan/templates/StylesheetRoot;->getDefaultRootRule()Lorg/apache/xalan/templates/ElemTemplate;
+Lorg/apache/xalan/templates/StylesheetRoot;->getDefaultRule()Lorg/apache/xalan/templates/ElemTemplate;
+Lorg/apache/xalan/templates/StylesheetRoot;->getDefaultTextRule()Lorg/apache/xalan/templates/ElemTemplate;
+Lorg/apache/xalan/templates/StylesheetRoot;->getTemplateComposed(Lorg/apache/xml/utils/QName;)Lorg/apache/xalan/templates/ElemTemplate;
+Lorg/apache/xalan/transformer/ClonerToResultTree;->cloneToResultTree(IILorg/apache/xml/dtm/DTM;Lorg/apache/xml/serializer/SerializationHandler;Z)V
+Lorg/apache/xalan/transformer/DecimalToRoman;-><init>(JLjava/lang/String;JLjava/lang/String;)V
+Lorg/apache/xalan/transformer/DecimalToRoman;->m_postLetter:Ljava/lang/String;
+Lorg/apache/xalan/transformer/DecimalToRoman;->m_postValue:J
+Lorg/apache/xalan/transformer/DecimalToRoman;->m_preLetter:Ljava/lang/String;
+Lorg/apache/xalan/transformer/DecimalToRoman;->m_preValue:J
+Lorg/apache/xalan/transformer/MsgMgr;->error(Ljavax/xml/transform/SourceLocator;Lorg/w3c/dom/Node;Lorg/w3c/dom/Node;Ljava/lang/String;)V
+Lorg/apache/xalan/transformer/TransformerImpl;->createSerializationHandler(Ljavax/xml/transform/Result;Lorg/apache/xalan/templates/OutputProperties;)Lorg/apache/xml/serializer/SerializationHandler;
+Lorg/apache/xalan/transformer/TransformerImpl;->executeChildTemplates(Lorg/apache/xalan/templates/ElemTemplateElement;Lorg/w3c/dom/Node;Lorg/apache/xml/utils/QName;Lorg/xml/sax/ContentHandler;)V
+Lorg/apache/xalan/transformer/TransformerImpl;->executeChildTemplates(Lorg/apache/xalan/templates/ElemTemplateElement;Z)V
+Lorg/apache/xalan/transformer/TransformerImpl;->getCountersTable()Lorg/apache/xalan/transformer/CountersTable;
+Lorg/apache/xalan/transformer/TransformerImpl;->getCurrentTemplateElements()Lorg/apache/xml/utils/ObjectStack;
+Lorg/apache/xalan/transformer/TransformerImpl;->getCurrentTemplateElementsCount()I
+Lorg/apache/xalan/transformer/TransformerImpl;->getMatchedNode()I
+Lorg/apache/xalan/transformer/TransformerImpl;->getMatchedTemplate()Lorg/apache/xalan/templates/ElemTemplate;
+Lorg/apache/xalan/transformer/TransformerImpl;->getMode()Lorg/apache/xml/utils/QName;
+Lorg/apache/xalan/transformer/TransformerImpl;->getMsgMgr()Lorg/apache/xalan/transformer/MsgMgr;
+Lorg/apache/xalan/transformer/TransformerImpl;->getOutputFormat()Lorg/apache/xalan/templates/OutputProperties;
+Lorg/apache/xalan/transformer/TransformerImpl;->getResultTreeHandler()Lorg/apache/xml/serializer/SerializationHandler;
+Lorg/apache/xalan/transformer/TransformerImpl;->getSerializationHandler()Lorg/apache/xml/serializer/SerializationHandler;
+Lorg/apache/xalan/transformer/TransformerImpl;->getXPathContext()Lorg/apache/xpath/XPathContext;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_attrSetStack:Ljava/util/Stack;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_currentMatchedNodes:Lorg/apache/xml/utils/NodeVector;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_currentMatchTemplates:Ljava/util/Stack;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_currentTemplateElements:Lorg/apache/xml/utils/ObjectStack;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_currentTemplateRuleIsNull:Lorg/apache/xml/utils/BoolStack;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_inputContentHandler:Lorg/xml/sax/ContentHandler;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_outputTarget:Ljavax/xml/transform/Result;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_stringWriterObjectPool:Lorg/apache/xml/utils/ObjectPool;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_urlOfSource:Ljava/lang/String;
+Lorg/apache/xalan/transformer/TransformerImpl;->m_xcontext:Lorg/apache/xpath/XPathContext;
+Lorg/apache/xalan/transformer/TransformerImpl;->popCurrentFuncResult()Ljava/lang/Object;
+Lorg/apache/xalan/transformer/TransformerImpl;->pushCurrentFuncResult(Ljava/lang/Object;)V
+Lorg/apache/xalan/transformer/TransformerImpl;->pushElemTemplateElement(Lorg/apache/xalan/templates/ElemTemplateElement;)V
+Lorg/apache/xalan/Version;->getVersion()Ljava/lang/String;
+Lorg/apache/xalan/xslt/EnvironmentCheck;-><init>()V
+Lorg/apache/xalan/xslt/EnvironmentCheck;->appendEnvironmentReport(Lorg/w3c/dom/Node;Lorg/w3c/dom/Document;Ljava/util/Hashtable;)V
+Lorg/apache/xalan/xslt/EnvironmentCheck;->getEnvironmentHash()Ljava/util/Hashtable;
+Lorg/apache/xalan/xslt/ObjectFactory;->findClassLoader()Ljava/lang/ClassLoader;
+Lorg/apache/xalan/xslt/ObjectFactory;->newInstance(Ljava/lang/String;Ljava/lang/ClassLoader;Z)Ljava/lang/Object;
+Lorg/apache/xml/dtm/Axis;->getNames(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/Axis;->isReverse(I)Z
+Lorg/apache/xml/dtm/DTM;->getDocument()I
+Lorg/apache/xml/dtm/DTM;->getDocumentRoot(I)I
+Lorg/apache/xml/dtm/DTM;->getFirstChild(I)I
+Lorg/apache/xml/dtm/DTM;->getNextSibling(I)I
+Lorg/apache/xml/dtm/DTM;->getNode(I)Lorg/w3c/dom/Node;
+Lorg/apache/xml/dtm/DTM;->getNodeName(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/DTM;->getNodeType(I)S
+Lorg/apache/xml/dtm/DTM;->getParent(I)I
+Lorg/apache/xml/dtm/DTM;->getSourceLocatorFor(I)Ljavax/xml/transform/SourceLocator;
+Lorg/apache/xml/dtm/DTM;->getStringValue(I)Lorg/apache/xml/utils/XMLString;
+Lorg/apache/xml/dtm/DTM;->migrateTo(Lorg/apache/xml/dtm/DTMManager;)V
+Lorg/apache/xml/dtm/DTMAxisIterator;->cloneIterator()Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/DTMAxisIterator;->getLast()I
+Lorg/apache/xml/dtm/DTMAxisIterator;->getNodeByPosition(I)I
+Lorg/apache/xml/dtm/DTMAxisIterator;->getPosition()I
+Lorg/apache/xml/dtm/DTMAxisIterator;->gotoMark()V
+Lorg/apache/xml/dtm/DTMAxisIterator;->isReverse()Z
+Lorg/apache/xml/dtm/DTMAxisIterator;->next()I
+Lorg/apache/xml/dtm/DTMAxisIterator;->reset()Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/DTMAxisIterator;->setMark()V
+Lorg/apache/xml/dtm/DTMAxisIterator;->setRestartable(Z)V
+Lorg/apache/xml/dtm/DTMAxisIterator;->setStartNode(I)Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/DTMException;-><init>(Ljava/lang/String;)V
+Lorg/apache/xml/dtm/DTMFilter;->acceptNode(II)S
+Lorg/apache/xml/dtm/DTMIterator;->cloneWithReset()Lorg/apache/xml/dtm/DTMIterator;
+Lorg/apache/xml/dtm/DTMIterator;->getCurrentPos()I
+Lorg/apache/xml/dtm/DTMIterator;->getDTM(I)Lorg/apache/xml/dtm/DTM;
+Lorg/apache/xml/dtm/DTMIterator;->nextNode()I
+Lorg/apache/xml/dtm/DTMIterator;->runTo(I)V
+Lorg/apache/xml/dtm/DTMIterator;->setCurrentPos(I)V
+Lorg/apache/xml/dtm/DTMIterator;->setRoot(ILjava/lang/Object;)V
+Lorg/apache/xml/dtm/DTMIterator;->setShouldCacheNodes(Z)V
+Lorg/apache/xml/dtm/DTMManager;->getDTM(Ljavax/xml/transform/Source;ZLorg/apache/xml/dtm/DTMWSFilter;ZZ)Lorg/apache/xml/dtm/DTM;
+Lorg/apache/xml/dtm/DTMManager;->getXMLStringFactory()Lorg/apache/xml/utils/XMLStringFactory;
+Lorg/apache/xml/dtm/DTMManager;->release(Lorg/apache/xml/dtm/DTM;Z)Z
+Lorg/apache/xml/dtm/ref/CoroutineManager;-><init>()V
+Lorg/apache/xml/dtm/ref/CoroutineManager;->co_joinCoroutineSet(I)I
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;-><init>()V
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->includeSelf()Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->reset()Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->resetPosition()Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->returnNode(I)I
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->setRestartable(Z)V
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->_includeSelf:Z
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->_isRestartable:Z
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->_last:I
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->_markedNode:I
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->_position:I
+Lorg/apache/xml/dtm/ref/DTMAxisIteratorBase;->_startNode:I
+Lorg/apache/xml/dtm/ref/DTMAxisIterNodeList;-><init>(Lorg/apache/xml/dtm/DTM;Lorg/apache/xml/dtm/DTMAxisIterator;)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->appendChild(IZZ)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->appendTextChild(Ljava/lang/String;)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->declareNamespaceInContext(II)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->documentRegistration()V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->documentRelease()V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->ensureSizeOfIndex(II)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->error(Ljava/lang/String;)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->findGTE([IIII)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->findInSortedSuballocatedIntVector(Lorg/apache/xml/utils/SuballocatedIntVector;I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->findNamespaceContext(I)Lorg/apache/xml/utils/SuballocatedIntVector;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocument()I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocumentAllDeclarationsProcessed()Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocumentBaseURI()Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocumentEncoding(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocumentRoot(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocumentStandalone(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocumentSystemIdentifier(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDocumentVersion(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getDTMIDs()Lorg/apache/xml/utils/SuballocatedIntVector;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getExpandedTypeID(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getExpandedTypeID(Ljava/lang/String;Ljava/lang/String;I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getFirstChild(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getFirstNamespaceNode(IZ)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getLastChild(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getLevel(I)S
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getLocalNameFromExpandedNameID(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getManager()Lorg/apache/xml/dtm/DTMManager;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNamespaceFromExpandedNameID(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNamespaceType(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNextAttribute(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNextNamespaceNode(IIZ)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNextSibling(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNode(I)Lorg/w3c/dom/Node;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNodeHandle(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNodeIdent(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getNodeType(I)S
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getOwnerDocument(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getParent(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getPreviousSibling(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getShouldStripWhitespace()Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getStringValueChunk(II[I)[C
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->getStringValueChunkCount(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->hasChildNodes(I)Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->indexNode(II)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->isCharacterElementContentWhitespace(I)Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->isDocumentAllDeclarationsProcessed(I)Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->isNodeAfter(II)Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->isSupported(Ljava/lang/String;Ljava/lang/String;)Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->makeNodeHandle(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->makeNodeIdentity(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_expandedNameTable:Lorg/apache/xml/dtm/ref/ExpandedNameTable;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_exptype:Lorg/apache/xml/utils/SuballocatedIntVector;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_firstch:Lorg/apache/xml/utils/SuballocatedIntVector;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_nextsib:Lorg/apache/xml/utils/SuballocatedIntVector;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_parent:Lorg/apache/xml/utils/SuballocatedIntVector;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_prevsib:Lorg/apache/xml/utils/SuballocatedIntVector;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_size:I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_wsfilter:Lorg/apache/xml/dtm/DTMWSFilter;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->m_xstrf:Lorg/apache/xml/utils/XMLStringFactory;
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->popShouldStripWhitespace()V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->pushShouldStripWhitespace(Z)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->setDocumentBaseURI(Ljava/lang/String;)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->setFeature(Ljava/lang/String;Z)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->setShouldStripWhitespace(Z)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->supportsPreStripping()Z
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->_exptype(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->_firstch(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->_level(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->_nextsib(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->_parent(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->_prevsib(I)I
+Lorg/apache/xml/dtm/ref/DTMDefaultBase;->_type(I)S
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$InternalAxisIteratorBase;-><init>(Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$InternalAxisIteratorBase;->_currentNode:I
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$NamespaceIterator;-><init>(Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$NamespaceIterator;->next()I
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$NamespaceIterator;->setStartNode(I)Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$NthDescendantIterator;-><init>(Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;I)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$SingletonIterator;-><init>(Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators$SingletonIterator;-><init>(Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;I)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;-><init>(Lorg/apache/xml/dtm/DTMManager;Ljavax/xml/transform/Source;ILorg/apache/xml/dtm/DTMWSFilter;Lorg/apache/xml/utils/XMLStringFactory;Z)V
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;->getAxisIterator(I)Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseIterators;->getTypedAxisIterator(II)Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/DTMDefaultBaseTraversers;->getAxisTraverser(I)Lorg/apache/xml/dtm/DTMAxisTraverser;
+Lorg/apache/xml/dtm/ref/DTMManagerDefault;-><init>()V
+Lorg/apache/xml/dtm/ref/DTMManagerDefault;->addDTM(Lorg/apache/xml/dtm/DTM;I)V
+Lorg/apache/xml/dtm/ref/DTMManagerDefault;->addDTM(Lorg/apache/xml/dtm/DTM;II)V
+Lorg/apache/xml/dtm/ref/DTMManagerDefault;->getFirstFreeDTMID()I
+Lorg/apache/xml/dtm/ref/DTMManagerDefault;->getXMLReader(Ljavax/xml/transform/Source;)Lorg/xml/sax/XMLReader;
+Lorg/apache/xml/dtm/ref/DTMManagerDefault;->releaseXMLReader(Lorg/xml/sax/XMLReader;)V
+Lorg/apache/xml/dtm/ref/DTMNodeIterator;-><init>(Lorg/apache/xml/dtm/DTMIterator;)V
+Lorg/apache/xml/dtm/ref/DTMNodeIterator;->getDTMIterator()Lorg/apache/xml/dtm/DTMIterator;
+Lorg/apache/xml/dtm/ref/DTMNodeIterator;->getRoot()Lorg/w3c/dom/Node;
+Lorg/apache/xml/dtm/ref/DTMNodeList;-><init>(Lorg/apache/xml/dtm/DTMIterator;)V
+Lorg/apache/xml/dtm/ref/DTMNodeProxy;-><init>(Lorg/apache/xml/dtm/DTM;I)V
+Lorg/apache/xml/dtm/ref/DTMNodeProxy;->getDTM()Lorg/apache/xml/dtm/DTM;
+Lorg/apache/xml/dtm/ref/DTMNodeProxy;->getDTMNodeNumber()I
+Lorg/apache/xml/dtm/ref/DTMNodeProxy;->getStringValue()Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMStringPool;-><init>()V
+Lorg/apache/xml/dtm/ref/DTMStringPool;->indexToString(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/DTMStringPool;->m_intToString:Ljava/util/Vector;
+Lorg/apache/xml/dtm/ref/DTMStringPool;->removeAllElements()V
+Lorg/apache/xml/dtm/ref/DTMStringPool;->stringToIndex(Ljava/lang/String;)I
+Lorg/apache/xml/dtm/ref/ExpandedNameTable;->getExpandedTypeID(Ljava/lang/String;Ljava/lang/String;I)I
+Lorg/apache/xml/dtm/ref/ExpandedNameTable;->getExpandedTypeID(Ljava/lang/String;Ljava/lang/String;IZ)I
+Lorg/apache/xml/dtm/ref/ExpandedNameTable;->getLocalName(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/ExpandedNameTable;->getSize()I
+Lorg/apache/xml/dtm/ref/ExpandedNameTable;->getType(I)S
+Lorg/apache/xml/dtm/ref/IncrementalSAXSource;->deliverMoreNodes(Z)Ljava/lang/Object;
+Lorg/apache/xml/dtm/ref/IncrementalSAXSource;->setContentHandler(Lorg/xml/sax/ContentHandler;)V
+Lorg/apache/xml/dtm/ref/IncrementalSAXSource;->setLexicalHandler(Lorg/xml/sax/ext/LexicalHandler;)V
+Lorg/apache/xml/dtm/ref/IncrementalSAXSource;->startParse(Lorg/xml/sax/InputSource;)V
+Lorg/apache/xml/dtm/ref/IncrementalSAXSource_Filter;-><init>()V
+Lorg/apache/xml/dtm/ref/IncrementalSAXSource_Filter;->setXMLReader(Lorg/xml/sax/XMLReader;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$AncestorIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$AncestorIterator;->next()I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$AncestorIterator;->setStartNode(I)Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$AttributeIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$ChildrenIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$ChildrenIterator;->setStartNode(I)Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$DescendantIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$FollowingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$FollowingSiblingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$ParentIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$ParentIterator;->setNodeType(I)Lorg/apache/xml/dtm/DTMAxisIterator;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$PrecedingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$PrecedingSiblingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedAncestorIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedAttributeIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedChildrenIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedDescendantIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedFollowingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedFollowingSiblingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedPrecedingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedPrecedingSiblingIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2$TypedSingletonIterator;-><init>(Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;I)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;-><init>(Lorg/apache/xml/dtm/DTMManager;Ljavax/xml/transform/Source;ILorg/apache/xml/dtm/DTMWSFilter;Lorg/apache/xml/utils/XMLStringFactory;ZIZZZ)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->copyAttribute(IILorg/apache/xml/serializer/SerializationHandler;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->copyAttributes(ILorg/apache/xml/serializer/SerializationHandler;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->copyElement(IILorg/apache/xml/serializer/SerializationHandler;)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->copyNS(ILorg/apache/xml/serializer/SerializationHandler;Z)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->copyTextNode(ILorg/apache/xml/serializer/SerializationHandler;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->dispatchCharactersEvents(ILorg/xml/sax/ContentHandler;Z)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getFirstAttribute(I)I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getIdForNamespace(Ljava/lang/String;)I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getLocalName(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getNodeName(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getNodeNameX(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getNodeValue(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getStringValue()Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getStringValue(I)Lorg/apache/xml/utils/XMLString;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->getStringValueX(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->m_buildIdIndex:Z
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->_exptype2(I)I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->_exptype2Type(I)I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->_firstch2(I)I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM2;->_nextsib2(I)I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->dispatchToEvents(ILorg/xml/sax/ContentHandler;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getAttributeNode(ILjava/lang/String;Ljava/lang/String;)I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getContentHandler()Lorg/xml/sax/ContentHandler;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getDeclHandler()Lorg/xml/sax/ext/DeclHandler;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getDocumentTypeDeclarationPublicIdentifier()Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getDocumentTypeDeclarationSystemIdentifier()Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getDTDHandler()Lorg/xml/sax/DTDHandler;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getEntityResolver()Lorg/xml/sax/EntityResolver;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getErrorHandler()Lorg/xml/sax/ErrorHandler;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getLexicalHandler()Lorg/xml/sax/ext/LexicalHandler;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getNamespaceURI(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getNumberOfNodes()I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getPrefix(I)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getSourceLocatorFor(I)Ljavax/xml/transform/SourceLocator;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->getUnparsedEntityURI(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->isAttributeSpecified(I)Z
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->migrateTo(Lorg/apache/xml/dtm/DTMManager;)V
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->m_idAttributes:Ljava/util/Hashtable;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->m_parents:Lorg/apache/xml/utils/IntStack;
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->m_previous:I
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->needsTwoThreads()Z
+Lorg/apache/xml/dtm/ref/sax2dtm/SAX2DTM;->setProperty(Ljava/lang/String;Ljava/lang/Object;)V
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getContextClassLoader()Ljava/lang/ClassLoader;
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getFileExists(Ljava/io/File;)Z
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getFileInputStream(Ljava/io/File;)Ljava/io/FileInputStream;
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getInstance()Lorg/apache/xml/dtm/ref/SecuritySupport;
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getLastModified(Ljava/io/File;)J
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getParentClassLoader(Ljava/lang/ClassLoader;)Ljava/lang/ClassLoader;
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getResourceAsStream(Ljava/lang/ClassLoader;Ljava/lang/String;)Ljava/io/InputStream;
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getSystemClassLoader()Ljava/lang/ClassLoader;
+Lorg/apache/xml/dtm/ref/SecuritySupport;->getSystemProperty(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/res/XMLErrorResources;-><init>()V
+Lorg/apache/xml/res/XMLMessages;->createXMLMessage(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
+Lorg/apache/xml/serializer/CharInfo$CharKey;-><init>(C)V
+Lorg/apache/xml/serializer/CharInfo;-><init>(Ljava/lang/String;Ljava/lang/String;Z)V
+Lorg/apache/xml/serializer/CharInfo;->get(I)Z
+Lorg/apache/xml/serializer/CharInfo;->getCharInfo(Ljava/lang/String;Ljava/lang/String;)Lorg/apache/xml/serializer/CharInfo;
+Lorg/apache/xml/serializer/CharInfo;->set(I)V
+Lorg/apache/xml/serializer/dom3/LSSerializerImpl;-><init>()V
+Lorg/apache/xml/serializer/DOMSerializer;->serialize(Lorg/w3c/dom/Node;)V
+Lorg/apache/xml/serializer/ElemContext;->m_elementName:Ljava/lang/String;
+Lorg/apache/xml/serializer/ElemContext;->m_elementURI:Ljava/lang/String;
+Lorg/apache/xml/serializer/ElemContext;->m_startTagOpen:Z
+Lorg/apache/xml/serializer/ElemContext;->push(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Lorg/apache/xml/serializer/ElemContext;
+Lorg/apache/xml/serializer/ElemDesc;->isAttrFlagSet(Ljava/lang/String;I)Z
+Lorg/apache/xml/serializer/Encodings;->convertMime2JavaEncoding(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/serializer/Encodings;->getMimeEncoding(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/serializer/Encodings;->getWriter(Ljava/io/OutputStream;Ljava/lang/String;)Ljava/io/Writer;
+Lorg/apache/xml/serializer/NamespaceMappings;-><init>()V
+Lorg/apache/xml/serializer/NamespaceMappings;->generateNextPrefix()Ljava/lang/String;
+Lorg/apache/xml/serializer/NamespaceMappings;->lookupNamespace(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/serializer/NamespaceMappings;->lookupPrefix(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/serializer/OutputPropertiesFactory;->getDefaultMethodProperties(Ljava/lang/String;)Ljava/util/Properties;
+Lorg/apache/xml/serializer/OutputPropertyUtils;->getBooleanProperty(Ljava/lang/String;Ljava/util/Properties;)Z
+Lorg/apache/xml/serializer/OutputPropertyUtils;->getIntProperty(Ljava/lang/String;Ljava/util/Properties;)I
+Lorg/apache/xml/serializer/SerializationHandler;->close()V
+Lorg/apache/xml/serializer/SerializationHandler;->flushPending()V
+Lorg/apache/xml/serializer/SerializationHandler;->setEscaping(Z)Z
+Lorg/apache/xml/serializer/SerializationHandler;->setIndentAmount(I)V
+Lorg/apache/xml/serializer/SerializationHandler;->setNamespaceMappings(Lorg/apache/xml/serializer/NamespaceMappings;)V
+Lorg/apache/xml/serializer/Serializer;->asContentHandler()Lorg/xml/sax/ContentHandler;
+Lorg/apache/xml/serializer/Serializer;->asDOMSerializer()Lorg/apache/xml/serializer/DOMSerializer;
+Lorg/apache/xml/serializer/Serializer;->getOutputFormat()Ljava/util/Properties;
+Lorg/apache/xml/serializer/Serializer;->getOutputStream()Ljava/io/OutputStream;
+Lorg/apache/xml/serializer/Serializer;->getWriter()Ljava/io/Writer;
+Lorg/apache/xml/serializer/Serializer;->reset()Z
+Lorg/apache/xml/serializer/Serializer;->setOutputFormat(Ljava/util/Properties;)V
+Lorg/apache/xml/serializer/Serializer;->setOutputStream(Ljava/io/OutputStream;)V
+Lorg/apache/xml/serializer/Serializer;->setWriter(Ljava/io/Writer;)V
+Lorg/apache/xml/serializer/SerializerBase;->fireCharEvent([CII)V
+Lorg/apache/xml/serializer/SerializerBase;->fireCommentEvent([CII)V
+Lorg/apache/xml/serializer/SerializerBase;->fireEndDoc()V
+Lorg/apache/xml/serializer/SerializerBase;->fireEndElem(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerBase;->fireEscapingEvent(Ljava/lang/String;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerBase;->getDoctypePublic()Ljava/lang/String;
+Lorg/apache/xml/serializer/SerializerBase;->getDoctypeSystem()Ljava/lang/String;
+Lorg/apache/xml/serializer/SerializerBase;->getEncoding()Ljava/lang/String;
+Lorg/apache/xml/serializer/SerializerBase;->getPrefixPart(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/serializer/SerializerBase;->getVersion()Ljava/lang/String;
+Lorg/apache/xml/serializer/SerializerBase;->m_attributes:Lorg/apache/xml/serializer/AttributesImplSerializer;
+Lorg/apache/xml/serializer/SerializerBase;->m_charsBuff:[C
+Lorg/apache/xml/serializer/SerializerBase;->m_elemContext:Lorg/apache/xml/serializer/ElemContext;
+Lorg/apache/xml/serializer/SerializerBase;->m_needToCallStartDocument:Z
+Lorg/apache/xml/serializer/SerializerBase;->m_tracer:Lorg/apache/xml/serializer/SerializerTrace;
+Lorg/apache/xml/serializer/SerializerBase;->setDoctypePublic(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerBase;->setDoctypeSystem(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerBase;->setIndent(Z)V
+Lorg/apache/xml/serializer/SerializerBase;->setMediaType(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerBase;->setOmitXMLDeclaration(Z)V
+Lorg/apache/xml/serializer/SerializerBase;->setStandalone(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerBase;->setStandaloneInternal(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerBase;->setVersion(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/SerializerFactory;->getSerializer(Ljava/util/Properties;)Lorg/apache/xml/serializer/Serializer;
+Lorg/apache/xml/serializer/SerializerTraceWriter;-><init>(Ljava/io/Writer;Lorg/apache/xml/serializer/SerializerTrace;)V
+Lorg/apache/xml/serializer/ToHTMLStream;-><init>()V
+Lorg/apache/xml/serializer/ToHTMLStream;->getElemDesc(Ljava/lang/String;)Lorg/apache/xml/serializer/ElemDesc;
+Lorg/apache/xml/serializer/ToSAXHandler;-><init>(Lorg/xml/sax/ContentHandler;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToSAXHandler;-><init>(Lorg/xml/sax/ContentHandler;Lorg/xml/sax/ext/LexicalHandler;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToSAXHandler;->m_lexHandler:Lorg/xml/sax/ext/LexicalHandler;
+Lorg/apache/xml/serializer/ToSAXHandler;->m_saxHandler:Lorg/xml/sax/ContentHandler;
+Lorg/apache/xml/serializer/ToSAXHandler;->reset()Z
+Lorg/apache/xml/serializer/ToSAXHandler;->startDocumentInternal()V
+Lorg/apache/xml/serializer/ToSAXHandler;->startElement(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToStream;->setCdataSectionElements(Ljava/lang/String;Ljava/util/Properties;)V
+Lorg/apache/xml/serializer/ToStream;->setEncoding(Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToStream;->setIndentAmount(I)V
+Lorg/apache/xml/serializer/ToTextSAXHandler;-><init>(Lorg/xml/sax/ContentHandler;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToTextSAXHandler;-><init>(Lorg/xml/sax/ContentHandler;Lorg/xml/sax/ext/LexicalHandler;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToTextStream;-><init>()V
+Lorg/apache/xml/serializer/ToUnknownStream;-><init>()V
+Lorg/apache/xml/serializer/ToXMLSAXHandler;-><init>(Lorg/xml/sax/ContentHandler;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToXMLSAXHandler;-><init>(Lorg/xml/sax/ContentHandler;Lorg/xml/sax/ext/LexicalHandler;Ljava/lang/String;)V
+Lorg/apache/xml/serializer/ToXMLStream;-><init>()V
+Lorg/apache/xml/serializer/WriterToASCI;-><init>(Ljava/io/OutputStream;)V
+Lorg/apache/xml/serializer/WriterToUTF8Buffered;-><init>(Ljava/io/OutputStream;)V
+Lorg/apache/xml/utils/DefaultErrorHandler;-><init>()V
+Lorg/apache/xml/utils/DefaultErrorHandler;->printLocation(Ljava/io/PrintWriter;Ljava/lang/Throwable;)V
+Lorg/apache/xml/utils/DOMHelper;->isNodeAfter(Lorg/w3c/dom/Node;Lorg/w3c/dom/Node;)Z
+Lorg/apache/xml/utils/DOMHelper;->isNodeTheSame(Lorg/w3c/dom/Node;Lorg/w3c/dom/Node;)Z
+Lorg/apache/xml/utils/FastStringBuffer;->append(Ljava/lang/String;)V
+Lorg/apache/xml/utils/FastStringBuffer;->getString(II)Ljava/lang/String;
+Lorg/apache/xml/utils/FastStringBuffer;->length()I
+Lorg/apache/xml/utils/IntStack;->peek()I
+Lorg/apache/xml/utils/ObjectVector;->elementAt(I)Ljava/lang/Object;
+Lorg/apache/xml/utils/ObjectVector;->size()I
+Lorg/apache/xml/utils/PrefixResolverDefault;-><init>(Lorg/w3c/dom/Node;)V
+Lorg/apache/xml/utils/PrefixResolverDefault;->getNamespaceForPrefix(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/utils/QName;-><init>(Ljava/lang/String;)V
+Lorg/apache/xml/utils/QName;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Lorg/apache/xml/utils/QName;->getLocalName()Ljava/lang/String;
+Lorg/apache/xml/utils/SAXSourceLocator;-><init>(Lorg/xml/sax/SAXParseException;)V
+Lorg/apache/xml/utils/StringBufferPool;->free(Lorg/apache/xml/utils/FastStringBuffer;)V
+Lorg/apache/xml/utils/StringBufferPool;->get()Lorg/apache/xml/utils/FastStringBuffer;
+Lorg/apache/xml/utils/StringVector;->elementAt(I)Ljava/lang/String;
+Lorg/apache/xml/utils/StringVector;->size()I
+Lorg/apache/xml/utils/StylesheetPIHandler;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lorg/apache/xml/utils/StylesheetPIHandler;->getAssociatedStylesheet()Ljavax/xml/transform/Source;
+Lorg/apache/xml/utils/StylesheetPIHandler;->setBaseId(Ljava/lang/String;)V
+Lorg/apache/xml/utils/StylesheetPIHandler;->setURIResolver(Ljavax/xml/transform/URIResolver;)V
+Lorg/apache/xml/utils/SuballocatedIntVector;-><init>(I)V
+Lorg/apache/xml/utils/SuballocatedIntVector;->elementAt(I)I
+Lorg/apache/xml/utils/SuballocatedIntVector;->setElementAt(II)V
+Lorg/apache/xml/utils/SuballocatedIntVector;->size()I
+Lorg/apache/xml/utils/SystemIDResolver;->getAbsoluteURI(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/utils/SystemIDResolver;->getAbsoluteURI(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/utils/SystemIDResolver;->getAbsoluteURIFromRelative(Ljava/lang/String;)Ljava/lang/String;
+Lorg/apache/xml/utils/SystemIDResolver;->isAbsoluteURI(Ljava/lang/String;)Z
+Lorg/apache/xml/utils/URI$MalformedURIException;-><init>(Ljava/lang/String;)V
+Lorg/apache/xml/utils/URI;-><init>(Ljava/lang/String;)V
+Lorg/apache/xml/utils/URI;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lorg/apache/xml/utils/URI;-><init>(Lorg/apache/xml/utils/URI;)V
+Lorg/apache/xml/utils/URI;-><init>(Lorg/apache/xml/utils/URI;Ljava/lang/String;)V
+Lorg/apache/xml/utils/URI;->getFragment()Ljava/lang/String;
+Lorg/apache/xml/utils/URI;->getHost()Ljava/lang/String;
+Lorg/apache/xml/utils/URI;->getPath()Ljava/lang/String;
+Lorg/apache/xml/utils/URI;->getPort()I
+Lorg/apache/xml/utils/URI;->getQueryString()Ljava/lang/String;
+Lorg/apache/xml/utils/URI;->getScheme()Ljava/lang/String;
+Lorg/apache/xml/utils/URI;->getUserinfo()Ljava/lang/String;
+Lorg/apache/xml/utils/URI;->setFragment(Ljava/lang/String;)V
+Lorg/apache/xml/utils/URI;->setHost(Ljava/lang/String;)V
+Lorg/apache/xml/utils/URI;->setPort(I)V
+Lorg/apache/xml/utils/URI;->setScheme(Ljava/lang/String;)V
+Lorg/apache/xml/utils/URI;->setUserinfo(Ljava/lang/String;)V
+Lorg/apache/xml/utils/WrappedRuntimeException;-><init>(Ljava/lang/Exception;)V
+Lorg/apache/xml/utils/WrappedRuntimeException;->getException()Ljava/lang/Exception;
+Lorg/apache/xml/utils/XML11Char;->isXML11ValidNCName(Ljava/lang/String;)Z
+Lorg/apache/xml/utils/XML11Char;->isXML11ValidQName(Ljava/lang/String;)Z
+Lorg/apache/xml/utils/XMLReaderManager;->getInstance()Lorg/apache/xml/utils/XMLReaderManager;
+Lorg/apache/xml/utils/XMLReaderManager;->getXMLReader()Lorg/xml/sax/XMLReader;
+Lorg/apache/xml/utils/XMLReaderManager;->releaseXMLReader(Lorg/xml/sax/XMLReader;)V
+Lorg/apache/xml/utils/XMLString;->dispatchCharactersEvents(Lorg/xml/sax/ContentHandler;)V
+Lorg/apache/xml/utils/XMLString;->equals(Lorg/apache/xml/utils/XMLString;)Z
+Lorg/apache/xml/utils/XMLString;->fixWhiteSpace(ZZZ)Lorg/apache/xml/utils/XMLString;
+Lorg/apache/xml/utils/XMLStringDefault;-><init>(Ljava/lang/String;)V
+Lorg/apache/xml/utils/XMLStringFactory;-><init>()V
+Lorg/apache/xml/utils/XMLStringFactory;->emptystr()Lorg/apache/xml/utils/XMLString;
+Lorg/apache/xml/utils/XMLStringFactory;->newstr(Ljava/lang/String;)Lorg/apache/xml/utils/XMLString;
+Lorg/apache/xpath/axes/ChildTestIterator;-><init>(Lorg/apache/xml/dtm/DTMAxisTraverser;)V
+Lorg/apache/xpath/axes/DescendantIterator;-><init>()V
+Lorg/apache/xpath/axes/LocPathIterator;->getDTM(I)Lorg/apache/xml/dtm/DTM;
+Lorg/apache/xpath/axes/LocPathIterator;->getPrefixResolver()Lorg/apache/xml/utils/PrefixResolver;
+Lorg/apache/xpath/axes/LocPathIterator;->getXPathContext()Lorg/apache/xpath/XPathContext;
+Lorg/apache/xpath/axes/NodeSequence;->getContainedIter()Lorg/apache/xml/dtm/DTMIterator;
+Lorg/apache/xpath/axes/NodeSequence;->nextNode()I
+Lorg/apache/xpath/axes/OneStepIterator;-><init>(Lorg/apache/xml/dtm/DTMAxisIterator;I)V
+Lorg/apache/xpath/CachedXPathAPI;-><init>()V
+Lorg/apache/xpath/CachedXPathAPI;-><init>(Lorg/apache/xpath/CachedXPathAPI;)V
+Lorg/apache/xpath/CachedXPathAPI;->eval(Lorg/w3c/dom/Node;Ljava/lang/String;)Lorg/apache/xpath/objects/XObject;
+Lorg/apache/xpath/CachedXPathAPI;->getXPathContext()Lorg/apache/xpath/XPathContext;
+Lorg/apache/xpath/CachedXPathAPI;->selectNodeList(Lorg/w3c/dom/Node;Ljava/lang/String;)Lorg/w3c/dom/NodeList;
+Lorg/apache/xpath/CachedXPathAPI;->selectNodeList(Lorg/w3c/dom/Node;Ljava/lang/String;Lorg/w3c/dom/Node;)Lorg/w3c/dom/NodeList;
+Lorg/apache/xpath/CachedXPathAPI;->selectSingleNode(Lorg/w3c/dom/Node;Ljava/lang/String;)Lorg/w3c/dom/Node;
+Lorg/apache/xpath/CachedXPathAPI;->selectSingleNode(Lorg/w3c/dom/Node;Ljava/lang/String;Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node;
+Lorg/apache/xpath/compiler/FunctionTable;-><init>()V
+Lorg/apache/xpath/compiler/FunctionTable;->installFunction(Ljava/lang/String;Ljava/lang/Class;)I
+Lorg/apache/xpath/Expression;->assertion(ZLjava/lang/String;)V
+Lorg/apache/xpath/Expression;->error(Lorg/apache/xpath/XPathContext;Ljava/lang/String;[Ljava/lang/Object;)V
+Lorg/apache/xpath/Expression;->exprGetParent()Lorg/apache/xpath/ExpressionNode;
+Lorg/apache/xpath/ExpressionNode;->exprGetParent()Lorg/apache/xpath/ExpressionNode;
+Lorg/apache/xpath/functions/FuncCurrent;-><init>()V
+Lorg/apache/xpath/functions/FuncExtFunction;->getFunctionName()Ljava/lang/String;
+Lorg/apache/xpath/functions/FuncExtFunction;->getMethodKey()Ljava/lang/Object;
+Lorg/apache/xpath/functions/Function;-><init>()V
+Lorg/apache/xpath/functions/WrongNumberArgsException;-><init>(Ljava/lang/String;)V
+Lorg/apache/xpath/NodeSet;-><init>()V
+Lorg/apache/xpath/NodeSet;-><init>(Lorg/w3c/dom/Node;)V
+Lorg/apache/xpath/NodeSet;-><init>(Lorg/w3c/dom/NodeList;)V
+Lorg/apache/xpath/NodeSet;-><init>(Lorg/w3c/dom/traversal/NodeIterator;)V
+Lorg/apache/xpath/NodeSet;->addElement(Lorg/w3c/dom/Node;)V
+Lorg/apache/xpath/NodeSet;->addNode(Lorg/w3c/dom/Node;)V
+Lorg/apache/xpath/NodeSet;->contains(Lorg/w3c/dom/Node;)Z
+Lorg/apache/xpath/NodeSet;->elementAt(I)Lorg/w3c/dom/Node;
+Lorg/apache/xpath/NodeSet;->setShouldCacheNodes(Z)V
+Lorg/apache/xpath/NodeSetDTM;-><init>(Lorg/w3c/dom/NodeList;Lorg/apache/xpath/XPathContext;)V
+Lorg/apache/xpath/NodeSetDTM;-><init>(Lorg/w3c/dom/traversal/NodeIterator;Lorg/apache/xpath/XPathContext;)V
+Lorg/apache/xpath/NodeSetDTM;->addNode(I)V
+Lorg/apache/xpath/NodeSetDTM;->detach()V
+Lorg/apache/xpath/NodeSetDTM;->getLength()I
+Lorg/apache/xpath/NodeSetDTM;->item(I)I
+Lorg/apache/xpath/objects/XBoolean;-><init>(Z)V
+Lorg/apache/xpath/objects/XBoolean;->bool()Z
+Lorg/apache/xpath/objects/XBoolean;->str()Ljava/lang/String;
+Lorg/apache/xpath/objects/XBooleanStatic;-><init>(Z)V
+Lorg/apache/xpath/objects/XNodeSet;-><init>(ILorg/apache/xml/dtm/DTMManager;)V
+Lorg/apache/xpath/objects/XNodeSet;-><init>(Lorg/apache/xml/dtm/DTMIterator;)V
+Lorg/apache/xpath/objects/XNodeSet;-><init>(Lorg/apache/xml/dtm/DTMManager;)V
+Lorg/apache/xpath/objects/XNodeSet;->iterRaw()Lorg/apache/xml/dtm/DTMIterator;
+Lorg/apache/xpath/objects/XNodeSet;->mutableNodeset()Lorg/apache/xpath/NodeSetDTM;
+Lorg/apache/xpath/objects/XNodeSet;->nodelist()Lorg/w3c/dom/NodeList;
+Lorg/apache/xpath/objects/XNumber;-><init>(D)V
+Lorg/apache/xpath/objects/XNumber;->num()D
+Lorg/apache/xpath/objects/XNumber;->str()Ljava/lang/String;
+Lorg/apache/xpath/objects/XObject;->bool()Z
+Lorg/apache/xpath/objects/XObject;->create(Ljava/lang/Object;)Lorg/apache/xpath/objects/XObject;
+Lorg/apache/xpath/objects/XObject;->getType()I
+Lorg/apache/xpath/objects/XObject;->getTypeString()Ljava/lang/String;
+Lorg/apache/xpath/objects/XObject;->iter()Lorg/apache/xml/dtm/DTMIterator;
+Lorg/apache/xpath/objects/XObject;->nodelist()Lorg/w3c/dom/NodeList;
+Lorg/apache/xpath/objects/XObject;->nodeset()Lorg/w3c/dom/traversal/NodeIterator;
+Lorg/apache/xpath/objects/XObject;->num()D
+Lorg/apache/xpath/objects/XObject;->object()Ljava/lang/Object;
+Lorg/apache/xpath/objects/XObject;->str()Ljava/lang/String;
+Lorg/apache/xpath/objects/XObject;->xstr()Lorg/apache/xml/utils/XMLString;
+Lorg/apache/xpath/objects/XRTreeFrag;-><init>(ILorg/apache/xpath/XPathContext;)V
+Lorg/apache/xpath/objects/XRTreeFrag;->asNodeIterator()Lorg/apache/xml/dtm/DTMIterator;
+Lorg/apache/xpath/objects/XRTreeFrag;->convertToNodeset()Lorg/w3c/dom/NodeList;
+Lorg/apache/xpath/objects/XString;-><init>(Ljava/lang/String;)V
+Lorg/apache/xpath/objects/XString;->num()D
+Lorg/apache/xpath/patterns/NodeTest;->setWhatToShow(I)V
+Lorg/apache/xpath/res/XPATHErrorResources;-><init>()V
+Lorg/apache/xpath/res/XPATHMessages;->createXPATHMessage(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;
+Lorg/apache/xpath/XPath;-><init>(Ljava/lang/String;Ljavax/xml/transform/SourceLocator;Lorg/apache/xml/utils/PrefixResolver;I)V
+Lorg/apache/xpath/XPath;-><init>(Ljava/lang/String;Ljavax/xml/transform/SourceLocator;Lorg/apache/xml/utils/PrefixResolver;ILjavax/xml/transform/ErrorListener;)V
+Lorg/apache/xpath/XPath;->execute(Lorg/apache/xpath/XPathContext;ILorg/apache/xml/utils/PrefixResolver;)Lorg/apache/xpath/objects/XObject;
+Lorg/apache/xpath/XPath;->execute(Lorg/apache/xpath/XPathContext;Lorg/w3c/dom/Node;Lorg/apache/xml/utils/PrefixResolver;)Lorg/apache/xpath/objects/XObject;
+Lorg/apache/xpath/XPath;->getPatternString()Ljava/lang/String;
+Lorg/apache/xpath/XPathAPI;->selectNodeList(Lorg/w3c/dom/Node;Ljava/lang/String;)Lorg/w3c/dom/NodeList;
+Lorg/apache/xpath/XPathAPI;->selectNodeList(Lorg/w3c/dom/Node;Ljava/lang/String;Lorg/w3c/dom/Node;)Lorg/w3c/dom/NodeList;
+Lorg/apache/xpath/XPathAPI;->selectSingleNode(Lorg/w3c/dom/Node;Ljava/lang/String;)Lorg/w3c/dom/Node;
+Lorg/apache/xpath/XPathAPI;->selectSingleNode(Lorg/w3c/dom/Node;Ljava/lang/String;Lorg/w3c/dom/Node;)Lorg/w3c/dom/Node;
+Lorg/apache/xpath/XPathContext$XPathExpressionContext;->getDTMManager()Lorg/apache/xml/dtm/DTMManager;
+Lorg/apache/xpath/XPathContext$XPathExpressionContext;->getXPathContext()Lorg/apache/xpath/XPathContext;
+Lorg/apache/xpath/XPathContext;-><init>()V
+Lorg/apache/xpath/XPathContext;-><init>(Ljava/lang/Object;)V
+Lorg/apache/xpath/XPathContext;->getAxesIteratorStackStacks()Ljava/util/Stack;
+Lorg/apache/xpath/XPathContext;->getContextNodeList()Lorg/apache/xml/dtm/DTMIterator;
+Lorg/apache/xpath/XPathContext;->getContextNodeListsStack()Ljava/util/Stack;
+Lorg/apache/xpath/XPathContext;->getCurrentExpressionNodeStack()Lorg/apache/xml/utils/IntStack;
+Lorg/apache/xpath/XPathContext;->getCurrentNode()I
+Lorg/apache/xpath/XPathContext;->getCurrentNodeStack()Lorg/apache/xml/utils/IntStack;
+Lorg/apache/xpath/XPathContext;->getDTM(I)Lorg/apache/xml/dtm/DTM;
+Lorg/apache/xpath/XPathContext;->getDTMHandleFromNode(Lorg/w3c/dom/Node;)I
+Lorg/apache/xpath/XPathContext;->getDTMManager()Lorg/apache/xml/dtm/DTMManager;
+Lorg/apache/xpath/XPathContext;->getExpressionContext()Lorg/apache/xalan/extensions/ExpressionContext;
+Lorg/apache/xpath/XPathContext;->getNamespaceContext()Lorg/apache/xml/utils/PrefixResolver;
+Lorg/apache/xpath/XPathContext;->getOwnerObject()Ljava/lang/Object;
+Lorg/apache/xpath/XPathContext;->getSAXLocator()Ljavax/xml/transform/SourceLocator;
+Lorg/apache/xpath/XPathContext;->getVarStack()Lorg/apache/xpath/VariableStack;
+Lorg/apache/xpath/XPathContext;->m_dtmManager:Lorg/apache/xml/dtm/DTMManager;
+Lorg/apache/xpath/XPathContext;->popContextNodeList()V
+Lorg/apache/xpath/XPathContext;->popCurrentNode()V
+Lorg/apache/xpath/XPathContext;->pushContextNodeList(Lorg/apache/xml/dtm/DTMIterator;)V
+Lorg/apache/xpath/XPathContext;->pushCurrentNode(I)V
+Lorg/apache/xpath/XPathContext;->reset()V
+Lorg/apache/xpath/XPathContext;->setAxesIteratorStackStacks(Ljava/util/Stack;)V
+Lorg/apache/xpath/XPathContext;->setContextNodeListsStack(Ljava/util/Stack;)V
+Lorg/apache/xpath/XPathContext;->setCurrentExpressionNodeStack(Lorg/apache/xml/utils/IntStack;)V
+Lorg/apache/xpath/XPathContext;->setCurrentNodeStack(Lorg/apache/xml/utils/IntStack;)V
+Lorg/apache/xpath/XPathContext;->setSecureProcessing(Z)V
+Lorg/apache/xpath/XPathContext;->setVarStack(Lorg/apache/xpath/VariableStack;)V
+Lorg/ccil/cowan/tagsoup/AttributesImpl;-><init>(Lorg/xml/sax/Attributes;)V
+Lorg/ccil/cowan/tagsoup/AttributesImpl;->addAttribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
Lorg/ccil/cowan/tagsoup/AttributesImpl;->data:[Ljava/lang/String;
Lorg/ccil/cowan/tagsoup/AttributesImpl;->length:I
+Lorg/ccil/cowan/tagsoup/AttributesImpl;->setAttribute(ILjava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lorg/ccil/cowan/tagsoup/AttributesImpl;->setValue(ILjava/lang/String;)V
+Lorg/ccil/cowan/tagsoup/AutoDetector;->autoDetectingReader(Ljava/io/InputStream;)Ljava/io/Reader;
+Lorg/ccil/cowan/tagsoup/Element;-><init>(Lorg/ccil/cowan/tagsoup/ElementType;Z)V
+Lorg/ccil/cowan/tagsoup/Element;->anonymize()V
+Lorg/ccil/cowan/tagsoup/Element;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
+Lorg/ccil/cowan/tagsoup/Element;->canContain(Lorg/ccil/cowan/tagsoup/Element;)Z
+Lorg/ccil/cowan/tagsoup/Element;->clean()V
+Lorg/ccil/cowan/tagsoup/Element;->flags()I
+Lorg/ccil/cowan/tagsoup/Element;->localName()Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Element;->name()Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Element;->namespace()Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Element;->next()Lorg/ccil/cowan/tagsoup/Element;
+Lorg/ccil/cowan/tagsoup/Element;->parent()Lorg/ccil/cowan/tagsoup/ElementType;
+Lorg/ccil/cowan/tagsoup/Element;->preclosed:Z
+Lorg/ccil/cowan/tagsoup/Element;->setAttribute(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lorg/ccil/cowan/tagsoup/Element;->setNext(Lorg/ccil/cowan/tagsoup/Element;)V
+Lorg/ccil/cowan/tagsoup/Element;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl;
+Lorg/ccil/cowan/tagsoup/Element;->theNext:Lorg/ccil/cowan/tagsoup/Element;
+Lorg/ccil/cowan/tagsoup/Element;->theType:Lorg/ccil/cowan/tagsoup/ElementType;
+Lorg/ccil/cowan/tagsoup/ElementType;-><init>(Ljava/lang/String;IIILorg/ccil/cowan/tagsoup/Schema;)V
+Lorg/ccil/cowan/tagsoup/ElementType;->atts()Lorg/ccil/cowan/tagsoup/AttributesImpl;
+Lorg/ccil/cowan/tagsoup/ElementType;->setAttribute(Lorg/ccil/cowan/tagsoup/AttributesImpl;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
Lorg/ccil/cowan/tagsoup/ElementType;->theAtts:Lorg/ccil/cowan/tagsoup/AttributesImpl;
Lorg/ccil/cowan/tagsoup/ElementType;->theFlags:I
Lorg/ccil/cowan/tagsoup/ElementType;->theLocalName:Ljava/lang/String;
@@ -2292,91 +5642,500 @@ Lorg/ccil/cowan/tagsoup/ElementType;->theName:Ljava/lang/String;
Lorg/ccil/cowan/tagsoup/ElementType;->theNamespace:Ljava/lang/String;
Lorg/ccil/cowan/tagsoup/ElementType;->theParent:Lorg/ccil/cowan/tagsoup/ElementType;
Lorg/ccil/cowan/tagsoup/ElementType;->theSchema:Lorg/ccil/cowan/tagsoup/Schema;
+Lorg/ccil/cowan/tagsoup/HTMLScanner;-><init>()V
Lorg/ccil/cowan/tagsoup/HTMLSchema;-><init>()V
+Lorg/ccil/cowan/tagsoup/jaxp/SAXFactoryImpl;-><init>()V
+Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;-><init>()V
+Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;->newInstance(Ljava/util/Map;)Lorg/ccil/cowan/tagsoup/jaxp/SAXParserImpl;
Lorg/ccil/cowan/tagsoup/Parser;-><init>()V
+Lorg/ccil/cowan/tagsoup/Parser;->bogonsEmpty:Z
+Lorg/ccil/cowan/tagsoup/Parser;->CDATAElements:Z
+Lorg/ccil/cowan/tagsoup/Parser;->cleanPublicid(Ljava/lang/String;)Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->defaultAttributes:Z
+Lorg/ccil/cowan/tagsoup/Parser;->etagchars:[C
+Lorg/ccil/cowan/tagsoup/Parser;->expandEntities(Ljava/lang/String;)Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->getInputStream(Ljava/lang/String;Ljava/lang/String;)Ljava/io/InputStream;
+Lorg/ccil/cowan/tagsoup/Parser;->ignorableWhitespace:Z
+Lorg/ccil/cowan/tagsoup/Parser;->ignoreBogons:Z
+Lorg/ccil/cowan/tagsoup/Parser;->lookupEntity([CII)I
+Lorg/ccil/cowan/tagsoup/Parser;->makeName([CII)Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->pop()V
+Lorg/ccil/cowan/tagsoup/Parser;->push(Lorg/ccil/cowan/tagsoup/Element;)V
+Lorg/ccil/cowan/tagsoup/Parser;->rectify(Lorg/ccil/cowan/tagsoup/Element;)V
+Lorg/ccil/cowan/tagsoup/Parser;->restart(Lorg/ccil/cowan/tagsoup/Element;)V
+Lorg/ccil/cowan/tagsoup/Parser;->restartablyPop()V
+Lorg/ccil/cowan/tagsoup/Parser;->rootBogons:Z
+Lorg/ccil/cowan/tagsoup/Parser;->schemaProperty:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->split(Ljava/lang/String;)[Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->theAttributeName:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->theAutoDetector:Lorg/ccil/cowan/tagsoup/AutoDetector;
+Lorg/ccil/cowan/tagsoup/Parser;->theContentHandler:Lorg/xml/sax/ContentHandler;
+Lorg/ccil/cowan/tagsoup/Parser;->theDoctypeIsPresent:Z
+Lorg/ccil/cowan/tagsoup/Parser;->theDoctypeSystemId:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->theFeatures:Ljava/util/HashMap;
+Lorg/ccil/cowan/tagsoup/Parser;->theLexicalHandler:Lorg/xml/sax/ext/LexicalHandler;
+Lorg/ccil/cowan/tagsoup/Parser;->theNewElement:Lorg/ccil/cowan/tagsoup/Element;
+Lorg/ccil/cowan/tagsoup/Parser;->thePCDATA:Lorg/ccil/cowan/tagsoup/Element;
+Lorg/ccil/cowan/tagsoup/Parser;->thePITarget:Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->theSaved:Lorg/ccil/cowan/tagsoup/Element;
+Lorg/ccil/cowan/tagsoup/Parser;->theScanner:Lorg/ccil/cowan/tagsoup/Scanner;
+Lorg/ccil/cowan/tagsoup/Parser;->theSchema:Lorg/ccil/cowan/tagsoup/Schema;
+Lorg/ccil/cowan/tagsoup/Parser;->theStack:Lorg/ccil/cowan/tagsoup/Element;
+Lorg/ccil/cowan/tagsoup/Parser;->trimquotes(Ljava/lang/String;)Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Parser;->virginStack:Z
+Lorg/ccil/cowan/tagsoup/PYXScanner;-><init>()V
+Lorg/ccil/cowan/tagsoup/PYXWriter;-><init>(Ljava/io/Writer;)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->aname([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->aval([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->entity([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->eof([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->etag([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->gi([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->pcdata([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->pi([CII)V
+Lorg/ccil/cowan/tagsoup/ScanHandler;->stagc([CII)V
+Lorg/ccil/cowan/tagsoup/Scanner;->startCDATA()V
+Lorg/ccil/cowan/tagsoup/Schema;->elementType(Ljava/lang/String;III)V
+Lorg/ccil/cowan/tagsoup/Schema;->getElementType(Ljava/lang/String;)Lorg/ccil/cowan/tagsoup/ElementType;
+Lorg/ccil/cowan/tagsoup/Schema;->getEntity(Ljava/lang/String;)I
+Lorg/ccil/cowan/tagsoup/Schema;->getPrefix()Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Schema;->getURI()Ljava/lang/String;
+Lorg/ccil/cowan/tagsoup/Schema;->parent(Ljava/lang/String;Ljava/lang/String;)V
Lorg/ccil/cowan/tagsoup/Schema;->theElementTypes:Ljava/util/HashMap;
Lorg/ccil/cowan/tagsoup/Schema;->theEntities:Ljava/util/HashMap;
Lorg/ccil/cowan/tagsoup/Schema;->thePrefix:Ljava/lang/String;
Lorg/ccil/cowan/tagsoup/Schema;->theRoot:Lorg/ccil/cowan/tagsoup/ElementType;
Lorg/ccil/cowan/tagsoup/Schema;->theURI:Ljava/lang/String;
-Lsun/misc/Cleaner;->clean()V
-Lsun/misc/Unsafe;->addressSize()I
-Lsun/misc/Unsafe;->allocateInstance(Ljava/lang/Class;)Ljava/lang/Object;
-Lsun/misc/Unsafe;->allocateMemory(J)J
-Lsun/misc/Unsafe;->arrayBaseOffset(Ljava/lang/Class;)I
-Lsun/misc/Unsafe;->arrayIndexScale(Ljava/lang/Class;)I
-Lsun/misc/Unsafe;->compareAndSwapInt(Ljava/lang/Object;JII)Z
-Lsun/misc/Unsafe;->compareAndSwapLong(Ljava/lang/Object;JJJ)Z
-Lsun/misc/Unsafe;->compareAndSwapObject(Ljava/lang/Object;JLjava/lang/Object;Ljava/lang/Object;)Z
-Lsun/misc/Unsafe;->copyMemory(JJJ)V
-Lsun/misc/Unsafe;->copyMemoryFromPrimitiveArray(Ljava/lang/Object;JJJ)V
-Lsun/misc/Unsafe;->copyMemoryToPrimitiveArray(JLjava/lang/Object;JJ)V
-Lsun/misc/Unsafe;->freeMemory(J)V
-Lsun/misc/Unsafe;->fullFence()V
-Lsun/misc/Unsafe;->getAndAddInt(Ljava/lang/Object;JI)I
-Lsun/misc/Unsafe;->getAndAddLong(Ljava/lang/Object;JJ)J
-Lsun/misc/Unsafe;->getAndSetInt(Ljava/lang/Object;JI)I
-Lsun/misc/Unsafe;->getAndSetLong(Ljava/lang/Object;JJ)J
-Lsun/misc/Unsafe;->getAndSetObject(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;
-Lsun/misc/Unsafe;->getArrayBaseOffsetForComponentType(Ljava/lang/Class;)I
-Lsun/misc/Unsafe;->getArrayIndexScaleForComponentType(Ljava/lang/Class;)I
-Lsun/misc/Unsafe;->getBoolean(Ljava/lang/Object;J)Z
-Lsun/misc/Unsafe;->getByte(J)B
-Lsun/misc/Unsafe;->getByte(Ljava/lang/Object;J)B
-Lsun/misc/Unsafe;->getChar(J)C
-Lsun/misc/Unsafe;->getChar(Ljava/lang/Object;J)C
-Lsun/misc/Unsafe;->getDouble(J)D
-Lsun/misc/Unsafe;->getDouble(Ljava/lang/Object;J)D
-Lsun/misc/Unsafe;->getFloat(J)F
-Lsun/misc/Unsafe;->getFloat(Ljava/lang/Object;J)F
-Lsun/misc/Unsafe;->getInt(J)I
-Lsun/misc/Unsafe;->getInt(Ljava/lang/Object;J)I
-Lsun/misc/Unsafe;->getIntVolatile(Ljava/lang/Object;J)I
-Lsun/misc/Unsafe;->getLong(J)J
-Lsun/misc/Unsafe;->getLong(Ljava/lang/Object;J)J
-Lsun/misc/Unsafe;->getLongVolatile(Ljava/lang/Object;J)J
-Lsun/misc/Unsafe;->getObject(Ljava/lang/Object;J)Ljava/lang/Object;
-Lsun/misc/Unsafe;->getObjectVolatile(Ljava/lang/Object;J)Ljava/lang/Object;
-Lsun/misc/Unsafe;->getShort(J)S
-Lsun/misc/Unsafe;->getShort(Ljava/lang/Object;J)S
-Lsun/misc/Unsafe;->getUnsafe()Lsun/misc/Unsafe;
-Lsun/misc/Unsafe;->INVALID_FIELD_OFFSET:I
-Lsun/misc/Unsafe;->loadFence()V
-Lsun/misc/Unsafe;->objectFieldOffset(Ljava/lang/reflect/Field;)J
-Lsun/misc/Unsafe;->pageSize()I
-Lsun/misc/Unsafe;->park(ZJ)V
-Lsun/misc/Unsafe;->putBoolean(Ljava/lang/Object;JZ)V
-Lsun/misc/Unsafe;->putByte(JB)V
-Lsun/misc/Unsafe;->putByte(Ljava/lang/Object;JB)V
-Lsun/misc/Unsafe;->putChar(JC)V
-Lsun/misc/Unsafe;->putChar(Ljava/lang/Object;JC)V
-Lsun/misc/Unsafe;->putDouble(JD)V
-Lsun/misc/Unsafe;->putDouble(Ljava/lang/Object;JD)V
-Lsun/misc/Unsafe;->putFloat(JF)V
-Lsun/misc/Unsafe;->putFloat(Ljava/lang/Object;JF)V
-Lsun/misc/Unsafe;->putInt(JI)V
-Lsun/misc/Unsafe;->putInt(Ljava/lang/Object;JI)V
-Lsun/misc/Unsafe;->putIntVolatile(Ljava/lang/Object;JI)V
-Lsun/misc/Unsafe;->putLong(JJ)V
-Lsun/misc/Unsafe;->putLong(Ljava/lang/Object;JJ)V
-Lsun/misc/Unsafe;->putLongVolatile(Ljava/lang/Object;JJ)V
-Lsun/misc/Unsafe;->putObject(Ljava/lang/Object;JLjava/lang/Object;)V
-Lsun/misc/Unsafe;->putObjectVolatile(Ljava/lang/Object;JLjava/lang/Object;)V
-Lsun/misc/Unsafe;->putOrderedInt(Ljava/lang/Object;JI)V
-Lsun/misc/Unsafe;->putOrderedLong(Ljava/lang/Object;JJ)V
-Lsun/misc/Unsafe;->putOrderedObject(Ljava/lang/Object;JLjava/lang/Object;)V
-Lsun/misc/Unsafe;->putShort(JS)V
-Lsun/misc/Unsafe;->putShort(Ljava/lang/Object;JS)V
-Lsun/misc/Unsafe;->setMemory(JJB)V
-Lsun/misc/Unsafe;->storeFence()V
-Lsun/misc/Unsafe;->theUnsafe:Lsun/misc/Unsafe;
-Lsun/misc/Unsafe;->THE_ONE:Lsun/misc/Unsafe;
-Lsun/misc/Unsafe;->unpark(Ljava/lang/Object;)V
-Lsun/misc/URLClassPath$JarLoader;->getJarFile()Ljava/util/jar/JarFile;
-Lsun/misc/URLClassPath;->lmap:Ljava/util/HashMap;
-Lsun/misc/URLClassPath;->loaders:Ljava/util/ArrayList;
-Lsun/misc/URLClassPath;->urls:Ljava/util/Stack;
-Lsun/nio/ch/DirectBuffer;->cleaner()Lsun/misc/Cleaner;
-Lsun/security/x509/AlgorithmId;->get(Ljava/lang/String;)Lsun/security/x509/AlgorithmId;
-Lsun/security/x509/AlgorithmId;->getName()Ljava/lang/String;
-Lsun/security/x509/AVA;->hasRFC2253Keyword()Z
+Lorg/ccil/cowan/tagsoup/XMLWriter;-><init>(Ljava/io/Writer;)V
+Lorg/ccil/cowan/tagsoup/XMLWriter;->htmlMode:Z
+Lorg/ccil/cowan/tagsoup/XMLWriter;->setOutput(Ljava/io/Writer;)V
+Lorg/ccil/cowan/tagsoup/XMLWriter;->setOutputProperty(Ljava/lang/String;Ljava/lang/String;)V
+Lorg/ccil/cowan/tagsoup/XMLWriter;->setPrefix(Ljava/lang/String;Ljava/lang/String;)V
+Lorg/xml/sax/helpers/NamespaceSupport$Context;-><init>(Lorg/xml/sax/helpers/NamespaceSupport;)V
+Lorg/xml/sax/helpers/ParserAdapter$AttributeListAdapter;-><init>(Lorg/xml/sax/helpers/ParserAdapter;)V
+Lsun/misc/ASCIICaseInsensitiveComparator;->CASE_INSENSITIVE_ORDER:Ljava/util/Comparator;
+Lsun/misc/ASCIICaseInsensitiveComparator;->lowerCaseHashCode(Ljava/lang/String;)I
+Lsun/misc/BASE64Decoder;-><init>()V
+Lsun/misc/BASE64Decoder;->pem_convert_array:[B
+Lsun/misc/BASE64Encoder;-><init>()V
+Lsun/misc/BASE64Encoder;->pem_array:[C
+Lsun/misc/CEFormatException;-><init>(Ljava/lang/String;)V
+Lsun/misc/CEStreamExhausted;-><init>()V
+Lsun/misc/CharacterDecoder;-><init>()V
+Lsun/misc/CharacterEncoder;-><init>()V
+Lsun/misc/CharacterEncoder;->encodeBuffer([B)Ljava/lang/String;
+Lsun/misc/CharacterEncoder;->encodeBufferPrefix(Ljava/io/OutputStream;)V
+Lsun/misc/CharacterEncoder;->pStream:Ljava/io/PrintStream;
+Lsun/misc/Cleaner;->create(Ljava/lang/Object;Ljava/lang/Runnable;)Lsun/misc/Cleaner;
+Lsun/misc/FloatingDecimal;->$assertionsDisabled:Z
+Lsun/misc/FloatingDecimal;->getHexDigit(Ljava/lang/String;I)I
+Lsun/misc/FloatingDecimal;->stripLeadingZeros(Ljava/lang/String;)Ljava/lang/String;
+Lsun/misc/FormattedFloatingDecimal$Form;->COMPATIBLE:Lsun/misc/FormattedFloatingDecimal$Form;
+Lsun/misc/FormattedFloatingDecimal$Form;->DECIMAL_FLOAT:Lsun/misc/FormattedFloatingDecimal$Form;
+Lsun/misc/FormattedFloatingDecimal$Form;->SCIENTIFIC:Lsun/misc/FormattedFloatingDecimal$Form;
+Lsun/misc/FormattedFloatingDecimal;->$assertionsDisabled:Z
+Lsun/misc/FpUtils;->$assertionsDisabled:Z
+Lsun/misc/FpUtils;->rawCopySign(DD)D
+Lsun/misc/HexDumpEncoder;-><init>()V
+Lsun/misc/HexDumpEncoder;->currentByte:I
+Lsun/misc/HexDumpEncoder;->offset:I
+Lsun/misc/HexDumpEncoder;->thisLine:[B
+Lsun/misc/HexDumpEncoder;->thisLineLength:I
+Lsun/misc/IOUtils;->readFully(Ljava/io/InputStream;IZ)[B
+Lsun/misc/JarIndex;-><init>([Ljava/lang/String;)V
+Lsun/misc/JarIndex;->write(Ljava/io/OutputStream;)V
+Lsun/misc/MessageUtils;-><init>()V
+Lsun/misc/MetaIndex;->forJar(Ljava/io/File;)Lsun/misc/MetaIndex;
+Lsun/misc/MetaIndex;->registerDirectory(Ljava/io/File;)V
+Lsun/misc/VM;->maxDirectMemory()J
+Lsun/net/ftp/FtpClient;-><init>()V
+Lsun/net/util/IPAddressUtil;->isIPv4LiteralAddress(Ljava/lang/String;)Z
+Lsun/net/util/IPAddressUtil;->isIPv6LiteralAddress(Ljava/lang/String;)Z
+Lsun/net/www/MessageHeader;-><init>()V
+Lsun/net/www/MessageHeader;-><init>(Ljava/io/InputStream;)V
+Lsun/net/www/MessageHeader;->add(Ljava/lang/String;Ljava/lang/String;)V
+Lsun/net/www/MessageHeader;->findValue(Ljava/lang/String;)Ljava/lang/String;
+Lsun/net/www/MessageHeader;->prepend(Ljava/lang/String;Ljava/lang/String;)V
+Lsun/net/www/MessageHeader;->print(Ljava/io/PrintStream;)V
+Lsun/net/www/MessageHeader;->set(Ljava/lang/String;Ljava/lang/String;)V
+Lsun/net/www/ParseUtil;->decode(Ljava/lang/String;)Ljava/lang/String;
+Lsun/net/www/ParseUtil;->encodePath(Ljava/lang/String;Z)Ljava/lang/String;
+Lsun/net/www/ParseUtil;->fileToEncodedURL(Ljava/io/File;)Ljava/net/URL;
+Lsun/net/www/URLConnection;-><init>(Ljava/net/URL;)V
+Lsun/net/www/URLConnection;->setProperties(Lsun/net/www/MessageHeader;)V
+Lsun/nio/ch/DirectBuffer;->address()J
+Lsun/nio/ch/FileChannelImpl;->unmap0(JJ)I
+Lsun/nio/ch/SelectorImpl;->publicSelectedKeys:Ljava/util/Set;
+Lsun/nio/ch/SelectorImpl;->selectedKeys:Ljava/util/Set;
+Lsun/nio/cs/HistoricallyNamedCharset;->historicalName()Ljava/lang/String;
+Lsun/nio/cs/ThreadLocalCoders;->decoderFor(Ljava/lang/Object;)Ljava/nio/charset/CharsetDecoder;
+Lsun/nio/fs/BasicFileAttributesHolder;->get()Ljava/nio/file/attribute/BasicFileAttributes;
+Lsun/reflect/misc/ReflectUtil;->checkPackageAccess(Ljava/lang/Class;)V
+Lsun/reflect/misc/ReflectUtil;->checkPackageAccess(Ljava/lang/String;)V
+Lsun/reflect/misc/ReflectUtil;->isPackageAccessible(Ljava/lang/Class;)Z
+Lsun/reflect/misc/ReflectUtil;->isSubclassOf(Ljava/lang/Class;Ljava/lang/Class;)Z
+Lsun/reflect/Reflection;->ensureMemberAccess(Ljava/lang/Class;Ljava/lang/Class;Ljava/lang/Object;I)V
+Lsun/reflect/Reflection;->isSubclassOf(Ljava/lang/Class;Ljava/lang/Class;)Z
+Lsun/security/action/GetBooleanAction;-><init>(Ljava/lang/String;)V
+Lsun/security/action/GetIntegerAction;-><init>(Ljava/lang/String;I)V
+Lsun/security/action/GetPropertyAction;-><init>(Ljava/lang/String;)V
+Lsun/security/action/GetPropertyAction;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Lsun/security/jca/GetInstance$Instance;->impl:Ljava/lang/Object;
+Lsun/security/jca/GetInstance$Instance;->provider:Ljava/security/Provider;
+Lsun/security/jca/GetInstance;->getInstance(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Lsun/security/jca/GetInstance$Instance;
+Lsun/security/jca/GetInstance;->getInstance(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;Ljava/lang/String;)Lsun/security/jca/GetInstance$Instance;
+Lsun/security/jca/GetInstance;->getInstance(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/String;Ljava/lang/Object;Ljava/security/Provider;)Lsun/security/jca/GetInstance$Instance;
+Lsun/security/jca/JCAUtil;->getSecureRandom()Ljava/security/SecureRandom;
+Lsun/security/jca/ProviderConfig;->argument:Ljava/lang/String;
+Lsun/security/jca/ProviderConfig;->CL_STRING:[Ljava/lang/Class;
+Lsun/security/jca/ProviderConfig;->disableLoad()V
+Lsun/security/jca/ProviderConfig;->hasArgument()Z
+Lsun/security/jca/ProviderList;->getService(Ljava/lang/String;Ljava/lang/String;)Ljava/security/Provider$Service;
+Lsun/security/jca/Providers;->getProviderList()Lsun/security/jca/ProviderList;
+Lsun/security/jca/Providers;->startJarVerification()Ljava/lang/Object;
+Lsun/security/jca/Providers;->stopJarVerification(Ljava/lang/Object;)V
+Lsun/security/pkcs/ContentInfo;-><init>(Lsun/security/util/ObjectIdentifier;Lsun/security/util/DerValue;)V
+Lsun/security/pkcs/ContentInfo;-><init>([B)V
+Lsun/security/pkcs/ContentInfo;->DATA_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/pkcs/ContentInfo;->encode(Lsun/security/util/DerOutputStream;)V
+Lsun/security/pkcs/ContentInfo;->getData()[B
+Lsun/security/pkcs/ParsingException;-><init>(Ljava/lang/String;)V
+Lsun/security/pkcs/PKCS7;-><init>([B)V
+Lsun/security/pkcs/PKCS7;-><init>([Lsun/security/x509/AlgorithmId;Lsun/security/pkcs/ContentInfo;[Ljava/security/cert/X509Certificate;[Ljava/security/cert/X509CRL;[Lsun/security/pkcs/SignerInfo;)V
+Lsun/security/pkcs/PKCS7;-><init>([Lsun/security/x509/AlgorithmId;Lsun/security/pkcs/ContentInfo;[Ljava/security/cert/X509Certificate;[Lsun/security/pkcs/SignerInfo;)V
+Lsun/security/pkcs/PKCS7;->encodeSignedData(Ljava/io/OutputStream;)V
+Lsun/security/pkcs/PKCS7;->getCertificates()[Ljava/security/cert/X509Certificate;
+Lsun/security/pkcs/PKCS7;->getContentInfo()Lsun/security/pkcs/ContentInfo;
+Lsun/security/pkcs/PKCS7;->getSignerInfos()[Lsun/security/pkcs/SignerInfo;
+Lsun/security/pkcs/PKCS7;->verify(Lsun/security/pkcs/SignerInfo;[B)Lsun/security/pkcs/SignerInfo;
+Lsun/security/pkcs/PKCS7;->verify([B)[Lsun/security/pkcs/SignerInfo;
+Lsun/security/pkcs/PKCS8Key;-><init>()V
+Lsun/security/pkcs/PKCS8Key;->algid:Lsun/security/x509/AlgorithmId;
+Lsun/security/pkcs/PKCS8Key;->encodedKey:[B
+Lsun/security/pkcs/PKCS8Key;->key:[B
+Lsun/security/pkcs/PKCS9Attribute;-><init>(Ljava/lang/String;Ljava/lang/Object;)V
+Lsun/security/pkcs/PKCS9Attribute;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/pkcs/PKCS9Attribute;-><init>(Lsun/security/util/ObjectIdentifier;Ljava/lang/Object;)V
+Lsun/security/pkcs/PKCS9Attribute;->CONTENT_TYPE_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/pkcs/PKCS9Attribute;->derEncode(Ljava/io/OutputStream;)V
+Lsun/security/pkcs/PKCS9Attribute;->EMAIL_ADDRESS_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/pkcs/PKCS9Attribute;->getOID()Lsun/security/util/ObjectIdentifier;
+Lsun/security/pkcs/PKCS9Attribute;->getValue()Ljava/lang/Object;
+Lsun/security/pkcs/PKCS9Attribute;->MESSAGE_DIGEST_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/pkcs/PKCS9Attribute;->SIGNING_TIME_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/pkcs/PKCS9Attributes;-><init>(Lsun/security/util/DerInputStream;)V
+Lsun/security/pkcs/PKCS9Attributes;-><init>(Lsun/security/util/DerInputStream;Z)V
+Lsun/security/pkcs/PKCS9Attributes;-><init>([Lsun/security/pkcs/PKCS9Attribute;)V
+Lsun/security/pkcs/PKCS9Attributes;->encode(BLjava/io/OutputStream;)V
+Lsun/security/pkcs/PKCS9Attributes;->getAttribute(Ljava/lang/String;)Lsun/security/pkcs/PKCS9Attribute;
+Lsun/security/pkcs/PKCS9Attributes;->getAttributeValue(Lsun/security/util/ObjectIdentifier;)Ljava/lang/Object;
+Lsun/security/pkcs/PKCS9Attributes;->getDerEncoding()[B
+Lsun/security/pkcs/SignerInfo;-><init>(Lsun/security/x509/X500Name;Ljava/math/BigInteger;Lsun/security/x509/AlgorithmId;Lsun/security/pkcs/PKCS9Attributes;Lsun/security/x509/AlgorithmId;[BLsun/security/pkcs/PKCS9Attributes;)V
+Lsun/security/pkcs/SignerInfo;-><init>(Lsun/security/x509/X500Name;Ljava/math/BigInteger;Lsun/security/x509/AlgorithmId;Lsun/security/x509/AlgorithmId;[B)V
+Lsun/security/pkcs/SignerInfo;->getCertificate(Lsun/security/pkcs/PKCS7;)Ljava/security/cert/X509Certificate;
+Lsun/security/pkcs/SignerInfo;->getCertificateChain(Lsun/security/pkcs/PKCS7;)Ljava/util/ArrayList;
+Lsun/security/pkcs/SignerInfo;->getDigestAlgorithmId()Lsun/security/x509/AlgorithmId;
+Lsun/security/pkcs/SignerInfo;->getDigestEncryptionAlgorithmId()Lsun/security/x509/AlgorithmId;
+Lsun/security/pkcs/SignerInfo;->getEncryptedDigest()[B
+Lsun/security/provider/certpath/X509CertificatePair;->clearCache()V
+Lsun/security/provider/certpath/X509CertPath;-><init>(Ljava/io/InputStream;)V
+Lsun/security/provider/certpath/X509CertPath;-><init>(Ljava/io/InputStream;Ljava/lang/String;)V
+Lsun/security/provider/certpath/X509CertPath;-><init>(Ljava/util/List;)V
+Lsun/security/provider/certpath/X509CertPath;->certs:Ljava/util/List;
+Lsun/security/provider/certpath/X509CertPath;->getEncodingsStatic()Ljava/util/Iterator;
+Lsun/security/provider/X509Factory;->addToCache(Lsun/security/util/Cache;[BLjava/lang/Object;)V
+Lsun/security/provider/X509Factory;->certCache:Lsun/security/util/Cache;
+Lsun/security/provider/X509Factory;->crlCache:Lsun/security/util/Cache;
+Lsun/security/provider/X509Factory;->getFromCache(Lsun/security/util/Cache;[B)Ljava/lang/Object;
+Lsun/security/provider/X509Factory;->intern(Ljava/security/cert/X509Certificate;)Lsun/security/x509/X509CertImpl;
+Lsun/security/provider/X509Factory;->intern(Ljava/security/cert/X509CRL;)Lsun/security/x509/X509CRLImpl;
+Lsun/security/timestamp/TimestampToken;-><init>([B)V
+Lsun/security/timestamp/TimestampToken;->getDate()Ljava/util/Date;
+Lsun/security/timestamp/TimestampToken;->getHashAlgorithm()Lsun/security/x509/AlgorithmId;
+Lsun/security/timestamp/TimestampToken;->getHashedMessage()[B
+Lsun/security/timestamp/TimestampToken;->getNonce()Ljava/math/BigInteger;
+Lsun/security/util/BitArray;-><init>(I[B)V
+Lsun/security/util/BitArray;->toByteArray()[B
+Lsun/security/util/Cache;-><init>()V
+Lsun/security/util/Cache;->clear()V
+Lsun/security/util/Cache;->get(Ljava/lang/Object;)Ljava/lang/Object;
+Lsun/security/util/Cache;->newHardMemoryCache(I)Lsun/security/util/Cache;
+Lsun/security/util/Cache;->put(Ljava/lang/Object;Ljava/lang/Object;)V
+Lsun/security/util/Debug;->getInstance(Ljava/lang/String;)Lsun/security/util/Debug;
+Lsun/security/util/Debug;->println()V
+Lsun/security/util/Debug;->println(Ljava/lang/String;)V
+Lsun/security/util/Debug;->toHexString(Ljava/math/BigInteger;)Ljava/lang/String;
+Lsun/security/util/DerIndefLenConverter;-><init>()V
+Lsun/security/util/DerIndefLenConverter;->convert([B)[B
+Lsun/security/util/DerIndefLenConverter;->data:[B
+Lsun/security/util/DerIndefLenConverter;->dataPos:I
+Lsun/security/util/DerIndefLenConverter;->dataSize:I
+Lsun/security/util/DerIndefLenConverter;->isIndefinite(I)Z
+Lsun/security/util/DerIndefLenConverter;->newData:[B
+Lsun/security/util/DerIndefLenConverter;->numOfTotalLenBytes:I
+Lsun/security/util/DerIndefLenConverter;->parseLength()I
+Lsun/security/util/DerIndefLenConverter;->parseTag()V
+Lsun/security/util/DerIndefLenConverter;->parseValue(I)V
+Lsun/security/util/DerIndefLenConverter;->writeLengthAndValue()V
+Lsun/security/util/DerIndefLenConverter;->writeTag()V
+Lsun/security/util/DerInputStream;-><init>([B)V
+Lsun/security/util/DerInputStream;->available()I
+Lsun/security/util/DerInputStream;->getBigInteger()Ljava/math/BigInteger;
+Lsun/security/util/DerInputStream;->getBitString()[B
+Lsun/security/util/DerInputStream;->getDerValue()Lsun/security/util/DerValue;
+Lsun/security/util/DerInputStream;->getInteger()I
+Lsun/security/util/DerInputStream;->getOctetString()[B
+Lsun/security/util/DerInputStream;->getOID()Lsun/security/util/ObjectIdentifier;
+Lsun/security/util/DerInputStream;->getSequence(I)[Lsun/security/util/DerValue;
+Lsun/security/util/DerInputStream;->getSet(I)[Lsun/security/util/DerValue;
+Lsun/security/util/DerInputStream;->getSet(IZ)[Lsun/security/util/DerValue;
+Lsun/security/util/DerInputStream;->getUTCTime()Ljava/util/Date;
+Lsun/security/util/DerInputStream;->getUTF8String()Ljava/lang/String;
+Lsun/security/util/DerInputStream;->mark(I)V
+Lsun/security/util/DerInputStream;->peekByte()I
+Lsun/security/util/DerInputStream;->reset()V
+Lsun/security/util/DerInputStream;->subStream(IZ)Lsun/security/util/DerInputStream;
+Lsun/security/util/DerInputStream;->tag:B
+Lsun/security/util/DerOutputStream;-><init>()V
+Lsun/security/util/DerOutputStream;-><init>(I)V
+Lsun/security/util/DerOutputStream;->putBitString([B)V
+Lsun/security/util/DerOutputStream;->putBoolean(Z)V
+Lsun/security/util/DerOutputStream;->putDerValue(Lsun/security/util/DerValue;)V
+Lsun/security/util/DerOutputStream;->putIA5String(Ljava/lang/String;)V
+Lsun/security/util/DerOutputStream;->putInteger(I)V
+Lsun/security/util/DerOutputStream;->putInteger(Ljava/math/BigInteger;)V
+Lsun/security/util/DerOutputStream;->putNull()V
+Lsun/security/util/DerOutputStream;->putOctetString([B)V
+Lsun/security/util/DerOutputStream;->putOID(Lsun/security/util/ObjectIdentifier;)V
+Lsun/security/util/DerOutputStream;->putOrderedSetOf(B[Lsun/security/util/DerEncoder;)V
+Lsun/security/util/DerOutputStream;->putPrintableString(Ljava/lang/String;)V
+Lsun/security/util/DerOutputStream;->putSequence([Lsun/security/util/DerValue;)V
+Lsun/security/util/DerOutputStream;->putUTCTime(Ljava/util/Date;)V
+Lsun/security/util/DerOutputStream;->putUTF8String(Ljava/lang/String;)V
+Lsun/security/util/DerOutputStream;->write(BLsun/security/util/DerOutputStream;)V
+Lsun/security/util/DerOutputStream;->write(B[B)V
+Lsun/security/util/DerValue;-><init>(B[B)V
+Lsun/security/util/DerValue;-><init>(Ljava/io/InputStream;)V
+Lsun/security/util/DerValue;-><init>(Ljava/lang/String;)V
+Lsun/security/util/DerValue;-><init>([B)V
+Lsun/security/util/DerValue;-><init>([BII)V
+Lsun/security/util/DerValue;->buffer:Lsun/security/util/DerInputBuffer;
+Lsun/security/util/DerValue;->createTag(BZB)B
+Lsun/security/util/DerValue;->data:Lsun/security/util/DerInputStream;
+Lsun/security/util/DerValue;->encode(Lsun/security/util/DerOutputStream;)V
+Lsun/security/util/DerValue;->getAsString()Ljava/lang/String;
+Lsun/security/util/DerValue;->getBigInteger()Ljava/math/BigInteger;
+Lsun/security/util/DerValue;->getBitString()[B
+Lsun/security/util/DerValue;->getData()Lsun/security/util/DerInputStream;
+Lsun/security/util/DerValue;->getDataBytes()[B
+Lsun/security/util/DerValue;->getOctetString()[B
+Lsun/security/util/DerValue;->getOID()Lsun/security/util/ObjectIdentifier;
+Lsun/security/util/DerValue;->getPositiveBigInteger()Ljava/math/BigInteger;
+Lsun/security/util/DerValue;->getUnalignedBitString()Lsun/security/util/BitArray;
+Lsun/security/util/DerValue;->isConstructed()Z
+Lsun/security/util/DerValue;->isContextSpecific()Z
+Lsun/security/util/DerValue;->isContextSpecific(B)Z
+Lsun/security/util/DerValue;->isPrintableStringChar(C)Z
+Lsun/security/util/DerValue;->resetTag(B)V
+Lsun/security/util/DerValue;->tag:B
+Lsun/security/util/DerValue;->toByteArray()[B
+Lsun/security/util/DerValue;->toDerInputStream()Lsun/security/util/DerInputStream;
+Lsun/security/util/ManifestDigester$Entry;->digest(Ljava/security/MessageDigest;)[B
+Lsun/security/util/ManifestDigester$Entry;->digestWorkaround(Ljava/security/MessageDigest;)[B
+Lsun/security/util/ManifestDigester;-><init>([B)V
+Lsun/security/util/ManifestDigester;->get(Ljava/lang/String;Z)Lsun/security/util/ManifestDigester$Entry;
+Lsun/security/util/ManifestDigester;->manifestDigest(Ljava/security/MessageDigest;)[B
+Lsun/security/util/MemoryCache$HardCacheEntry;-><init>(Ljava/lang/Object;Ljava/lang/Object;J)V
+Lsun/security/util/MemoryCache$SoftCacheEntry;-><init>(Ljava/lang/Object;Ljava/lang/Object;JLjava/lang/ref/ReferenceQueue;)V
+Lsun/security/util/ObjectIdentifier;-><init>(Ljava/lang/String;)V
+Lsun/security/util/ObjectIdentifier;-><init>([I)V
+Lsun/security/util/ObjectIdentifier;->equals(Lsun/security/util/ObjectIdentifier;)Z
+Lsun/security/util/ObjectIdentifier;->newInternal([I)Lsun/security/util/ObjectIdentifier;
+Lsun/security/util/PropertyExpander;->expand(Ljava/lang/String;)Ljava/lang/String;
+Lsun/security/util/ResourcesMgr;->getString(Ljava/lang/String;)Ljava/lang/String;
+Lsun/security/util/SecurityConstants;->CREATE_CLASSLOADER_PERMISSION:Ljava/lang/RuntimePermission;
+Lsun/security/util/SecurityConstants;->GET_CLASSLOADER_PERMISSION:Ljava/lang/RuntimePermission;
+Lsun/security/util/SecurityConstants;->MODIFY_THREADGROUP_PERMISSION:Ljava/lang/RuntimePermission;
+Lsun/security/util/SecurityConstants;->MODIFY_THREAD_PERMISSION:Ljava/lang/RuntimePermission;
+Lsun/security/util/SignatureFileVerifier;->isBlockOrSF(Ljava/lang/String;)Z
+Lsun/security/x509/AccessDescription;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/x509/AccessDescription;->getAccessLocation()Lsun/security/x509/GeneralName;
+Lsun/security/x509/AccessDescription;->getAccessMethod()Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;-><init>()V
+Lsun/security/x509/AlgorithmId;-><init>(Lsun/security/util/ObjectIdentifier;)V
+Lsun/security/x509/AlgorithmId;-><init>(Lsun/security/util/ObjectIdentifier;Ljava/security/AlgorithmParameters;)V
+Lsun/security/x509/AlgorithmId;->derEncode(Ljava/io/OutputStream;)V
+Lsun/security/x509/AlgorithmId;->DSA_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->EC_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->encode()[B
+Lsun/security/x509/AlgorithmId;->encode(Lsun/security/util/DerOutputStream;)V
+Lsun/security/x509/AlgorithmId;->equals(Lsun/security/x509/AlgorithmId;)Z
+Lsun/security/x509/AlgorithmId;->getAlgorithmId(Ljava/lang/String;)Lsun/security/x509/AlgorithmId;
+Lsun/security/x509/AlgorithmId;->getDigAlgFromSigAlg(Ljava/lang/String;)Ljava/lang/String;
+Lsun/security/x509/AlgorithmId;->getEncAlgFromSigAlg(Ljava/lang/String;)Ljava/lang/String;
+Lsun/security/x509/AlgorithmId;->getEncodedParams()[B
+Lsun/security/x509/AlgorithmId;->getOID()Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->getParameters()Ljava/security/AlgorithmParameters;
+Lsun/security/x509/AlgorithmId;->MD2_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->MD5_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->params:Lsun/security/util/DerValue;
+Lsun/security/x509/AlgorithmId;->parse(Lsun/security/util/DerValue;)Lsun/security/x509/AlgorithmId;
+Lsun/security/x509/AlgorithmId;->RSAEncryption_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->sha1WithRSAEncryption_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->SHA256_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->SHA384_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->SHA512_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AlgorithmId;->SHA_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AttributeNameEnumeration;-><init>()V
+Lsun/security/x509/AVA;-><init>(Lsun/security/util/ObjectIdentifier;Lsun/security/util/DerValue;)V
+Lsun/security/x509/AVA;->getDerValue()Lsun/security/util/DerValue;
+Lsun/security/x509/AVA;->getObjectIdentifier()Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AVA;->getValueString()Ljava/lang/String;
+Lsun/security/x509/AVA;->toRFC2253CanonicalString()Ljava/lang/String;
+Lsun/security/x509/AVAComparator;->INSTANCE:Ljava/util/Comparator;
+Lsun/security/x509/AVAKeyword;->getOID(Ljava/lang/String;ILjava/util/Map;)Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AVAKeyword;->isCompliant(I)Z
+Lsun/security/x509/AVAKeyword;->keyword:Ljava/lang/String;
+Lsun/security/x509/AVAKeyword;->keywordMap:Ljava/util/Map;
+Lsun/security/x509/AVAKeyword;->oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/AVAKeyword;->oidMap:Ljava/util/Map;
+Lsun/security/x509/CertificateAlgorithmId;-><init>(Lsun/security/x509/AlgorithmId;)V
+Lsun/security/x509/CertificateExtensions;-><init>()V
+Lsun/security/x509/CertificateExtensions;-><init>(Lsun/security/util/DerInputStream;)V
+Lsun/security/x509/CertificateExtensions;->encode(Ljava/io/OutputStream;Z)V
+Lsun/security/x509/CertificateExtensions;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/CertificateExtensions;->set(Ljava/lang/String;Ljava/lang/Object;)V
+Lsun/security/x509/CertificateIssuerName;-><init>(Lsun/security/x509/X500Name;)V
+Lsun/security/x509/CertificateSerialNumber;-><init>(I)V
+Lsun/security/x509/CertificateSerialNumber;-><init>(Ljava/math/BigInteger;)V
+Lsun/security/x509/CertificateSubjectName;-><init>(Lsun/security/x509/X500Name;)V
+Lsun/security/x509/CertificateSubjectName;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/CertificateValidity;-><init>(Ljava/util/Date;Ljava/util/Date;)V
+Lsun/security/x509/CertificateVersion;-><init>(I)V
+Lsun/security/x509/CertificateX509Key;-><init>(Ljava/security/PublicKey;)V
+Lsun/security/x509/CRLDistributionPointsExtension;->encodeThis()V
+Lsun/security/x509/CRLNumberExtension;-><init>(Ljava/lang/Boolean;Ljava/lang/Object;)V
+Lsun/security/x509/CRLNumberExtension;->encodeThis()V
+Lsun/security/x509/CRLNumberExtension;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/Extension;-><init>(Lsun/security/x509/Extension;)V
+Lsun/security/x509/Extension;->encode(Lsun/security/util/DerOutputStream;)V
+Lsun/security/x509/Extension;->getExtensionId()Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/GeneralName;-><init>(Lsun/security/x509/GeneralNameInterface;)V
+Lsun/security/x509/GeneralName;->getName()Lsun/security/x509/GeneralNameInterface;
+Lsun/security/x509/GeneralName;->getType()I
+Lsun/security/x509/GeneralNames;-><init>()V
+Lsun/security/x509/GeneralNames;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/x509/GeneralNames;->add(Lsun/security/x509/GeneralName;)Lsun/security/x509/GeneralNames;
+Lsun/security/x509/GeneralNames;->encode(Lsun/security/util/DerOutputStream;)V
+Lsun/security/x509/GeneralNames;->isEmpty()Z
+Lsun/security/x509/KeyIdentifier;-><init>(Ljava/security/PublicKey;)V
+Lsun/security/x509/KeyIdentifier;->getIdentifier()[B
+Lsun/security/x509/KeyIdentifier;->octetString:[B
+Lsun/security/x509/KeyUsageExtension;-><init>([Z)V
+Lsun/security/x509/KeyUsageExtension;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/NetscapeCertTypeExtension;-><init>([B)V
+Lsun/security/x509/NetscapeCertTypeExtension;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/OIDMap$OIDInfo;->clazz:Ljava/lang/Class;
+Lsun/security/x509/OIDMap;->getClass(Lsun/security/util/ObjectIdentifier;)Ljava/lang/Class;
+Lsun/security/x509/OIDMap;->nameMap:Ljava/util/Map;
+Lsun/security/x509/OIDMap;->oidMap:Ljava/util/Map;
+Lsun/security/x509/PKIXExtensions;->CertificateIssuer_Id:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/SerialNumber;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/x509/SubjectAlternativeNameExtension;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/SubjectKeyIdentifierExtension;-><init>([B)V
+Lsun/security/x509/UniqueIdentity;-><init>(Lsun/security/util/DerInputStream;)V
+Lsun/security/x509/UniqueIdentity;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/x509/UniqueIdentity;->encode(Lsun/security/util/DerOutputStream;B)V
+Lsun/security/x509/URIName;->getName()Ljava/lang/String;
+Lsun/security/x509/URIName;->getScheme()Ljava/lang/String;
+Lsun/security/x509/X500Name;-><init>(Ljava/lang/String;)V
+Lsun/security/x509/X500Name;-><init>(Ljava/lang/String;Ljava/lang/String;)V
+Lsun/security/x509/X500Name;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lsun/security/x509/X500Name;-><init>(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
+Lsun/security/x509/X500Name;-><init>(Lsun/security/util/DerInputStream;)V
+Lsun/security/x509/X500Name;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/x509/X500Name;-><init>([B)V
+Lsun/security/x509/X500Name;->allAvas()Ljava/util/List;
+Lsun/security/x509/X500Name;->asX500Name(Ljavax/security/auth/x500/X500Principal;)Lsun/security/x509/X500Name;
+Lsun/security/x509/X500Name;->asX500Principal()Ljavax/security/auth/x500/X500Principal;
+Lsun/security/x509/X500Name;->commonName_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->countryName_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->DNQUALIFIER_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->DOMAIN_COMPONENT_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->encode(Lsun/security/util/DerOutputStream;)V
+Lsun/security/x509/X500Name;->GENERATIONQUALIFIER_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->getCommonName()Ljava/lang/String;
+Lsun/security/x509/X500Name;->GIVENNAME_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->INITIALS_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->ipAddress_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->isEmpty()Z
+Lsun/security/x509/X500Name;->localityName_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->orgName_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->orgUnitName_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->SERIALNUMBER_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->stateName_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->streetAddress_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->SURNAME_OID:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->title_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X500Name;->userid_oid:Lsun/security/util/ObjectIdentifier;
+Lsun/security/x509/X509CertImpl;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/x509/X509CertImpl;-><init>(Lsun/security/x509/X509CertInfo;)V
+Lsun/security/x509/X509CertImpl;-><init>([B)V
+Lsun/security/x509/X509CertImpl;->algId:Lsun/security/x509/AlgorithmId;
+Lsun/security/x509/X509CertImpl;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/X509CertImpl;->getEncodedInternal()[B
+Lsun/security/x509/X509CertImpl;->parse(Lsun/security/util/DerValue;)V
+Lsun/security/x509/X509CertImpl;->readOnly:Z
+Lsun/security/x509/X509CertImpl;->sign(Ljava/security/PrivateKey;Ljava/lang/String;)V
+Lsun/security/x509/X509CertImpl;->signature:[B
+Lsun/security/x509/X509CertImpl;->signedCert:[B
+Lsun/security/x509/X509CertInfo;-><init>()V
+Lsun/security/x509/X509CertInfo;-><init>([B)V
+Lsun/security/x509/X509CertInfo;->get(Ljava/lang/String;)Ljava/lang/Object;
+Lsun/security/x509/X509CertInfo;->set(Ljava/lang/String;Ljava/lang/Object;)V
+Lsun/security/x509/X509CRLEntryImpl;->getExtension(Lsun/security/util/ObjectIdentifier;)Lsun/security/x509/Extension;
+Lsun/security/x509/X509CRLImpl;-><init>(Ljava/io/InputStream;)V
+Lsun/security/x509/X509CRLImpl;-><init>(Lsun/security/util/DerValue;)V
+Lsun/security/x509/X509CRLImpl;-><init>([B)V
+Lsun/security/x509/X509CRLImpl;->getEncodedInternal()[B
+Lsun/security/x509/X509Key;-><init>()V
+Lsun/security/x509/X509Key;->algid:Lsun/security/x509/AlgorithmId;
+Lsun/security/x509/X509Key;->encodedKey:[B
+Lsun/security/x509/X509Key;->key:[B
+Lsun/security/x509/X509Key;->parse(Lsun/security/util/DerValue;)Ljava/security/PublicKey;
+Lsun/security/x509/X509Key;->unusedBits:I
+Lsun/util/calendar/AbstractCalendar;->getDayOfWeekDateOnOrBefore(JI)J
+Lsun/util/calendar/AbstractCalendar;->getTimeOfDayValue(Lsun/util/calendar/CalendarDate;)J
+Lsun/util/calendar/BaseCalendar$Date;->getNormalizedYear()I
+Lsun/util/calendar/BaseCalendar$Date;->setNormalizedYear(I)V
+Lsun/util/calendar/CalendarDate;->getDayOfMonth()I
+Lsun/util/calendar/CalendarDate;->getMonth()I
+Lsun/util/calendar/CalendarDate;->getTimeOfDay()J
+Lsun/util/calendar/CalendarDate;->getYear()I
+Lsun/util/calendar/CalendarDate;->setDate(III)Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/CalendarDate;->setDayOfMonth(I)Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/CalendarDate;->setHours(I)Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/CalendarDate;->setMillis(I)Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/CalendarDate;->setMinutes(I)Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/CalendarDate;->setSeconds(I)Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/CalendarSystem;->forName(Ljava/lang/String;)Lsun/util/calendar/CalendarSystem;
+Lsun/util/calendar/CalendarSystem;->getGregorianCalendar()Lsun/util/calendar/Gregorian;
+Lsun/util/calendar/CalendarSystem;->getTime(Lsun/util/calendar/CalendarDate;)J
+Lsun/util/calendar/CalendarSystem;->newCalendarDate(Ljava/util/TimeZone;)Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/CalendarSystem;->validate(Lsun/util/calendar/CalendarDate;)Z
+Lsun/util/calendar/CalendarUtils;->floorDivide(II)I
+Lsun/util/calendar/CalendarUtils;->floorDivide(JJ)J
+Lsun/util/calendar/CalendarUtils;->mod(II)I
+Lsun/util/calendar/CalendarUtils;->mod(JJ)J
+Lsun/util/calendar/Era;-><init>(Ljava/lang/String;Ljava/lang/String;JZ)V
+Lsun/util/calendar/Era;->getAbbreviation()Ljava/lang/String;
+Lsun/util/calendar/Era;->getName()Ljava/lang/String;
+Lsun/util/calendar/Era;->getSinceDate()Lsun/util/calendar/CalendarDate;
+Lsun/util/calendar/ImmutableGregorianDate;->unsupported()V
+Lsun/util/calendar/LocalGregorianCalendar$Date;->getNormalizedYear()I
+Lsun/util/calendar/LocalGregorianCalendar$Date;->setEra(Lsun/util/calendar/Era;)Lsun/util/calendar/LocalGregorianCalendar$Date;
+Lsun/util/calendar/LocalGregorianCalendar$Date;->setNormalizedYear(I)V
+Lsun/util/calendar/LocalGregorianCalendar$Date;->setYear(I)Lsun/util/calendar/LocalGregorianCalendar$Date;
+Lsun/util/calendar/LocalGregorianCalendar;->newCalendarDate(Ljava/util/TimeZone;)Lsun/util/calendar/LocalGregorianCalendar$Date;
+Lsun/util/calendar/LocalGregorianCalendar;->normalize(Lsun/util/calendar/CalendarDate;)Z
+Lsun/util/calendar/LocalGregorianCalendar;->validate(Lsun/util/calendar/CalendarDate;)Z
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index a66681956233..86ed267eafdb 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -120,6 +120,8 @@ import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillManager.AutofillClient;
import android.view.autofill.AutofillPopupWindow;
import android.view.autofill.IAutofillWindowPresenter;
+import android.view.intelligence.ContentCaptureEvent;
+import android.view.intelligence.IntelligenceManager;
import android.widget.AdapterView;
import android.widget.Toast;
import android.widget.Toolbar;
@@ -821,6 +823,10 @@ public class Activity extends ContextThemeWrapper
/** The autofill manager. Always access via {@link #getAutofillManager()}. */
@Nullable private AutofillManager mAutofillManager;
+ /** The screen observation manager. Always access via {@link #getIntelligenceManager()}. */
+ @Nullable private IntelligenceManager mIntelligenceManager;
+
+
static final class NonConfigurationInstances {
Object activity;
HashMap<String, Object> children;
@@ -994,7 +1000,7 @@ public class Activity extends ContextThemeWrapper
}
/**
- * (Create and) return the autofill manager
+ * (Creates, sets and) returns the autofill manager
*
* @return The autofill manager
*/
@@ -1006,6 +1012,43 @@ public class Activity extends ContextThemeWrapper
return mAutofillManager;
}
+ /**
+ * (Creates, sets, and ) returns the intelligence manager
+ *
+ * @return The intelligence manager
+ */
+ @NonNull private IntelligenceManager getIntelligenceManager() {
+ if (mIntelligenceManager == null) {
+ mIntelligenceManager = getSystemService(IntelligenceManager.class);
+ }
+ return mIntelligenceManager;
+ }
+
+ private void notifyIntelligenceManagerIfNeeded(@ContentCaptureEvent.EventType int event) {
+ final IntelligenceManager im = getIntelligenceManager();
+ if (im == null || !im.isContentCaptureEnabled()) {
+ return;
+ }
+ switch (event) {
+ case ContentCaptureEvent.TYPE_ACTIVITY_CREATED:
+ //TODO(b/111276913): decide whether the InteractionSessionId should be
+ // saved / restored in the activity bundle.
+ im.onActivityCreated(mToken, getComponentName());
+ break;
+ case ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED:
+ im.onActivityDestroyed();
+ break;
+ case ContentCaptureEvent.TYPE_ACTIVITY_STARTED:
+ case ContentCaptureEvent.TYPE_ACTIVITY_RESUMED:
+ case ContentCaptureEvent.TYPE_ACTIVITY_PAUSED:
+ case ContentCaptureEvent.TYPE_ACTIVITY_STOPPED:
+ im.onActivityLifecycleEvent(event);
+ break;
+ default:
+ Log.w(TAG, "notifyIntelligenceManagerIfNeeded(): invalid type " + event);
+ }
+ }
+
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(newBase);
@@ -1081,6 +1124,8 @@ public class Activity extends ContextThemeWrapper
}
mRestoredFromBundle = savedInstanceState != null;
mCalled = true;
+
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_CREATED);
}
/**
@@ -1314,6 +1359,7 @@ public class Activity extends ContextThemeWrapper
if (mAutoFillResetNeeded) {
getAutofillManager().onVisibleForAutofill();
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STARTED);
}
/**
@@ -1396,6 +1442,7 @@ public class Activity extends ContextThemeWrapper
}
}
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_RESUMED);
mCalled = true;
}
@@ -1789,6 +1836,7 @@ public class Activity extends ContextThemeWrapper
mAutoFillIgnoreFirstResumePause = false;
}
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_PAUSED);
mCalled = true;
}
@@ -1977,6 +2025,7 @@ public class Activity extends ContextThemeWrapper
getAutofillManager().onPendingSaveUi(AutofillManager.PENDING_UI_OPERATION_CANCEL,
mIntent.getIBinderExtra(AutofillManager.EXTRA_RESTORE_SESSION_TOKEN));
}
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_STOPPED);
}
}
@@ -2047,6 +2096,9 @@ public class Activity extends ContextThemeWrapper
}
getApplication().dispatchActivityDestroyed(this);
+
+ notifyIntelligenceManagerIfNeeded(ContentCaptureEvent.TYPE_ACTIVITY_DESTROYED);
+
}
/**
@@ -6403,9 +6455,16 @@ public class Activity extends ContextThemeWrapper
void dumpInner(@NonNull String prefix, @Nullable FileDescriptor fd,
@NonNull PrintWriter writer, @Nullable String[] args) {
- if (args != null && args.length > 0 && args[0].equals("--autofill")) {
- dumpAutofillManager(prefix, writer);
- return;
+ if (args != null && args.length > 0) {
+ // Handle special cases
+ switch (args[0]) {
+ case "--autofill":
+ dumpAutofillManager(prefix, writer);
+ return;
+ case "--intelligence":
+ dumpIntelligenceManager(prefix, writer);
+ return;
+ }
}
writer.print(prefix); writer.print("Local Activity ");
writer.print(Integer.toHexString(System.identityHashCode(this)));
@@ -6435,6 +6494,7 @@ public class Activity extends ContextThemeWrapper
mHandler.getLooper().dump(new PrintWriterPrinter(writer), prefix);
dumpAutofillManager(prefix, writer);
+ dumpIntelligenceManager(prefix, writer);
ResourcesManager.getInstance().dump(prefix, writer);
}
@@ -6450,6 +6510,15 @@ public class Activity extends ContextThemeWrapper
}
}
+ void dumpIntelligenceManager(String prefix, PrintWriter writer) {
+ final IntelligenceManager im = getIntelligenceManager();
+ if (im != null) {
+ im.dump(prefix, writer);
+ } else {
+ writer.print(prefix); writer.println("No IntelligenceManager");
+ }
+ }
+
/**
* Bit indicating that this activity is "immersive" and should not be
* interrupted by notifications if possible.
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 7df8de0f7b66..1e2244e11bd2 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -1612,6 +1612,20 @@ public class AppOpsManager {
}
/**
+ * Retrieve the default mode for the app op.
+ *
+ * @param appOp The app op name
+ *
+ * @return the default mode for the app op
+ *
+ * @hide
+ */
+ @SystemApi
+ public static int opToDefaultMode(@NonNull String appOp) {
+ return opToDefaultMode(strOpToOp(appOp));
+ }
+
+ /**
* Retrieve the human readable mode.
* @hide
*/
@@ -2483,26 +2497,6 @@ public class AppOpsManager {
}
}
- /**
- * Resets given app op in its default mode for app ops in the UID.
- * This applies to all apps currently in the UID or installed in this UID in the future.
- *
- * @param appOp The app op.
- * @param uid The UID for which to set the app.
- *
- * @hide
- */
- @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES)
- @SystemApi
- public void resetUidMode(String appOp, int uid, boolean force) {
- int code = strOpToOp(appOp);
- if (!(opAllowsReset(code) || force)) {
- return;
- }
- int mode = opToDefaultMode(code);
- setUidMode(code, uid, mode);
- }
-
/** @hide */
public void setUserRestriction(int code, boolean restricted, IBinder token) {
setUserRestriction(code, restricted, token, /*exceptionPackages*/null);
diff --git a/core/java/android/app/AutomaticZenRule.java b/core/java/android/app/AutomaticZenRule.java
index 9d68133c01da..e2f2075f0a32 100644
--- a/core/java/android/app/AutomaticZenRule.java
+++ b/core/java/android/app/AutomaticZenRule.java
@@ -31,7 +31,10 @@ import java.util.Objects;
* Rule instance information for zen mode.
*/
public final class AutomaticZenRule implements Parcelable {
-
+ /* @hide */
+ private static final int ENABLED = 1;
+ /* @hide */
+ private static final int DISABLED = 0;
private boolean enabled = false;
private String name;
private @InterruptionFilter int interruptionFilter;
@@ -39,6 +42,7 @@ public final class AutomaticZenRule implements Parcelable {
private ComponentName owner;
private long creationTime;
private ZenPolicy mZenPolicy;
+ private boolean mModified = false;
/**
* Creates an automatic zen rule.
@@ -101,8 +105,8 @@ public final class AutomaticZenRule implements Parcelable {
}
public AutomaticZenRule(Parcel source) {
- enabled = source.readInt() == 1;
- if (source.readInt() == 1) {
+ enabled = source.readInt() == ENABLED;
+ if (source.readInt() == ENABLED) {
name = source.readString();
}
interruptionFilter = source.readInt();
@@ -110,6 +114,7 @@ public final class AutomaticZenRule implements Parcelable {
owner = source.readParcelable(null);
creationTime = source.readLong();
mZenPolicy = source.readParcelable(null);
+ mModified = source.readInt() == ENABLED;
}
/**
@@ -148,6 +153,14 @@ public final class AutomaticZenRule implements Parcelable {
}
/**
+ * Returns whether this rule's name has been modified by the user.
+ * @hide
+ */
+ public boolean isModified() {
+ return mModified;
+ }
+
+ /**
* Gets the zen policy.
*/
public ZenPolicy getZenPolicy() {
@@ -191,6 +204,14 @@ public final class AutomaticZenRule implements Parcelable {
}
/**
+ * Sets modified state of this rule.
+ * @hide
+ */
+ public void setModified(boolean modified) {
+ this.mModified = modified;
+ }
+
+ /**
* Sets the zen policy.
*/
public void setZenPolicy(ZenPolicy zenPolicy) {
@@ -204,7 +225,7 @@ public final class AutomaticZenRule implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(enabled ? 1 : 0);
+ dest.writeInt(enabled ? ENABLED : DISABLED);
if (name != null) {
dest.writeInt(1);
dest.writeString(name);
@@ -216,6 +237,7 @@ public final class AutomaticZenRule implements Parcelable {
dest.writeParcelable(owner, 0);
dest.writeLong(creationTime);
dest.writeParcelable(mZenPolicy, 0);
+ dest.writeInt(mModified ? ENABLED : DISABLED);
}
@Override
@@ -237,6 +259,7 @@ public final class AutomaticZenRule implements Parcelable {
if (o == this) return true;
final AutomaticZenRule other = (AutomaticZenRule) o;
return other.enabled == enabled
+ && other.mModified == mModified
&& Objects.equals(other.name, name)
&& other.interruptionFilter == interruptionFilter
&& Objects.equals(other.conditionId, conditionId)
@@ -248,7 +271,7 @@ public final class AutomaticZenRule implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(enabled, name, interruptionFilter, conditionId, owner, creationTime,
- mZenPolicy);
+ mZenPolicy, mModified);
}
public static final Parcelable.Creator<AutomaticZenRule> CREATOR
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 519a2749e5bb..e7597620e138 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -265,17 +265,6 @@ interface IActivityManager {
void getMyMemoryState(out ActivityManager.RunningAppProcessInfo outInfo);
boolean killProcessesBelowForeground(in String reason);
UserInfo getCurrentUser();
- /**
- * Informs ActivityManagerService that the keyguard is showing.
- *
- * @param showingKeyguard True if the keyguard is showing, false otherwise.
- * @param showingAod True if AOD is showing, false otherwise.
- * @param secondaryDisplayShowing The displayId of the secondary display on which the keyguard
- * is showing, or INVALID_DISPLAY if there is no such display. Only meaningful if
- * showing is true.
- */
- void setLockScreenShown(boolean showingKeyguard, boolean showingAod,
- int secondaryDisplayShowing);
// 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.
int getLaunchedFromUid(in IBinder activityToken);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index fcfcc2192d9e..6f11a762c6cd 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -245,16 +245,16 @@ interface IActivityTaskManager {
ActivityManager.StackInfo getStackInfo(int windowingMode, int activityType);
/**
- * Informs ActivityManagerService that the keyguard is showing.
+ * Informs ActivityTaskManagerService that the keyguard is showing.
*
* @param showingKeyguard True if the keyguard is showing, false otherwise.
* @param showingAod True if AOD is showing, false otherwise.
- * @param secondaryDisplayShowing The displayId of the secondary display on which the keyguard
- * is showing, or INVALID_DISPLAY if there is no such display. Only meaningful if
- * showing is true.
+ * @param secondaryDisplaysShowing The displayId's of the secondary displays on which the
+ * keyguard is showing, or {@code null} if there is no such display. Only meaningful if showing
+ * is {@code true}.
*/
void setLockScreenShown(boolean showingKeyguard, boolean showingAod,
- int secondaryDisplayShowing);
+ in int[] secondaryDisplaysShowing);
Bundle getAssistContextExtras(int requestType);
boolean launchAssistIntent(in Intent intent, int requestType, in String hint, int userHandle,
in Bundle args);
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 508ea3b40cce..e95f9abed908 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -66,6 +66,8 @@ import android.hardware.fingerprint.IFingerprintService;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.IHdmiControlService;
import android.hardware.input.InputManager;
+import android.hardware.iris.IIrisService;
+import android.hardware.iris.IrisManager;
import android.hardware.location.ContextHubManager;
import android.hardware.radio.RadioManager;
import android.hardware.usb.IUsbManager;
@@ -161,6 +163,8 @@ import android.view.accessibility.CaptioningManager;
import android.view.autofill.AutofillManager;
import android.view.autofill.IAutoFillManager;
import android.view.inputmethod.InputMethodManager;
+import android.view.intelligence.IIntelligenceManager;
+import android.view.intelligence.IntelligenceManager;
import android.view.textclassifier.TextClassificationManager;
import android.view.textservice.TextServicesManager;
@@ -836,6 +840,18 @@ final class SystemServiceRegistry {
}
});
+ registerService(Context.IRIS_SERVICE, IrisManager.class,
+ new CachedServiceFetcher<IrisManager>() {
+ @Override
+ public IrisManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ final IBinder binder =
+ ServiceManager.getServiceOrThrow(Context.IRIS_SERVICE);
+ IIrisService service = IIrisService.Stub.asInterface(binder);
+ return new IrisManager(ctx.getOuterContext(), service);
+ }
+ });
+
registerService(Context.BIOMETRIC_SERVICE, BiometricManager.class,
new CachedServiceFetcher<BiometricManager>() {
@Override
@@ -1018,6 +1034,17 @@ final class SystemServiceRegistry {
return new AutofillManager(ctx.getOuterContext(), service);
}});
+ registerService(Context.INTELLIGENCE_MANAGER_SERVICE, IntelligenceManager.class,
+ new CachedServiceFetcher<IntelligenceManager>() {
+ @Override
+ public IntelligenceManager createService(ContextImpl ctx)
+ throws ServiceNotFoundException {
+ // Get the services without throwing as this is an optional feature
+ IBinder b = ServiceManager.getService(Context.INTELLIGENCE_MANAGER_SERVICE);
+ IIntelligenceManager service = IIntelligenceManager.Stub.asInterface(b);
+ return new IntelligenceManager(ctx.getOuterContext(), service);
+ }});
+
registerService(Context.VR_SERVICE, VrManager.class, new CachedServiceFetcher<VrManager>() {
@Override
public VrManager createService(ContextImpl ctx) throws ServiceNotFoundException {
diff --git a/core/java/android/app/assist/AssistStructure.java b/core/java/android/app/assist/AssistStructure.java
index fefb8d3fc139..43f902a2a7f7 100644
--- a/core/java/android/app/assist/AssistStructure.java
+++ b/core/java/android/app/assist/AssistStructure.java
@@ -2,6 +2,7 @@ package android.app.assist;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
@@ -713,7 +714,11 @@ public class AssistStructure implements Parcelable {
ViewNode[] mChildren;
- ViewNode() {
+ // TODO(b/111276913): temporarily made public / @hide until we decide what will be used by
+ // ScreenObservation.
+ /** @hide */
+ @SystemApi
+ public ViewNode() {
}
ViewNode(ParcelTransferReader reader, int nestingLevel) {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index e3788004cf5a..ccf8417bee56 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3706,6 +3706,17 @@ public abstract class Context {
/**
* Use with {@link #getSystemService(String)} to retrieve a
+ * {@link android.hardware.iris.IrisManager} for handling management
+ * of iris authentication.
+ *
+ * @hide
+ * @see #getSystemService
+ * @see android.hardware.iris.IrisManager
+ */
+ public static final String IRIS_SERVICE = "iris";
+
+ /**
+ * Use with {@link #getSystemService(String)} to retrieve a
* {@link android.hardware.biometrics.BiometricManager} for handling management
* of face authentication.
*
@@ -3854,6 +3865,14 @@ public abstract class Context {
public static final String AUTOFILL_MANAGER_SERVICE = "autofill";
/**
+ * Official published name of the intelligence service.
+ *
+ * @hide
+ * @see #getSystemService(String)
+ */
+ public static final String INTELLIGENCE_MANAGER_SERVICE = "intelligence";
+
+ /**
* Use with {@link #getSystemService(String)} to access the
* {@link com.android.server.voiceinteraction.SoundTriggerService}.
*
diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java
index d3652e8825b5..877dfee138da 100644
--- a/core/java/android/content/SharedPreferences.java
+++ b/core/java/android/content/SharedPreferences.java
@@ -57,6 +57,9 @@ public interface SharedPreferences {
*
* <p>This callback will be run on your main thread.
*
+ * <p><em>Note: This callback will not be triggered when preferences are cleared via
+ * {@link Editor#clear()}.</em>
+ *
* @param sharedPreferences The {@link SharedPreferences} that received
* the change.
* @param key The key of the preference that was changed, added, or
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 1f700f758dc8..67b86c0e6e42 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -855,6 +855,14 @@ public abstract class PackageManager {
*/
public static final int INSTALL_VIRTUAL_PRELOAD = 0x00010000;
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that this package
+ * is an APEX package
+ *
+ * @hide
+ */
+ public static final int INSTALL_APEX = 0x00020000;
+
/** @hide */
@IntDef(flag = true, prefix = { "DONT_KILL_APP" }, value = {
DONT_KILL_APP
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index a8bbeab03f0a..096301c92faa 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -25,6 +25,7 @@ import android.os.Parcelable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -78,6 +79,7 @@ public final class SharedLibraryInfo implements Parcelable {
private final @Type int mType;
private final VersionedPackage mDeclaringPackage;
private final List<VersionedPackage> mDependentPackages;
+ private List<SharedLibraryInfo> mDependencies;
/**
* Creates a new instance.
@@ -91,7 +93,8 @@ public final class SharedLibraryInfo implements Parcelable {
* @hide
*/
public SharedLibraryInfo(String path, String packageName, String name, long version, int type,
- VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages) {
+ VersionedPackage declaringPackage, List<VersionedPackage> dependentPackages,
+ List<SharedLibraryInfo> dependencies) {
mPath = path;
mPackageName = packageName;
mName = name;
@@ -99,11 +102,13 @@ public final class SharedLibraryInfo implements Parcelable {
mType = type;
mDeclaringPackage = declaringPackage;
mDependentPackages = dependentPackages;
+ mDependencies = dependencies;
}
private SharedLibraryInfo(Parcel parcel) {
this(parcel.readString(), parcel.readString(), parcel.readString(), parcel.readLong(),
- parcel.readInt(), parcel.readParcelable(null), parcel.readArrayList(null));
+ parcel.readInt(), parcel.readParcelable(null), parcel.readArrayList(null),
+ parcel.createTypedArrayList(SharedLibraryInfo.CREATOR));
}
/**
@@ -150,6 +155,47 @@ public final class SharedLibraryInfo implements Parcelable {
}
/**
+ * Add a library dependency to that library. Note that this
+ * should be called under the package manager lock.
+ *
+ * @hide
+ */
+ public void addDependency(@Nullable SharedLibraryInfo info) {
+ if (info == null) {
+ // For convenience of the caller, allow null to be passed.
+ // This can happen when we create the dependencies of builtin
+ // libraries.
+ return;
+ }
+ if (mDependencies == null) {
+ mDependencies = new ArrayList<>();
+ }
+ mDependencies.add(info);
+ }
+
+ /**
+ * Clear all dependencies.
+ *
+ * @hide
+ */
+ public void clearDependencies() {
+ mDependencies = null;
+ }
+
+ /**
+ * Gets the libraries this library directly depends on. Note that
+ * the package manager prevents recursive dependencies when installing
+ * a package.
+ *
+ * @return The dependencies.
+ *
+ * @hide
+ */
+ public @Nullable List<SharedLibraryInfo> getDependencies() {
+ return mDependencies;
+ }
+
+ /**
* @deprecated Use {@link #getLongVersion()} instead.
*/
@Deprecated
@@ -232,6 +278,7 @@ public final class SharedLibraryInfo implements Parcelable {
parcel.writeInt(mType);
parcel.writeParcelable(mDeclaringPackage, flags);
parcel.writeList(mDependentPackages);
+ parcel.writeTypedList(mDependencies);
}
private static String typeToString(int type) {
diff --git a/core/java/android/content/pm/SharedLibraryNames.java b/core/java/android/content/pm/SharedLibraryNames.java
index 387d29e81dfc..5afc8a9721b4 100644
--- a/core/java/android/content/pm/SharedLibraryNames.java
+++ b/core/java/android/content/pm/SharedLibraryNames.java
@@ -22,15 +22,15 @@ package android.content.pm;
*/
public class SharedLibraryNames {
- static final String ANDROID_HIDL_BASE = "android.hidl.base-V1.0-java";
+ public static final String ANDROID_HIDL_BASE = "android.hidl.base-V1.0-java";
- static final String ANDROID_HIDL_MANAGER = "android.hidl.manager-V1.0-java";
+ public static final String ANDROID_HIDL_MANAGER = "android.hidl.manager-V1.0-java";
- static final String ANDROID_TEST_BASE = "android.test.base";
+ public static final String ANDROID_TEST_BASE = "android.test.base";
- static final String ANDROID_TEST_MOCK = "android.test.mock";
+ public static final String ANDROID_TEST_MOCK = "android.test.mock";
- static final String ANDROID_TEST_RUNNER = "android.test.runner";
+ public static final String ANDROID_TEST_RUNNER = "android.test.runner";
- static final String ORG_APACHE_HTTP_LEGACY = "org.apache.http.legacy";
+ public static final String ORG_APACHE_HTTP_LEGACY = "org.apache.http.legacy";
}
diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java
index 0350effd84b8..5f2374995775 100644
--- a/core/java/android/content/res/AssetManager.java
+++ b/core/java/android/content/res/AssetManager.java
@@ -1064,6 +1064,17 @@ public final class AssetManager implements AutoCloseable {
}
}
+ @UnsupportedAppUsage
+ void setThemeTo(long dstThemePtr, @NonNull AssetManager srcAssetManager, long srcThemePtr) {
+ synchronized (this) {
+ ensureValidLocked();
+ synchronized (srcAssetManager) {
+ srcAssetManager.ensureValidLocked();
+ nativeThemeCopy(mObject, dstThemePtr, srcAssetManager.mObject, srcThemePtr);
+ }
+ }
+ }
+
@Override
protected void finalize() throws Throwable {
if (DEBUG_REFS && mNumRefs != 0) {
@@ -1375,7 +1386,8 @@ public final class AssetManager implements AutoCloseable {
private static native void nativeThemeDestroy(long themePtr);
private static native void nativeThemeApplyStyle(long ptr, long themePtr, @StyleRes int resId,
boolean force);
- static native void nativeThemeCopy(long destThemePtr, long sourceThemePtr);
+ private static native void nativeThemeCopy(long dstAssetManagerPtr, long dstThemePtr,
+ long srcAssetManagerPtr, long srcThemePtr);
static native void nativeThemeClear(long themePtr);
private static native int nativeThemeGetAttributeValue(long ptr, long themePtr,
@AttrRes int resId, @NonNull TypedValue outValue, boolean resolve);
diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java
index 6a4aae66c848..14eb11ab8863 100644
--- a/core/java/android/content/res/FontResourcesParser.java
+++ b/core/java/android/content/res/FontResourcesParser.java
@@ -76,6 +76,10 @@ public class FontResourcesParser {
// A class represents font element in xml file which points a file in resource.
public static final class FontFileResourceEntry {
+ public static final int RESOLVE_BY_FONT_TABLE = Typeface.RESOLVE_BY_FONT_TABLE;
+ public static final int UPRIGHT = 0;
+ public static final int ITALIC = 1;
+
private final @NonNull String mFileName;
private int mWeight;
private int mItalic;
@@ -216,7 +220,7 @@ public class FontResourcesParser {
int weight = array.getInt(R.styleable.FontFamilyFont_fontWeight,
Typeface.RESOLVE_BY_FONT_TABLE);
int italic = array.getInt(R.styleable.FontFamilyFont_fontStyle,
- Typeface.RESOLVE_BY_FONT_TABLE);
+ FontFileResourceEntry.RESOLVE_BY_FONT_TABLE);
String variationSettings = array.getString(
R.styleable.FontFamilyFont_fontVariationSettings);
int ttcIndex = array.getInt(R.styleable.FontFamilyFont_ttcIndex, 0);
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index dfa30a22597e..2ad4f625ef8c 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -944,7 +944,8 @@ public class ResourcesImpl {
}
return Typeface.createFromResources(familyEntry, mAssets, file);
}
- return Typeface.createFromResources(mAssets, file, value.assetCookie);
+ return new Typeface.Builder(mAssets, file, false /* isAsset */, value.assetCookie)
+ .build();
} catch (XmlPullParserException e) {
Log.e(TAG, "Failed to parse xml resource " + file, e);
} catch (IOException e) {
@@ -1335,7 +1336,7 @@ public class ResourcesImpl {
void setTo(ThemeImpl other) {
synchronized (mKey) {
synchronized (other.mKey) {
- AssetManager.nativeThemeCopy(mTheme, other.mTheme);
+ mAssets.setThemeTo(mTheme, other.mAssets, other.mTheme);
mThemeResId = other.mThemeResId;
mKey.setTo(other.getKey());
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index 46e66e0dbef5..33cc7a84b335 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -1583,7 +1583,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* {@link android.graphics.ImageFormat#RAW12 RAW12}.</li>
* <li>Processed (but not-stalling): any non-RAW format without a stall duration. Typically
* {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888},
- * {@link android.graphics.ImageFormat#NV21 NV21}, or {@link android.graphics.ImageFormat#YV12 YV12}.</li>
+ * {@link android.graphics.ImageFormat#NV21 NV21}, {@link android.graphics.ImageFormat#YV12 YV12}, or {@link android.graphics.ImageFormat#Y8 Y8} .</li>
* </ul>
* <p><b>Range of valid values:</b><br></p>
* <p>For processed (and stalling) format streams, &gt;= 1.</p>
@@ -1646,6 +1646,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <li>{@link android.graphics.ImageFormat#NV21 NV21}</li>
* <li>{@link android.graphics.ImageFormat#YV12 YV12}</li>
* <li>Implementation-defined formats, i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#isOutputSupportedFor(Class) }</li>
+ * <li>{@link android.graphics.ImageFormat#Y8 Y8}</li>
* </ul>
* <p>For full guarantees, query {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration } with a
* processed format -- it will return 0 for a non-stalling stream.</p>
@@ -2122,6 +2123,35 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* or output will never hurt maximum frame rate (i.e. {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputStallDuration getOutputStallDuration(ImageFormat.PRIVATE, size)} is always 0),</p>
* <p>Attempting to configure an input stream with output streams not
* listed as available in this map is not valid.</p>
+ * <p>Additionally, if the camera device is MONOCHROME with Y8 support, it will also support
+ * the following map of formats if its dependent capability
+ * ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}) is supported:</p>
+ * <table>
+ * <thead>
+ * <tr>
+ * <th align="left">Input Format</th>
+ * <th align="left">Output Format</th>
+ * <th align="left">Capability</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td align="left">{@link android.graphics.ImageFormat#PRIVATE }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#Y8 }</td>
+ * <td align="left">PRIVATE_REPROCESSING</td>
+ * </tr>
+ * <tr>
+ * <td align="left">{@link android.graphics.ImageFormat#Y8 }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#JPEG }</td>
+ * <td align="left">YUV_REPROCESSING</td>
+ * </tr>
+ * <tr>
+ * <td align="left">{@link android.graphics.ImageFormat#Y8 }</td>
+ * <td align="left">{@link android.graphics.ImageFormat#Y8 }</td>
+ * <td align="left">YUV_REPROCESSING</td>
+ * </tr>
+ * </tbody>
+ * </table>
* <p><b>Optional</b> - This value may be {@code null} on some devices.</p>
*
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
@@ -2297,6 +2327,7 @@ public final class CameraCharacteristics extends CameraMetadata<CameraCharacteri
* <li>{@link android.graphics.ImageFormat#YUV_420_888 }</li>
* <li>{@link android.graphics.ImageFormat#RAW10 }</li>
* <li>{@link android.graphics.ImageFormat#RAW12 }</li>
+ * <li>{@link android.graphics.ImageFormat#Y8 }</li>
* </ul>
* <p>All other formats may or may not have an allowed stall duration on
* a per-capability basis; refer to {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES android.request.availableCapabilities}
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index ce88697fa8db..ac00f1488b14 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -356,6 +356,12 @@ public abstract class CameraDevice implements AutoCloseable {
* </table><br>
* </p>
*
+ * <p>MONOCHROME-capability ({@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}
+ * includes {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME MONOCHROME})
+ * supporting {@link android.graphics.ImageFormat#Y8 Y8} support substituting {@code YUV}
+ * streams with {@code Y8} in all guaranteed stream combinations for the device's hardware level
+ * and capabilities.</p>
+ *
* <p>FULL-level ({@link CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL}
* {@code == }{@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_FULL FULL}) devices
* support at least the following stream combinations in addition to those for
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index d4dc181e5eec..ffc22641f025 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -539,6 +539,8 @@ public abstract class CameraMetadata<TKey> {
* <li>{@link android.graphics.ImageFormat#PRIVATE } will be reprocessable into both
* {@link android.graphics.ImageFormat#YUV_420_888 } and
* {@link android.graphics.ImageFormat#JPEG } formats.</li>
+ * <li>For a MONOCHROME camera supporting Y8 format, {@link android.graphics.ImageFormat#PRIVATE } will be reprocessable into
+ * {@link android.graphics.ImageFormat#Y8 }.</li>
* <li>The maximum available resolution for PRIVATE streams
* (both input/output) will match the maximum available
* resolution of JPEG streams.</li>
@@ -612,7 +614,7 @@ public abstract class CameraMetadata<TKey> {
* then the list of resolutions for YUV_420_888 from {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes } contains at
* least one resolution &gt;= 8 megapixels, with a minimum frame duration of &lt;= 1/20
* s.</p>
- * <p>If the device supports the {@link android.graphics.ImageFormat#RAW10 }, {@link android.graphics.ImageFormat#RAW12 }, then those can also be
+ * <p>If the device supports the {@link android.graphics.ImageFormat#RAW10 }, {@link android.graphics.ImageFormat#RAW12 }, {@link android.graphics.ImageFormat#Y8 }, then those can also be
* captured at the same rate as the maximum-size YUV_420_888 resolution is.</p>
* <p>If the device supports the PRIVATE_REPROCESSING capability, then the same guarantees
* as for the YUV_420_888 format also apply to the {@link android.graphics.ImageFormat#PRIVATE } format.</p>
@@ -646,6 +648,8 @@ public abstract class CameraMetadata<TKey> {
* {@link android.graphics.ImageFormat#YUV_420_888 } and {@link android.graphics.ImageFormat#JPEG } formats.</li>
* <li>The maximum available resolution for {@link android.graphics.ImageFormat#YUV_420_888 } streams (both input/output) will match the
* maximum available resolution of {@link android.graphics.ImageFormat#JPEG } streams.</li>
+ * <li>For a MONOCHROME camera with Y8 format support, all the requirements mentioned
+ * above for YUV_420_888 apply for Y8 format as well.</li>
* <li>Static metadata {@link CameraCharacteristics#REPROCESS_MAX_CAPTURE_STALL android.reprocess.maxCaptureStall}.</li>
* <li>Only the below controls are effective for reprocessing requests and will be present
* in capture results. The reprocess requests are from the original capture results
@@ -692,8 +696,8 @@ public abstract class CameraMetadata<TKey> {
* <li>The {@link CameraCharacteristics#DEPTH_DEPTH_IS_EXCLUSIVE android.depth.depthIsExclusive} entry is listed by this device.</li>
* <li>As of Android P, the {@link CameraCharacteristics#LENS_POSE_REFERENCE android.lens.poseReference} entry is listed by this device.</li>
* <li>A LIMITED camera with only the DEPTH_OUTPUT capability does not have to support
- * normal YUV_420_888, JPEG, and PRIV-format outputs. It only has to support the DEPTH16
- * format.</li>
+ * normal YUV_420_888, Y8, JPEG, and PRIV-format outputs. It only has to support the
+ * DEPTH16 format.</li>
* </ul>
* <p>Generally, depth output operates at a slower frame rate than standard color capture,
* so the DEPTH16 and DEPTH_POINT_CLOUD formats will commonly have a stall duration that
@@ -877,6 +881,10 @@ public abstract class CameraMetadata<TKey> {
/**
* <p>The camera device is a monochrome camera that doesn't contain a color filter array,
* and the pixel values on U and V planes are all 128.</p>
+ * <p>A MONOCHROME camera must support the guaranteed stream combinations required for
+ * its device level and capabilities. Additionally, if the monochrome camera device
+ * supports Y8 format, all mandatory stream combination requirements related to {@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888} apply
+ * to {@link android.graphics.ImageFormat#Y8 Y8} as well.</p>
* @see CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES
*/
public static final int REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME = 12;
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 4a20468276d3..2744e9111509 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -3277,8 +3277,8 @@ public final class CaptureRequest extends CameraMetadata<CaptureRequest.Key<?>>
* will not slow down capture rate when applying correction. FAST may be the same as OFF if
* any correction at all would slow down capture rate. Every output stream will have a
* similar amount of enhancement applied.</p>
- * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
- * applied to any RAW output.</p>
+ * <p>The correction only applies to processed outputs such as YUV, Y8, JPEG, or DEPTH16; it is
+ * not applied to any RAW output.</p>
* <p>This control will be on by default on devices that support this control. Applications
* disabling distortion correction need to pay extra attention with the coordinate system of
* metering regions, crop region, and face rectangles. When distortion correction is OFF,
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index a7e185c9853b..2b67f3e6adcb 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -4620,8 +4620,8 @@ public class CaptureResult extends CameraMetadata<CaptureResult.Key<?>> {
* will not slow down capture rate when applying correction. FAST may be the same as OFF if
* any correction at all would slow down capture rate. Every output stream will have a
* similar amount of enhancement applied.</p>
- * <p>The correction only applies to processed outputs such as YUV, JPEG, or DEPTH16; it is not
- * applied to any RAW output.</p>
+ * <p>The correction only applies to processed outputs such as YUV, Y8, JPEG, or DEPTH16; it is
+ * not applied to any RAW output.</p>
* <p>This control will be on by default on devices that support this control. Applications
* disabling distortion correction need to pay extra attention with the coordinate system of
* metering regions, crop region, and face rectangles. When distortion correction is OFF,
diff --git a/core/java/android/hardware/iris/IIrisService.aidl b/core/java/android/hardware/iris/IIrisService.aidl
new file mode 100644
index 000000000000..8cf3c13b1465
--- /dev/null
+++ b/core/java/android/hardware/iris/IIrisService.aidl
@@ -0,0 +1,24 @@
+/*
+ * 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.hardware.iris;
+
+/**
+ * Communication channel from client to the iris service. These methods are all require the
+ * MANAGE_BIOMETRIC signature permission.
+ * @hide
+ */
+interface IIrisService {
+} \ No newline at end of file
diff --git a/core/java/android/hardware/iris/IrisManager.java b/core/java/android/hardware/iris/IrisManager.java
new file mode 100644
index 000000000000..281ac4769a8d
--- /dev/null
+++ b/core/java/android/hardware/iris/IrisManager.java
@@ -0,0 +1,34 @@
+/*
+ * 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.hardware.iris;
+
+import android.annotation.SystemService;
+import android.content.Context;
+
+/**
+ * A class that coordinates access to the iris authentication hardware.
+ * @hide
+ */
+@SystemService(Context.IRIS_SERVICE)
+public class IrisManager {
+
+ /**
+ * @hide
+ */
+ public IrisManager(Context context, IIrisService service) {
+ }
+}
diff --git a/core/java/android/hardware/location/ContextHubBroadcastReceiver.java b/core/java/android/hardware/location/ContextHubBroadcastReceiver.java
deleted file mode 100644
index e0cc8b7de634..000000000000
--- a/core/java/android/hardware/location/ContextHubBroadcastReceiver.java
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Copyright 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.hardware.location;
-
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.os.Handler;
-
-/**
- * A BroadcastReceiver that can be used with the Context Hub Service notifications.
- *
- * @hide
- */
-public class ContextHubBroadcastReceiver extends BroadcastReceiver {
- // The context at which this receiver operates in
- private Context mContext;
-
- // The handler to post callbacks to when receiving Context Hub Service intents
- private Handler mHandler;
-
- // The callback to be invoked when receiving Context Hub Service intents
- private ContextHubClientCallback mCallback;
-
- // The string to use as the broadcast action for this receiver
- private String mAction;
-
- // True when this receiver is registered to receive Intents, false otherwise
- private boolean mRegistered = false;
-
- public ContextHubBroadcastReceiver(Context context, Handler handler,
- ContextHubClientCallback callback, String tag) {
- mContext = context;
- mHandler = handler;
- mCallback = callback;
- mAction = tag;
- }
-
- /**
- * Registers this receiver to receive Intents from the Context Hub Service. This method must
- * only be invoked when the receiver is not registered.
- *
- * @throws IllegalStateException if the receiver is already registered
- */
- public void register() throws IllegalStateException {
- if (mRegistered) {
- throw new IllegalStateException(
- "Cannot register ContextHubBroadcastReceiver multiple times");
- }
- IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(mAction);
- mContext.registerReceiver(this, intentFilter, null /* broadcastPermission */, mHandler);
- mRegistered = true;
- }
-
- /**
- * Unregisters this receiver. This method must only be invoked if {@link #register()} is
- * previously invoked.
- *
- * @throws IllegalStateException if the receiver is not yet registered
- */
- public void unregister() throws IllegalStateException {
- if (!mRegistered) {
- throw new IllegalStateException(
- "Cannot unregister ContextHubBroadcastReceiver when not registered");
- }
- mContext.unregisterReceiver(this);
- mRegistered = false;
- }
-
- /**
- * Creates a new PendingIntent associated with this receiver.
- *
- * @param flags the flags {@link PendingIntent.Flags} to use for the PendingIntent
- *
- * @return a PendingIntent to receive notifications for this receiver
- */
- public PendingIntent getPendingIntent(@PendingIntent.Flags int flags) {
- return PendingIntent.getBroadcast(
- mContext, 0 /* requestCode */, new Intent(mAction), flags);
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- // TODO: Implement this
- }
-}
diff --git a/core/java/android/hardware/location/ContextHubClient.java b/core/java/android/hardware/location/ContextHubClient.java
index 56da719e7869..9f11246d7372 100644
--- a/core/java/android/hardware/location/ContextHubClient.java
+++ b/core/java/android/hardware/location/ContextHubClient.java
@@ -19,6 +19,7 @@ import android.annotation.NonNull;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.app.PendingIntent;
+import android.content.Intent;
import android.os.RemoteException;
import com.android.internal.util.Preconditions;
@@ -113,7 +114,8 @@ public class ContextHubClient implements Closeable {
* describes the Context Hub the intent event was for. The intent will also have an extra
* {@link ContextHubManager.EXTRA_EVENT_TYPE} of type {@link ContextHubManager.Event}, which
* will contain the type of the event. See {@link ContextHubManager.Event} for description of
- * each event type, along with event-specific extra fields.
+ * each event type, along with event-specific extra fields. A client can use
+ * {@link ContextHubIntentEvent.fromIntent(Intent)} to parse the Intent generated by the event.
*
* When the intent is received, this client can be recreated through
* {@link ContextHubManager.createClient(PendingIntent, ContextHubInfo,
@@ -126,10 +128,6 @@ public class ContextHubClient implements Closeable {
* continued to be maintained at the Context Hub Service until
* {@link #unregisterIntent(PendingIntent)} is called for registered intents.
*
- * See {@link ContextHubBroadcastReceiver} for a helper class to generate the
- * {@link PendingIntent} through a {@link BroadcastReceiver}, and maps an {@link Intent} to a
- * {@link ContextHubClientCallback}.
- *
* @param pendingIntent the PendingIntent to register for this client
* @param nanoAppId the unique ID of the nanoapp to receive events for
* @return true on success, false otherwise
diff --git a/core/java/android/hardware/location/ContextHubManager.java b/core/java/android/hardware/location/ContextHubManager.java
index b0b77f31c24d..9acefa567ed6 100644
--- a/core/java/android/hardware/location/ContextHubManager.java
+++ b/core/java/android/hardware/location/ContextHubManager.java
@@ -808,7 +808,7 @@ public final class ContextHubManager {
*
* @throws IllegalArgumentException if hubInfo does not represent a valid hub, or pendingIntent
* was not associated with a client
- * @throws IllegalStateException if there were too many registered clients at the service
+ * @throws IllegalStateException if the client is already registered to a valid callback
* @throws NullPointerException if pendingIntent, hubInfo, callback, or executor is null
*
* @hide
@@ -818,8 +818,24 @@ public final class ContextHubManager {
@NonNull PendingIntent pendingIntent, @NonNull ContextHubInfo hubInfo,
@NonNull ContextHubClientCallback callback,
@NonNull @CallbackExecutor Executor executor) {
- // TODO: Implement this
- throw new UnsupportedOperationException("Not implemented yet");
+ Preconditions.checkNotNull(pendingIntent, "PendingIntent cannot be null");
+ Preconditions.checkNotNull(callback, "Callback cannot be null");
+ Preconditions.checkNotNull(hubInfo, "ContextHubInfo cannot be null");
+ Preconditions.checkNotNull(executor, "Executor cannot be null");
+
+ ContextHubClient client = new ContextHubClient(hubInfo);
+ IContextHubClientCallback clientInterface = createClientCallback(
+ client, callback, executor);
+
+ IContextHubClient clientProxy;
+ try {
+ clientProxy = mService.bindClient(pendingIntent, clientInterface, hubInfo.getId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ client.setClientProxy(clientProxy);
+ return client;
}
/**
@@ -833,7 +849,7 @@ public final class ContextHubManager {
*
* @throws IllegalArgumentException if hubInfo does not represent a valid hub, or pendingIntent
* was not associated with a client
- * @throws IllegalStateException if there were too many registered clients at the service
+ * @throws IllegalStateException if the client is already registered to a valid callback
* @throws NullPointerException if pendingIntent, hubInfo, or callback is null
*
* @hide
diff --git a/core/java/android/hardware/location/IContextHubService.aidl b/core/java/android/hardware/location/IContextHubService.aidl
index 233e857d8e67..9b0acdf14724 100644
--- a/core/java/android/hardware/location/IContextHubService.aidl
+++ b/core/java/android/hardware/location/IContextHubService.aidl
@@ -17,6 +17,7 @@
package android.hardware.location;
// Declare any non-default types here with import statements
+import android.app.PendingIntent;
import android.hardware.location.ContextHubInfo;
import android.hardware.location.ContextHubMessage;
import android.hardware.location.NanoApp;
@@ -60,6 +61,11 @@ interface IContextHubService {
// Creates a client to send and receive messages
IContextHubClient createClient(in IContextHubClientCallback client, int contextHubId);
+ // Binds an existing client to a new callback interface, provided a previously registered
+ // PendingIntent
+ IContextHubClient bindClient(
+ in PendingIntent pendingIntent, in IContextHubClientCallback client, int contextHubId);
+
// Returns a list of ContextHub objects of available hubs
List<ContextHubInfo> getContextHubs();
diff --git a/core/java/android/net/MacAddress.java b/core/java/android/net/MacAddress.java
index 98f356722bf3..4cd000113b7e 100644
--- a/core/java/android/net/MacAddress.java
+++ b/core/java/android/net/MacAddress.java
@@ -393,4 +393,19 @@ public final class MacAddress implements Parcelable {
}
return out;
}
+
+ /**
+ * Checks if this MAC Address matches the provided range.
+ *
+ * @param baseAddress MacAddress representing the base address to compare with.
+ * @param mask MacAddress representing the mask to use during comparison.
+ * @return true if this MAC Address matches the given range.
+ *
+ * @hide
+ */
+ public boolean matches(@NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
+ Preconditions.checkNotNull(baseAddress);
+ Preconditions.checkNotNull(mask);
+ return (mAddr & mask.mAddr) == (baseAddress.mAddr & mask.mAddr);
+ }
}
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 1a84197974b4..92b316914d82 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -936,6 +936,21 @@ public class UserManager {
public static final String DISALLOW_AUTOFILL = "no_autofill";
/**
+ * Specifies if the contents of a user's screen is not allowed to be captured for artificial
+ * intelligence purposes.
+ *
+ * <p>Device owner and profile owner can set this restriction. When it is set by device owner,
+ * only the target user will be affected.
+ *
+ * <p>The default value is <code>false</code>.
+ *
+ * @see DevicePolicyManager#addUserRestriction(ComponentName, String)
+ * @see DevicePolicyManager#clearUserRestriction(ComponentName, String)
+ * @see #getUserRestrictions()
+ */
+ public static final String DISALLOW_INTELLIGENCE_CAPTURE = "no_intelligence_capture";
+
+ /**
* Specifies if user switching is blocked on the current user.
*
* <p> This restriction can only be set by the device owner, it will be applied to all users.
diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java
index a1d1c5736116..76607e9d42d2 100644
--- a/core/java/android/provider/FontsContract.java
+++ b/core/java/android/provider/FontsContract.java
@@ -15,8 +15,6 @@
*/
package android.provider;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
@@ -25,22 +23,22 @@ import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ProviderInfo;
import android.content.pm.Signature;
import android.database.Cursor;
import android.graphics.Typeface;
+import android.graphics.fonts.Font;
+import android.graphics.fonts.FontFamily;
+import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
import android.net.Uri;
-import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.ParcelFileDescriptor;
import android.os.Process;
-import android.os.ResultReceiver;
-import android.util.ArraySet;
import android.util.Log;
import android.util.LruCache;
@@ -49,7 +47,6 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import java.io.FileInputStream;
-import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -64,11 +61,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
/**
* Utility class to deal with Font ContentProviders.
@@ -636,7 +633,34 @@ public class FontsContract {
if (uriBuffer.isEmpty()) {
return null;
}
- return new Typeface.Builder(fonts, uriBuffer).build();
+
+ FontFamily.Builder familyBuilder = null;
+ for (FontInfo fontInfo : fonts) {
+ final ByteBuffer buffer = uriBuffer.get(fontInfo.getUri());
+ if (buffer == null) {
+ continue;
+ }
+ try {
+ final Font font = new Font.Builder(buffer)
+ .setWeight(fontInfo.getWeight())
+ .setSlant(fontInfo.isItalic()
+ ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT)
+ .setTtcIndex(fontInfo.getTtcIndex())
+ .setFontVariationSettings(fontInfo.getAxes())
+ .build();
+ if (familyBuilder == null) {
+ familyBuilder = new FontFamily.Builder(font);
+ } else {
+ familyBuilder.addFont(font);
+ }
+ } catch (IOException e) {
+ continue;
+ }
+ }
+ if (familyBuilder == null) {
+ return null;
+ }
+ return new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
}
/**
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a94591718260..a30e38aeed0c 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -819,6 +819,15 @@ public final class Settings {
"android.settings.action.MANAGE_WRITE_SETTINGS";
/**
+ * Activity Action: Show screen for controlling app usage properties for an app.
+ * Input: Intent's extra EXTRA_PACKAGE_NAME must specify the application package name.
+ * Output: Nothing.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_APP_USAGE_SETTINGS =
+ "android.settings.action.APP_USAGE_SETTINGS";
+
+ /**
* Activity Action: Show screen of details about a particular application.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
@@ -10276,6 +10285,18 @@ public final class Settings {
public static final String WIFI_LINK_SPEED_METRICS_ENABLED =
"wifi_link_speed_metrics_enabled";
+ /**
+ * Setting to enable the PNO frequency culling optimization.
+ * Disabled by default, and setting it to 1 will enable it.
+ * The value is boolean (0 or 1).
+ * @hide
+ */
+ public static final String WIFI_PNO_FREQUENCY_CULLING_ENABLED =
+ "wifi_pno_frequency_culling_enabled";
+
+ private static final Validator WIFI_PNO_FREQUENCY_CULLING_ENABLED_VALIDATOR =
+ BOOLEAN_VALIDATOR;
+
/**
* The maximum number of times we will retry a connection to an access
* point for which we have failed in acquiring an IP address from DHCP.
@@ -11478,6 +11499,24 @@ public final class Settings {
public static final String NETWORK_WATCHLIST_ENABLED = "network_watchlist_enabled";
/**
+ * Whether or not show hidden launcher icon apps feature is enabled.
+ * Type: int (0 for false, 1 for true)
+ * Default: 0
+ * @hide
+ */
+ public static final String SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED =
+ "show_hidden_icon_apps_enabled";
+
+ /**
+ * Whether or not show new app installed notification is enabled.
+ * Type: int (0 for false, 1 for true)
+ * Default: 0
+ * @hide
+ */
+ public static final String SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED =
+ "show_new_app_installed_notification_enabled";
+
+ /**
* Flag to keep background restricted profiles running after exiting. If disabled,
* the restricted profile can be put into stopped state as soon as the user leaves it.
* Type: int (0 for false, 1 for true)
@@ -12469,6 +12508,17 @@ public final class Settings {
"privileged_device_identifier_target_q_behavior_enabled";
/**
+ * If set to 1, the device identifier check will be relaxed to the previous READ_PHONE_STATE
+ * permission check for 3P apps.
+ *
+ * STOPSHIP: Remove this once we ship with the new device identifier check enabled.
+ *
+ * @hide
+ */
+ public static final String PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED =
+ "privileged_device_identifier_3p_check_relaxed";
+
+ /**
* If set to 1, SettingsProvider's restoreAnyVersion="true" attribute will be ignored
* and restoring to lower version of platform API will be skipped.
*
@@ -12683,6 +12733,8 @@ public final class Settings {
VALIDATORS.put(DEVICE_PROVISIONING_MOBILE_DATA_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(REQUIRE_PASSWORD_TO_DECRYPT, BOOLEAN_VALIDATOR);
VALIDATORS.put(DEVICE_DEMO_MODE, BOOLEAN_VALIDATOR);
+ VALIDATORS.put(WIFI_PNO_FREQUENCY_CULLING_ENABLED,
+ WIFI_PNO_FREQUENCY_CULLING_ENABLED_VALIDATOR);
}
/**
diff --git a/core/java/android/service/intelligence/IIntelligenceService.aidl b/core/java/android/service/intelligence/IIntelligenceService.aidl
new file mode 100644
index 000000000000..bacad8b44783
--- /dev/null
+++ b/core/java/android/service/intelligence/IIntelligenceService.aidl
@@ -0,0 +1,39 @@
+/*
+ * 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.intelligence;
+
+import android.service.intelligence.InteractionSessionId;
+import android.service.intelligence.InteractionContext;
+
+import android.view.intelligence.ContentCaptureEvent;
+
+import java.util.List;
+
+
+/**
+ * Interface from the system to an intelligence service.
+ *
+ * @hide
+ */
+oneway interface IIntelligenceService {
+
+ // Called when session is created (context not null) or destroyed (context null)
+ void onSessionLifecycle(in InteractionContext context, in InteractionSessionId sessionId);
+
+ void onContentCaptureEvents(in InteractionSessionId sessionId,
+ in List<ContentCaptureEvent> events);
+}
diff --git a/core/java/android/service/intelligence/IntelligenceService.java b/core/java/android/service/intelligence/IntelligenceService.java
new file mode 100644
index 000000000000..a2b60f044657
--- /dev/null
+++ b/core/java/android/service/intelligence/IntelligenceService.java
@@ -0,0 +1,126 @@
+/*
+ * 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.intelligence;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallSuper;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.util.Log;
+import android.view.intelligence.ContentCaptureEvent;
+
+import java.util.List;
+
+/**
+ * A service used to capture the content of the screen.
+ *
+ * <p>The data collected by this service can be analyzed and combined with other sources to provide
+ * contextual data in other areas of the system such as Autofill.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class IntelligenceService extends Service {
+
+ private static final String TAG = "IntelligenceService";
+
+ /**
+ * The {@link Intent} that must be declared as handled by the service.
+ * To be supported, the service must also require the
+ * {@link android.Manifest.permission#BIND_INTELLIGENCE_SERVICE} permission so
+ * that other applications can not abuse it.
+ */
+ public static final String SERVICE_INTERFACE =
+ "android.service.intelligence.IntelligenceService";
+
+ private Handler mHandler;
+
+ private final IIntelligenceService mInterface = new IIntelligenceService.Stub() {
+
+ @Override
+ public void onSessionLifecycle(InteractionContext context, InteractionSessionId sessionId)
+ throws RemoteException {
+ if (context != null) {
+ mHandler.sendMessage(
+ obtainMessage(IntelligenceService::onCreateInteractionSession,
+ IntelligenceService.this, context, sessionId));
+ } else {
+ mHandler.sendMessage(
+ obtainMessage(IntelligenceService::onDestroyInteractionSession,
+ IntelligenceService.this, sessionId));
+ }
+ }
+ @Override
+ public void onContentCaptureEvents(InteractionSessionId sessionId,
+ List<ContentCaptureEvent> events) {
+ mHandler.sendMessage(
+ obtainMessage(IntelligenceService::onContentCaptureEvent,
+ IntelligenceService.this, sessionId, events));
+
+ }
+ };
+
+ @CallSuper
+ @Override
+ public void onCreate() {
+ super.onCreate();
+ mHandler = new Handler(Looper.getMainLooper(), null, true);
+ }
+
+ /** @hide */
+ @Override
+ public final IBinder onBind(Intent intent) {
+ if (SERVICE_INTERFACE.equals(intent.getAction())) {
+ return mInterface.asBinder();
+ }
+ Log.w(TAG, "Tried to bind to wrong intent: " + intent);
+ return null;
+ }
+
+ /**
+ * Creates a new interaction session.
+ *
+ * @param context interaction context
+ * @param sessionId the session's Id
+ */
+ public void onCreateInteractionSession(@NonNull InteractionContext context,
+ @NonNull InteractionSessionId sessionId) {}
+
+ /**
+ * Notifies the service of {@link ContentCaptureEvent events} associated with a content capture
+ * session.
+ *
+ * @param sessionId the session's Id
+ * @param events the events
+ */
+ // TODO(b/111276913): rename to onContentCaptureEvents
+ public abstract void onContentCaptureEvent(@NonNull InteractionSessionId sessionId,
+ @NonNull List<ContentCaptureEvent> events);
+
+ /**
+ * Destroys the interaction session.
+ *
+ * @param sessionId the id of the session to destroy
+ */
+ public void onDestroyInteractionSession(@NonNull InteractionSessionId sessionId) {}
+}
diff --git a/core/java/android/service/intelligence/InteractionContext.aidl b/core/java/android/service/intelligence/InteractionContext.aidl
new file mode 100644
index 000000000000..4ce6aa45d4a1
--- /dev/null
+++ b/core/java/android/service/intelligence/InteractionContext.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.intelligence;
+
+parcelable InteractionContext;
diff --git a/core/java/android/service/intelligence/InteractionContext.java b/core/java/android/service/intelligence/InteractionContext.java
new file mode 100644
index 000000000000..c1803ad259d5
--- /dev/null
+++ b/core/java/android/service/intelligence/InteractionContext.java
@@ -0,0 +1,157 @@
+/*
+ * 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.intelligence;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.app.TaskInfo;
+import android.content.ComponentName;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+// TODO(b/111276913): add javadocs / implement Parcelable / implement equals/hashcode/toString
+/** @hide */
+@SystemApi
+public final class InteractionContext implements Parcelable {
+
+ /**
+ * Flag used to indicate that the app explicitly disabled content capture for the activity
+ * (using
+ * {@link android.view.intelligence.IntelligenceManager#disableContentCapture()}),
+ * in which case the service will just receive activity-level events.
+ */
+ public static final int FLAG_DISABLED_BY_APP = 0x1;
+
+ /**
+ * Flag used to indicate that the activity's window is tagged with
+ * {@link android.view.Display#FLAG_SECURE}, in which case the service will just receive
+ * activity-level events.
+ */
+ public static final int FLAG_DISABLED_BY_FLAG_SECURE = 0x2;
+
+ /** @hide */
+ @IntDef(flag = true, prefix = { "FLAG_" }, value = {
+ FLAG_DISABLED_BY_APP,
+ FLAG_DISABLED_BY_FLAG_SECURE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ContextCreationFlags{}
+
+ // TODO(b/111276913): create new object for taskId + componentName / reuse on other places
+ private final @NonNull ComponentName mComponentName;
+ private final int mTaskId;
+ private final int mDisplayId;
+ private final int mFlags;
+
+
+ /** @hide */
+ public InteractionContext(@NonNull ComponentName componentName, int taskId, int displayId,
+ int flags) {
+ mComponentName = Preconditions.checkNotNull(componentName);
+ mTaskId = taskId;
+ mDisplayId = displayId;
+ mFlags = flags;
+ }
+
+ /**
+ * Gets the id of the {@link TaskInfo task} associated with this context.
+ */
+ public int getTaskId() {
+ return mTaskId;
+ }
+
+ /**
+ * Gets the activity associated with this context.
+ */
+ public @NonNull ComponentName getActivityComponent() {
+ return mComponentName;
+ }
+
+ /**
+ * Gets the ID of the display associated with this context, as defined by
+ * {G android.hardware.display.DisplayManager#getDisplay(int) DisplayManager.getDisplay()}.
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ /**
+ * Gets the flags associated with this context.
+ *
+ * @return any combination of {@link #FLAG_DISABLED_BY_FLAG_SECURE} and
+ * {@link #FLAG_DISABLED_BY_APP}.
+ */
+ public @ContextCreationFlags int getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * @hide
+ */
+ // TODO(b/111276913): dump to proto as well
+ public void dump(PrintWriter pw) {
+ pw.print("comp="); pw.print(mComponentName.flattenToShortString());
+ pw.print(", taskId="); pw.print(mTaskId);
+ pw.print(", displayId="); pw.print(mDisplayId);
+ if (mFlags > 0) {
+ pw.print(", flags="); pw.print(mFlags);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return "Context[act=" + mComponentName.flattenToShortString() + ", taskId=" + mTaskId
+ + ", displayId=" + mDisplayId + ", flags=" + mFlags + "]";
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeParcelable(mComponentName, flags);
+ parcel.writeInt(mTaskId);
+ parcel.writeInt(mDisplayId);
+ parcel.writeInt(mFlags);
+ }
+
+ public static final Parcelable.Creator<InteractionContext> CREATOR =
+ new Parcelable.Creator<InteractionContext>() {
+
+ @Override
+ public InteractionContext createFromParcel(Parcel parcel) {
+ final ComponentName componentName = parcel.readParcelable(null);
+ final int taskId = parcel.readInt();
+ final int displayId = parcel.readInt();
+ final int flags = parcel.readInt();
+ return new InteractionContext(componentName, taskId, displayId, flags);
+ }
+
+ @Override
+ public InteractionContext[] newArray(int size) {
+ return new InteractionContext[size];
+ }
+ };
+}
diff --git a/core/java/android/service/intelligence/InteractionSessionId.aidl b/core/java/android/service/intelligence/InteractionSessionId.aidl
new file mode 100644
index 000000000000..a5392b684a11
--- /dev/null
+++ b/core/java/android/service/intelligence/InteractionSessionId.aidl
@@ -0,0 +1,19 @@
+/**
+ * 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.intelligence;
+
+parcelable InteractionSessionId;
diff --git a/core/java/android/service/intelligence/InteractionSessionId.java b/core/java/android/service/intelligence/InteractionSessionId.java
new file mode 100644
index 000000000000..667193b14113
--- /dev/null
+++ b/core/java/android/service/intelligence/InteractionSessionId.java
@@ -0,0 +1,123 @@
+/*
+ * 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.intelligence;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.io.PrintWriter;
+import java.util.UUID;
+
+// TODO(b/111276913): add javadocs / implement equals/hashcode/string
+/** @hide */
+@SystemApi
+public final class InteractionSessionId implements Parcelable {
+
+ private final @NonNull String mValue;
+
+ /**
+ * Creates a new instance.
+ *
+ * @hide
+ */
+ public InteractionSessionId() {
+ this(UUID.randomUUID().toString());
+ }
+
+ /**
+ * Creates a new instance.
+ *
+ * @param value The internal value.
+ *
+ * @hide
+ */
+ public InteractionSessionId(@NonNull String value) {
+ mValue = value;
+ }
+
+ /**
+ * @hide
+ */
+ public String getValue() {
+ return mValue;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((mValue == null) ? 0 : mValue.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (obj == null) return false;
+ if (getClass() != obj.getClass()) return false;
+ final InteractionSessionId other = (InteractionSessionId) obj;
+ if (mValue == null) {
+ if (other.mValue != null) return false;
+ } else if (!mValue.equals(other.mValue)) {
+ return false;
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * <p><b>NOTE: </b>this method is only useful for debugging purposes and is not guaranteed to
+ * be stable, hence it should not be used to identify the session.
+ */
+ @Override
+ public String toString() {
+ return mValue;
+ }
+
+ /** @hide */
+ // TODO(b/111276913): dump to proto as well
+ public void dump(PrintWriter pw) {
+ pw.print(mValue);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeString(mValue);
+ }
+
+ public static final Parcelable.Creator<InteractionSessionId> CREATOR =
+ new Parcelable.Creator<InteractionSessionId>() {
+
+ @Override
+ public InteractionSessionId createFromParcel(Parcel parcel) {
+ return new InteractionSessionId(parcel.readString());
+ }
+
+ @Override
+ public InteractionSessionId[] newArray(int size) {
+ return new InteractionSessionId[size];
+ }
+ };
+}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 2d67d79062b9..769dd1b7a0cd 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -36,6 +36,7 @@ public class FeatureFlagUtils {
public static final String PERSIST_PREFIX = "persist." + FFLAG_OVERRIDE_PREFIX;
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
public static final String EMERGENCY_DIAL_SHORTCUTS = "settings_emergency_dial_shortcuts";
+ public static final String SAFETY_HUB = "settings_safety_hub";
public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
private static final Map<String, String> DEFAULT_FLAGS;
@@ -51,6 +52,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(HEARING_AID_SETTINGS, "false");
DEFAULT_FLAGS.put(EMERGENCY_DIAL_SHORTCUTS, "true");
DEFAULT_FLAGS.put("settings_network_and_internet_v2", "false");
+ DEFAULT_FLAGS.put(SAFETY_HUB, "false");
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index dffbbb7afb9e..453d7885f4d2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -9852,12 +9852,12 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
// We weren't called from within a direct call to fitSystemWindows,
// call into it as a fallback in case we're in a class that overrides it
// and has logic to perform.
- if (fitSystemWindows(insets.getSystemWindowInsets())) {
+ if (fitSystemWindows(insets.getSystemWindowInsetsAsRect())) {
return insets.consumeSystemWindowInsets();
}
} else {
// We were called from within a direct call to fitSystemWindows.
- if (fitSystemWindowsInt(insets.getSystemWindowInsets())) {
+ if (fitSystemWindowsInt(insets.getSystemWindowInsetsAsRect())) {
return insets.consumeSystemWindowInsets();
}
}
@@ -9960,7 +9960,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
protected boolean computeFitSystemWindows(Rect inoutInsets, Rect outLocalInsets) {
WindowInsets innerInsets = computeSystemWindowInsets(new WindowInsets(inoutInsets),
outLocalInsets);
- inoutInsets.set(innerInsets.getSystemWindowInsets());
+ inoutInsets.set(innerInsets.getSystemWindowInsetsAsRect());
return innerInsets.isSystemWindowInsetsConsumed();
}
@@ -9979,7 +9979,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
|| mAttachInfo == null
|| ((mAttachInfo.mSystemUiVisibility & SYSTEM_UI_LAYOUT_FLAGS) == 0
&& !mAttachInfo.mOverscanRequested)) {
- outLocalInsets.set(in.getSystemWindowInsets());
+ outLocalInsets.set(in.getSystemWindowInsetsAsRect());
return in.consumeSystemWindowInsets().inset(outLocalInsets);
} else {
// The application wants to take care of fitting system window for
@@ -14730,7 +14730,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
*/
public float getCameraDistance() {
final float dpi = mResources.getDisplayMetrics().densityDpi;
- return -(mRenderNode.getCameraDistance() * dpi);
+ return mRenderNode.getCameraDistance() * dpi;
}
/**
@@ -14776,7 +14776,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
final float dpi = mResources.getDisplayMetrics().densityDpi;
invalidateViewProperty(true, false);
- mRenderNode.setCameraDistance(-Math.abs(distance) / dpi);
+ mRenderNode.setCameraDistance(Math.abs(distance) / dpi);
invalidateViewProperty(false, false);
invalidateParentIfNeededAndWasQuickRejected();
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 48761486d9dc..dd1f6407682f 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6877,7 +6877,7 @@ public final class ViewRootImpl implements ViewParent,
RenderNode renderNode = view.mRenderNode;
info[0]++;
if (renderNode != null) {
- info[1] += renderNode.getDebugSize();
+ info[1] += renderNode.computeApproximateMemoryUsage();
}
if (view instanceof ViewGroup) {
diff --git a/core/java/android/view/WindowInsets.java b/core/java/android/view/WindowInsets.java
index 8628da374930..4a7e783ffbdb 100644
--- a/core/java/android/view/WindowInsets.java
+++ b/core/java/android/view/WindowInsets.java
@@ -17,8 +17,10 @@
package android.view;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
+import android.graphics.Insets;
import android.graphics.Rect;
import com.android.internal.util.Preconditions;
@@ -43,26 +45,24 @@ import java.util.Objects;
*/
public final class WindowInsets {
- private Rect mSystemWindowInsets;
- private Rect mWindowDecorInsets;
- private Rect mStableInsets;
- private Rect mTempRect;
- private boolean mIsRound;
- private DisplayCutout mDisplayCutout;
+ @NonNull private final Insets mSystemWindowInsets;
+ @NonNull private final Insets mWindowDecorInsets;
+ @NonNull private final Insets mStableInsets;
+ @Nullable private Rect mTempRect;
+ private final boolean mIsRound;
+ @Nullable private final DisplayCutout mDisplayCutout;
/**
* In multi-window we force show the navigation bar. Because we don't want that the surface size
* changes in this mode, we instead have a flag whether the navigation bar size should always
* be consumed, so the app is treated like there is no virtual navigation bar at all.
*/
- private boolean mAlwaysConsumeNavBar;
+ private final boolean mAlwaysConsumeNavBar;
- private boolean mSystemWindowInsetsConsumed = false;
- private boolean mWindowDecorInsetsConsumed = false;
- private boolean mStableInsetsConsumed = false;
- private boolean mDisplayCutoutConsumed = false;
-
- private static final Rect EMPTY_RECT = new Rect(0, 0, 0, 0);
+ private final boolean mSystemWindowInsetsConsumed;
+ private final boolean mWindowDecorInsetsConsumed;
+ private final boolean mStableInsetsConsumed;
+ private final boolean mDisplayCutoutConsumed;
/**
* Since new insets may be added in the future that existing apps couldn't
@@ -74,21 +74,27 @@ public final class WindowInsets {
public static final WindowInsets CONSUMED;
static {
- CONSUMED = new WindowInsets(null, null, null, false, false, null);
+ CONSUMED = new WindowInsets((Insets) null, null, null, false, false, null);
}
/** @hide */
public WindowInsets(Rect systemWindowInsets, Rect windowDecorInsets, Rect stableInsets,
boolean isRound, boolean alwaysConsumeNavBar, DisplayCutout displayCutout) {
+ this(Insets.of(systemWindowInsets), Insets.of(windowDecorInsets), Insets.of(stableInsets),
+ isRound, alwaysConsumeNavBar, displayCutout);
+ }
+
+ private WindowInsets(Insets systemWindowInsets, Insets windowDecorInsets,
+ Insets stableInsets, boolean isRound, boolean alwaysConsumeNavBar,
+ DisplayCutout displayCutout) {
mSystemWindowInsetsConsumed = systemWindowInsets == null;
- mSystemWindowInsets = mSystemWindowInsetsConsumed
- ? EMPTY_RECT : new Rect(systemWindowInsets);
+ mSystemWindowInsets = mSystemWindowInsetsConsumed ? Insets.NONE : systemWindowInsets;
mWindowDecorInsetsConsumed = windowDecorInsets == null;
- mWindowDecorInsets = mWindowDecorInsetsConsumed ? EMPTY_RECT : new Rect(windowDecorInsets);
+ mWindowDecorInsets = mWindowDecorInsetsConsumed ? Insets.NONE : windowDecorInsets;
mStableInsetsConsumed = stableInsets == null;
- mStableInsets = mStableInsetsConsumed ? EMPTY_RECT : new Rect(stableInsets);
+ mStableInsets = mStableInsetsConsumed ? Insets.NONE : stableInsets;
mIsRound = isRound;
mAlwaysConsumeNavBar = alwaysConsumeNavBar;
@@ -104,16 +110,21 @@ public final class WindowInsets {
* @param src Source to copy insets from
*/
public WindowInsets(WindowInsets src) {
- mSystemWindowInsets = src.mSystemWindowInsets;
- mWindowDecorInsets = src.mWindowDecorInsets;
- mStableInsets = src.mStableInsets;
- mSystemWindowInsetsConsumed = src.mSystemWindowInsetsConsumed;
- mWindowDecorInsetsConsumed = src.mWindowDecorInsetsConsumed;
- mStableInsetsConsumed = src.mStableInsetsConsumed;
- mIsRound = src.mIsRound;
- mAlwaysConsumeNavBar = src.mAlwaysConsumeNavBar;
- mDisplayCutout = src.mDisplayCutout;
- mDisplayCutoutConsumed = src.mDisplayCutoutConsumed;
+ this(src.mSystemWindowInsetsConsumed ? null : src.mSystemWindowInsets,
+ src.mWindowDecorInsetsConsumed ? null : src.mWindowDecorInsets,
+ src.mStableInsetsConsumed ? null : src.mStableInsets,
+ src.mIsRound, src.mAlwaysConsumeNavBar,
+ displayCutoutCopyConstructorArgument(src));
+ }
+
+ private static DisplayCutout displayCutoutCopyConstructorArgument(WindowInsets w) {
+ if (w.mDisplayCutoutConsumed) {
+ return null;
+ } else if (w.mDisplayCutout == null) {
+ return DisplayCutout.NO_CUTOUT;
+ } else {
+ return w.mDisplayCutout;
+ }
}
/** @hide */
@@ -126,22 +137,35 @@ public final class WindowInsets {
* Used to provide a safe copy of the system window insets to pass through
* to the existing fitSystemWindows method and other similar internals.
* @hide
+ *
+ * @deprecated use {@link #getSystemWindowInsets()} instead.
*/
- @UnsupportedAppUsage
- public Rect getSystemWindowInsets() {
+ @Deprecated
+ @NonNull
+ public Rect getSystemWindowInsetsAsRect() {
if (mTempRect == null) {
mTempRect = new Rect();
}
- if (mSystemWindowInsets != null) {
- mTempRect.set(mSystemWindowInsets);
- } else {
- // If there were no system window insets, this is just empty.
- mTempRect.setEmpty();
- }
+ mTempRect.set(mSystemWindowInsets.left, mSystemWindowInsets.top,
+ mSystemWindowInsets.right, mSystemWindowInsets.bottom);
return mTempRect;
}
/**
+ * Returns the system window insets in pixels.
+ *
+ * <p>The system window inset represents the area of a full-screen window that is
+ * partially or fully obscured by the status bar, navigation bar, IME or other system windows.
+ * </p>
+ *
+ * @return The system window insets
+ */
+ @NonNull
+ public Insets getSystemWindowInsets() {
+ return mSystemWindowInsets;
+ }
+
+ /**
* Returns the left system window inset in pixels.
*
* <p>The system window inset represents the area of a full-screen window that is
@@ -304,11 +328,13 @@ public final class WindowInsets {
*
* @return A modified copy of this WindowInsets
*/
+ @NonNull
public WindowInsets consumeDisplayCutout() {
- final WindowInsets result = new WindowInsets(this);
- result.mDisplayCutout = null;
- result.mDisplayCutoutConsumed = true;
- return result;
+ return new WindowInsets(mSystemWindowInsetsConsumed ? null : mSystemWindowInsets,
+ mWindowDecorInsetsConsumed ? null : mWindowDecorInsets,
+ mStableInsetsConsumed ? null : mStableInsets,
+ mIsRound, mAlwaysConsumeNavBar,
+ null /* displayCutout */);
}
@@ -349,101 +375,95 @@ public final class WindowInsets {
*
* @return A modified copy of this WindowInsets
*/
+ @NonNull
public WindowInsets consumeSystemWindowInsets() {
- final WindowInsets result = new WindowInsets(this);
- result.mSystemWindowInsets = EMPTY_RECT;
- result.mSystemWindowInsetsConsumed = true;
- return result;
- }
-
- /**
- * Returns a copy of this WindowInsets with selected system window insets fully consumed.
- *
- * @param left true to consume the left system window inset
- * @param top true to consume the top system window inset
- * @param right true to consume the right system window inset
- * @param bottom true to consume the bottom system window inset
- * @return A modified copy of this WindowInsets
- * @hide pending API
- */
- public WindowInsets consumeSystemWindowInsets(boolean left, boolean top,
- boolean right, boolean bottom) {
- if (left || top || right || bottom) {
- final WindowInsets result = new WindowInsets(this);
- result.mSystemWindowInsets = new Rect(
- left ? 0 : mSystemWindowInsets.left,
- top ? 0 : mSystemWindowInsets.top,
- right ? 0 : mSystemWindowInsets.right,
- bottom ? 0 : mSystemWindowInsets.bottom);
- return result;
- }
- return this;
+ return new WindowInsets(null /* systemWindowInsets */,
+ mWindowDecorInsetsConsumed ? null : mWindowDecorInsets,
+ mStableInsetsConsumed ? null : mStableInsets,
+ mIsRound, mAlwaysConsumeNavBar,
+ displayCutoutCopyConstructorArgument(this));
}
+ // TODO(b/119190588): replace @code with @link below
/**
* Returns a copy of this WindowInsets with selected system window insets replaced
* with new values.
*
+ * <p>Note: If the system window insets are already consumed, this method will return them
+ * unchanged on {@link android.os.Build.VERSION_CODES#Q Q} and later. Prior to
+ * {@link android.os.Build.VERSION_CODES#Q Q}, the new values were applied regardless of
+ * whether they were consumed, and this method returns invalid non-zero consumed insets.
+ *
* @param left New left inset in pixels
* @param top New top inset in pixels
* @param right New right inset in pixels
* @param bottom New bottom inset in pixels
* @return A modified copy of this WindowInsets
- */
- public WindowInsets replaceSystemWindowInsets(int left, int top,
- int right, int bottom) {
- final WindowInsets result = new WindowInsets(this);
- result.mSystemWindowInsets = new Rect(left, top, right, bottom);
- return result;
+ * @deprecated use {@code Builder#Builder(WindowInsets)} with
+ * {@link Builder#setSystemWindowInsets(Insets)} instead.
+ */
+ @Deprecated
+ @NonNull
+ public WindowInsets replaceSystemWindowInsets(int left, int top, int right, int bottom) {
+ // Compat edge case: what should this do if the insets have already been consumed?
+ // On platforms prior to Q, the behavior was to override the insets with non-zero values,
+ // but leave them consumed, which is invalid (consumed insets must be zero).
+ // The behavior is now keeping them consumed and discarding the new insets.
+ if (mSystemWindowInsetsConsumed) {
+ return this;
+ }
+ return new Builder(this).setSystemWindowInsets(Insets.of(left, top, right, bottom)).build();
}
+ // TODO(b/119190588): replace @code with @link below
/**
* Returns a copy of this WindowInsets with selected system window insets replaced
* with new values.
*
+ * <p>Note: If the system window insets are already consumed, this method will return them
+ * unchanged on {@link android.os.Build.VERSION_CODES#Q Q} and later. Prior to
+ * {@link android.os.Build.VERSION_CODES#Q Q}, the new values were applied regardless of
+ * whether they were consumed, and this method returns invalid non-zero consumed insets.
+ *
* @param systemWindowInsets New system window insets. Each field is the inset in pixels
* for that edge
* @return A modified copy of this WindowInsets
+ * @deprecated use {@code Builder#Builder(WindowInsets)} with
+ * {@link Builder#setSystemWindowInsets(Insets)} instead.
*/
+ @Deprecated
+ @NonNull
public WindowInsets replaceSystemWindowInsets(Rect systemWindowInsets) {
- final WindowInsets result = new WindowInsets(this);
- result.mSystemWindowInsets = new Rect(systemWindowInsets);
- return result;
+ return replaceSystemWindowInsets(systemWindowInsets.left, systemWindowInsets.top,
+ systemWindowInsets.right, systemWindowInsets.bottom);
}
/**
* @hide
*/
+ @NonNull
public WindowInsets consumeWindowDecorInsets() {
- final WindowInsets result = new WindowInsets(this);
- result.mWindowDecorInsets.set(0, 0, 0, 0);
- result.mWindowDecorInsetsConsumed = true;
- return result;
+ return new WindowInsets(mSystemWindowInsetsConsumed ? null : mSystemWindowInsets,
+ null /* windowDecorInsets */,
+ mStableInsetsConsumed ? null : mStableInsets,
+ mIsRound, mAlwaysConsumeNavBar,
+ displayCutoutCopyConstructorArgument(this));
}
/**
- * @hide
- */
- public WindowInsets consumeWindowDecorInsets(boolean left, boolean top,
- boolean right, boolean bottom) {
- if (left || top || right || bottom) {
- final WindowInsets result = new WindowInsets(this);
- result.mWindowDecorInsets = new Rect(left ? 0 : mWindowDecorInsets.left,
- top ? 0 : mWindowDecorInsets.top,
- right ? 0 : mWindowDecorInsets.right,
- bottom ? 0 : mWindowDecorInsets.bottom);
- return result;
- }
- return this;
- }
-
- /**
- * @hide
+ * Returns the stable insets in pixels.
+ *
+ * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+ * partially or fully obscured by the system UI elements. This value does not change
+ * based on the visibility state of those elements; for example, if the status bar is
+ * normally shown, but temporarily hidden, the stable inset will still provide the inset
+ * associated with the status bar being shown.</p>
+ *
+ * @return The stable insets
*/
- public WindowInsets replaceWindowDecorInsets(int left, int top, int right, int bottom) {
- final WindowInsets result = new WindowInsets(this);
- result.mWindowDecorInsets = new Rect(left, top, right, bottom);
- return result;
+ @NonNull
+ public Insets getStableInsets() {
+ return mStableInsets;
}
/**
@@ -527,11 +547,13 @@ public final class WindowInsets {
*
* @return A modified copy of this WindowInsets
*/
+ @NonNull
public WindowInsets consumeStableInsets() {
- final WindowInsets result = new WindowInsets(this);
- result.mStableInsets = EMPTY_RECT;
- result.mStableInsetsConsumed = true;
- return result;
+ return new WindowInsets(mSystemWindowInsetsConsumed ? null : mSystemWindowInsets,
+ mWindowDecorInsetsConsumed ? null : mWindowDecorInsets,
+ null /* stableInsets */,
+ mIsRound, mAlwaysConsumeNavBar,
+ displayCutoutCopyConstructorArgument(this));
}
/**
@@ -555,8 +577,11 @@ public final class WindowInsets {
* Returns a copy of this instance inset in the given directions.
*
* @see #inset(int, int, int, int)
+ * @deprecated use {@link #inset(Insets)}
* @hide
*/
+ @Deprecated
+ @NonNull
public WindowInsets inset(Rect r) {
return inset(r.left, r.top, r.right, r.bottom);
}
@@ -564,6 +589,17 @@ public final class WindowInsets {
/**
* Returns a copy of this instance inset in the given directions.
*
+ * @see #inset(int, int, int, int)
+ * @hide
+ */
+ @NonNull
+ public WindowInsets inset(Insets insets) {
+ return inset(insets.left, insets.top, insets.right, insets.bottom);
+ }
+
+ /**
+ * Returns a copy of this instance inset in the given directions.
+ *
* This is intended for dispatching insets to areas of the window that are smaller than the
* current area.
*
@@ -579,35 +615,27 @@ public final class WindowInsets {
* @param bottom the amount of insets to remove from the bottom. Must be non-negative.
*
* @return the inset insets
- *
- * @hide pending API
*/
- @UnsupportedAppUsage
+ @NonNull
public WindowInsets inset(int left, int top, int right, int bottom) {
Preconditions.checkArgumentNonnegative(left);
Preconditions.checkArgumentNonnegative(top);
Preconditions.checkArgumentNonnegative(right);
Preconditions.checkArgumentNonnegative(bottom);
- WindowInsets result = new WindowInsets(this);
- if (!result.mSystemWindowInsetsConsumed) {
- result.mSystemWindowInsets =
- insetInsets(result.mSystemWindowInsets, left, top, right, bottom);
- }
- if (!result.mWindowDecorInsetsConsumed) {
- result.mWindowDecorInsets =
- insetInsets(result.mWindowDecorInsets, left, top, right, bottom);
- }
- if (!result.mStableInsetsConsumed) {
- result.mStableInsets = insetInsets(result.mStableInsets, left, top, right, bottom);
- }
- if (mDisplayCutout != null) {
- result.mDisplayCutout = result.mDisplayCutout.inset(left, top, right, bottom);
- if (result.mDisplayCutout.isEmpty()) {
- result.mDisplayCutout = null;
- }
- }
- return result;
+ return new WindowInsets(
+ mSystemWindowInsetsConsumed ? null :
+ insetInsets(mSystemWindowInsets, left, top, right, bottom),
+ mWindowDecorInsetsConsumed ? null :
+ insetInsets(mWindowDecorInsets, left, top, right, bottom),
+ mStableInsetsConsumed ? null :
+ insetInsets(mStableInsets, left, top, right, bottom),
+ mIsRound, mAlwaysConsumeNavBar,
+ mDisplayCutoutConsumed
+ ? null :
+ mDisplayCutout == null
+ ? DisplayCutout.NO_CUTOUT
+ : mDisplayCutout.inset(left, top, right, bottom));
}
@Override
@@ -634,7 +662,7 @@ public final class WindowInsets {
mWindowDecorInsetsConsumed, mStableInsetsConsumed, mDisplayCutoutConsumed);
}
- private static Rect insetInsets(Rect insets, int left, int top, int right, int bottom) {
+ private static Insets insetInsets(Insets insets, int left, int top, int right, int bottom) {
int newLeft = Math.max(0, insets.left - left);
int newTop = Math.max(0, insets.top - top);
int newRight = Math.max(0, insets.right - right);
@@ -642,7 +670,7 @@ public final class WindowInsets {
if (newLeft == left && newTop == top && newRight == right && newBottom == bottom) {
return insets;
}
- return new Rect(newLeft, newTop, newRight, newBottom);
+ return Insets.of(newLeft, newTop, newRight, newBottom);
}
/**
@@ -651,4 +679,122 @@ public final class WindowInsets {
boolean isSystemWindowInsetsConsumed() {
return mSystemWindowInsetsConsumed;
}
+
+ /**
+ * Builder for WindowInsets.
+ */
+ public static class Builder {
+
+ private Insets mSystemWindowInsets;
+ private Insets mStableInsets;
+ private DisplayCutout mDisplayCutout;
+
+ private Insets mWindowDecorInsets;
+ private boolean mIsRound;
+ private boolean mAlwaysConsumeNavBar;
+
+ /**
+ * Creates a builder where all insets are initially consumed.
+ */
+ public Builder() {
+ }
+
+ /**
+ * Creates a builder where all insets are initialized from {@link WindowInsets}.
+ *
+ * @param insets the instance to initialize from.
+ */
+ public Builder(WindowInsets insets) {
+ mSystemWindowInsets = insets.mSystemWindowInsetsConsumed ? null
+ : insets.mSystemWindowInsets;
+ mStableInsets = insets.mStableInsetsConsumed ? null : insets.mStableInsets;
+ mDisplayCutout = displayCutoutCopyConstructorArgument(insets);
+ mWindowDecorInsets = insets.mWindowDecorInsetsConsumed ? null
+ : insets.mWindowDecorInsets;
+ mIsRound = insets.mIsRound;
+ mAlwaysConsumeNavBar = insets.mAlwaysConsumeNavBar;
+ }
+
+ /**
+ * Sets system window insets in pixels.
+ *
+ * <p>The system window inset represents the area of a full-screen window that is
+ * partially or fully obscured by the status bar, navigation bar, IME or other system
+ * windows.</p>
+ *
+ * @see #getSystemWindowInsets()
+ * @return itself
+ */
+ @NonNull
+ public Builder setSystemWindowInsets(@NonNull Insets systemWindowInsets) {
+ Preconditions.checkNotNull(systemWindowInsets);
+ mSystemWindowInsets = systemWindowInsets;
+ return this;
+ }
+
+ /**
+ * Sets the stable insets in pixels.
+ *
+ * <p>The stable inset represents the area of a full-screen window that <b>may</b> be
+ * partially or fully obscured by the system UI elements. This value does not change
+ * based on the visibility state of those elements; for example, if the status bar is
+ * normally shown, but temporarily hidden, the stable inset will still provide the inset
+ * associated with the status bar being shown.</p>
+ *
+ * @see #getStableInsets()
+ * @return itself
+ */
+ @NonNull
+ public Builder setStableInsets(@NonNull Insets stableInsets) {
+ Preconditions.checkNotNull(stableInsets);
+ mStableInsets = stableInsets;
+ return this;
+ }
+
+ /**
+ * Sets the display cutout.
+ *
+ * @see #getDisplayCutout()
+ * @param displayCutout the display cutout or null if there is none
+ * @return itself
+ */
+ @NonNull
+ public Builder setDisplayCutout(@Nullable DisplayCutout displayCutout) {
+ mDisplayCutout = displayCutout != null ? displayCutout : DisplayCutout.NO_CUTOUT;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setWindowDecorInsets(@NonNull Insets windowDecorInsets) {
+ Preconditions.checkNotNull(windowDecorInsets);
+ mWindowDecorInsets = windowDecorInsets;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setRound(boolean round) {
+ mIsRound = round;
+ return this;
+ }
+
+ /** @hide */
+ @NonNull
+ public Builder setAlwaysConsumeNavBar(boolean alwaysConsumeNavBar) {
+ mAlwaysConsumeNavBar = alwaysConsumeNavBar;
+ return this;
+ }
+
+ /**
+ * Builds a {@link WindowInsets} instance.
+ *
+ * @return the {@link WindowInsets} instance.
+ */
+ @NonNull
+ public WindowInsets build() {
+ return new WindowInsets(mSystemWindowInsets, mWindowDecorInsets, mStableInsets,
+ mIsRound, mAlwaysConsumeNavBar, mDisplayCutout);
+ }
+ }
}
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.aidl b/core/java/android/view/intelligence/ContentCaptureEvent.aidl
new file mode 100644
index 000000000000..c66a6cb0d486
--- /dev/null
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.aidl
@@ -0,0 +1,19 @@
+/*
+ * 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.view.intelligence;
+
+parcelable ContentCaptureEvent;
diff --git a/core/java/android/view/intelligence/ContentCaptureEvent.java b/core/java/android/view/intelligence/ContentCaptureEvent.java
new file mode 100644
index 000000000000..2530ae3b3124
--- /dev/null
+++ b/core/java/android/view/intelligence/ContentCaptureEvent.java
@@ -0,0 +1,226 @@
+/*
+ * 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.view.intelligence;
+
+import android.annotation.IntDef;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.view.autofill.AutofillId;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+// TODO(b/111276913): add javadocs / implement Parcelable / implement
+/** @hide */
+@SystemApi
+public final class ContentCaptureEvent implements Parcelable {
+
+ /** @hide */
+ public static final int TYPE_ACTIVITY_DESTROYED = -2;
+ /** @hide */
+ public static final int TYPE_ACTIVITY_CREATED = -1;
+
+ /**
+ * Called when the activity is started.
+ */
+ public static final int TYPE_ACTIVITY_STARTED = 1;
+
+ /**
+ * Called when the activity is resumed.
+ */
+ public static final int TYPE_ACTIVITY_RESUMED = 2;
+
+ /**
+ * Called when the activity is paused.
+ */
+ public static final int TYPE_ACTIVITY_PAUSED = 3;
+
+ /**
+ * Called when the activity is stopped.
+ */
+ public static final int TYPE_ACTIVITY_STOPPED = 4;
+
+ /**
+ * Called when a node has been added to the screen and is visible to the user.
+ *
+ * <p>The metadata of the node is available through {@link #getViewNode()}.
+ */
+ public static final int TYPE_VIEW_ADDED = 5;
+
+ /**
+ * Called when a node has been removed from the screen and is not visible to the user anymore.
+ *
+ * <p>The id of the node is available through {@link #getId()}.
+ */
+ public static final int TYPE_VIEW_REMOVED = 6;
+
+ /**
+ * Called when the text of a node has been changed.
+ *
+ * <p>The id of the node is available through {@link #getId()}, and the new text is
+ * available through {@link #getText()}.
+ */
+ public static final int TYPE_VIEW_TEXT_CHANGED = 7;
+
+ // TODO(b/111276913): add event to indicate when FLAG_SECURE was changed?
+
+ /** @hide */
+ @IntDef(prefix = { "TYPE_" }, value = {
+ TYPE_ACTIVITY_STARTED,
+ TYPE_ACTIVITY_PAUSED,
+ TYPE_ACTIVITY_RESUMED,
+ TYPE_ACTIVITY_STOPPED,
+ TYPE_VIEW_ADDED,
+ TYPE_VIEW_REMOVED,
+ TYPE_VIEW_TEXT_CHANGED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface EventType{}
+
+ private final int mType;
+ private final long mEventTime;
+ private final int mFlags;
+
+
+ /** @hide */
+ public ContentCaptureEvent(int type, long eventTime, int flags) {
+ mType = type;
+ mEventTime = eventTime;
+ mFlags = flags;
+ }
+
+ /**
+ * Gets the type of the event.
+ *
+ * @return one of {@link #TYPE_ACTIVITY_STARTED}, {@link #TYPE_ACTIVITY_RESUMED},
+ * {@link #TYPE_ACTIVITY_PAUSED}, {@link #TYPE_ACTIVITY_STOPPED},
+ * {@link #TYPE_VIEW_ADDED}, {@link #TYPE_VIEW_REMOVED}, or {@link #TYPE_VIEW_TEXT_CHANGED}.
+ */
+ public @EventType int getType() {
+ return mType;
+ }
+
+ /**
+ * Gets when the event was generated, in ms.
+ */
+ public long getEventTime() {
+ return mEventTime;
+ }
+
+ /**
+ * Gets optional flags associated with the event.
+ *
+ * @return either {@code 0} or
+ * {@link android.view.intelligence.IntelligenceManager#FLAG_USER_INPUT}.
+ */
+ public int getFlags() {
+ return mFlags;
+ }
+
+ /**
+ * Gets the whole metadata of the node associated with the event.
+ *
+ * <p>Only set on {@link #TYPE_VIEW_ADDED} events.
+ */
+ @Nullable
+ public ViewNode getViewNode() {
+ return null;
+ }
+
+ /**
+ * Gets the {@link AutofillId} of the node associated with the event.
+ *
+ * <p>Only set on {@link #TYPE_VIEW_REMOVED} and {@link #TYPE_VIEW_TEXT_CHANGED} events.
+ */
+ @Nullable
+ public AutofillId getId() {
+ return null;
+ }
+
+ /**
+ * Gets the current text of the node associated with the event.
+ *
+ * <p>Only set on {@link #TYPE_VIEW_TEXT_CHANGED} events.
+ */
+ @Nullable
+ public CharSequence getText() {
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder string = new StringBuilder("ContentCaptureEvent[type=")
+ .append(getTypeAsString(mType)).append(", time=").append(mEventTime);
+ if (mFlags > 0) {
+ string.append(", flags=").append(mFlags);
+ }
+ return string.append(']').toString();
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel parcel, int flags) {
+ parcel.writeInt(mType);
+ parcel.writeLong(mEventTime);
+ parcel.writeInt(mFlags);
+ }
+
+ public static final Parcelable.Creator<ContentCaptureEvent> CREATOR =
+ new Parcelable.Creator<ContentCaptureEvent>() {
+
+ @Override
+ public ContentCaptureEvent createFromParcel(Parcel parcel) {
+ final int type = parcel.readInt();
+ final long eventTime = parcel.readLong();
+ final int flags = parcel.readInt();
+ return new ContentCaptureEvent(type, eventTime, flags);
+ }
+
+ @Override
+ public ContentCaptureEvent[] newArray(int size) {
+ return new ContentCaptureEvent[size];
+ }
+ };
+
+
+ /** @hide */
+ public static String getTypeAsString(@EventType int type) {
+ switch (type) {
+ case TYPE_ACTIVITY_STARTED:
+ return "ACTIVITY_STARTED";
+ case TYPE_ACTIVITY_RESUMED:
+ return "ACTIVITY_RESUMED";
+ case TYPE_ACTIVITY_PAUSED:
+ return "ACTIVITY_PAUSED";
+ case TYPE_ACTIVITY_STOPPED:
+ return "ACTIVITY_STOPPED";
+ case TYPE_VIEW_ADDED:
+ return "VIEW_ADDED";
+ case TYPE_VIEW_REMOVED:
+ return "VIEW_REMOVED";
+ case TYPE_VIEW_TEXT_CHANGED:
+ return "VIEW_TEXT_CHANGED";
+ default:
+ return "UKNOWN_TYPE: " + type;
+ }
+ }
+}
diff --git a/core/java/android/view/intelligence/IIntelligenceManager.aidl b/core/java/android/view/intelligence/IIntelligenceManager.aidl
new file mode 100644
index 000000000000..2f128de1f53d
--- /dev/null
+++ b/core/java/android/view/intelligence/IIntelligenceManager.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.view.intelligence;
+
+import android.content.ComponentName;
+import android.os.IBinder;
+import android.service.intelligence.InteractionSessionId;
+import android.view.intelligence.ContentCaptureEvent;
+
+import com.android.internal.os.IResultReceiver;
+
+import java.util.List;
+
+/**
+ * {@hide}
+ */
+oneway interface IIntelligenceManager {
+ /**
+ * Starts a session, sending the "remote" sessionId to the receiver.
+ */
+ void startSession(int userId, IBinder activityToken, in ComponentName componentName,
+ in InteractionSessionId sessionId, int flags, in IResultReceiver result);
+
+ /**
+ * Finishes a session.
+ */
+ void finishSession(int userId, in InteractionSessionId sessionId);
+
+ /**
+ * Sends a batch of events
+ */
+ void sendEvents(int userId, in InteractionSessionId sessionId,
+ in List<ContentCaptureEvent> events);
+}
diff --git a/core/java/android/view/intelligence/IntelligenceManager.java b/core/java/android/view/intelligence/IntelligenceManager.java
new file mode 100644
index 000000000000..9bf6c2ce6184
--- /dev/null
+++ b/core/java/android/view/intelligence/IntelligenceManager.java
@@ -0,0 +1,349 @@
+/*
+ * 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.view.intelligence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.service.intelligence.InteractionSessionId;
+import android.util.Log;
+import android.view.intelligence.ContentCaptureEvent.EventType;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.Preconditions;
+
+import java.io.PrintWriter;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * TODO(b/111276913): add javadocs / implement
+ */
+@SystemService(Context.INTELLIGENCE_MANAGER_SERVICE)
+public final class IntelligenceManager {
+
+ private static final String TAG = "IntelligenceManager";
+
+ // TODO(b/111276913): define a way to dynamically set it (for example, using settings?)
+ private static final boolean VERBOSE = false;
+
+ /**
+ * Used to indicate that a text change was caused by user input (for example, through IME).
+ */
+ //TODO(b/111276913): link to notifyTextChanged() method once available
+ public static final int FLAG_USER_INPUT = 0x1;
+
+
+ /**
+ * Initial state, when there is no session.
+ *
+ * @hide
+ */
+ public static final int STATE_UNKNOWN = 0;
+
+ /**
+ * Service's startSession() was called, but server didn't confirm it was created yet.
+ *
+ * @hide
+ */
+ public static final int STATE_WAITING_FOR_SERVER = 1;
+
+ /**
+ * Session is active.
+ *
+ * @hide
+ */
+ public static final int STATE_ACTIVE = 2;
+
+ private final Context mContext;
+
+ @Nullable
+ private final IIntelligenceManager mService;
+
+ private final Object mLock = new Object();
+
+ @Nullable
+ @GuardedBy("mLock")
+ private InteractionSessionId mId;
+
+ @GuardedBy("mLock")
+ private int mState = STATE_UNKNOWN;
+
+ @GuardedBy("mLock")
+ private IBinder mApplicationToken;
+
+ // TODO(b/111276913): replace by an interface name implemented by Activity, similar to
+ // AutofillClient
+ @GuardedBy("mLock")
+ private ComponentName mComponentName;
+
+ /** @hide */
+ public IntelligenceManager(@NonNull Context context, @Nullable IIntelligenceManager service) {
+ mContext = Preconditions.checkNotNull(context, "context cannot be null");
+ mService = service;
+ }
+
+ /** @hide */
+ public void onActivityCreated(@NonNull IBinder token, @NonNull ComponentName componentName) {
+ if (!isContentCaptureEnabled()) return;
+
+ synchronized (mLock) {
+ if (mState != STATE_UNKNOWN) {
+ Log.w(TAG, "ignoring onActivityStarted(" + token + ") while on state "
+ + getStateAsStringLocked());
+ return;
+ }
+ mState = STATE_WAITING_FOR_SERVER;
+ mId = new InteractionSessionId();
+ mApplicationToken = token;
+ mComponentName = componentName;
+
+ if (VERBOSE) {
+ Log.v(TAG, "onActivityStarted(): token=" + token + ", act=" + componentName
+ + ", id=" + mId);
+ }
+ final int flags = 0; // TODO(b/111276913): get proper flags
+
+ try {
+ mService.startSession(mContext.getUserId(), mApplicationToken, componentName,
+ mId, flags, new IResultReceiver.Stub() {
+ @Override
+ public void send(int resultCode, Bundle resultData)
+ throws RemoteException {
+ synchronized (mLock) {
+ if (resultCode > 0) {
+ mState = STATE_ACTIVE;
+ } else {
+ // TODO(b/111276913): handle other cases like disabled by
+ // service
+ mState = STATE_UNKNOWN;
+ }
+ if (VERBOSE) {
+ Log.v(TAG, "onActivityStarted() result: code=" + resultCode
+ + ", id=" + mId
+ + ", state=" + getStateAsStringLocked());
+ }
+ }
+ }
+ });
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Used for intermediate events (i.e, other than created and destroyed).
+ *
+ * @hide
+ */
+ public void onActivityLifecycleEvent(@EventType int type) {
+ if (!isContentCaptureEnabled()) return;
+
+ //TODO(b/111276913): should buffer event (and call service on handler thread), instead of
+ // calling right away
+ final ContentCaptureEvent event = new ContentCaptureEvent(type, SystemClock.uptimeMillis(),
+ 0);
+ final List<ContentCaptureEvent> events = Arrays.asList(event);
+
+ synchronized (mLock) {
+ //TODO(b/111276913): check session state; for example, how to handle if it's waiting for
+ // remote id
+
+ if (VERBOSE) {
+ Log.v(TAG, "onActivityLifecycleEvent() for " + mComponentName.flattenToShortString()
+ + ": " + ContentCaptureEvent.getTypeAsString(type));
+ }
+
+ try {
+ mService.sendEvents(mContext.getUserId(), mId, events);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /** @hide */
+ public void onActivityDestroyed() {
+ if (!isContentCaptureEnabled()) return;
+
+ synchronized (mLock) {
+ //TODO(b/111276913): check state (for example, how to handle if it's waiting for remote
+ // id) and send it to the cache of batched commands
+
+ if (VERBOSE) {
+ Log.v(TAG, "onActivityDestroyed(): state=" + getStateAsStringLocked()
+ + ", mId=" + mId);
+ }
+
+ try {
+ mService.finishSession(mContext.getUserId(), mId);
+ mState = STATE_UNKNOWN;
+ mId = null;
+ mApplicationToken = null;
+ mComponentName = null;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Returns the component name of the {@code android.service.intelligence.IntelligenceService}
+ * that is enabled for the current user.
+ */
+ @Nullable
+ public ComponentName getIntelligenceServiceComponentName() {
+ //TODO(b/111276913): implement
+ return null;
+ }
+
+ /**
+ * Checks whether content capture is enabled for this activity.
+ */
+ public boolean isContentCaptureEnabled() {
+ //TODO(b/111276913): properly implement by checking if it was explicitly disabled by
+ // service, or if service is not set
+ // (and probably renamign to isEnabledLocked()
+ return mService != null;
+ }
+
+ /**
+ * Called by apps to disable content capture.
+ *
+ * <p><b>Note: </b> this call is not persisted accross reboots, so apps should typically call
+ * it on {@link android.app.Activity#onCreate(android.os.Bundle, android.os.PersistableBundle)}.
+ */
+ public void disableContentCapture() {
+ //TODO(b/111276913): implement
+ }
+
+ /**
+ * Called by the the service {@link android.service.intelligence.IntelligenceService}
+ * to define whether content capture should be enabled for activities with such
+ * {@link android.content.ComponentName}.
+ *
+ * <p>Useful to blacklist a particular activity.
+ *
+ * @throws UnsupportedOperationException if not called by the UID that owns the
+ * {@link android.service.intelligence.IntelligenceService} associated with the
+ * current user.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void setActivityContentCaptureEnabled(@NonNull ComponentName activity,
+ boolean enabled) {
+ //TODO(b/111276913): implement
+ }
+
+ /**
+ * Called by the the service {@link android.service.intelligence.IntelligenceService}
+ * to define whether content capture should be enabled for activities of the app with such
+ * {@code packageName}.
+ *
+ * <p>Useful to blacklist any activity from a particular app.
+ *
+ * @throws UnsupportedOperationException if not called by the UID that owns the
+ * {@link android.service.intelligence.IntelligenceService} associated with the
+ * current user.
+ *
+ * @hide
+ */
+ @SystemApi
+ public void setPackageContentCaptureEnabled(@NonNull String packageName, boolean enabled) {
+ //TODO(b/111276913): implement
+ }
+
+ /**
+ * Gets the activities where content capture was disabled by
+ * {@link #setActivityContentCaptureEnabled(ComponentName, boolean)}.
+ *
+ * @throws UnsupportedOperationException if not called by the UID that owns the
+ * {@link android.service.intelligence.IntelligenceService} associated with the
+ * current user.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public Set<ComponentName> getContentCaptureDisabledActivities() {
+ //TODO(b/111276913): implement
+ return null;
+ }
+
+ /**
+ * Gets the apps where content capture was disabled by
+ * {@link #setPackageContentCaptureEnabled(String, boolean)}.
+ *
+ * @throws UnsupportedOperationException if not called by the UID that owns the
+ * {@link android.service.intelligence.IntelligenceService} associated with the
+ * current user.
+ *
+ * @hide
+ */
+ @SystemApi
+ @NonNull
+ public Set<String> getContentCaptureDisabledPackages() {
+ //TODO(b/111276913): implement
+ return null;
+ }
+
+ /** @hide */
+ public void dump(String prefix, PrintWriter pw) {
+ pw.print(prefix); pw.println("IntelligenceManager");
+ final String prefix2 = prefix + " ";
+ synchronized (mLock) {
+ pw.print(prefix2); pw.print("mContext: "); pw.println(mContext);
+ pw.print(prefix2); pw.print("mService: "); pw.println(mService);
+ pw.print(prefix2); pw.print("user: "); pw.println(mContext.getUserId());
+ pw.print(prefix2); pw.print("enabled: "); pw.println(isContentCaptureEnabled());
+ pw.print(prefix2); pw.print("id: "); pw.println(mId);
+ pw.print(prefix2); pw.print("state: "); pw.print(mState); pw.print(" (");
+ pw.print(getStateAsStringLocked()); pw.println(")");
+ pw.print(prefix2); pw.print("appToken: "); pw.println(mApplicationToken);
+ pw.print(prefix2); pw.print("componentName: "); pw.println(mComponentName);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private String getStateAsStringLocked() {
+ return getStateAsString(mState);
+ }
+
+ @NonNull
+ private static String getStateAsString(int state) {
+ switch (state) {
+ case STATE_UNKNOWN:
+ return "UNKNOWN";
+ case STATE_WAITING_FOR_SERVER:
+ return "WAITING_FOR_SERVER";
+ case STATE_ACTIVE:
+ return "ACTIVE";
+ default:
+ return "INVALID:" + state;
+ }
+ }
+}
diff --git a/core/java/android/view/intelligence/ViewNode.java b/core/java/android/view/intelligence/ViewNode.java
new file mode 100644
index 000000000000..357ecf599f7a
--- /dev/null
+++ b/core/java/android/view/intelligence/ViewNode.java
@@ -0,0 +1,44 @@
+/*
+ * 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.view.intelligence;
+
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.assist.AssistStructure;
+import android.view.autofill.AutofillId;
+
+//TODO(b/111276913): add javadocs / implement Parcelable / implement
+//TODO(b/111276913): for now it's extending ViewNode directly as it needs most of its properties,
+// but it might be better to create a common, abstract android.view.ViewNode class that both extend
+// instead
+/** @hide */
+@SystemApi
+public final class ViewNode extends AssistStructure.ViewNode {
+
+ /** @hide */
+ public ViewNode() {
+ }
+
+ /**
+ * Returns the {@link AutofillId} of this view's parent, if the parent is also part of the
+ * screen observation tree.
+ */
+ @Nullable
+ public AutofillId getParentAutofillId() {
+ //TODO(b/111276913): implement
+ return null;
+ }
+}
diff --git a/core/java/android/widget/Magnifier.java b/core/java/android/widget/Magnifier.java
index 6a3fc0fad4dd..9da2a4307a93 100644
--- a/core/java/android/widget/Magnifier.java
+++ b/core/java/android/widget/Magnifier.java
@@ -28,6 +28,7 @@ import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
+import android.graphics.Insets;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.PixelFormat;
@@ -568,7 +569,7 @@ public final class Magnifier {
private Point getCurrentClampedWindowCoordinates() {
final Rect windowBounds;
if (mParentSurface.mIsMainWindowSurface) {
- final Rect systemInsets = mView.getRootWindowInsets().getSystemWindowInsets();
+ final Insets systemInsets = mView.getRootWindowInsets().getSystemWindowInsets();
windowBounds = new Rect(systemInsets.left, systemInsets.top,
mParentSurface.mWidth - systemInsets.right,
mParentSurface.mHeight - systemInsets.bottom);
diff --git a/core/java/com/android/internal/app/procstats/ProcessStats.java b/core/java/com/android/internal/app/procstats/ProcessStats.java
index e7ac5664c3ee..19d8a836fc4c 100644
--- a/core/java/com/android/internal/app/procstats/ProcessStats.java
+++ b/core/java/com/android/internal/app/procstats/ProcessStats.java
@@ -1396,6 +1396,11 @@ public final class ProcessStats implements Parcelable {
return as;
}
+ // See b/118826162 -- to avoid logspaming, we rate limit the WTF.
+ private static final long INVERSE_PROC_STATE_WTF_MIN_INTERVAL_MS = 10_000L;
+ private long mNextInverseProcStateWtfUptime;
+ private int mSkippedInverseProcStateWtfCount;
+
public void updateTrackingAssociationsLocked(int curSeq, long now) {
final int NUM = mTrackingAssociations.size();
for (int i = NUM - 1; i >= 0; i--) {
@@ -1417,12 +1422,24 @@ public final class ProcessStats implements Parcelable {
} else {
act.stopActive(now);
if (act.mProcState < procState) {
- Slog.w(TAG, "Tracking association " + act + " whose proc state "
- + act.mProcState + " is better than process " + proc
- + " proc state " + procState);
+ final long nowUptime = SystemClock.uptimeMillis();
+ if (mNextInverseProcStateWtfUptime > nowUptime) {
+ mSkippedInverseProcStateWtfCount++;
+ } else {
+ // TODO We still see it during boot related to GMS-core.
+ // b/118826162
+ Slog.wtf(TAG, "Tracking association " + act + " whose proc state "
+ + act.mProcState + " is better than process " + proc
+ + " proc state " + procState
+ + " (" + mSkippedInverseProcStateWtfCount + " skipped)");
+ mSkippedInverseProcStateWtfCount = 0;
+ mNextInverseProcStateWtfUptime =
+ nowUptime + INVERSE_PROC_STATE_WTF_MIN_INTERVAL_MS;
+ }
}
}
} else {
+ // Don't need rate limiting on it.
Slog.wtf(TAG, "Tracking association without process: " + act
+ " in " + act.getAssociationState());
}
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index aa7bdb62a87c..e2c23de70c00 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1001,7 +1001,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
insets.getSystemWindowInsetRight(), 0);
}
}
- mFrameOffsets.set(insets.getSystemWindowInsets());
+ mFrameOffsets.set(insets.getSystemWindowInsetsAsRect());
insets = updateColorViews(insets, true /* animate */);
insets = updateStatusGuard(insets);
if (getForeground() != null) {
diff --git a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
index 4a1c95532ba0..ba0ff01b68de 100644
--- a/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
+++ b/core/java/com/android/internal/widget/ActionBarOverlayLayout.java
@@ -313,8 +313,7 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
pullChildren();
final int vis = getWindowSystemUiVisibility();
- final boolean stable = (vis & SYSTEM_UI_FLAG_LAYOUT_STABLE) != 0;
- final Rect systemInsets = insets.getSystemWindowInsets();
+ final Rect systemInsets = insets.getSystemWindowInsetsAsRect();
// The top and bottom action bars are always within the content area.
boolean changed = applyInsets(mActionBarTop, systemInsets, true, true, false, true);
diff --git a/core/java/com/android/internal/widget/LockPatternView.java b/core/java/com/android/internal/widget/LockPatternView.java
index b799728e4a7e..25a5a0734bf5 100644
--- a/core/java/com/android/internal/widget/LockPatternView.java
+++ b/core/java/com/android/internal/widget/LockPatternView.java
@@ -69,7 +69,7 @@ public class LockPatternView extends View {
private static final int ASPECT_LOCK_HEIGHT = 2; // Fixed height; width will be minimum of (w,h)
private static final boolean PROFILE_DRAWING = false;
- private static final float LINE_FADE_ALPHA_MULTIPLIER = 3.5f;
+ private static final float LINE_FADE_ALPHA_MULTIPLIER = 1.5f;
private final CellState[][] mCellStates;
private final int mDotSize;
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index e07a20880b94..2e7501f0e0be 100644
--- a/core/jni/android/graphics/FontFamily.cpp
+++ b/core/jni/android/graphics/FontFamily.cpp
@@ -83,7 +83,8 @@ static jlong FontFamily_create(jlong builderPtr) {
return 0;
}
std::shared_ptr<minikin::FontFamily> family = std::make_shared<minikin::FontFamily>(
- builder->langId, builder->variant, std::move(builder->fonts));
+ builder->langId, builder->variant, std::move(builder->fonts),
+ true /* isCustomFallback */);
if (family->getCoverage().length() == 0) {
return 0;
}
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index d391de75aa9a..a8b0640c3a73 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -28,6 +28,7 @@
#include "SkBlurDrawLooper.h"
#include "SkColorFilter.h"
+#include "SkFontTypes.h"
#include "SkMaskFilter.h"
#include "SkPath.h"
#include "SkPathEffect.h"
@@ -684,13 +685,13 @@ namespace PaintGlue {
}
static jint getHinting(jlong paintHandle) {
- return reinterpret_cast<Paint*>(paintHandle)->getHinting()
- == Paint::kNo_Hinting ? 0 : 1;
+ return (SkFontHinting)reinterpret_cast<Paint*>(paintHandle)->getHinting()
+ == kNo_SkFontHinting ? 0 : 1;
}
static void setHinting(jlong paintHandle, jint mode) {
reinterpret_cast<Paint*>(paintHandle)->setHinting(
- mode == 0 ? Paint::kNo_Hinting : Paint::kNormal_Hinting);
+ mode == 0 ? kNo_SkFontHinting : kNormal_SkFontHinting);
}
static void setAntiAlias(jlong paintHandle, jboolean aa) {
diff --git a/core/jni/android/graphics/fonts/FontFamily.cpp b/core/jni/android/graphics/fonts/FontFamily.cpp
index 767e068381d9..249e4f3e9212 100644
--- a/core/jni/android/graphics/fonts/FontFamily.cpp
+++ b/core/jni/android/graphics/fonts/FontFamily.cpp
@@ -57,7 +57,7 @@ static void FontFamily_Builder_addFont(jlong builderPtr, jlong fontPtr) {
// Regular JNI
static jlong FontFamily_Builder_build(JNIEnv* env, jobject clazz, jlong builderPtr,
- jstring langTags, jint variant) {
+ jstring langTags, jint variant, jboolean isCustomFallback) {
std::unique_ptr<NativeFamilyBuilder> builder(toBuilder(builderPtr));
uint32_t localeId;
if (langTags == nullptr) {
@@ -67,7 +67,8 @@ static jlong FontFamily_Builder_build(JNIEnv* env, jobject clazz, jlong builderP
localeId = minikin::registerLocaleList(str.c_str());
}
std::shared_ptr<minikin::FontFamily> family = std::make_shared<minikin::FontFamily>(
- localeId, static_cast<minikin::FamilyVariant>(variant), std::move(builder->fonts));
+ localeId, static_cast<minikin::FamilyVariant>(variant), std::move(builder->fonts),
+ isCustomFallback);
if (family->getCoverage().length() == 0) {
// No coverage means minikin rejected given font for some reasons.
jniThrowException(env, "java/lang/IllegalArgumentException",
@@ -87,7 +88,7 @@ static jlong FontFamily_Builder_GetReleaseFunc() {
static const JNINativeMethod gFontFamilyBuilderMethods[] = {
{ "nInitBuilder", "()J", (void*) FontFamily_Builder_initBuilder },
{ "nAddFont", "(JJ)V", (void*) FontFamily_Builder_addFont },
- { "nBuild", "(JLjava/lang/String;I)J", (void*) FontFamily_Builder_build },
+ { "nBuild", "(JLjava/lang/String;IZ)J", (void*) FontFamily_Builder_build },
{ "nGetReleaseNativeFamily", "()J", (void*) FontFamily_Builder_GetReleaseFunc },
};
diff --git a/core/jni/android_media_AudioFormat.h b/core/jni/android_media_AudioFormat.h
index f7f13a5f0431..99b5f8592e5d 100644
--- a/core/jni/android_media_AudioFormat.h
+++ b/core/jni/android_media_AudioFormat.h
@@ -37,6 +37,7 @@
#define ENCODING_AAC_XHE 16
#define ENCODING_AC4 17
#define ENCODING_E_AC3_JOC 18
+#define ENCODING_DOLBY_MAT 19
#define ENCODING_INVALID 0
#define ENCODING_DEFAULT 1
@@ -85,6 +86,8 @@ static inline audio_format_t audioFormatToNative(int audioFormat)
return AUDIO_FORMAT_E_AC3_JOC;
case ENCODING_DEFAULT:
return AUDIO_FORMAT_DEFAULT;
+ case ENCODING_DOLBY_MAT:
+ return AUDIO_FORMAT_MAT;
default:
return AUDIO_FORMAT_INVALID;
}
@@ -134,6 +137,11 @@ static inline int audioFormatFromNative(audio_format_t nativeFormat)
return ENCODING_AC4;
case AUDIO_FORMAT_E_AC3_JOC:
return ENCODING_E_AC3_JOC;
+ case AUDIO_FORMAT_MAT:
+ case AUDIO_FORMAT_MAT_1_0:
+ case AUDIO_FORMAT_MAT_2_0:
+ case AUDIO_FORMAT_MAT_2_1:
+ return ENCODING_DOLBY_MAT;
case AUDIO_FORMAT_DEFAULT:
return ENCODING_DEFAULT;
default:
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 830ca832fb95..b2d44e73d861 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1208,13 +1208,23 @@ static void NativeThemeApplyStyle(JNIEnv* env, jclass /*clazz*/, jlong ptr, jlon
// jniThrowException(env, "java/lang/IllegalArgumentException", error_msg.c_str());
}
-static void NativeThemeCopy(JNIEnv* env, jclass /*clazz*/, jlong dst_theme_ptr,
- jlong src_theme_ptr) {
+static void NativeThemeCopy(JNIEnv* env, jclass /*clazz*/, jlong dst_asset_manager_ptr,
+ jlong dst_theme_ptr, jlong src_asset_manager_ptr, jlong src_theme_ptr) {
Theme* dst_theme = reinterpret_cast<Theme*>(dst_theme_ptr);
Theme* src_theme = reinterpret_cast<Theme*>(src_theme_ptr);
- if (!dst_theme->SetTo(*src_theme)) {
- jniThrowException(env, "java/lang/IllegalArgumentException",
- "Themes are from different AssetManagers");
+
+ if (dst_asset_manager_ptr != src_asset_manager_ptr) {
+ ScopedLock<AssetManager2> dst_assetmanager(AssetManagerFromLong(dst_asset_manager_ptr));
+ CHECK(dst_theme->GetAssetManager() == &(*dst_assetmanager));
+ (void) dst_assetmanager;
+
+ ScopedLock <AssetManager2> src_assetmanager(AssetManagerFromLong(src_asset_manager_ptr));
+ CHECK(src_theme->GetAssetManager() == &(*src_assetmanager));
+ (void) src_assetmanager;
+
+ dst_theme->SetTo(*src_theme);
+ } else {
+ dst_theme->SetTo(*src_theme);
}
}
@@ -1255,10 +1265,11 @@ static void NativeThemeDump(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr, jlong
Theme* theme = reinterpret_cast<Theme*>(theme_ptr);
CHECK(theme->GetAssetManager() == &(*assetmanager));
(void) assetmanager;
- (void) theme;
(void) priority;
(void) tag;
(void) prefix;
+
+ theme->Dump();
}
static jint NativeThemeGetChangingConfigurations(JNIEnv* /*env*/, jclass /*clazz*/,
@@ -1377,7 +1388,7 @@ static const JNINativeMethod gAssetManagerMethods[] = {
{"nativeThemeCreate", "(J)J", (void*)NativeThemeCreate},
{"nativeThemeDestroy", "(J)V", (void*)NativeThemeDestroy},
{"nativeThemeApplyStyle", "(JJIZ)V", (void*)NativeThemeApplyStyle},
- {"nativeThemeCopy", "(JJ)V", (void*)NativeThemeCopy},
+ {"nativeThemeCopy", "(JJJJ)V", (void*)NativeThemeCopy},
{"nativeThemeClear", "(J)V", (void*)NativeThemeClear},
{"nativeThemeGetAttributeValue", "(JJILandroid/util/TypedValue;Z)I",
(void*)NativeThemeGetAttributeValue},
diff --git a/core/jni/android_view_RenderNode.cpp b/core/jni/android_view_RenderNode.cpp
index bb71a5d4accf..e89b5933fdc8 100644
--- a/core/jni/android_view_RenderNode.cpp
+++ b/core/jni/android_view_RenderNode.cpp
@@ -295,6 +295,22 @@ static jboolean android_view_RenderNode_setBottom(jlong renderNodePtr, int botto
return SET_AND_DIRTY(setBottom, bottom, RenderNode::Y);
}
+static jint android_view_RenderNode_getLeft(jlong renderNodePtr) {
+ return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getLeft();
+}
+
+static jint android_view_RenderNode_getTop(jlong renderNodePtr) {
+ return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getTop();
+}
+
+static jint android_view_RenderNode_getRight(jlong renderNodePtr) {
+ return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getRight();
+}
+
+static jint android_view_RenderNode_getBottom(jlong renderNodePtr) {
+ return reinterpret_cast<RenderNode*>(renderNodePtr)->stagingProperties().getBottom();
+}
+
static jboolean android_view_RenderNode_setLeftTopRightBottom(jlong renderNodePtr,
int left, int top, int right, int bottom) {
RenderNode* renderNode = reinterpret_cast<RenderNode*>(renderNodePtr);
@@ -645,6 +661,10 @@ static const JNINativeMethod gMethods[] = {
{ "nSetTop", "(JI)Z", (void*) android_view_RenderNode_setTop },
{ "nSetRight", "(JI)Z", (void*) android_view_RenderNode_setRight },
{ "nSetBottom", "(JI)Z", (void*) android_view_RenderNode_setBottom },
+ { "nGetLeft", "(J)I", (void*) android_view_RenderNode_getLeft },
+ { "nGetTop", "(J)I", (void*) android_view_RenderNode_getTop },
+ { "nGetRight", "(J)I", (void*) android_view_RenderNode_getRight },
+ { "nGetBottom", "(J)I", (void*) android_view_RenderNode_getBottom },
{ "nSetLeftTopRightBottom","(JIIII)Z", (void*) android_view_RenderNode_setLeftTopRightBottom },
{ "nOffsetLeftAndRight", "(JI)Z", (void*) android_view_RenderNode_offsetLeftAndRight },
{ "nOffsetTopAndBottom", "(JI)Z", (void*) android_view_RenderNode_offsetTopAndBottom },
diff --git a/core/proto/android/os/incident.proto b/core/proto/android/os/incident.proto
index 8f289700aede..0b9e347ce5d1 100644
--- a/core/proto/android/os/incident.proto
+++ b/core/proto/android/os/incident.proto
@@ -26,6 +26,7 @@ import "frameworks/base/core/proto/android/os/kernelwake.proto";
import "frameworks/base/core/proto/android/os/pagetypeinfo.proto";
import "frameworks/base/core/proto/android/os/procrank.proto";
import "frameworks/base/core/proto/android/os/ps.proto";
+import "frameworks/base/core/proto/android/os/statsdata.proto";
import "frameworks/base/core/proto/android/os/system_properties.proto";
import "frameworks/base/core/proto/android/providers/settings.proto";
import "frameworks/base/core/proto/android/server/activitymanagerservice.proto";
@@ -301,6 +302,12 @@ message IncidentProto {
(section).userdebug_and_eng_only = true
];
+ optional android.os.StatsDataDumpProto stats_data = 3023 [
+ (section).type = SECTION_DUMPSYS,
+ (section).args = "stats --proto",
+ (section).userdebug_and_eng_only = true
+ ];
+
// Reserved for OEMs.
extensions 50000 to 100000;
}
diff --git a/core/proto/android/os/statsdata.proto b/core/proto/android/os/statsdata.proto
new file mode 100644
index 000000000000..25d76b869259
--- /dev/null
+++ b/core/proto/android/os/statsdata.proto
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+syntax = "proto2";
+option java_multiple_files = true;
+
+package android.os;
+
+import "frameworks/base/libs/incident/proto/android/privacy.proto";
+
+// Dump of statsd report data (dumpsys stats --proto).
+message StatsDataDumpProto {
+ option (android.msg_privacy).dest = DEST_AUTOMATIC;
+
+ // The following is an android.os.statsd.ConfigMetricsReportList, which is defined
+ // in frameworks/base/cmds/statsd/src/stats_log.proto. It should not be imported (even weakly)
+ // in AOSP because it would drag with it atoms.proto, which is enormous and awkward.
+ repeated bytes config_metrics_report_list = 1;
+
+} \ No newline at end of file
diff --git a/core/proto/android/providers/settings/global.proto b/core/proto/android/providers/settings/global.proto
index 307297781a60..69ebb59ffda4 100644
--- a/core/proto/android/providers/settings/global.proto
+++ b/core/proto/android/providers/settings/global.proto
@@ -725,8 +725,10 @@ message GlobalSettingsProto {
optional SettingProto set_install_location = 103 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto shortcut_manager_constants = 104;
optional SettingProto show_first_crash_dialog = 105 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_hidden_launcher_icon_apps_enabled = 141 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto show_restart_in_crash_dialog = 106 [ (android.privacy).dest = DEST_AUTOMATIC ];
optional SettingProto show_mute_in_crash_dialog = 107 [ (android.privacy).dest = DEST_AUTOMATIC ];
+ optional SettingProto show_new_app_installed_notification_enabled = 142 [ (android.privacy).dest = DEST_AUTOMATIC ];
message SmartSelection {
option (android.msg_privacy).dest = DEST_EXPLICIT;
@@ -966,5 +968,5 @@ message GlobalSettingsProto {
// Please insert fields in alphabetical order and group them into messages
// if possible (to avoid reaching the method limit).
- // Next tag = 141;
+ // Next tag = 143;
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 48d1dff02971..093a86089aab 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -401,6 +401,7 @@
<protected-broadcast android:name="android.telecom.action.DEFAULT_DIALER_CHANGED" />
<protected-broadcast android:name="android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED" />
<protected-broadcast android:name="android.provider.action.SMS_MMS_DB_CREATED" />
+ <protected-broadcast android:name="android.provider.action.SMS_MMS_DB_LOST" />
<protected-broadcast android:name="android.intent.action.CONTENT_CHANGED" />
<protected-broadcast android:name="android.provider.Telephony.MMS_DOWNLOADED" />
@@ -3018,6 +3019,14 @@
<permission android:name="android.permission.BIND_TEXTCLASSIFIER_SERVICE"
android:protectionLevel="signature" />
+ <!-- Must be required by a android.service.intelligence.IntelligenceService,
+ 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_INTELLIGENCE_SERVICE"
+ android:protectionLevel="signature" />
+
<!-- Must be required by hotword enrollment application,
to ensure that only the system can interact with it.
@hide <p>Not for use by third-party applications.</p> -->
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9ea82a9b9c2e..8b7cafbbc4d3 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1130,14 +1130,13 @@
<string name="permdesc_accessFineLocation">This app can get your exact location only when it is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them. This may increase battery consumption.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_accessCoarseLocation">access approximate location
- (network-based)</string>
+ <string name="permlab_accessCoarseLocation">access approximate location (network-based) only in the foreground</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessCoarseLocation" product="tablet">This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your tablet for the app to be able to use them.</string>
+ <string name="permdesc_accessCoarseLocation" product="tablet">This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when when the app is in the foreground. These location services must be turned on and available on your tablet for the app to be able to use them.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessCoarseLocation" product="tv">This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your TV for the app to be able to use them.</string>
+ <string name="permdesc_accessCoarseLocation" product="tv">This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when when the app is in the foreground. These location services must be turned on and available on your TV for the app to be able to use them.</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_accessCoarseLocation" product="default">This app can get your location based on network sources such as cell towers and Wi-Fi networks. These location services must be turned on and available on your phone for the app to be able to use them.</string>
+ <string name="permdesc_accessCoarseLocation" product="default">This app can get your location based on network sources such as cell towers and Wi-Fi networks, but only when the app is in the foreground. These location services must be turned on and available on your phone for the app to be able to use them.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_accessBackgroundLocation">access location in the background</string>
diff --git a/core/res/res/xml/sms_short_codes.xml b/core/res/res/xml/sms_short_codes.xml
index 7b3d940b91f3..716376997f81 100644
--- a/core/res/res/xml/sms_short_codes.xml
+++ b/core/res/res/xml/sms_short_codes.xml
@@ -187,7 +187,7 @@
<shortcode country="my" pattern="\\d{5}" premium="32298|33776" free="22099|28288" />
<!-- The Netherlands, 4 digits, known premium codes listed, plus EU -->
- <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223" />
+ <shortcode country="nl" pattern="\\d{4}" premium="4466|5040" free="116\\d{3}|2223|6225|2223|1662" />
<!-- Nigeria -->
<shortcode country="ng" pattern="\\d{1,5}" free="2441" />
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index c298770502b6..d5dc9034ef85 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -370,6 +370,7 @@ public class SettingsBackupTest {
Settings.Global.PRIVATE_DNS_DEFAULT_MODE,
Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED,
Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED,
+ Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED,
Settings.Global.PROVISIONING_APN_ALARM_DELAY_IN_MS,
Settings.Global.RADIO_BLUETOOTH,
Settings.Global.RADIO_CELL,
@@ -393,7 +394,9 @@ public class SettingsBackupTest {
Settings.Global.SETTINGS_USE_PSD_API,
Settings.Global.SHORTCUT_MANAGER_CONSTANTS,
Settings.Global.SHOW_FIRST_CRASH_DIALOG,
+ Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED,
Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG,
+ Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED,
Settings.Global.SHOW_NOTIFICATION_CHANNEL_WARNINGS,
Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG,
Settings.Global.SHOW_TEMPERATURE_WARNING,
@@ -486,6 +489,7 @@ public class SettingsBackupTest {
Settings.Global.WIFI_IDLE_MS,
Settings.Global.WIFI_IS_UNUSABLE_EVENT_METRICS_ENABLED,
Settings.Global.WIFI_LINK_SPEED_METRICS_ENABLED,
+ Settings.Global.WIFI_PNO_FREQUENCY_CULLING_ENABLED,
Settings.Global.WIFI_MAX_DHCP_RETRY_COUNT,
Settings.Global.WIFI_MOBILE_DATA_TRANSITION_WAKELOCK_TIMEOUT_MS,
Settings.Global.WIFI_NETWORK_SHOW_RSSI,
diff --git a/core/tests/coretests/src/android/view/ViewRootImplTest.java b/core/tests/coretests/src/android/view/ViewRootImplTest.java
index c8e46fcdf3fd..ca6d6cfedb76 100644
--- a/core/tests/coretests/src/android/view/ViewRootImplTest.java
+++ b/core/tests/coretests/src/android/view/ViewRootImplTest.java
@@ -20,6 +20,7 @@ import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import android.content.Context;
+import android.graphics.Insets;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.support.test.InstrumentationRegistry;
@@ -57,9 +58,8 @@ public class ViewRootImplTest {
mViewRootImpl.getAttachInfo().getStableInsets().set(-10, -20, -30 , -40);
final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
- assertThat(insets.getSystemWindowInsets(), equalTo(new Rect()));
- assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
- insets.getStableInsetRight(), insets.getStableInsetBottom()), equalTo(new Rect()));
+ assertThat(insets.getSystemWindowInsets(), equalTo(Insets.NONE));
+ assertThat(insets.getStableInsets(), equalTo(Insets.NONE));
}
@Test
@@ -68,10 +68,8 @@ public class ViewRootImplTest {
mViewRootImpl.getAttachInfo().getStableInsets().set(10, -20, 30 , -40);
final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
- assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(0, 20, 0, 40)));
- assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
- insets.getStableInsetRight(), insets.getStableInsetBottom()),
- equalTo(new Rect(10, 0, 30, 0)));
+ assertThat(insets.getSystemWindowInsets(), equalTo(Insets.of(0, 20, 0, 40)));
+ assertThat(insets.getStableInsets(), equalTo(Insets.of(10, 0, 30, 0)));
}
@Test
@@ -80,10 +78,8 @@ public class ViewRootImplTest {
mViewRootImpl.getAttachInfo().getStableInsets().set(10, 20, 30 , 40);
final WindowInsets insets = mViewRootImpl.getWindowInsets(true /* forceConstruct */);
- assertThat(insets.getSystemWindowInsets(), equalTo(new Rect(10, 20, 30, 40)));
- assertThat(new Rect(insets.getStableInsetLeft(), insets.getStableInsetTop(),
- insets.getStableInsetRight(), insets.getStableInsetBottom()),
- equalTo(new Rect(10, 20, 30, 40)));
+ assertThat(insets.getSystemWindowInsets(), equalTo(Insets.of(10, 20, 30, 40)));
+ assertThat(insets.getStableInsets(), equalTo(Insets.of(10, 20, 30, 40)));
}
private static class ViewRootImplAccessor {
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index e35a3be6dbbf..3b0dc9d9f125 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -205,11 +205,70 @@ public class Canvas extends BaseCanvas {
mBitmap = bitmap;
}
- /** @hide */
- public void insertReorderBarrier() {}
+ /**
+ * @deprecated use {@link #enableZ()} instead
+ * @hide */
+ @Deprecated
+ public void insertReorderBarrier() {
+ enableZ();
+ }
- /** @hide */
- public void insertInorderBarrier() {}
+ /**
+ * @deprecated use {@link #disableZ()} instead
+ * @hide */
+ @Deprecated
+ public void insertInorderBarrier() {
+ disableZ();
+ }
+
+ /**
+ * <p>Enables Z support which defaults to disabled. This allows for RenderNodes drawn with
+ * {@link #drawRenderNode(RenderNode)} to be re-arranged based off of their
+ * {@link RenderNode#getElevation()} and {@link RenderNode#getTranslationZ()}
+ * values. It also enables rendering of shadows for RenderNodes with an elevation or
+ * translationZ.</p>
+ *
+ * <p>Any draw reordering will not be moved before this call. A typical usage of this might
+ * look something like:
+ *
+ * <pre class="prettyprint">
+ * void draw(Canvas canvas) {
+ * // Draw any background content
+ * canvas.drawColor(backgroundColor);
+ *
+ * // Begin drawing that may be reordered based off of Z
+ * canvas.enableZ();
+ * for (RenderNode child : children) {
+ * canvas.drawRenderNode(child);
+ * }
+ * // End drawing that may be reordered based off of Z
+ * canvas.disableZ();
+ *
+ * // Draw any overlays
+ * canvas.drawText("I'm on top of everything!", 0, 0, paint);
+ * }
+ * </pre>
+ * </p>
+ *
+ * Note: This is not impacted by any {@link #save()} or {@link #restore()} calls as it is not
+ * considered to be part of the current matrix or clip.
+ *
+ * See {@link #disableZ()}
+ */
+ public void enableZ() {
+ }
+
+ /**
+ * Disables Z support, preventing any RenderNodes drawn after this point from being
+ * visually reordered or having shadows rendered.
+ *
+ * Note: This is not impacted by any {@link #save()} or {@link #restore()} calls as it is not
+ * considered to be part of the current matrix or clip.
+ *
+ * See {@link #enableZ()}
+ */
+ public void disableZ() {
+ }
/**
* Return true if the device that the current layer draws into is opaque
@@ -2110,4 +2169,17 @@ public class Canvas extends BaseCanvas {
super.drawVertices(mode, vertexCount, verts, vertOffset, texs, texOffset,
colors, colorOffset, indices, indexOffset, indexCount, paint);
}
+
+ /**
+ * Draws the given RenderNode. This is only supported in hardware rendering, which can be
+ * verified by asserting that {@link #isHardwareAccelerated()} is true. If
+ * {@link #isHardwareAccelerated()} is false then this throws an exception.
+ *
+ * See {@link RenderNode} for more information on what a RenderNode is and how to use it.
+ *
+ * @param renderNode The RenderNode to draw, must be non-null.
+ */
+ public void drawRenderNode(@NonNull RenderNode renderNode) {
+ throw new IllegalArgumentException("Software rendering doesn't support drawRenderNode");
+ }
}
diff --git a/graphics/java/android/graphics/ImageFormat.java b/graphics/java/android/graphics/ImageFormat.java
index 9546a4aec330..c580c46cc888 100644
--- a/graphics/java/android/graphics/ImageFormat.java
+++ b/graphics/java/android/graphics/ImageFormat.java
@@ -16,8 +16,6 @@
package android.graphics;
-import android.annotation.UnsupportedAppUsage;
-
public class ImageFormat {
/*
* these constants are chosen to be binary compatible with their previous
@@ -92,20 +90,21 @@ public class ImageFormat {
* </ul>
* </p>
*
- * <pre> y_size = stride * height </pre>
+ * <pre> size = stride * height </pre>
*
* <p>For example, the {@link android.media.Image} object can provide data
- * in this format from a {@link android.hardware.camera2.CameraDevice}
- * through a {@link android.media.ImageReader} object if this format is
- * supported by {@link android.hardware.camera2.CameraDevice}.</p>
+ * in this format from a {@link android.hardware.camera2.CameraDevice} (if
+ * supported) through a {@link android.media.ImageReader} object. The
+ * {@link android.media.Image#getPlanes() Image#getPlanes()} will return a
+ * single plane containing the pixel data. The pixel stride is always 1 in
+ * {@link android.media.Image.Plane#getPixelStride()}, and the
+ * {@link android.media.Image.Plane#getRowStride()} describes the vertical
+ * neighboring pixel distance (in bytes) between adjacent rows.</p>
*
* @see android.media.Image
* @see android.media.ImageReader
* @see android.hardware.camera2.CameraDevice
- *
- * @hide
*/
- @UnsupportedAppUsage
public static final int Y8 = 0x20203859;
/**
@@ -787,6 +786,7 @@ public class ImageFormat {
case DEPTH_POINT_CLOUD:
case PRIVATE:
case RAW_DEPTH:
+ case Y8:
return true;
}
diff --git a/graphics/java/android/graphics/RecordingCanvas.java b/graphics/java/android/graphics/RecordingCanvas.java
index 7af006b4bdf0..fd5d62406da7 100644
--- a/graphics/java/android/graphics/RecordingCanvas.java
+++ b/graphics/java/android/graphics/RecordingCanvas.java
@@ -18,7 +18,6 @@ package android.graphics;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
import android.util.Pools.SynchronizedPool;
import android.view.TextureLayer;
@@ -27,17 +26,20 @@ import dalvik.annotation.optimization.FastNative;
/**
* A Canvas implementation that records view system drawing operations for deferred rendering.
- * This is intended for use with RenderNode. This class keeps a list of all the Paint and
- * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being freed while
+ * This is used in combination with RenderNode. This class keeps a list of all the Paint and
+ * Bitmap objects that it draws, preventing the backing memory of Bitmaps from being released while
* the RecordingCanvas is still holding a native reference to the memory.
*
- * @hide
+ * This is obtained by calling {@link RenderNode#startRecording()} and is valid until the matching
+ * {@link RenderNode#endRecording()} is called. It must not be retained beyond that as it is
+ * internally reused.
*/
public final class RecordingCanvas extends BaseRecordingCanvas {
// The recording canvas pool should be large enough to handle a deeply nested
// view hierarchy because display lists are generated recursively.
private static final int POOL_LIMIT = 25;
+ /** @hide */
public static final int MAX_BITMAP_SIZE = 100 * 1024 * 1024; // 100 MB
private static final SynchronizedPool<RecordingCanvas> sPool =
@@ -50,6 +52,7 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
private int mWidth;
private int mHeight;
+ /** @hide */
static RecordingCanvas obtain(@NonNull RenderNode node, int width, int height) {
if (node == null) throw new IllegalArgumentException("node cannot be null");
RecordingCanvas canvas = sPool.acquire();
@@ -65,15 +68,18 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
return canvas;
}
+ /** @hide */
void recycle() {
mNode = null;
sPool.release(this);
}
+ /** @hide */
long finishRecording() {
return nFinishRecording(mNativeCanvasWrapper);
}
+ /** @hide */
@Override
public boolean isRecordingFor(Object o) {
return o == mNode;
@@ -138,12 +144,12 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
///////////////////////////////////////////////////////////////////////////
@Override
- public void insertReorderBarrier() {
+ public void enableZ() {
nInsertReorderBarrier(mNativeCanvasWrapper, true);
}
@Override
- public void insertInorderBarrier() {
+ public void disableZ() {
nInsertReorderBarrier(mNativeCanvasWrapper, false);
}
@@ -159,7 +165,6 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
*
* @hide
*/
- @UnsupportedAppUsage
public void callDrawGLFunction2(long drawGLFunction) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunction, null);
}
@@ -178,7 +183,6 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
*
* @hide
*/
- @UnsupportedAppUsage
public void drawGLFunctor2(long drawGLFunctor, @Nullable Runnable releasedCallback) {
nCallDrawGLFunction(mNativeCanvasWrapper, drawGLFunctor, releasedCallback);
}
@@ -192,8 +196,8 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
*
* @param renderNode The RenderNode to draw.
*/
- @UnsupportedAppUsage
- public void drawRenderNode(RenderNode renderNode) {
+ @Override
+ public void drawRenderNode(@NonNull RenderNode renderNode) {
nDrawRenderNode(mNativeCanvasWrapper, renderNode.mNativeRenderNode);
}
@@ -225,7 +229,6 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
*
* @hide
*/
- @UnsupportedAppUsage
public void drawCircle(CanvasProperty<Float> cx, CanvasProperty<Float> cy,
CanvasProperty<Float> radius, CanvasProperty<Paint> paint) {
nDrawCircle(mNativeCanvasWrapper, cx.getNativeContainer(), cy.getNativeContainer(),
@@ -254,6 +257,7 @@ public final class RecordingCanvas extends BaseRecordingCanvas {
paint.getNativeContainer());
}
+ /** @hide */
@Override
protected void throwIfCannotDraw(Bitmap bitmap) {
super.throwIfCannotDraw(bitmap);
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index 320fb20e5b98..12128b3384bf 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.view.NativeVectorDrawableAnimator;
import android.view.RenderNodeAnimator;
+import android.view.Surface;
import android.view.View;
import dalvik.annotation.optimization.CriticalNative;
@@ -137,7 +138,28 @@ import java.lang.annotation.RetentionPolicy;
* that the RenderNode is only used on the same thread it is drawn with. For example when using
* RenderNode with a custom View, then that RenderNode must only be used from the UI thread.</p>
*
- * @hide
+ * <h3>When to re-render</h3>
+ * <p>Many of the RenderNode mutation methods, such as {@link #setTranslationX(float)}, return
+ * a boolean indicating if the value actually changed or not. This is useful in detecting
+ * if a new frame should be rendered or not. A typical usage would look like:
+ * <pre class="prettyprint">
+ * public void translateTo(int x, int y) {
+ * boolean needsUpdate = myRenderNode.setTranslationX(x);
+ * needsUpdate |= myRenderNode.setTranslationY(y);
+ * if (needsUpdate) {
+ * myOwningView.invalidate();
+ * }
+ * }
+ * </pre>
+ * This is marginally faster than doing a more explicit up-front check if the value changed by
+ * comparing the desired value against {@link #getTranslationX()} as it minimizes JNI transitions.
+ * The actual mechanism of requesting a new frame to be rendered will depend on how this
+ * RenderNode is being drawn. If it's drawn to a containing View, as in the above snippet,
+ * then simply invalidating that View works. If instead the RenderNode is being drawn to a Canvas
+ * directly such as with {@link Surface#lockHardwareCanvas()} then a new frame needs to be drawn
+ * by calling {@link Surface#lockHardwareCanvas()}, re-drawing the root RenderNode or whatever
+ * top-level content is desired, and finally calling {@link Surface#unlockCanvasAndPost(Canvas)}.
+ * </p>
*/
public class RenderNode {
@@ -147,7 +169,9 @@ public class RenderNode {
RenderNode.class.getClassLoader(), nGetNativeFinalizer(), 1024);
}
- /** Not for general use; use only if you are ThreadedRenderer or RecordingCanvas.
+ /**
+ * Not for general use; use only if you are ThreadedRenderer or RecordingCanvas.
+ *
* @hide
*/
public final long mNativeRenderNode;
@@ -174,9 +198,13 @@ public class RenderNode {
* drawing operations, and store / apply render properties when drawn.
*
* @param name The name of the RenderNode, used for debugging purpose. May be null.
- *
* @return A new RenderNode.
*/
+ public static @NonNull RenderNode create(@Nullable String name) {
+ return new RenderNode(name, null);
+ }
+
+ /** @hide */
public static RenderNode create(String name, @Nullable AnimationHost animationHost) {
return new RenderNode(name, animationHost);
}
@@ -186,6 +214,8 @@ public class RenderNode {
*
* Note: This will *NOT* incRef() on the native object, however it will
* decRef() when it is destroyed. The caller should have already incRef'd it
+ *
+ * @hide
*/
public static RenderNode adopt(long nativePtr) {
return new RenderNode(nativePtr);
@@ -220,6 +250,8 @@ public class RenderNode {
/**
* Enable callbacks for position changes.
+ *
+ * @hide
*/
public void requestPositionUpdates(PositionUpdateListener listener) {
nRequestPositionUpdates(mNativeRenderNode, listener);
@@ -234,15 +266,13 @@ public class RenderNode {
* {@link #endRecording()} must be called when the recording is finished in order to apply
* the updated display list.
*
- * @param width The width of the recording viewport. This will not alter the width of the
- * RenderNode itself, that must be set with {@link #setLeft(int)} and
- * {@link #setRight(int)}
+ * @param width The width of the recording viewport. This will not alter the width of the
+ * RenderNode itself, that must be set with {@link #setLeft(int)} and
+ * {@link #setRight(int)}
* @param height The height of the recording viewport. This will not alter the height of the
* RenderNode itself, that must be set with {@link #setTop(int)} and
* {@link #setBottom(int)}.
- *
* @return A canvas to record drawing operations.
- *
* @see #endRecording()
* @see #hasDisplayList()
*/
@@ -261,20 +291,20 @@ public class RenderNode {
* with {@link #setLeftTopRightBottom(int, int, int, int)}.
*/
public RecordingCanvas startRecording() {
- return RecordingCanvas.obtain(this,
- nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
+ return startRecording(nGetWidth(mNativeRenderNode), nGetHeight(mNativeRenderNode));
}
/**
- * @deprecated use {@link #startRecording(int, int)} instead
* @hide
+ * @deprecated use {@link #startRecording(int, int)} instead
*/
@Deprecated
public RecordingCanvas start(int width, int height) {
return startRecording(width, height);
}
- /**`
+ /**
+ * `
* Ends the recording for this display list. Calling this method marks
* the display list valid and {@link #hasDisplayList()} will return true.
*
@@ -294,8 +324,8 @@ public class RenderNode {
}
/**
- * @deprecated use {@link #endRecording()} instead
* @hide
+ * @deprecated use {@link #endRecording()} instead
*/
@Deprecated
public void end(RecordingCanvas canvas) {
@@ -373,21 +403,52 @@ public class RenderNode {
///////////////////////////////////////////////////////////////////////////
/**
- * TODO
+ * @hide
+ * @deprecated use {@link #setUseCompositingLayer(boolean, Paint)} instead
*/
+ @Deprecated
public boolean setLayerType(int layerType) {
return nSetLayerType(mNativeRenderNode, layerType);
}
/**
- * TODO
+ * @hide
+ * @deprecated use {@link #setUseCompositingLayer(boolean, Paint)} instead
*/
+ @Deprecated
public boolean setLayerPaint(@Nullable Paint paint) {
return nSetLayerPaint(mNativeRenderNode, paint != null ? paint.getNativeInstance() : 0);
}
/**
+ * Controls whether or not to force this RenderNode to render to an intermediate buffer.
+ * Internally RenderNode will already promote itself to a composition layer if it's useful
+ * for performance or required for the current combination of {@link #setAlpha(float)} and
+ * {@link #setHasOverlappingRendering(boolean)}.
+ *
+ * The usage of this is instead to allow for either overriding of the internal behavior
+ * if it's measured to be necessary for the particular rendering content in question or, more
+ * usefully, to add a composition effect to the RenderNode via the optional paint parameter.
+ *
+ * Note: When a RenderNode is using a compositing layer it will also result in
+ * clipToBounds=true behavior.
+ *
+ * @param forceToLayer if true this forces the RenderNode to use an intermediate buffer.
+ * Default & generally recommended value is false.
+ * @param paint The blend mode, alpha, and ColorFilter to apply to the compositing layer.
+ * Only applies if forceToLayer is true.
+ * @return true if anything changed, false otherwise
+ */
+ public boolean setUseCompositingLayer(boolean forceToLayer, @Nullable Paint paint) {
+ boolean didChange = nSetLayerType(mNativeRenderNode, forceToLayer ? 2 : 0);
+ didChange |= nSetLayerPaint(mNativeRenderNode,
+ paint != null ? paint.getNativeInstance() : 0);
+ return didChange;
+ }
+
+ /**
* Sets the clip bounds of the RenderNode.
+ *
* @param rect the bounds to clip to. If null, the clip bounds are reset
* @return True if the clip bounds changed, false otherwise
*/
@@ -410,19 +471,19 @@ public class RenderNode {
}
/**
- * Sets whether the display list should be drawn immediately after the
- * closest ancestor display list containing a projection receiver.
+ * Sets whether the RenderNode should be drawn immediately after the
+ * closest ancestor RenderNode containing a projection receiver.
*
* @param shouldProject true if the display list should be projected onto a
- * containing volume.
+ * containing volume.
*/
public boolean setProjectBackwards(boolean shouldProject) {
return nSetProjectBackwards(mNativeRenderNode, shouldProject);
}
/**
- * Sets whether the display list is a projection receiver - that its parent
- * DisplayList should draw any descendent DisplayLists with
+ * Sets whether the RenderNode is a projection receiver - that its parent
+ * RenderNode should draw any descendent RenderNodes with
* ProjectBackwards=true directly on top of it. Default value is false.
*/
public boolean setProjectionReceiver(boolean shouldRecieve) {
@@ -433,14 +494,18 @@ public class RenderNode {
* Sets the outline, defining the shape that casts a shadow, and the path to
* be clipped if setClipToOutline is set.
*
- * Deep copies the data into native to simplify reference ownership.
+ * This will make a copy of the provided {@link Outline}, so any future modifications
+ * to the outline will need to call {@link #setOutline(Outline)} with the modified
+ * outline for those changes to be applied.
+ *
+ * @param outline The outline to use for this RenderNode.
*/
public boolean setOutline(@Nullable Outline outline) {
if (outline == null) {
return nSetOutlineNone(mNativeRenderNode);
}
- switch(outline.mMode) {
+ switch (outline.mMode) {
case Outline.MODE_EMPTY:
return nSetOutlineEmpty(mNativeRenderNode);
case Outline.MODE_ROUND_RECT:
@@ -457,28 +522,63 @@ public class RenderNode {
}
/**
+ * Checks if the RenderNode has a shadow. That is, if the combination of {@link #getElevation()}
+ * and {@link #getTranslationZ()} is greater than zero, there is an {@link Outline} set with
+ * a valid shadow caster path, and the provided outline has a non-zero
+ * {@link Outline#getAlpha()}.
+ *
* @return True if this RenderNode has a shadow, false otherwise
*/
public boolean hasShadow() {
return nHasShadow(mNativeRenderNode);
}
- /** setSpotShadowColor */
+ /**
+ * Sets the color of the spot shadow that is drawn when the RenderNode has a positive Z or
+ * elevation value and is drawn inside of a {@link Canvas#enableZ()} section.
+ * <p>
+ * By default the shadow color is black. Generally, this color will be opaque so the intensity
+ * of the shadow is consistent between different RenderNodes with different colors.
+ * <p>
+ * The opacity of the final spot shadow is a function of the shadow caster height, the
+ * alpha channel of the outlineSpotShadowColor (typically opaque), and the
+ * {@link android.R.attr#spotShadowAlpha} theme attribute
+ *
+ * @param color The color this RenderNode will cast for its elevation spot shadow.
+ */
public boolean setSpotShadowColor(int color) {
return nSetSpotShadowColor(mNativeRenderNode, color);
}
- /** setAmbientShadowColor */
- public boolean setAmbientShadowColor(int color) {
- return nSetAmbientShadowColor(mNativeRenderNode, color);
- }
-
- /** getSpotShadowColor */
+ /**
+ * @return The shadow color set by {@link #setSpotShadowColor(int)}, or black if nothing
+ * was set
+ */
public int getSpotShadowColor() {
return nGetSpotShadowColor(mNativeRenderNode);
}
- /** getAmbientShadowColor */
+ /**
+ * Sets the color of the ambient shadow that is drawn when the RenderNode has a positive Z or
+ * elevation value and is drawn inside of a {@link Canvas#enableZ()} section.
+ * <p>
+ * By default the shadow color is black. Generally, this color will be opaque so the intensity
+ * of the shadow is consistent between different RenderNodes with different colors.
+ * <p>
+ * The opacity of the final ambient shadow is a function of the shadow caster height, the
+ * alpha channel of the outlineAmbientShadowColor (typically opaque), and the
+ * {@link android.R.attr#ambientShadowAlpha} theme attribute.
+ *
+ * @param color The color this RenderNode will cast for its elevation shadow.
+ */
+ public boolean setAmbientShadowColor(int color) {
+ return nSetAmbientShadowColor(mNativeRenderNode, color);
+ }
+
+ /**
+ * @return The shadow color set by {@link #setAmbientShadowColor(int)}, or black if
+ * nothing was set
+ */
public int getAmbientShadowColor() {
return nGetAmbientShadowColor(mNativeRenderNode);
}
@@ -503,6 +603,8 @@ public class RenderNode {
/**
* Controls the RenderNode's circular reveal clip.
+ *
+ * @hide
*/
public boolean setRevealClip(boolean shouldClip,
float x, float y, float radius) {
@@ -514,6 +616,7 @@ public class RenderNode {
* transforms (such as {@link #setScaleX(float)}, {@link #setRotation(float)}, etc.)
*
* @param matrix A transform matrix to apply to this display list
+ * @hide TODO Do we want this?
*/
public boolean setStaticMatrix(Matrix matrix) {
return nSetStaticMatrix(mNativeRenderNode, matrix.native_instance);
@@ -526,6 +629,7 @@ public class RenderNode {
* for the matrix parameter.
*
* @param matrix The matrix, null indicates that the matrix should be cleared.
+ * @hide TODO Do we want this?
*/
public boolean setAnimationMatrix(Matrix matrix) {
return nSetAnimationMatrix(mNativeRenderNode,
@@ -536,7 +640,6 @@ public class RenderNode {
* Sets the translucency level for the display list.
*
* @param alpha The translucency of the display list, must be a value between 0.0f and 1.0f
- *
* @see View#setAlpha(float)
* @see #getAlpha()
*/
@@ -548,7 +651,6 @@ public class RenderNode {
* Returns the translucency level of this display list.
*
* @return A value between 0.0f and 1.0f
- *
* @see #setAlpha(float)
*/
public float getAlpha() {
@@ -562,7 +664,6 @@ public class RenderNode {
*
* @param hasOverlappingRendering False if the content is guaranteed to be non-overlapping,
* true otherwise.
- *
* @see android.view.View#hasOverlappingRendering()
* @see #hasOverlappingRendering()
*/
@@ -573,17 +674,28 @@ public class RenderNode {
/** @hide */
@IntDef({USAGE_BACKGROUND})
@Retention(RetentionPolicy.SOURCE)
- public @interface UsageHint {}
+ public @interface UsageHint {
+ }
- /** The default usage hint */
+ /**
+ * The default usage hint
+ *
+ * @hide
+ */
public static final int USAGE_UNKNOWN = 0;
- /** Usage is background content */
+ /**
+ * Usage is background content
+ *
+ * @hide
+ */
public static final int USAGE_BACKGROUND = 1;
/**
* Provides a hint on what this RenderNode's display list content contains. This hint is used
* for automatic content transforms to improve accessibility or similar.
+ *
+ * @hide
*/
public void setUsageHint(@UsageHint int usageHint) {
nSetUsageHint(mNativeRenderNode, usageHint);
@@ -593,7 +705,6 @@ public class RenderNode {
* Indicates whether the content of this display list overlaps.
*
* @return True if this display list renders content which overlaps, false otherwise.
- *
* @see #setHasOverlappingRendering(boolean)
*/
public boolean hasOverlappingRendering() {
@@ -623,7 +734,6 @@ public class RenderNode {
* Sets the translation value for the display list on the X axis.
*
* @param translationX The X axis translation value of the display list, in pixels
- *
* @see View#setTranslationX(float)
* @see #getTranslationX()
*/
@@ -644,7 +754,6 @@ public class RenderNode {
* Sets the translation value for the display list on the Y axis.
*
* @param translationY The Y axis translation value of the display list, in pixels
- *
* @see View#setTranslationY(float)
* @see #getTranslationY()
*/
@@ -684,7 +793,6 @@ public class RenderNode {
* Sets the rotation value for the display list around the Z axis.
*
* @param rotation The rotation value of the display list, in degrees
- *
* @see View#setRotation(float)
* @see #getRotation()
*/
@@ -705,7 +813,6 @@ public class RenderNode {
* Sets the rotation value for the display list around the X axis.
*
* @param rotationX The rotation value of the display list, in degrees
- *
* @see View#setRotationX(float)
* @see #getRotationX()
*/
@@ -726,7 +833,6 @@ public class RenderNode {
* Sets the rotation value for the display list around the Y axis.
*
* @param rotationY The rotation value of the display list, in degrees
- *
* @see View#setRotationY(float)
* @see #getRotationY()
*/
@@ -747,7 +853,6 @@ public class RenderNode {
* Sets the scale value for the display list on the X axis.
*
* @param scaleX The scale value of the display list
- *
* @see View#setScaleX(float)
* @see #getScaleX()
*/
@@ -768,7 +873,6 @@ public class RenderNode {
* Sets the scale value for the display list on the Y axis.
*
* @param scaleY The scale value of the display list
- *
* @see View#setScaleY(float)
* @see #getScaleY()
*/
@@ -789,7 +893,6 @@ public class RenderNode {
* Sets the pivot value for the display list on the X axis
*
* @param pivotX The pivot value of the display list on the X axis, in pixels
- *
* @see View#setPivotX(float)
* @see #getPivotX()
*/
@@ -810,7 +913,6 @@ public class RenderNode {
* Sets the pivot value for the display list on the Y axis
*
* @param pivotY The pivot value of the display list on the Y axis, in pixels
- *
* @see View#setPivotY(float)
* @see #getPivotY()
*/
@@ -827,135 +929,222 @@ public class RenderNode {
return nGetPivotY(mNativeRenderNode);
}
+ /**
+ * @return Whether or not a pivot was explicitly set with {@link #setPivotX(float)} or
+ * {@link #setPivotY(float)}. If no pivot has been set then the pivot will be the center
+ * of the RenderNode.
+ */
public boolean isPivotExplicitlySet() {
return nIsPivotExplicitlySet(mNativeRenderNode);
}
- /** lint */
+ /**
+ * Clears any pivot previously set by a call to {@link #setPivotX(float)} or
+ * {@link #setPivotY(float)}. After calling this {@link #isPivotExplicitlySet()} will be false
+ * and the pivot used for rotation will return to default of being centered on the view.
+ */
public boolean resetPivot() {
return nResetPivot(mNativeRenderNode);
}
/**
- * Sets the camera distance for the display list. Refer to
- * {@link View#setCameraDistance(float)} for more information on how to
- * use this property.
+ * <p>Sets the distance along the Z axis (orthogonal to the X/Y plane on which
+ * RenderNodes are drawn) from the camera to this RenderNode. The camera's distance
+ * affects 3D transformations, for instance rotations around the X and Y
+ * axis. If the rotationX or rotationY properties are changed and this view is
+ * large (more than half the size of the screen), it is recommended to always
+ * use a camera distance that's greater than the height (X axis rotation) or
+ * the width (Y axis rotation) of this view.</p>
+ *
+ * <p>The distance of the camera from the drawing plane can have an affect on the
+ * perspective distortion of the RenderNode when it is rotated around the x or y axis.
+ * For example, a large distance will result in a large viewing angle, and there
+ * will not be much perspective distortion of the view as it rotates. A short
+ * distance may cause much more perspective distortion upon rotation, and can
+ * also result in some drawing artifacts if the rotated view ends up partially
+ * behind the camera (which is why the recommendation is to use a distance at
+ * least as far as the size of the view, if the view is to be rotated.)</p>
*
- * @param distance The distance in Z of the camera of the display list
+ * <p>The distance is expressed in pixels and must always be positive</p>
*
- * @see View#setCameraDistance(float)
- * @see #getCameraDistance()
+ * @param distance The distance in pixels, must always be positive
+ * @see #setRotationX(float)
+ * @see #setRotationY(float)
*/
public boolean setCameraDistance(float distance) {
- return nSetCameraDistance(mNativeRenderNode, distance);
+ if (!Float.isFinite(distance) || distance < 0.0f) {
+ throw new IllegalArgumentException("distance must be finite & positive, given="
+ + distance);
+ }
+ // Native actually wants this to be negative not positive, so we flip it.
+ return nSetCameraDistance(mNativeRenderNode, -distance);
}
/**
- * Returns the distance in Z of the camera of the display list.
+ * Returns the distance in Z of the camera for this RenderNode
*
+ * @return the distance along the Z axis in pixels.
* @see #setCameraDistance(float)
*/
public float getCameraDistance() {
- return nGetCameraDistance(mNativeRenderNode);
+ return -nGetCameraDistance(mNativeRenderNode);
}
/**
- * Sets the left position for the display list.
+ * Sets the left position for the RenderNode.
*
- * @param left The left position, in pixels, of the display list
- *
- * @see View#setLeft(int)
+ * @param left The left position, in pixels, of the RenderNode
+ * @return true if the value changed, false otherwise
*/
public boolean setLeft(int left) {
return nSetLeft(mNativeRenderNode, left);
}
/**
- * Sets the top position for the display list.
- *
- * @param top The top position, in pixels, of the display list
+ * Sets the top position for the RenderNode.
*
- * @see View#setTop(int)
+ * @param top The top position, in pixels, of the RenderNode
+ * @return true if the value changed, false otherwise.
*/
public boolean setTop(int top) {
return nSetTop(mNativeRenderNode, top);
}
/**
- * Sets the right position for the display list.
- *
- * @param right The right position, in pixels, of the display list
+ * Sets the right position for the RenderNode.
*
- * @see View#setRight(int)
+ * @param right The right position, in pixels, of the RenderNode
+ * @return true if the value changed, false otherwise.
*/
public boolean setRight(int right) {
return nSetRight(mNativeRenderNode, right);
}
/**
- * Sets the bottom position for the display list.
+ * Sets the bottom position for the RenderNode.
*
- * @param bottom The bottom position, in pixels, of the display list
- *
- * @see View#setBottom(int)
+ * @param bottom The bottom position, in pixels, of the RenderNode
+ * @return true if the value changed, false otherwise.
*/
public boolean setBottom(int bottom) {
return nSetBottom(mNativeRenderNode, bottom);
}
/**
- * Sets the left and top positions for the display list
+ * Gets the left position for the RenderNode.
+ *
+ * See {@link #setLeft(int)}
+ *
+ * @return the left position in pixels
+ */
+ public int getLeft() {
+ return nGetLeft(mNativeRenderNode);
+ }
+
+ /**
+ * Gets the top position for the RenderNode.
+ *
+ * See {@link #setTop(int)}
+ *
+ * @return the top position in pixels
+ */
+ public int getTop() {
+ return nGetTop(mNativeRenderNode);
+ }
+
+ /**
+ * Gets the right position for the RenderNode.
+ *
+ * See {@link #setRight(int)}
+ *
+ * @return the right position in pixels
+ */
+ public int getRight() {
+ return nGetRight(mNativeRenderNode);
+ }
+
+ /**
+ * Gets the bottom position for the RenderNode.
+ *
+ * See {@link #setBottom(int)}
+ *
+ * @return the bottom position in pixels
+ */
+ public int getBottom() {
+ return nGetBottom(mNativeRenderNode);
+ }
+
+ /**
+ * Gets the width of the RenderNode, which is the right - left.
*
- * @param left The left position of the display list, in pixels
- * @param top The top position of the display list, in pixels
- * @param right The right position of the display list, in pixels
- * @param bottom The bottom position of the display list, in pixels
+ * @return the width of the RenderNode
+ */
+ public int getWidth() {
+ return nGetWidth(mNativeRenderNode);
+ }
+
+ /**
+ * Gets the height of the RenderNode, which is the bottom - top.
*
- * @see View#setLeft(int)
- * @see View#setTop(int)
- * @see View#setRight(int)
- * @see View#setBottom(int)
+ * @return the height of the RenderNode
+ */
+ public int getHeight() {
+ return nGetHeight(mNativeRenderNode);
+ }
+
+ /**
+ * Sets the left, top, right, and bottom of the RenderNode.
+ *
+ * @param left The left position of the RenderNode, in pixels
+ * @param top The top position of the RenderNode, in pixels
+ * @param right The right position of the RenderNode, in pixels
+ * @param bottom The bottom position of the RenderNode, in pixels
+ * @return true if any values changed, false otherwise.
+ * @see #setLeft(int)
+ * @see #setTop(int)
+ * @see #setRight(int)
+ * @see #setBottom(int)
*/
public boolean setLeftTopRightBottom(int left, int top, int right, int bottom) {
return nSetLeftTopRightBottom(mNativeRenderNode, left, top, right, bottom);
}
/**
- * Offsets the left and right positions for the display list
+ * Offsets the left and right positions for the RenderNode
*
- * @param offset The amount that the left and right positions of the display
- * list are offset, in pixels
- *
- * @see View#offsetLeftAndRight(int)
+ * @param offset The amount that the left and right positions are offset in pixels
+ * @return true if any values changed, false otherwise.
*/
public boolean offsetLeftAndRight(int offset) {
return nOffsetLeftAndRight(mNativeRenderNode, offset);
}
/**
- * Offsets the top and bottom values for the display list
- *
- * @param offset The amount that the top and bottom positions of the display
- * list are offset, in pixels
+ * Offsets the top and bottom values for the RenderNode
*
- * @see View#offsetTopAndBottom(int)
+ * @param offset The amount that the left and right positions are offset in pixels
+ * @return true if any values changed, false otherwise.
*/
public boolean offsetTopAndBottom(int offset) {
return nOffsetTopAndBottom(mNativeRenderNode, offset);
}
/**
- * Outputs the display list to the log. This method exists for use by
+ * Outputs the RenderNode to the log. This method exists for use by
* tools to output display lists for selected nodes to the log.
+ *
+ * @hide TODO: Expose? Should the shape of this be different than forced dump to logcat?
*/
public void output() {
nOutput(mNativeRenderNode);
}
/**
- * Gets the size of the DisplayList for debug purposes.
+ * Gets the approximate memory usage of the RenderNode for debug purposes. Does not include
+ * the memory usage of any child RenderNodes nor any bitmaps, only the memory usage of
+ * this RenderNode and any data it owns.
*/
- public int getDebugSize() {
+ public int computeApproximateMemoryUsage() {
return nGetDebugSize(mNativeRenderNode);
}
@@ -995,13 +1184,16 @@ public class RenderNode {
* For now this interface exists to de-couple RenderNode from anything View-specific in a
* bit of a kludge.
*
- * @hide */
+ * @hide
+ */
public interface AnimationHost {
- /** checkstyle */
+ /** @hide */
void registerAnimatingRenderNode(RenderNode animator);
- /** checkstyle */
+
+ /** @hide */
void registerVectorDrawableAnimator(NativeVectorDrawableAnimator animator);
- /** checkstyle */
+
+ /** @hide */
boolean isAttached();
}
@@ -1039,14 +1231,18 @@ public class RenderNode {
private static native long nCreate(String name);
private static native long nGetNativeFinalizer();
+
private static native void nOutput(long renderNode);
+
private static native int nGetDebugSize(long renderNode);
+
private static native void nRequestPositionUpdates(long renderNode,
PositionUpdateListener callback);
// Animations
private static native void nAddAnimator(long renderNode, long animatorPtr);
+
private static native void nEndAllAnimators(long renderNode);
@@ -1069,8 +1265,10 @@ public class RenderNode {
@CriticalNative
private static native void nGetTransformMatrix(long renderNode, long nativeMatrix);
+
@CriticalNative
private static native void nGetInverseTransformMatrix(long renderNode, long nativeMatrix);
+
@CriticalNative
private static native boolean nHasIdentityMatrix(long renderNode);
@@ -1078,135 +1276,208 @@ public class RenderNode {
@CriticalNative
private static native boolean nOffsetTopAndBottom(long renderNode, int offset);
+
@CriticalNative
private static native boolean nOffsetLeftAndRight(long renderNode, int offset);
+
@CriticalNative
private static native boolean nSetLeftTopRightBottom(long renderNode, int left, int top,
int right, int bottom);
+
@CriticalNative
- private static native boolean nSetBottom(long renderNode, int bottom);
+ private static native boolean nSetLeft(long renderNode, int left);
+
+ @CriticalNative
+ private static native boolean nSetTop(long renderNode, int top);
+
@CriticalNative
private static native boolean nSetRight(long renderNode, int right);
+
@CriticalNative
- private static native boolean nSetTop(long renderNode, int top);
+ private static native boolean nSetBottom(long renderNode, int bottom);
+
@CriticalNative
- private static native boolean nSetLeft(long renderNode, int left);
+ private static native int nGetLeft(long renderNode);
+
+ @CriticalNative
+ private static native int nGetTop(long renderNode);
+
+ @CriticalNative
+ private static native int nGetRight(long renderNode);
+
+ @CriticalNative
+ private static native int nGetBottom(long renderNode);
+
@CriticalNative
private static native boolean nSetCameraDistance(long renderNode, float distance);
+
@CriticalNative
private static native boolean nSetPivotY(long renderNode, float pivotY);
+
@CriticalNative
private static native boolean nSetPivotX(long renderNode, float pivotX);
+
@CriticalNative
private static native boolean nResetPivot(long renderNode);
+
@CriticalNative
private static native boolean nSetLayerType(long renderNode, int layerType);
+
@CriticalNative
private static native boolean nSetLayerPaint(long renderNode, long paint);
+
@CriticalNative
private static native boolean nSetClipToBounds(long renderNode, boolean clipToBounds);
+
@CriticalNative
private static native boolean nSetClipBounds(long renderNode, int left, int top,
int right, int bottom);
+
@CriticalNative
private static native boolean nSetClipBoundsEmpty(long renderNode);
+
@CriticalNative
private static native boolean nSetProjectBackwards(long renderNode, boolean shouldProject);
+
@CriticalNative
private static native boolean nSetProjectionReceiver(long renderNode, boolean shouldRecieve);
+
@CriticalNative
private static native boolean nSetOutlineRoundRect(long renderNode, int left, int top,
int right, int bottom, float radius, float alpha);
+
@CriticalNative
private static native boolean nSetOutlineConvexPath(long renderNode, long nativePath,
float alpha);
+
@CriticalNative
private static native boolean nSetOutlineEmpty(long renderNode);
+
@CriticalNative
private static native boolean nSetOutlineNone(long renderNode);
+
@CriticalNative
private static native boolean nHasShadow(long renderNode);
+
@CriticalNative
private static native boolean nSetSpotShadowColor(long renderNode, int color);
+
@CriticalNative
private static native boolean nSetAmbientShadowColor(long renderNode, int color);
+
@CriticalNative
private static native int nGetSpotShadowColor(long renderNode);
+
@CriticalNative
private static native int nGetAmbientShadowColor(long renderNode);
+
@CriticalNative
private static native boolean nSetClipToOutline(long renderNode, boolean clipToOutline);
+
@CriticalNative
private static native boolean nSetRevealClip(long renderNode,
boolean shouldClip, float x, float y, float radius);
+
@CriticalNative
private static native boolean nSetAlpha(long renderNode, float alpha);
+
@CriticalNative
private static native boolean nSetHasOverlappingRendering(long renderNode,
boolean hasOverlappingRendering);
+
@CriticalNative
private static native void nSetUsageHint(long renderNode, int usageHint);
+
@CriticalNative
private static native boolean nSetElevation(long renderNode, float lift);
+
@CriticalNative
private static native boolean nSetTranslationX(long renderNode, float translationX);
+
@CriticalNative
private static native boolean nSetTranslationY(long renderNode, float translationY);
+
@CriticalNative
private static native boolean nSetTranslationZ(long renderNode, float translationZ);
+
@CriticalNative
private static native boolean nSetRotation(long renderNode, float rotation);
+
@CriticalNative
private static native boolean nSetRotationX(long renderNode, float rotationX);
+
@CriticalNative
private static native boolean nSetRotationY(long renderNode, float rotationY);
+
@CriticalNative
private static native boolean nSetScaleX(long renderNode, float scaleX);
+
@CriticalNative
private static native boolean nSetScaleY(long renderNode, float scaleY);
+
@CriticalNative
private static native boolean nSetStaticMatrix(long renderNode, long nativeMatrix);
+
@CriticalNative
private static native boolean nSetAnimationMatrix(long renderNode, long animationMatrix);
@CriticalNative
private static native boolean nHasOverlappingRendering(long renderNode);
+
@CriticalNative
private static native boolean nGetClipToOutline(long renderNode);
+
@CriticalNative
private static native float nGetAlpha(long renderNode);
+
@CriticalNative
private static native float nGetCameraDistance(long renderNode);
+
@CriticalNative
private static native float nGetScaleX(long renderNode);
+
@CriticalNative
private static native float nGetScaleY(long renderNode);
+
@CriticalNative
private static native float nGetElevation(long renderNode);
+
@CriticalNative
private static native float nGetTranslationX(long renderNode);
+
@CriticalNative
private static native float nGetTranslationY(long renderNode);
+
@CriticalNative
private static native float nGetTranslationZ(long renderNode);
+
@CriticalNative
private static native float nGetRotation(long renderNode);
+
@CriticalNative
private static native float nGetRotationX(long renderNode);
+
@CriticalNative
private static native float nGetRotationY(long renderNode);
+
@CriticalNative
private static native boolean nIsPivotExplicitlySet(long renderNode);
+
@CriticalNative
private static native float nGetPivotX(long renderNode);
+
@CriticalNative
private static native float nGetPivotY(long renderNode);
+
@CriticalNative
private static native int nGetWidth(long renderNode);
+
@CriticalNative
private static native int nGetHeight(long renderNode);
+
@CriticalNative
private static native boolean nSetAllowForceDark(long renderNode, boolean allowForceDark);
+
@CriticalNative
private static native boolean nGetAllowForceDark(long renderNode);
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 5c0c38ee7666..7e8bfb300c1a 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -27,10 +27,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
+import android.graphics.fonts.Font;
+import android.graphics.fonts.FontFamily;
import android.graphics.fonts.FontStyle;
import android.graphics.fonts.FontVariationAxis;
import android.graphics.fonts.SystemFonts;
-import android.net.Uri;
import android.os.Build;
import android.provider.FontRequest;
import android.provider.FontsContract;
@@ -50,13 +51,10 @@ import libcore.util.NativeAllocationRegistry;
import java.io.File;
import java.io.FileDescriptor;
-import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -126,7 +124,8 @@ public class Typeface {
// We cannot support sSystemFallbackMap since we will migrate to public FontFamily API.
@UnsupportedAppUsage
- static final Map<String, FontFamily[]> sSystemFallbackMap = Collections.emptyMap();
+ static final Map<String, android.graphics.FontFamily[]> sSystemFallbackMap =
+ Collections.emptyMap();
/**
* @hide
@@ -164,6 +163,9 @@ public class Typeface {
private int[] mSupportedAxes;
private static final int[] EMPTY_AXES = {};
+ // The underlying font families.
+ private final FontFamily[] mFamilies;
+
@UnsupportedAppUsage
private static void setDefault(Typeface t) {
sDefaultTypeface = t;
@@ -192,38 +194,6 @@ public class Typeface {
/**
* @hide
- * Used by Resources to load a font resource of type font file.
- */
- @Nullable
- public static Typeface createFromResources(AssetManager mgr, String path, int cookie) {
- synchronized (sDynamicCacheLock) {
- final String key = Builder.createAssetUid(
- mgr, path, 0 /* ttcIndex */, null /* axes */,
- RESOLVE_BY_FONT_TABLE /* weight */, RESOLVE_BY_FONT_TABLE /* italic */,
- DEFAULT_FAMILY);
- Typeface typeface = sDynamicTypefaceCache.get(key);
- if (typeface != null) return typeface;
-
- FontFamily fontFamily = new FontFamily();
- // TODO: introduce ttc index and variation settings to resource type font.
- if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */,
- 0 /* ttcIndex */, RESOLVE_BY_FONT_TABLE /* weight */,
- RESOLVE_BY_FONT_TABLE /* italic */, null /* axes */)) {
- if (!fontFamily.freeze()) {
- return null;
- }
- FontFamily[] families = {fontFamily};
- typeface = createFromFamiliesWithDefault(families, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
- sDynamicTypefaceCache.put(key, typeface);
- return typeface;
- }
- }
- return null;
- }
-
- /**
- * @hide
* Used by Resources to load a font resource of type xml.
*/
@Nullable
@@ -258,21 +228,34 @@ public class Typeface {
// family is FontFamilyFilesResourceEntry
final FontFamilyFilesResourceEntry filesEntry = (FontFamilyFilesResourceEntry) entry;
- FontFamily fontFamily = new FontFamily();
- for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
- if (!fontFamily.addFontFromAssetManager(mgr, fontFile.getFileName(),
- 0 /* resourceCookie */, false /* isAsset */, fontFile.getTtcIndex(),
- fontFile.getWeight(), fontFile.getItalic(),
- FontVariationAxis.fromFontVariationSettings(fontFile.getVariationSettings()))) {
- return null;
+ try {
+ FontFamily.Builder familyBuilder = null;
+ for (final FontFileResourceEntry fontFile : filesEntry.getEntries()) {
+ final Font.Builder fontBuilder = new Font.Builder(mgr, fontFile.getFileName(),
+ false /* isAsset */, 0 /* cookie */)
+ .setTtcIndex(fontFile.getTtcIndex())
+ .setFontVariationSettings(fontFile.getVariationSettings());
+ if (fontFile.getWeight() != Typeface.RESOLVE_BY_FONT_TABLE) {
+ fontBuilder.setWeight(fontFile.getWeight());
+ }
+ if (fontFile.getItalic() != Typeface.RESOLVE_BY_FONT_TABLE) {
+ fontBuilder.setSlant(fontFile.getItalic() == FontFileResourceEntry.ITALIC
+ ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT);
+ }
+
+ if (familyBuilder == null) {
+ familyBuilder = new FontFamily.Builder(fontBuilder.build());
+ } else {
+ familyBuilder.addFont(fontBuilder.build());
+ }
}
+ if (familyBuilder == null) {
+ return Typeface.DEFAULT;
+ }
+ typeface = new Typeface.CustomFallbackBuilder(familyBuilder.build()).build();
+ } catch (IOException e) {
+ typeface = Typeface.DEFAULT;
}
- if (!fontFamily.freeze()) {
- return null;
- }
- FontFamily[] familyChain = { fontFamily };
- typeface = createFromFamiliesWithDefault(familyChain, DEFAULT_FAMILY,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE);
synchronized (sDynamicCacheLock) {
final String key = Builder.createAssetUid(mgr, path, 0 /* ttcIndex */,
null /* axes */, RESOLVE_BY_FONT_TABLE /* weight */,
@@ -339,15 +322,11 @@ public class Typeface {
/** @hide */
public static final int BOLD_WEIGHT = 700;
- private int mTtcIndex;
- private FontVariationAxis[] mAxes;
-
- private AssetManager mAssetManager;
- private String mPath;
- private FileDescriptor mFd;
+ // Kept for generating asset cache key.
+ private final AssetManager mAssetManager;
+ private final String mPath;
- private FontsContract.FontInfo[] mFonts;
- private Map<Uri, ByteBuffer> mFontBuffers;
+ private final Font.Builder mFontBuilder;
private String mFallbackFamilyName;
@@ -360,7 +339,9 @@ public class Typeface {
* @param path The file object refers to the font file.
*/
public Builder(@NonNull File path) {
- mPath = path.getAbsolutePath();
+ mFontBuilder = new Font.Builder(path);
+ mAssetManager = null;
+ mPath = null;
}
/**
@@ -372,7 +353,9 @@ public class Typeface {
* @param fd The file descriptor. The passed fd must be mmap-able.
*/
public Builder(@NonNull FileDescriptor fd) {
- mFd = fd;
+ mFontBuilder = new Font.Builder(fd);
+ mAssetManager = null;
+ mPath = null;
}
/**
@@ -381,7 +364,9 @@ public class Typeface {
* @param path The full path to the font file.
*/
public Builder(@NonNull String path) {
- mPath = path;
+ mFontBuilder = new Font.Builder(new File(path));
+ mAssetManager = null;
+ mPath = null;
}
/**
@@ -391,27 +376,22 @@ public class Typeface {
* @param path The file name of the font data in the asset directory
*/
public Builder(@NonNull AssetManager assetManager, @NonNull String path) {
- mAssetManager = Preconditions.checkNotNull(assetManager);
- mPath = Preconditions.checkStringNotEmpty(path);
+ this(assetManager, path, true /* is asset */, 0 /* cookie */);
}
/**
- * Constracts a builder from an array of FontsContract.FontInfo.
- *
- * Since {@link FontsContract.FontInfo} holds information about TTC indices and
- * variation settings, there is no need to call {@link #setTtcIndex} or
- * {@link #setFontVariationSettings}. Similary, {@link FontsContract.FontInfo} holds
- * weight and italic information, so {@link #setWeight} and {@link #setItalic} are used
- * for style matching during font selection.
+ * Constructs a builder from an asset manager and a file path in an asset directory.
*
- * @param fonts The array of {@link FontsContract.FontInfo}
- * @param buffers The mapping from URI to buffers to be used during building.
+ * @param assetManager The application's asset manager
+ * @param path The file name of the font data in the asset directory
+ * @param cookie a cookie for the asset
* @hide
*/
- public Builder(@NonNull FontsContract.FontInfo[] fonts,
- @NonNull Map<Uri, ByteBuffer> buffers) {
- mFonts = fonts;
- mFontBuffers = buffers;
+ public Builder(@NonNull AssetManager assetManager, @NonNull String path, boolean isAsset,
+ int cookie) {
+ mFontBuilder = new Font.Builder(assetManager, path, isAsset, cookie);
+ mAssetManager = assetManager;
+ mPath = path;
}
/**
@@ -423,6 +403,7 @@ public class Typeface {
*/
public Builder setWeight(@IntRange(from = 1, to = 1000) int weight) {
mWeight = weight;
+ mFontBuilder.setWeight(weight);
return this;
}
@@ -434,7 +415,8 @@ public class Typeface {
* @param italic {@code true} if the font is italic. Otherwise {@code false}.
*/
public Builder setItalic(boolean italic) {
- mItalic = italic ? STYLE_ITALIC : STYLE_NORMAL;
+ mItalic = italic ? FontStyle.FONT_SLANT_ITALIC : FontStyle.FONT_SLANT_UPRIGHT;
+ mFontBuilder.setSlant(mItalic);
return this;
}
@@ -446,11 +428,7 @@ public class Typeface {
* collection, do not call this method or specify 0.
*/
public Builder setTtcIndex(@IntRange(from = 0) int ttcIndex) {
- if (mFonts != null) {
- throw new IllegalArgumentException(
- "TTC index can not be specified for FontResult source.");
- }
- mTtcIndex = ttcIndex;
+ mFontBuilder.setTtcIndex(ttcIndex);
return this;
}
@@ -462,14 +440,7 @@ public class Typeface {
* format.
*/
public Builder setFontVariationSettings(@Nullable String variationSettings) {
- if (mFonts != null) {
- throw new IllegalArgumentException(
- "Font variation settings can not be specified for FontResult source.");
- }
- if (mAxes != null) {
- throw new IllegalStateException("Font variation settings are already set.");
- }
- mAxes = FontVariationAxis.fromFontVariationSettings(variationSettings);
+ mFontBuilder.setFontVariationSettings(variationSettings);
return this;
}
@@ -479,14 +450,7 @@ public class Typeface {
* @param axes An array of font variation axis tag-value pairs.
*/
public Builder setFontVariationSettings(@Nullable FontVariationAxis[] axes) {
- if (mFonts != null) {
- throw new IllegalArgumentException(
- "Font variation settings can not be specified for FontResult source.");
- }
- if (mAxes != null) {
- throw new IllegalStateException("Font variation settings are already set.");
- }
- mAxes = axes;
+ mFontBuilder.setFontVariationSettings(axes);
return this;
}
@@ -579,97 +543,55 @@ public class Typeface {
* @return Newly created Typeface. May return null if some parameters are invalid.
*/
public Typeface build() {
- if (mFd != null) { // Builder is created with file descriptor.
- try (FileInputStream fis = new FileInputStream(mFd)) {
- FileChannel channel = fis.getChannel();
- long size = channel.size();
- ByteBuffer buffer = channel.map(FileChannel.MapMode.READ_ONLY, 0, size);
-
- final FontFamily fontFamily = new FontFamily();
- if (!fontFamily.addFontFromBuffer(buffer, mTtcIndex, mAxes, mWeight, mItalic)) {
- fontFamily.abortCreation();
- return resolveFallbackTypeface();
- }
- if (!fontFamily.freeze()) {
- return resolveFallbackTypeface();
- }
- FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
- } catch (IOException e) {
- return resolveFallbackTypeface();
- }
- } else if (mAssetManager != null) { // Builder is created with asset manager.
- final String key = createAssetUid(
- mAssetManager, mPath, mTtcIndex, mAxes, mWeight, mItalic,
+ try {
+ final Font font = mFontBuilder.build();
+ final String key = mAssetManager == null ? null : createAssetUid(
+ mAssetManager, mPath, font.getTtcIndex(), font.getAxes(),
+ font.getStyle().getWeight(), font.getStyle().getSlant(),
mFallbackFamilyName);
- synchronized (sDynamicCacheLock) {
- Typeface typeface = sDynamicTypefaceCache.get(key);
- if (typeface != null) return typeface;
- final FontFamily fontFamily = new FontFamily();
- if (!fontFamily.addFontFromAssetManager(mAssetManager, mPath, mTtcIndex,
- true /* isAsset */, mTtcIndex, mWeight, mItalic, mAxes)) {
- fontFamily.abortCreation();
- return resolveFallbackTypeface();
- }
- if (!fontFamily.freeze()) {
- return resolveFallbackTypeface();
+ if (key != null) {
+ // Dynamic cache lookup is only for assets.
+ synchronized (sDynamicCacheLock) {
+ final Typeface typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) {
+ return typeface;
+ }
}
- FontFamily[] families = { fontFamily };
- typeface = createFromFamiliesWithDefault(families, mFallbackFamilyName,
- mWeight, mItalic);
- sDynamicTypefaceCache.put(key, typeface);
- return typeface;
- }
- } else if (mPath != null) { // Builder is created with file path.
- final FontFamily fontFamily = new FontFamily();
- if (!fontFamily.addFont(mPath, mTtcIndex, mAxes, mWeight, mItalic)) {
- fontFamily.abortCreation();
- return resolveFallbackTypeface();
}
- if (!fontFamily.freeze()) {
- return resolveFallbackTypeface();
+ final FontFamily family = new FontFamily.Builder(font).build();
+ final int weight = mWeight == RESOLVE_BY_FONT_TABLE
+ ? font.getStyle().getWeight() : mWeight;
+ final int slant = mItalic == RESOLVE_BY_FONT_TABLE
+ ? font.getStyle().getSlant() : mItalic;
+ final CustomFallbackBuilder builder = new CustomFallbackBuilder(family)
+ .setStyle(new FontStyle(weight, slant));
+ if (mFallbackFamilyName != null) {
+ builder.setSystemFallback(mFallbackFamilyName);
}
- FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
- } else if (mFonts != null) {
- final FontFamily fontFamily = new FontFamily();
- boolean atLeastOneFont = false;
- for (FontsContract.FontInfo font : mFonts) {
- final ByteBuffer fontBuffer = mFontBuffers.get(font.getUri());
- if (fontBuffer == null) {
- continue; // skip
+ final Typeface typeface = builder.build();
+ if (key != null) {
+ synchronized (sDynamicCacheLock) {
+ sDynamicTypefaceCache.put(key, typeface);
}
- final boolean success = fontFamily.addFontFromBuffer(fontBuffer,
- font.getTtcIndex(), font.getAxes(), font.getWeight(),
- font.isItalic() ? STYLE_ITALIC : STYLE_NORMAL);
- if (!success) {
- fontFamily.abortCreation();
- return null;
- }
- atLeastOneFont = true;
- }
- if (!atLeastOneFont) {
- // No fonts are avaialble. No need to create new Typeface and returns fallback
- // Typeface instead.
- fontFamily.abortCreation();
- return null;
}
- fontFamily.freeze();
- FontFamily[] families = { fontFamily };
- return createFromFamiliesWithDefault(families, mFallbackFamilyName, mWeight,
- mItalic);
+ return typeface;
+ } catch (IOException | IllegalArgumentException e) {
+ return resolveFallbackTypeface();
}
-
- // Must not reach here.
- throw new IllegalArgumentException("No source was set.");
}
}
/**
* A builder class for creating new Typeface instance.
*
+ * There are two font fallback mechanisms, custom font fallback and system font fallback.
+ * The custom font fallback is a simple ordered list. The text renderer tries to see if it can
+ * render a character with the first font and if that font does not support the character, try
+ * next one and so on. It will keep trying until end of the custom fallback chain. The maximum
+ * length of the custom fallback chain is 64.
+ * The system font fallback is a system pre-defined fallback chain. The system fallback is
+ * processed only when no matching font is found in the custom font fallback.
+ *
* <p>
* Examples,
* 1) Create Typeface from single ttf file.
@@ -703,72 +625,85 @@ public class Typeface {
* Font font = new Font.Builder("your_font_file.ttf").build();
* FontFamily family = new FontFamily.Builder(font).build();
* Typeface typeface = new Typeface.CustomFallbackBuilder(family)
- * .setFallback("serif") // Set serif font family as the fallback.
+ * .setSystemFallback("serif") // Set serif font family as the fallback.
+ * .build();
+ * </code>
+ * </pre>
+ * 4) Create Typeface from single ttf file and set another ttf file for the fallback.
+ * <pre>
+ * <code>
+ * Font font = new Font.Builder("English.ttf").build();
+ * FontFamily family = new FontFamily.Builder(font).build();
+ *
+ * Font fallbackFont = new Font.Builder("Arabic.ttf").build();
+ * FontFamily fallbackFamily = new FontFamily.Builder(fallbackFont).build();
+ * Typeface typeface = new Typeface.CustomFallbackBuilder(family)
+ * .addCustomFallback(fallbackFamily) // Specify fallback family.
+ * .setSystemFallback("serif") // Set serif font family as the fallback.
* .build();
* </code>
* </pre>
* </p>
*/
public static class CustomFallbackBuilder {
- // TODO: Remove package modifier once android.graphics.FontFamily is deprecated.
- private final android.graphics.fonts.FontFamily mFamily;
+ private static final int MAX_CUSTOM_FALLBACK = 64;
+ private final ArrayList<FontFamily> mFamilies = new ArrayList<>();
private String mFallbackName = null;
- private @IntRange(from = 0, to = 1000) int mWeight = 400;
- private boolean mItalic = false;
+ private @Nullable FontStyle mStyle;
/**
* Constructs a builder with a font family.
*
* @param family a family object
*/
- // TODO: Remove package modifier once android.graphics.FontFamily is deprecated.
- public CustomFallbackBuilder(@NonNull android.graphics.fonts.FontFamily family) {
+ public CustomFallbackBuilder(@NonNull FontFamily family) {
Preconditions.checkNotNull(family);
- mFamily = family;
+ mFamilies.add(family);
}
/**
* Sets a system fallback by name.
*
+ * For more information about fallback, see class description.
+ *
* @param familyName a family name to be used for fallback if the provided fonts can not be
* used
*/
- public CustomFallbackBuilder setFallback(@NonNull String familyName) {
+ public CustomFallbackBuilder setSystemFallback(@NonNull String familyName) {
Preconditions.checkNotNull(familyName);
mFallbackName = familyName;
return this;
}
/**
- * Sets a weight of the Typeface.
+ * Sets a font style of the Typeface.
*
- * If the font family doesn't have a font of given weight, system will select the closest
+ * If the font family doesn't have a font of given style, system will select the closest
* font from font family. For example, if a font family has fonts of 300 weight and 700
* weight then setWeight(400) is called, system will select the font of 300 weight.
*
- * @see Font#FONT_WEIGHT_THIN
- * @see Font#FONT_WEIGHT_EXTRA_LIGHT
- * @see Font#FONT_WEIGHT_LIGHT
- * @see Font#FONT_WEIGHT_NORMAL
- * @see Font#FONT_WEIGHT_MEDIUM
- * @see Font#FONT_WEIGHT_SEMI_BOLD
- * @see Font#FONT_WEIGHT_BOLD
- * @see Font#FONT_WEIGHT_EXTRA_BOLD
- * @see Font#FONT_WEIGHT_BLACK
- * @param weight a weight value
+ * @param style a font style
*/
- public CustomFallbackBuilder setWeight(@IntRange(from = 0, to = 1000) int weight) {
- mWeight = weight;
+ public CustomFallbackBuilder setStyle(@NonNull FontStyle style) {
+ mStyle = style;
return this;
}
/**
- * Sets a italic style of the Typeface.
+ * Append a font family to the end of the custom font fallback.
+ *
+ * You can set up to 64 custom fallback families including the first font family you passed
+ * to the constructor.
+ * For more information about fallback, see class description.
*
- * @param italic true if italic, otherwise false
+ * @param family a fallback family
+ * @throws IllegalArgumentException if you give more than 64 custom fallback families
*/
- public CustomFallbackBuilder setItalic(boolean italic) {
- mItalic = italic;
+ public CustomFallbackBuilder addCustomFallback(@NonNull FontFamily family) {
+ Preconditions.checkNotNull(family);
+ Preconditions.checkArgument(mFamilies.size() < MAX_CUSTOM_FALLBACK,
+ "Custom fallback limit exceeded(" + MAX_CUSTOM_FALLBACK + ")");
+ mFamilies.add(family);
return this;
}
@@ -778,14 +713,23 @@ public class Typeface {
* @return the Typeface object
*/
public Typeface build() {
- final android.graphics.fonts.FontFamily[] fallback =
- SystemFonts.getSystemFallback(mFallbackName);
- final long[] ptrArray = new long[fallback.length + 1];
- ptrArray[0] = mFamily.getNativePtr();
+ final int userFallbackSize = mFamilies.size();
+ final FontFamily[] fallback = SystemFonts.getSystemFallback(mFallbackName);
+ final FontFamily[] fullFamilies = new FontFamily[fallback.length + userFallbackSize];
+ final long[] ptrArray = new long[fallback.length + userFallbackSize];
+ for (int i = 0; i < userFallbackSize; ++i) {
+ ptrArray[i] = mFamilies.get(i).getNativePtr();
+ fullFamilies[i] = mFamilies.get(i);
+ }
for (int i = 0; i < fallback.length; ++i) {
- ptrArray[i + 1] = fallback[i].getNativePtr();
+ ptrArray[i + userFallbackSize] = fallback[i].getNativePtr();
+ fullFamilies[i + userFallbackSize] = fallback[i];
}
- return new Typeface(nativeCreateFromArray(ptrArray, mWeight, mItalic ? 1 : 0));
+ final int weight = mStyle == null ? 400 : mStyle.getWeight();
+ final int italic =
+ (mStyle == null || mStyle.getSlant() == FontStyle.FONT_SLANT_UPRIGHT) ? 0 : 1;
+
+ return new Typeface(nativeCreateFromArray(ptrArray, weight, italic), fullFamilies);
}
}
@@ -850,7 +794,7 @@ public class Typeface {
}
}
- typeface = new Typeface(nativeCreateFromTypeface(ni, style));
+ typeface = new Typeface(nativeCreateFromTypeface(ni, style), family.mFamilies);
styles.put(style, typeface);
}
return typeface;
@@ -919,7 +863,7 @@ public class Typeface {
typeface = new Typeface(
nativeCreateFromTypefaceWithExactStyle(
- base.native_instance, weight, italic));
+ base.native_instance, weight, italic), base.mFamilies);
innerCache.put(key, typeface);
}
return typeface;
@@ -928,8 +872,9 @@ public class Typeface {
/** @hide */
public static Typeface createFromTypefaceWithVariation(@Nullable Typeface family,
@NonNull List<FontVariationAxis> axes) {
- final long ni = family == null ? 0 : family.native_instance;
- return new Typeface(nativeCreateFromTypefaceWithVariation(ni, axes));
+ final Typeface base = family == null ? Typeface.DEFAULT : family;
+ return new Typeface(nativeCreateFromTypefaceWithVariation(base.native_instance, axes),
+ base.mFamilies);
}
/**
@@ -1015,7 +960,7 @@ public class Typeface {
*/
@Deprecated
@UnsupportedAppUsage
- private static Typeface createFromFamilies(FontFamily[] families) {
+ private static Typeface createFromFamilies(android.graphics.FontFamily[] families) {
long[] ptrArray = new long[families.length];
for (int i = 0; i < families.length; i++) {
ptrArray[i] = families[i].mNativePtr;
@@ -1029,14 +974,13 @@ public class Typeface {
*
* @param families array of font families
*/
- private static Typeface createFromFamilies(
- @Nullable android.graphics.fonts.FontFamily[] families) {
+ private static Typeface createFromFamilies(@Nullable FontFamily[] families) {
final long[] ptrArray = new long[families.length];
for (int i = 0; i < families.length; ++i) {
ptrArray[i] = families[i].getNativePtr();
}
return new Typeface(nativeCreateFromArray(ptrArray,
- RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE));
+ RESOLVE_BY_FONT_TABLE, RESOLVE_BY_FONT_TABLE), families);
}
/**
@@ -1044,8 +988,8 @@ public class Typeface {
* TODO: Remove private API use in supportlib: http://b/72665240
*/
@UnsupportedAppUsage
- private static Typeface createFromFamiliesWithDefault(FontFamily[] families, int weight,
- int italic) {
+ private static Typeface createFromFamiliesWithDefault(
+ android.graphics.FontFamily[] families, int weight, int italic) {
return createFromFamiliesWithDefault(families, DEFAULT_FAMILY, weight, italic);
}
@@ -1063,7 +1007,7 @@ public class Typeface {
* @param families array of font families
*/
@UnsupportedAppUsage
- private static Typeface createFromFamiliesWithDefault(FontFamily[] families,
+ private static Typeface createFromFamiliesWithDefault(android.graphics.FontFamily[] families,
String fallbackName, int weight, int italic) {
android.graphics.fonts.FontFamily[] fallback = SystemFonts.getSystemFallback(fallbackName);
long[] ptrArray = new long[families.length + fallback.length];
@@ -1084,6 +1028,19 @@ public class Typeface {
}
native_instance = ni;
+ mFamilies = new FontFamily[0];
+ sRegistry.registerNativeAllocation(this, native_instance);
+ mStyle = nativeGetStyle(ni);
+ mWeight = nativeGetWeight(ni);
+ }
+
+ private Typeface(long ni, @NonNull FontFamily[] families) {
+ if (ni == 0) {
+ throw new IllegalStateException("native typeface cannot be made");
+ }
+
+ native_instance = ni;
+ mFamilies = families;
sRegistry.registerNativeAllocation(this, native_instance);
mStyle = nativeGetStyle(ni);
mWeight = nativeGetWeight(ni);
@@ -1097,9 +1054,9 @@ public class Typeface {
/** @hide */
@VisibleForTesting
public static void initSystemDefaultTypefaces(Map<String, Typeface> systemFontMap,
- Map<String, android.graphics.fonts.FontFamily[]> fallbacks,
+ Map<String, FontFamily[]> fallbacks,
FontConfig.Alias[] aliases) {
- for (Map.Entry<String, android.graphics.fonts.FontFamily[]> entry : fallbacks.entrySet()) {
+ for (Map.Entry<String, FontFamily[]> entry : fallbacks.entrySet()) {
systemFontMap.put(entry.getKey(), createFromFamilies(entry.getValue()));
}
@@ -1110,7 +1067,8 @@ public class Typeface {
final Typeface base = systemFontMap.get(alias.getToName());
final int weight = alias.getWeight();
final Typeface newFace = weight == 400 ? base :
- new Typeface(nativeCreateWeightAlias(base.native_instance, weight));
+ new Typeface(nativeCreateWeightAlias(base.native_instance, weight),
+ base.mFamilies);
systemFontMap.put(alias.getName(), newFace);
}
}
diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java
index 0a8c68559c8c..7f165bfc6a7d 100644
--- a/graphics/java/android/graphics/fonts/Font.java
+++ b/graphics/java/android/graphics/fonts/Font.java
@@ -151,7 +151,21 @@ public final class Font {
* @param path the file name of the font data in the asset directory
*/
public Builder(@NonNull AssetManager am, @NonNull String path) {
- final long nativeAsset = nGetNativeAsset(am, path, true /* is asset */, 0 /* cookie */);
+ this(am, path, true /* is asset */, 0 /* cookie */);
+ }
+
+ /**
+ * Constructs a builder from an asset manager and a file path in an asset directory.
+ *
+ * @param am the application's asset manager
+ * @param path the file name of the font data in the asset directory
+ * @param isAsset true if the undelying data is in asset
+ * @param cookie set asset cookie
+ * @hide
+ */
+ public Builder(@NonNull AssetManager am, @NonNull String path, boolean isAsset,
+ int cookie) {
+ final long nativeAsset = nGetNativeAsset(am, path, isAsset, cookie);
if (nativeAsset == 0) {
mException = new FileNotFoundException("Unable to open " + path);
return;
@@ -293,7 +307,7 @@ public final class Font {
* will resolve the style by reading font tables.
*
* For example, if you want to use italic font as upright font, call {@code
- * setSlant(false)} explicitly.
+ * setSlant(FontStyle.FONT_SLANT_UPRIGHT)} explicitly.
*
* @return this builder
*/
@@ -447,23 +461,14 @@ public final class Font {
}
/**
- * Get a weight value associated with this font.
+ * Get a style associated with this font.
*
* @see Builder#setWeight(int)
- * @return a weight value
- */
- public @IntRange(from = 0, to = 1000)int getWeight() {
- return mFontStyle.getWeight();
- }
-
- /**
- * Get a slant value associated with this font.
- *
- * @see Builder#setSlant(boolean)
- * @return a slant value
+ * @see Builder#setSlant(int)
+ * @return a font style
*/
- public @FontStyle.FontSlant int getSlant() {
- return mFontStyle.getSlant();
+ public FontStyle getStyle() {
+ return mFontStyle;
}
/**
diff --git a/graphics/java/android/graphics/fonts/FontFamily.java b/graphics/java/android/graphics/fonts/FontFamily.java
index 52a37da47cff..c0f1b163ea11 100644
--- a/graphics/java/android/graphics/fonts/FontFamily.java
+++ b/graphics/java/android/graphics/fonts/FontFamily.java
@@ -108,29 +108,31 @@ public final class FontFamily {
* @return a font family
*/
public @NonNull FontFamily build() {
- return build("", FontConfig.Family.VARIANT_DEFAULT);
+ return build("", FontConfig.Family.VARIANT_DEFAULT, true /* isCustomFallback */);
}
/** @hide */
- public @NonNull FontFamily build(@NonNull String langTags, int variant) {
+ public @NonNull FontFamily build(@NonNull String langTags, int variant,
+ boolean isCustomFallback) {
final long builderPtr = nInitBuilder();
for (int i = 0; i < mFonts.size(); ++i) {
nAddFont(builderPtr, mFonts.get(i).getNativePtr());
}
- final long ptr = nBuild(builderPtr, langTags, variant);
+ final long ptr = nBuild(builderPtr, langTags, variant, isCustomFallback);
final FontFamily family = new FontFamily(mFonts, ptr);
sFamilyRegistory.registerNativeAllocation(family, ptr);
return family;
}
private static int makeStyleIdentifier(@NonNull Font font) {
- return font.getWeight() | (font.getSlant() << 16);
+ return font.getStyle().getWeight() | (font.getStyle().getSlant() << 16);
}
private static native long nInitBuilder();
@CriticalNative
private static native void nAddFont(long builderPtr, long fontPtr);
- private static native long nBuild(long builderPtr, String langTags, int variant);
+ private static native long nBuild(long builderPtr, String langTags, int variant,
+ boolean isCustomFallback);
@CriticalNative
private static native long nGetReleaseNativeFamily();
}
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index 750adb2757c8..4a9cf14d04a5 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -208,7 +208,7 @@ public final class SystemFonts {
b.addFont(font);
}
}
- return b == null ? null : b.build(languageTags, variant);
+ return b == null ? null : b.build(languageTags, variant, false /* isCustomFallback */);
}
private static void appendNamedFamily(@NonNull FontConfig.Family xmlFamily,
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 04cc5bb30ade..9e6948878b1d 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -21,6 +21,7 @@
#include <algorithm>
#include <iterator>
#include <set>
+#include <map>
#include "android-base/logging.h"
#include "android-base/stringprintf.h"
@@ -161,6 +162,13 @@ void AssetManager2::DumpToLog() const {
LOG(INFO) << base::StringPrintf("PG (%02x): ",
package_group.dynamic_ref_table.mAssignedPackageId)
<< list;
+
+ for (size_t i = 0; i < 256; i++) {
+ if (package_group.dynamic_ref_table.mLookupTable[i] != 0) {
+ LOG(INFO) << base::StringPrintf(" e[0x%02x] -> 0x%02x", (uint8_t) i,
+ package_group.dynamic_ref_table.mLookupTable[i]);
+ }
+ }
}
}
@@ -869,6 +877,17 @@ void AssetManager2::InvalidateCaches(uint32_t diff) {
}
}
+uint8_t AssetManager2::GetAssignedPackageId(const LoadedPackage* package) {
+ for (auto& package_group : package_groups_) {
+ for (auto& package2 : package_group.packages_) {
+ if (package2.loaded_package_ == package) {
+ return package_group.dynamic_ref_table.mAssignedPackageId;
+ }
+ }
+ }
+ return 0;
+}
+
std::unique_ptr<Theme> AssetManager2::NewTheme() {
return std::unique_ptr<Theme>(new Theme(this));
}
@@ -1054,44 +1073,231 @@ void Theme::Clear() {
}
}
-bool Theme::SetTo(const Theme& o) {
+void Theme::SetTo(const Theme& o) {
if (this == &o) {
- return true;
+ return;
}
type_spec_flags_ = o.type_spec_flags_;
- const bool copy_only_system = asset_manager_ != o.asset_manager_;
+ if (asset_manager_ == o.asset_manager_) {
+ // The theme comes from the same asset manager so all theme data can be copied exactly
+ for (size_t p = 0; p < packages_.size(); p++) {
+ const Package *package = o.packages_[p].get();
+ if (package == nullptr) {
+ // The other theme doesn't have this package, clear ours.
+ packages_[p].reset();
+ continue;
+ }
- for (size_t p = 0; p < packages_.size(); p++) {
- const Package* package = o.packages_[p].get();
- if (package == nullptr || (copy_only_system && p != 0x01)) {
- // The other theme doesn't have this package, clear ours.
- packages_[p].reset();
- continue;
+ if (packages_[p] == nullptr) {
+ // The other theme has this package, but we don't. Make one.
+ packages_[p].reset(new Package());
+ }
+
+ for (size_t t = 0; t < package->types.size(); t++) {
+ const ThemeType *type = package->types[t].get();
+ if (type == nullptr) {
+ // The other theme doesn't have this type, clear ours.
+ packages_[p]->types[t].reset();
+ continue;
+ }
+
+ // Create a new type and update it to theirs.
+ const size_t type_alloc_size = sizeof(ThemeType) + (type->entry_count * sizeof(ThemeEntry));
+ void *copied_data = malloc(type_alloc_size);
+ memcpy(copied_data, type, type_alloc_size);
+ packages_[p]->types[t].reset(reinterpret_cast<ThemeType *>(copied_data));
+ }
}
+ } else {
+ std::map<ApkAssetsCookie, ApkAssetsCookie> src_to_dest_asset_cookies;
+ typedef std::map<int, int> SourceToDestinationRuntimePackageMap;
+ std::map<ApkAssetsCookie, SourceToDestinationRuntimePackageMap> src_asset_cookie_id_map;
+
+ // Determine which ApkAssets are loaded in both theme AssetManagers
+ std::vector<const ApkAssets*> src_assets = o.asset_manager_->GetApkAssets();
+ for (size_t i = 0; i < src_assets.size(); i++) {
+ const ApkAssets* src_asset = src_assets[i];
+
+ std::vector<const ApkAssets*> dest_assets = asset_manager_->GetApkAssets();
+ for (size_t j = 0; j < dest_assets.size(); j++) {
+ const ApkAssets* dest_asset = dest_assets[j];
+
+ // Map the runtime package of the source apk asset to the destination apk asset
+ if (src_asset->GetPath() == dest_asset->GetPath()) {
+ const std::vector<std::unique_ptr<const LoadedPackage>>& src_packages =
+ src_asset->GetLoadedArsc()->GetPackages();
+ const std::vector<std::unique_ptr<const LoadedPackage>>& dest_packages =
+ dest_asset->GetLoadedArsc()->GetPackages();
+
+ SourceToDestinationRuntimePackageMap package_map;
+
+ // The source and destination package should have the same number of packages loaded in
+ // the same order.
+ const size_t N = src_packages.size();
+ CHECK(N == dest_packages.size())
+ << " LoadedArsc " << src_asset->GetPath() << " differs number of packages.";
+ for (size_t p = 0; p < N; p++) {
+ auto& src_package = src_packages[p];
+ auto& dest_package = dest_packages[p];
+ CHECK(src_package->GetPackageName() == dest_package->GetPackageName())
+ << " Package " << src_package->GetPackageName() << " differs in load order.";
+
+ int src_package_id = o.asset_manager_->GetAssignedPackageId(src_package.get());
+ int dest_package_id = asset_manager_->GetAssignedPackageId(dest_package.get());
+ package_map[src_package_id] = dest_package_id;
+ }
- if (packages_[p] == nullptr) {
- // The other theme has this package, but we don't. Make one.
- packages_[p].reset(new Package());
+ src_to_dest_asset_cookies.insert(std::pair<ApkAssetsCookie, ApkAssetsCookie>(i, j));
+ src_asset_cookie_id_map.insert(
+ std::pair<ApkAssetsCookie, SourceToDestinationRuntimePackageMap>(i, package_map));
+ break;
+ }
+ }
+ }
+
+ // Reset the data in the destination theme
+ for (size_t p = 0; p < packages_.size(); p++) {
+ if (packages_[p] != nullptr) {
+ packages_[p].reset();
+ }
}
- for (size_t t = 0; t < package->types.size(); t++) {
- const ThemeType* type = package->types[t].get();
+ for (size_t p = 0; p < packages_.size(); p++) {
+ const Package *package = o.packages_[p].get();
+ if (package == nullptr) {
+ continue;
+ }
+
+ for (size_t t = 0; t < package->types.size(); t++) {
+ const ThemeType *type = package->types[t].get();
+ if (type == nullptr) {
+ continue;
+ }
+
+ for (size_t e = 0; e < type->entry_count; e++) {
+ const ThemeEntry &entry = type->entries[e];
+ if (entry.value.dataType == Res_value::TYPE_NULL &&
+ entry.value.data != Res_value::DATA_NULL_EMPTY) {
+ continue;
+ }
+
+ // The package id of the attribute needs to be rewritten to the package id of the value in
+ // the destination
+ int attribute_dest_package_id = p;
+ if (attribute_dest_package_id != 0x01) {
+ // Find the cookie of the attribute resource id
+ FindEntryResult attribute_entry_result;
+ ApkAssetsCookie attribute_cookie =
+ o.asset_manager_->FindEntry(make_resid(p, t, e), 0 /* density_override */ , false,
+ &attribute_entry_result);
+
+ // Determine the package id of the attribute in the destination AssetManager
+ auto attribute_package_map = src_asset_cookie_id_map.find(attribute_cookie);
+ if (attribute_package_map == src_asset_cookie_id_map.end()) {
+ continue;
+ }
+ auto attribute_dest_package = attribute_package_map->second.find(
+ attribute_dest_package_id);
+ if (attribute_dest_package == attribute_package_map->second.end()) {
+ continue;
+ }
+ attribute_dest_package_id = attribute_dest_package->second;
+ }
+
+ // If the attribute value represents an attribute or reference, the package id of the
+ // value needs to be rewritten to the package id of the value in the destination
+ uint32_t attribue_data = entry.value.data;
+ if (entry.value.dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE
+ || entry.value.dataType == Res_value::TYPE_DYNAMIC_REFERENCE
+ || entry.value.dataType == Res_value::TYPE_ATTRIBUTE
+ || entry.value.dataType == Res_value::TYPE_REFERENCE) {
+
+ // Determine the package id of the reference in the destination AssetManager
+ auto value_package_map = src_asset_cookie_id_map.find(entry.cookie);
+ if (value_package_map == src_asset_cookie_id_map.end()) {
+ continue;
+ }
+
+ auto value_dest_package = value_package_map->second.find(
+ get_package_id(entry.value.data));
+ if (value_dest_package == value_package_map->second.end()) {
+ continue;
+ }
+
+ attribue_data = fix_package_id(entry.value.data, value_dest_package->second);
+ }
+
+ // Lazily instantiate the destination package
+ std::unique_ptr<Package>& dest_package = packages_[attribute_dest_package_id];
+ if (dest_package == nullptr) {
+ dest_package.reset(new Package());
+ }
+
+ // Lazily instantiate and resize the destination type
+ util::unique_cptr<ThemeType>& dest_type = dest_package->types[t];
+ if (dest_type == nullptr || dest_type->entry_count < type->entry_count) {
+ const size_t type_alloc_size = sizeof(ThemeType)
+ + (type->entry_count * sizeof(ThemeEntry));
+ void* dest_data = malloc(type_alloc_size);
+ memset(dest_data, 0, type->entry_count * sizeof(ThemeEntry));
+
+ // Copy the existing destination type values if the type is resized
+ if (dest_type != nullptr) {
+ memcpy(dest_data, type, sizeof(ThemeType)
+ + (dest_type->entry_count * sizeof(ThemeEntry)));
+ }
+
+ dest_type.reset(reinterpret_cast<ThemeType *>(dest_data));
+ dest_type->entry_count = type->entry_count;
+ }
+
+ // Find the cookie of the value in the destination
+ auto value_dest_cookie = src_to_dest_asset_cookies.find(entry.cookie);
+ if (value_dest_cookie == src_to_dest_asset_cookies.end()) {
+ continue;
+ }
+
+ dest_type->entries[e].cookie = value_dest_cookie->second;
+ dest_type->entries[e].value.dataType = entry.value.dataType;
+ dest_type->entries[e].value.data = attribue_data;
+ dest_type->entries[e].type_spec_flags = entry.type_spec_flags;
+ }
+ }
+ }
+ }
+}
+
+void Theme::Dump() const {
+ base::ScopedLogSeverity _log(base::INFO);
+ LOG(INFO) << base::StringPrintf("Theme(this=%p, AssetManager2=%p)", this, asset_manager_);
+
+ for (int p = 0; p < packages_.size(); p++) {
+ auto& package = packages_[p];
+ if (package == nullptr) {
+ continue;
+ }
+
+ for (int t = 0; t < package->types.size(); t++) {
+ auto& type = package->types[t];
if (type == nullptr) {
- // The other theme doesn't have this type, clear ours.
- packages_[p]->types[t].reset();
continue;
}
- // Create a new type and update it to theirs.
- const size_t type_alloc_size = sizeof(ThemeType) + (type->entry_count * sizeof(ThemeEntry));
- void* copied_data = malloc(type_alloc_size);
- memcpy(copied_data, type, type_alloc_size);
- packages_[p]->types[t].reset(reinterpret_cast<ThemeType*>(copied_data));
+ for (int e = 0; e < type->entry_count; e++) {
+ auto& entry = type->entries[e];
+ if (entry.value.dataType == Res_value::TYPE_NULL &&
+ entry.value.data != Res_value::DATA_NULL_EMPTY) {
+ continue;
+ }
+
+ LOG(INFO) << base::StringPrintf(" entry(0x%08x)=(0x%08x) type=(0x%02x), cookie(%d)",
+ make_resid(p, t, e), entry.value.data,
+ entry.value.dataType, entry.cookie);
+ }
}
}
- return true;
}
} // namespace android
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index dc4a0a706bae..388548b174f9 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -6998,18 +6998,28 @@ status_t DynamicRefTable::lookupResourceId(uint32_t* resId) const {
}
status_t DynamicRefTable::lookupResourceValue(Res_value* value) const {
- uint8_t resolvedType;
-
- if (value->dataType == Res_value::TYPE_ATTRIBUTE
- || value->dataType == Res_value::TYPE_DYNAMIC_ATTRIBUTE) {
- resolvedType = Res_value::TYPE_ATTRIBUTE;
-
- } else if (value->dataType == Res_value::TYPE_REFERENCE
- || value->dataType == Res_value::TYPE_DYNAMIC_REFERENCE) {
- resolvedType = Res_value::TYPE_REFERENCE;
+ uint8_t resolvedType = Res_value::TYPE_REFERENCE;
+ switch (value->dataType) {
+ case Res_value::TYPE_ATTRIBUTE:
+ resolvedType = Res_value::TYPE_ATTRIBUTE;
+ // fallthrough
+ case Res_value::TYPE_REFERENCE:
+ // Only resolve non-dynamic references and attributes if the package is loaded as a
+ // library or if a shared library is attempting to retrieve its own resource
+ if (!(mAppAsLib || (Res_GETPACKAGE(value->data) + 1) == 0)) {
+ return NO_ERROR;
+ }
- } else {
- return NO_ERROR;
+ // If the package is loaded as shared library, the resource reference
+ // also need to be fixed.
+ break;
+ case Res_value::TYPE_DYNAMIC_ATTRIBUTE:
+ resolvedType = Res_value::TYPE_ATTRIBUTE;
+ // fallthrough
+ case Res_value::TYPE_DYNAMIC_REFERENCE:
+ break;
+ default:
+ return NO_ERROR;
}
status_t err = lookupResourceId(&value->data);
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index 2f0ee01639fe..5312b062473a 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -74,6 +74,8 @@ struct FindEntryResult;
// AssetManager2 is the main entry point for accessing assets and resources.
// AssetManager2 provides caching of resources retrieved via the underlying ApkAssets.
class AssetManager2 {
+ friend Theme;
+
public:
struct ResourceName {
const char* package = nullptr;
@@ -285,6 +287,9 @@ class AssetManager2 {
// been seen while traversing bag parents.
const ResolvedBag* GetBag(uint32_t resid, std::vector<uint32_t>& child_resids);
+ // Retrieve the assigned package id of the package if loaded into this AssetManager
+ uint8_t GetAssignedPackageId(const LoadedPackage* package);
+
// The ordered list of ApkAssets to search. These are not owned by the AssetManager, and must
// have a longer lifetime.
std::vector<const ApkAssets*> apk_assets_;
@@ -355,11 +360,14 @@ class Theme {
bool ApplyStyle(uint32_t resid, bool force = false);
// Sets this Theme to be a copy of `o` if `o` has the same AssetManager as this Theme.
- // Returns false if the AssetManagers of the Themes were not compatible.
- bool SetTo(const Theme& o);
+ // If `o` does not have the same AssetManager as this theme, only attributes from ApkAssets loaded
+ // into both AssetManagers will be copied to this theme.
+ void SetTo(const Theme& o);
void Clear();
+ void Dump() const;
+
inline const AssetManager2* GetAssetManager() const {
return asset_manager_;
}
diff --git a/libs/androidfw/tests/DynamicRefTable_test.cpp b/libs/androidfw/tests/DynamicRefTable_test.cpp
index df44e343b2b4..5acc46a3c0d9 100644
--- a/libs/androidfw/tests/DynamicRefTable_test.cpp
+++ b/libs/androidfw/tests/DynamicRefTable_test.cpp
@@ -40,6 +40,26 @@ TEST(DynamicRefTableTest, LookupSharedLibSelfReferences) {
EXPECT_EQ(value2.data, 0x02010000);
};
+TEST(DynamicRefTableTest, LookupSharedLibSelfAttributes) {
+ // Shared library
+ DynamicRefTable shared_table(0x03, /* appAsLib */ false);
+ shared_table.addMapping(0x00, 0x03);
+ Res_value value;
+ value.dataType = Res_value::TYPE_ATTRIBUTE;
+ value.data = 0x00010000;
+ ASSERT_EQ(shared_table.lookupResourceValue(&value), NO_ERROR);
+ EXPECT_EQ(value.data, 0x03010000);
+
+ // App loaded as a shared library
+ DynamicRefTable shared_app_table(0x04, /* appAsLib */ true);
+ shared_app_table.addMapping(0x7f, 0x04);
+ Res_value value2;
+ value2.dataType = Res_value::TYPE_ATTRIBUTE;
+ value2.data = 0x7f010000;
+ ASSERT_EQ(shared_app_table.lookupResourceValue(&value2), NO_ERROR);
+ EXPECT_EQ(value2.data, 0x04010000);
+};
+
TEST(DynamicRefTableTest, LookupDynamicReferences) {
// Shared library
DynamicRefTable shared_table(0x2, /* appAsLib */ false);
@@ -51,24 +71,46 @@ TEST(DynamicRefTableTest, LookupDynamicReferences) {
ASSERT_EQ(shared_table.lookupResourceValue(&value), NO_ERROR);
EXPECT_EQ(value.data, 0x05010000);
- // App loaded as a shared library
+ // Regular application
+ DynamicRefTable app_table(0x7f, /* appAsLib */ false);
+ app_table.addMapping(0x03, 0x05);
+ Res_value value3;
+ value3.dataType = Res_value::TYPE_DYNAMIC_REFERENCE;
+ value3.data = 0x03010000;
+ ASSERT_EQ(app_table.lookupResourceValue(&value3), NO_ERROR);
+ EXPECT_EQ(value3.data, 0x05010000);
+};
+
+TEST(DynamicRefTableTest, LookupDynamicAttributes) {
+// App loaded as a shared library
DynamicRefTable shared_app_table(0x2, /* appAsLib */ true);
shared_app_table.addMapping(0x03, 0x05);
shared_app_table.addMapping(0x7f, 0x2);
Res_value value2;
- value2.dataType = Res_value::TYPE_DYNAMIC_REFERENCE;
+ value2.dataType = Res_value::TYPE_DYNAMIC_ATTRIBUTE;
value2.data = 0x03010000;
ASSERT_EQ(shared_app_table.lookupResourceValue(&value2), NO_ERROR);
EXPECT_EQ(value2.data, 0x05010000);
+}
+TEST(DynamicRefTableTest, DoNotLookupNonDynamicReferences) {
// Regular application
DynamicRefTable app_table(0x7f, /* appAsLib */ false);
- app_table.addMapping(0x03, 0x05);
- Res_value value3;
- value3.dataType = Res_value::TYPE_REFERENCE;
- value3.data = 0x03010000;
- ASSERT_EQ(app_table.lookupResourceValue(&value3), NO_ERROR);
- EXPECT_EQ(value3.data, 0x05010000);
+ Res_value value;
+ value.dataType = Res_value::TYPE_REFERENCE;
+ value.data = 0x03010000;
+ ASSERT_EQ(app_table.lookupResourceValue(&value), NO_ERROR);
+ EXPECT_EQ(value.data, 0x03010000);
+};
+
+TEST(DynamicRefTableTest, DoNotLookupNonDynamicAttributes) {
+ // App with custom package id
+ DynamicRefTable custom_app_table(0x8f, /* appAsLib */ false);
+ Res_value value2;
+ value2.dataType = Res_value::TYPE_ATTRIBUTE;
+ value2.data = 0x03010000;
+ ASSERT_EQ(custom_app_table.lookupResourceValue(&value2), NO_ERROR);
+ EXPECT_EQ(value2.data, 0x03010000);
};
} // namespace android \ No newline at end of file
diff --git a/libs/androidfw/tests/Theme_test.cpp b/libs/androidfw/tests/Theme_test.cpp
index 55d53edf6a2b..2c39ceead123 100644
--- a/libs/androidfw/tests/Theme_test.cpp
+++ b/libs/androidfw/tests/Theme_test.cpp
@@ -21,12 +21,14 @@
#include "TestHelpers.h"
#include "androidfw/ResourceUtils.h"
#include "data/lib_one/R.h"
+#include "data/lib_two/R.h"
#include "data/libclient/R.h"
#include "data/styles/R.h"
#include "data/system/R.h"
namespace app = com::android::app;
namespace lib_one = com::android::lib_one;
+namespace lib_two = com::android::lib_two;
namespace libclient = com::android::libclient;
namespace android {
@@ -263,7 +265,7 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) {
ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleThree));
// Copy the theme to theme_one.
- ASSERT_TRUE(theme_one->SetTo(*theme_two));
+ theme_one->SetTo(*theme_two);
// Clear theme_two to make sure we test that there WAS a copy.
theme_two->Clear();
@@ -279,12 +281,14 @@ TEST_F(ThemeTest, CopyThemeSameAssetManager) {
EXPECT_EQ(static_cast<uint32_t>(ResTable_typeSpec::SPEC_PUBLIC), flags);
}
-TEST_F(ThemeTest, OnlyCopySystemThemeWhenAssetManagersDiffer) {
+TEST_F(ThemeTest, OnlyCopySameAssetsThemeWhenAssetManagersDiffer) {
AssetManager2 assetmanager_one;
- assetmanager_one.SetApkAssets({system_assets_.get(), style_assets_.get()});
+ assetmanager_one.SetApkAssets({system_assets_.get(), lib_one_assets_.get(), style_assets_.get(),
+ libclient_assets_.get()});
AssetManager2 assetmanager_two;
- assetmanager_two.SetApkAssets({system_assets_.get(), style_assets_.get()});
+ assetmanager_two.SetApkAssets({system_assets_.get(), lib_two_assets_.get(), lib_one_assets_.get(),
+ style_assets_.get()});
auto theme_one = assetmanager_one.NewTheme();
ASSERT_TRUE(theme_one->ApplyStyle(app::R::style::StyleOne));
@@ -292,17 +296,34 @@ TEST_F(ThemeTest, OnlyCopySystemThemeWhenAssetManagersDiffer) {
auto theme_two = assetmanager_two.NewTheme();
ASSERT_TRUE(theme_two->ApplyStyle(R::style::Theme_One));
ASSERT_TRUE(theme_two->ApplyStyle(app::R::style::StyleTwo));
+ ASSERT_TRUE(theme_two->ApplyStyle(fix_package_id(lib_one::R::style::Theme, 0x03),
+ false /*force*/));
+ ASSERT_TRUE(theme_two->ApplyStyle(fix_package_id(lib_two::R::style::Theme, 0x02),
+ false /*force*/));
- EXPECT_TRUE(theme_one->SetTo(*theme_two));
+ theme_one->SetTo(*theme_two);
Res_value value;
uint32_t flags;
- // No app resources.
- EXPECT_EQ(kInvalidCookie, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags));
+ // System resources (present in destination asset manager)
+ EXPECT_EQ(0, theme_one->GetAttribute(R::attr::foreground, &value, &flags));
+
+ // The cookie of the style asset is 3 in the source and 2 in the destination.
+ // Check that the cookie has been rewritten to the destination values
+ EXPECT_EQ(2, theme_one->GetAttribute(app::R::attr::attr_one, &value, &flags));
+
+ // The cookie of the lib_one asset is 2 in the source and 1 in the destination.
+ // The package id of the lib_one package is 0x03 in the source and 0x02 in the destination
+ // Check that the cookie and packages have been rewritten to the destination values
+ EXPECT_EQ(1, theme_one->GetAttribute(fix_package_id(lib_one::R::attr::attr1, 0x02), &value,
+ &flags));
+ EXPECT_EQ(1, theme_one->GetAttribute(fix_package_id(lib_one::R::attr::attr2, 0x02), &value,
+ &flags));
- // Only system.
- EXPECT_NE(kInvalidCookie, theme_one->GetAttribute(R::attr::foreground, &value, &flags));
+ // attr2 references an attribute in lib_one. Check that the resolution of the attribute value is
+ // correct after the value of attr2 had its package id rewritten to the destination package id
+ EXPECT_EQ(700, value.data);
}
} // namespace android
diff --git a/libs/androidfw/tests/data/lib_two/R.h b/libs/androidfw/tests/data/lib_two/R.h
index c04a9d3b4de0..92b9cc10e7a8 100644
--- a/libs/androidfw/tests/data/lib_two/R.h
+++ b/libs/androidfw/tests/data/lib_two/R.h
@@ -24,12 +24,24 @@ namespace android {
namespace lib_two {
struct R {
+ struct attr {
+ enum : uint32_t {
+ attr3 = 0x02010000, // default
+ };
+ };
+
struct string {
enum : uint32_t {
LibraryString = 0x02020000, // default
foo = 0x02020001, // default
};
};
+
+ struct style {
+ enum : uint32_t {
+ Theme = 0x02030000, // default
+ };
+ };
};
} // namespace lib_two
diff --git a/libs/androidfw/tests/data/lib_two/lib_two.apk b/libs/androidfw/tests/data/lib_two/lib_two.apk
index ad44f9c21e31..486c23000276 100644
--- a/libs/androidfw/tests/data/lib_two/lib_two.apk
+++ b/libs/androidfw/tests/data/lib_two/lib_two.apk
Binary files differ
diff --git a/libs/androidfw/tests/data/lib_two/res/values/values.xml b/libs/androidfw/tests/data/lib_two/res/values/values.xml
index f4eea2610cab..340d14c34c5d 100644
--- a/libs/androidfw/tests/data/lib_two/res/values/values.xml
+++ b/libs/androidfw/tests/data/lib_two/res/values/values.xml
@@ -15,9 +15,17 @@
-->
<resources>
+ <public type="attr" name="attr3" id="0x00010000" />
+ <attr name="attr3" format="integer" />
+
<public type="string" name="LibraryString" id="0x00020000" />
<string name="LibraryString">Hi from library two</string>
<public type="string" name="foo" id="0x00020001" />
<string name="foo">Foo from lib_two</string>
+
+ <public type="style" name="Theme" id="0x02030000" />
+ <style name="Theme">
+ <item name="com.android.lib_two:attr3">800</item>
+ </style>
</resources>
diff --git a/libs/hwui/hwui/Bitmap.cpp b/libs/hwui/hwui/Bitmap.cpp
index 753557c2e120..75a6e722dd8a 100644
--- a/libs/hwui/hwui/Bitmap.cpp
+++ b/libs/hwui/hwui/Bitmap.cpp
@@ -286,7 +286,6 @@ void Bitmap::setAlphaType(SkAlphaType alphaType) {
}
void Bitmap::getSkBitmap(SkBitmap* outBitmap) {
- outBitmap->setHasHardwareMipMap(mHasHardwareMipMap);
if (isHardware()) {
outBitmap->allocPixels(SkImageInfo::Make(info().width(), info().height(),
info().colorType(), info().alphaType(), nullptr));
@@ -321,7 +320,6 @@ sk_sp<SkImage> Bitmap::makeImage(sk_sp<SkColorFilter>* outputColorFilter) {
SkBitmap skiaBitmap;
skiaBitmap.setInfo(info(), rowBytes());
skiaBitmap.setPixelRef(sk_ref_sp(this), 0, 0);
- skiaBitmap.setHasHardwareMipMap(mHasHardwareMipMap);
// Note we don't cache in this case, because the raster image holds a pointer to this Bitmap
// internally and ~Bitmap won't be invoked.
// TODO: refactor Bitmap to not derive from SkPixelRef, which would allow caching here.
diff --git a/libs/hwui/hwui/MinikinSkia.cpp b/libs/hwui/hwui/MinikinSkia.cpp
index 2ca40b96c0ba..05dc340e9ef3 100644
--- a/libs/hwui/hwui/MinikinSkia.cpp
+++ b/libs/hwui/hwui/MinikinSkia.cpp
@@ -139,7 +139,7 @@ std::shared_ptr<minikin::MinikinFont> MinikinFontSkia::createFontWithVariation(
uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) {
uint32_t flags = paint->getFlags();
- SkPaint::Hinting hinting = paint->getHinting();
+ SkFontHinting hinting = (SkFontHinting)paint->getHinting();
// select only flags that might affect text layout
flags &= (SkPaint::kAntiAlias_Flag | SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag |
SkPaint::kSubpixelText_Flag | SkPaint::kEmbeddedBitmapText_Flag |
@@ -150,7 +150,7 @@ uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) {
void MinikinFontSkia::unpackPaintFlags(SkPaint* paint, uint32_t paintFlags) {
paint->setFlags(paintFlags & SkPaint::kAllFlags);
- paint->setHinting(static_cast<SkPaint::Hinting>(paintFlags >> 16));
+ paint->setHinting(static_cast<SkFontHinting>(paintFlags >> 16));
}
void MinikinFontSkia::populateSkPaint(SkPaint* paint, const MinikinFont* font,
diff --git a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
index 3fa73a4dadda..596b8aff6d4a 100644
--- a/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
+++ b/libs/hwui/pipeline/skia/SkiaRecordingCanvas.cpp
@@ -81,6 +81,11 @@ void SkiaRecordingCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x,
}
void SkiaRecordingCanvas::insertReorderBarrier(bool enableReorder) {
+ if (mCurrentBarrier && enableReorder) {
+ // Already in a re-order section, nothing to do
+ return;
+ }
+
if (nullptr != mCurrentBarrier) {
// finish off the existing chunk
SkDrawable* drawable =
@@ -89,9 +94,8 @@ void SkiaRecordingCanvas::insertReorderBarrier(bool enableReorder) {
drawDrawable(drawable);
}
if (enableReorder) {
- mCurrentBarrier = (StartReorderBarrierDrawable*)
- mDisplayList->allocateDrawable<StartReorderBarrierDrawable>(
- mDisplayList.get());
+ mCurrentBarrier = mDisplayList->allocateDrawable<StartReorderBarrierDrawable>(
+ mDisplayList.get());
drawDrawable(mCurrentBarrier);
}
}
diff --git a/libs/hwui/service/GraphicsStatsService.cpp b/libs/hwui/service/GraphicsStatsService.cpp
index fb1fde283066..3d50d2d7e59c 100644
--- a/libs/hwui/service/GraphicsStatsService.cpp
+++ b/libs/hwui/service/GraphicsStatsService.cpp
@@ -232,9 +232,9 @@ void dumpAsTextToFd(protos::GraphicsStatsProto* proto, int fd) {
return;
}
dprintf(fd, "\nPackage: %s", proto->package_name().c_str());
- dprintf(fd, "\nVersion: %" PRId64, proto->version_code());
- dprintf(fd, "\nStats since: %" PRId64 "ns", proto->stats_start());
- dprintf(fd, "\nStats end: %" PRId64 "ns", proto->stats_end());
+ dprintf(fd, "\nVersion: %lld", proto->version_code());
+ dprintf(fd, "\nStats since: %lldns", proto->stats_start());
+ dprintf(fd, "\nStats end: %lldns", proto->stats_end());
auto summary = proto->summary();
dprintf(fd, "\nTotal frames rendered: %d", summary.total_frames());
dprintf(fd, "\nJanky frames: %d (%.2f%%)", summary.janky_frames(),
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
index 0377426ab0c2..ad765592eb55 100644
--- a/libs/protoutil/include/android/util/ProtoOutputStream.h
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -97,7 +97,6 @@ public:
bool write(uint64_t fieldId, double val);
bool write(uint64_t fieldId, float val);
bool write(uint64_t fieldId, int val);
- bool write(uint64_t fieldId, long val);
bool write(uint64_t fieldId, long long val);
bool write(uint64_t fieldId, bool val);
bool write(uint64_t fieldId, std::string val);
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp
index 0c62d522bd80..ff3fad6055e1 100644
--- a/libs/protoutil/src/ProtoOutputStream.cpp
+++ b/libs/protoutil/src/ProtoOutputStream.cpp
@@ -116,34 +116,6 @@ ProtoOutputStream::write(uint64_t fieldId, int val)
}
bool
-ProtoOutputStream::write(uint64_t fieldId, long val)
-{
- if (mCompact) return false;
- const uint32_t id = (uint32_t)fieldId;
- switch (fieldId & FIELD_TYPE_MASK) {
- case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break;
- case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break;
- case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break;
- case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break;
- case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break;
- case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break;
- case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break;
- case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break;
- case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break;
- case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break;
- case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break;
- case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break;
- case FIELD_TYPE_ENUM: writeEnumImpl(id, (int)val); break;
- case FIELD_TYPE_BOOL: writeBoolImpl(id, val != 0); break;
- default:
- ALOGW("Field type %d is not supported when writing long val.",
- (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT));
- return false;
- }
- return true;
-}
-
-bool
ProtoOutputStream::write(uint64_t fieldId, long long val)
{
return internalWrite(fieldId, val, "long long");
diff --git a/media/java/android/media/AudioFormat.java b/media/java/android/media/AudioFormat.java
index b34f2700f520..3e3e65188761 100644
--- a/media/java/android/media/AudioFormat.java
+++ b/media/java/android/media/AudioFormat.java
@@ -273,6 +273,11 @@ public final class AudioFormat implements Parcelable {
* supports {@link #ENCODING_E_AC3} but not {@link #ENCODING_E_AC3_JOC}.
**/
public static final int ENCODING_E_AC3_JOC = 18;
+ /** Audio data format: Dolby MAT (Metadata-enhanced Audio Transmission)
+ * Dolby MAT bitstreams are used to transmit Dolby TrueHD, channel-based PCM, or PCM with
+ * metadata (object audio) over HDMI (e.g. Dolby Atmos content).
+ **/
+ public static final int ENCODING_DOLBY_MAT = 19;
/** @hide */
public static String toLogFriendlyEncoding(int enc) {
@@ -313,6 +318,8 @@ public final class AudioFormat implements Parcelable {
return "ENCODING_AC4";
case ENCODING_E_AC3_JOC:
return "ENCODING_E_AC3_JOC";
+ case ENCODING_DOLBY_MAT:
+ return "ENCODING_DOLBY_MAT";
default :
return "invalid encoding " + enc;
}
@@ -520,26 +527,27 @@ public final class AudioFormat implements Parcelable {
public static boolean isValidEncoding(int audioFormat)
{
switch (audioFormat) {
- case ENCODING_PCM_16BIT:
- case ENCODING_PCM_8BIT:
- case ENCODING_PCM_FLOAT:
- case ENCODING_AC3:
- case ENCODING_E_AC3:
- case ENCODING_DTS:
- case ENCODING_DTS_HD:
- case ENCODING_MP3:
- case ENCODING_AAC_LC:
- case ENCODING_AAC_HE_V1:
- case ENCODING_AAC_HE_V2:
- case ENCODING_IEC61937:
- case ENCODING_DOLBY_TRUEHD:
- case ENCODING_AAC_ELD:
- case ENCODING_AAC_XHE:
- case ENCODING_AC4:
- case ENCODING_E_AC3_JOC:
- return true;
- default:
- return false;
+ case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_8BIT:
+ case ENCODING_PCM_FLOAT:
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ case ENCODING_DTS:
+ case ENCODING_DTS_HD:
+ case ENCODING_MP3:
+ case ENCODING_AAC_LC:
+ case ENCODING_AAC_HE_V1:
+ case ENCODING_AAC_HE_V2:
+ case ENCODING_IEC61937:
+ case ENCODING_DOLBY_TRUEHD:
+ case ENCODING_AAC_ELD:
+ case ENCODING_AAC_XHE:
+ case ENCODING_AC4:
+ case ENCODING_E_AC3_JOC:
+ case ENCODING_DOLBY_MAT:
+ return true;
+ default:
+ return false;
}
}
@@ -547,26 +555,27 @@ public final class AudioFormat implements Parcelable {
public static boolean isPublicEncoding(int audioFormat)
{
switch (audioFormat) {
- case ENCODING_PCM_16BIT:
- case ENCODING_PCM_8BIT:
- case ENCODING_PCM_FLOAT:
- case ENCODING_AC3:
- case ENCODING_E_AC3:
- case ENCODING_DTS:
- case ENCODING_DTS_HD:
- case ENCODING_MP3:
- case ENCODING_AAC_LC:
- case ENCODING_AAC_HE_V1:
- case ENCODING_AAC_HE_V2:
- case ENCODING_IEC61937:
- case ENCODING_DOLBY_TRUEHD:
- case ENCODING_AAC_ELD:
- case ENCODING_AAC_XHE:
- case ENCODING_AC4:
- case ENCODING_E_AC3_JOC:
- return true;
- default:
- return false;
+ case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_8BIT:
+ case ENCODING_PCM_FLOAT:
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ case ENCODING_DTS:
+ case ENCODING_DTS_HD:
+ case ENCODING_MP3:
+ case ENCODING_AAC_LC:
+ case ENCODING_AAC_HE_V1:
+ case ENCODING_AAC_HE_V2:
+ case ENCODING_IEC61937:
+ case ENCODING_DOLBY_TRUEHD:
+ case ENCODING_AAC_ELD:
+ case ENCODING_AAC_XHE:
+ case ENCODING_AC4:
+ case ENCODING_E_AC3_JOC:
+ case ENCODING_DOLBY_MAT:
+ return true;
+ default:
+ return false;
}
}
@@ -575,29 +584,30 @@ public final class AudioFormat implements Parcelable {
public static boolean isEncodingLinearPcm(int audioFormat)
{
switch (audioFormat) {
- case ENCODING_PCM_16BIT:
- case ENCODING_PCM_8BIT:
- case ENCODING_PCM_FLOAT:
- case ENCODING_DEFAULT:
- return true;
- case ENCODING_AC3:
- case ENCODING_E_AC3:
- case ENCODING_DTS:
- case ENCODING_DTS_HD:
- case ENCODING_MP3:
- case ENCODING_AAC_LC:
- case ENCODING_AAC_HE_V1:
- case ENCODING_AAC_HE_V2:
- case ENCODING_IEC61937: // wrapped in PCM but compressed
- case ENCODING_DOLBY_TRUEHD:
- case ENCODING_AAC_ELD:
- case ENCODING_AAC_XHE:
- case ENCODING_AC4:
- case ENCODING_E_AC3_JOC:
- return false;
- case ENCODING_INVALID:
- default:
- throw new IllegalArgumentException("Bad audio format " + audioFormat);
+ case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_8BIT:
+ case ENCODING_PCM_FLOAT:
+ case ENCODING_DEFAULT:
+ return true;
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ case ENCODING_DTS:
+ case ENCODING_DTS_HD:
+ case ENCODING_MP3:
+ case ENCODING_AAC_LC:
+ case ENCODING_AAC_HE_V1:
+ case ENCODING_AAC_HE_V2:
+ case ENCODING_IEC61937: // wrapped in PCM but compressed
+ case ENCODING_DOLBY_TRUEHD:
+ case ENCODING_AAC_ELD:
+ case ENCODING_AAC_XHE:
+ case ENCODING_AC4:
+ case ENCODING_E_AC3_JOC:
+ case ENCODING_DOLBY_MAT:
+ return false;
+ case ENCODING_INVALID:
+ default:
+ throw new IllegalArgumentException("Bad audio format " + audioFormat);
}
}
@@ -605,29 +615,30 @@ public final class AudioFormat implements Parcelable {
public static boolean isEncodingLinearFrames(int audioFormat)
{
switch (audioFormat) {
- case ENCODING_PCM_16BIT:
- case ENCODING_PCM_8BIT:
- case ENCODING_PCM_FLOAT:
- case ENCODING_IEC61937: // same size as stereo PCM
- case ENCODING_DEFAULT:
- return true;
- case ENCODING_AC3:
- case ENCODING_E_AC3:
- case ENCODING_DTS:
- case ENCODING_DTS_HD:
- case ENCODING_MP3:
- case ENCODING_AAC_LC:
- case ENCODING_AAC_HE_V1:
- case ENCODING_AAC_HE_V2:
- case ENCODING_DOLBY_TRUEHD:
- case ENCODING_AAC_ELD:
- case ENCODING_AAC_XHE:
- case ENCODING_AC4:
- case ENCODING_E_AC3_JOC:
- return false;
- case ENCODING_INVALID:
- default:
- throw new IllegalArgumentException("Bad audio format " + audioFormat);
+ case ENCODING_PCM_16BIT:
+ case ENCODING_PCM_8BIT:
+ case ENCODING_PCM_FLOAT:
+ case ENCODING_IEC61937: // same size as stereo PCM
+ case ENCODING_DEFAULT:
+ return true;
+ case ENCODING_AC3:
+ case ENCODING_E_AC3:
+ case ENCODING_DTS:
+ case ENCODING_DTS_HD:
+ case ENCODING_MP3:
+ case ENCODING_AAC_LC:
+ case ENCODING_AAC_HE_V1:
+ case ENCODING_AAC_HE_V2:
+ case ENCODING_DOLBY_TRUEHD:
+ case ENCODING_AAC_ELD:
+ case ENCODING_AAC_XHE:
+ case ENCODING_AC4:
+ case ENCODING_E_AC3_JOC:
+ case ENCODING_DOLBY_MAT:
+ return false;
+ case ENCODING_INVALID:
+ default:
+ throw new IllegalArgumentException("Bad audio format " + audioFormat);
}
}
/**
@@ -867,6 +878,7 @@ public final class AudioFormat implements Parcelable {
case ENCODING_AAC_XHE:
case ENCODING_AC4:
case ENCODING_E_AC3_JOC:
+ case ENCODING_DOLBY_MAT:
mEncoding = encoding;
break;
case ENCODING_INVALID:
@@ -1083,7 +1095,8 @@ public final class AudioFormat implements Parcelable {
ENCODING_AAC_ELD,
ENCODING_AAC_XHE,
ENCODING_AC4,
- ENCODING_E_AC3_JOC }
+ ENCODING_E_AC3_JOC,
+ ENCODING_DOLBY_MAT }
)
@Retention(RetentionPolicy.SOURCE)
public @interface Encoding {}
@@ -1098,6 +1111,7 @@ public final class AudioFormat implements Parcelable {
ENCODING_DOLBY_TRUEHD,
ENCODING_AC4,
ENCODING_E_AC3_JOC,
+ ENCODING_DOLBY_MAT,
};
/** @hide */
@@ -1109,7 +1123,8 @@ public final class AudioFormat implements Parcelable {
ENCODING_AAC_LC,
ENCODING_DOLBY_TRUEHD,
ENCODING_AC4,
- ENCODING_E_AC3_JOC }
+ ENCODING_E_AC3_JOC,
+ ENCODING_DOLBY_MAT }
)
@Retention(RetentionPolicy.SOURCE)
public @interface SurroundSoundEncoding {}
@@ -1141,6 +1156,8 @@ public final class AudioFormat implements Parcelable {
return "Dolby AC-4";
case ENCODING_E_AC3_JOC:
return "Dolby Atmos in Dolby Digital Plus";
+ case ENCODING_DOLBY_MAT:
+ return "Dolby MAT";
default:
return "Unknown surround sound format";
}
diff --git a/media/java/android/media/MediaPlayer2.java b/media/java/android/media/MediaPlayer2.java
index b51caa5adb3b..74701920988c 100644
--- a/media/java/android/media/MediaPlayer2.java
+++ b/media/java/android/media/MediaPlayer2.java
@@ -23,9 +23,7 @@ import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.graphics.SurfaceTexture;
-import android.net.Uri;
import android.os.Handler;
-import android.os.Parcel;
import android.os.PersistableBundle;
import android.view.Surface;
import android.view.SurfaceHolder;
@@ -34,7 +32,6 @@ import dalvik.system.CloseGuard;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -241,47 +238,6 @@ public abstract class MediaPlayer2 implements AutoCloseable
return new MediaPlayer2Impl(context);
}
- private static final String[] decodeMediaPlayer2Uri(String location) {
- Uri uri = Uri.parse(location);
- if (!"mediaplayer2".equals(uri.getScheme())) {
- return new String[] {location};
- }
-
- List<String> uris = uri.getQueryParameters("uri");
- if (uris.isEmpty()) {
- return new String[] {location};
- }
-
- List<String> keys = uri.getQueryParameters("key");
- List<String> values = uri.getQueryParameters("value");
- if (keys.size() != values.size()) {
- return new String[] {uris.get(0)};
- }
-
- List<String> ls = new ArrayList();
- ls.add(uris.get(0));
- for (int i = 0; i < keys.size() ; i++) {
- ls.add(keys.get(i));
- ls.add(values.get(i));
- }
-
- return ls.toArray(new String[ls.size()]);
- }
-
- private static final String encodeMediaPlayer2Uri(String uri, String[] keys, String[] values) {
- Uri.Builder builder = new Uri.Builder();
- builder.scheme("mediaplayer2").path("/").appendQueryParameter("uri", uri);
- if (keys == null || values == null || keys.length != values.length) {
- return builder.build().toString();
- }
- for (int i = 0; i < keys.length ; i++) {
- builder
- .appendQueryParameter("key", keys[i])
- .appendQueryParameter("value", values[i]);
- }
- return builder.build().toString();
- }
-
/**
* @hide
*/
@@ -291,12 +247,6 @@ public abstract class MediaPlayer2 implements AutoCloseable
}
/**
- * Returns a {@link MediaPlayerBase} implementation which runs based on
- * this MediaPlayer2 instance.
- */
- public abstract MediaPlayerBase getMediaPlayerBase();
-
- /**
* Releases the resources held by this {@code MediaPlayer2} object.
*
* It is considered good practice to call this method when you're
@@ -342,8 +292,7 @@ public abstract class MediaPlayer2 implements AutoCloseable
* Starts or resumes playback. If playback had previously been paused,
* playback will continue from where it was paused. If playback had
* reached end of stream and been paused, or never started before,
- * playback will start at the beginning. If the source had not been
- * prepared, the player will prepare the source and play.
+ * playback will start at the beginning.
*
* @return a token which can be used to cancel the operation later with {@link #cancel}.
*/
@@ -404,9 +353,8 @@ public abstract class MediaPlayer2 implements AutoCloseable
/**
* Gets the current buffered media source position received through progressive downloading.
- * The received buffering percentage indicates how much of the content has been buffered
- * or played. For example a buffering update of 80 percent when half the content
- * has already been played indicates that the next 30 percent of the
+ * For example a buffering update of 8000 milliseconds when 5000 milliseconds of the content
+ * has already been played indicates that the next 3000 milliseconds of the
* content to play has been buffered.
*
* @return the current buffered media source position in milliseconds
@@ -416,7 +364,6 @@ public abstract class MediaPlayer2 implements AutoCloseable
/**
* MediaPlayer2 has not been prepared or just has been reset.
* In this state, MediaPlayer2 doesn't fetch data.
- * @hide
*/
public static final int PLAYER_STATE_IDLE = 1001;
@@ -424,26 +371,23 @@ public abstract class MediaPlayer2 implements AutoCloseable
* MediaPlayer2 has been just prepared.
* In this state, MediaPlayer2 just fetches data from media source,
* but doesn't actively render data.
- * @hide
*/
public static final int PLAYER_STATE_PREPARED = 1002;
/**
* MediaPlayer2 is paused.
- * In this state, MediaPlayer2 doesn't actively render data.
- * @hide
+ * In this state, MediaPlayer2 has allocated resources to construct playback
+ * pipeline, but it doesn't actively render data.
*/
public static final int PLAYER_STATE_PAUSED = 1003;
/**
* MediaPlayer2 is actively playing back data.
- * @hide
*/
public static final int PLAYER_STATE_PLAYING = 1004;
/**
* MediaPlayer2 has hit some fatal error and cannot continue playback.
- * @hide
*/
public static final int PLAYER_STATE_ERROR = 1005;
@@ -469,7 +413,7 @@ public abstract class MediaPlayer2 implements AutoCloseable
/**
* Sets the audio attributes for this MediaPlayer2.
* See {@link AudioAttributes} for how to build and configure an instance of this class.
- * You must call this method before {@link #prepare()} in order
+ * You must call this method before {@link #play()} and {@link #pause()} in order
* for the audio attributes to become effective thereafter.
* @param attributes a non-null set of audio attributes
* @return a token which can be used to cancel the operation later with {@link #cancel}.
@@ -547,7 +491,7 @@ public abstract class MediaPlayer2 implements AutoCloseable
public abstract Object setPlayerVolume(float volume);
/**
- * Returns the current volume of this player to this player.
+ * Returns the current volume of this player.
* Note that it does not take into account the associated stream volume.
* @return the player volume.
*/
@@ -561,24 +505,9 @@ public abstract class MediaPlayer2 implements AutoCloseable
}
/**
- * Create a request parcel which can be routed to the native media
- * player using {@link #invoke(Parcel, Parcel)}. The Parcel
- * returned has the proper InterfaceToken set. The caller should
- * not overwrite that token, i.e it can only append data to the
- * Parcel.
- *
- * @return A parcel suitable to hold a request for the native
- * player.
- * {@hide}
- */
- public Parcel newRequest() {
- return null;
- }
-
- /**
* Insert a task in the command queue to help the client to identify whether a batch
* of commands has been finished. When this command is processed, a notification
- * {@code EventCallback.onCommandLabelReached} will be fired with the
+ * {@link EventCallback#onCommandLabelReached onCommandLabelReached} will be fired with the
* given {@code label}.
*
* @see EventCallback#onCommandLabelReached
@@ -595,16 +524,13 @@ public abstract class MediaPlayer2 implements AutoCloseable
* portion of the media.
*
* Either a surface holder or surface must be set if a display or video sink
- * is needed. Not calling this method or {@link #setSurface(Surface)}
+ * is needed. Not calling this method or {@link #setSurface(Surface)}
* when playing back a video will result in only the audio track being played.
* A null surface holder or surface will result in only the audio track being
* played.
*
* @param sh the SurfaceHolder to use for video display
- * @throws IllegalStateException if the internal player engine has not been
- * initialized or has been released.
* @return a token which can be used to cancel the operation later with {@link #cancel}.
- * @hide
*/
public abstract Object setDisplay(SurfaceHolder sh);
@@ -624,56 +550,44 @@ public abstract class MediaPlayer2 implements AutoCloseable
*
* @param surface The {@link Surface} to be used for the video portion of
* the media.
- * @throws IllegalStateException if the internal player engine has not been
- * initialized or has been released.
* @return a token which can be used to cancel the operation later with {@link #cancel}.
*/
// This is an asynchronous call.
public abstract Object setSurface(Surface surface);
- /* Do not change these video scaling mode values below without updating
- * their counterparts in system/window.h! Please do not forget to update
- * {@link #isVideoScalingModeSupported} when new video scaling modes
- * are added.
- */
/**
- * Specifies a video scaling mode. The content is stretched to the
- * surface rendering area. When the surface has the same aspect ratio
- * as the content, the aspect ratio of the content is maintained;
- * otherwise, the aspect ratio of the content is not maintained when video
- * is being rendered.
- * There is no content cropping with this video scaling mode.
- */
- public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1;
-
- /**
- * Specifies a video scaling mode. The content is scaled, maintaining
- * its aspect ratio. The whole surface area is always used. When the
- * aspect ratio of the content is the same as the surface, no content
- * is cropped; otherwise, content is cropped to fit the surface.
- * @hide
+ * Set the low-level power management behavior for this MediaPlayer2. This
+ * can be used when the MediaPlayer2 is not playing through a SurfaceHolder
+ * set with {@link #setDisplay(SurfaceHolder)} and thus can use the
+ * high-level {@link #setScreenOnWhilePlaying(boolean)} feature.
+ *
+ * <p>This function has the MediaPlayer2 access the low-level power manager
+ * service to control the device's power usage while playing is occurring.
+ * The parameter is a combination of {@link android.os.PowerManager} wake flags.
+ * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
+ * permission.
+ * By default, no attempt is made to keep the device awake during playback.
+ *
+ * @param context the Context to use
+ * @param mode the power/wake mode to set
+ * @return a token which can be used to cancel the operation later with {@link #cancel}.
+ * @see android.os.PowerManager
*/
- public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
+ // This is an asynchronous call.
+ public abstract Object setWakeMode(Context context, int mode);
/**
- * Sets video scaling mode. To make the target video scaling mode
- * effective during playback, this method must be called after
- * data source is set. If not called, the default video
- * scaling mode is {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}.
- *
- * <p> The supported video scaling modes are:
- * <ul>
- * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}
- * </ul>
+ * Control whether we should use the attached SurfaceHolder to keep the
+ * screen on while video playback is occurring. This is the preferred
+ * method over {@link #setWakeMode} where possible, since it doesn't
+ * require that the application have permission for low-level wake lock
+ * access.
*
- * @param mode target video scaling mode. Must be one of the supported
- * video scaling modes; otherwise, IllegalArgumentException will be thrown.
+ * @param screenOn Supply true to keep the screen on, false to allow it to turn off.
* @return a token which can be used to cancel the operation later with {@link #cancel}.
- *
- * @see MediaPlayer2#VIDEO_SCALING_MODE_SCALE_TO_FIT
- * @hide
*/
- public abstract Object setVideoScalingMode(int mode);
+ // This is an asynchronous call.
+ public abstract Object setScreenOnWhilePlaying(boolean screenOn);
/**
* Cancels a pending command.
@@ -702,7 +616,7 @@ public abstract class MediaPlayer2 implements AutoCloseable
* @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
* does not correspond to a valid audio device.
*/
- // This is an asynchronous call.
+ // This is a synchronous call.
@Override
public abstract boolean setPreferredDevice(AudioDeviceInfo deviceInfo);
@@ -747,36 +661,6 @@ public abstract class MediaPlayer2 implements AutoCloseable
AudioRouting.OnRoutingChangedListener listener);
/**
- * Set the low-level power management behavior for this MediaPlayer2.
- *
- * <p>This function has the MediaPlayer2 access the low-level power manager
- * service to control the device's power usage while playing is occurring.
- * The parameter is a combination of {@link android.os.PowerManager} wake flags.
- * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
- * permission.
- * By default, no attempt is made to keep the device awake during playback.
- *
- * @param context the Context to use
- * @param mode the power/wake mode to set
- * @see android.os.PowerManager
- * @hide
- */
- public abstract void setWakeMode(Context context, int mode);
-
- /**
- * Control whether we should use the attached SurfaceHolder to keep the
- * screen on while video playback is occurring. This is the preferred
- * method over {@link #setWakeMode} where possible, since it doesn't
- * require that the application have permission for low-level wake lock
- * access.
- *
- * @param screenOn Supply true to keep the screen on, false to allow it
- * to turn off.
- * @hide
- */
- public abstract void setScreenOnWhilePlaying(boolean screenOn);
-
- /**
* Returns the width of the video.
*
* @return the width of the video, or 0 if there is no video,
@@ -1719,17 +1603,20 @@ public abstract class MediaPlayer2 implements AutoCloseable
*/
public static final int CALL_COMPLETED_SET_BUFFERING_PARAMS = 31;
- /** The player just completed a call {@link #setVideoScalingMode}.
+ /** The player just completed a call {@link #setDisplay}.
+ * @see EventCallback#onCallCompleted
+ */
+ public static final int CALL_COMPLETED_SET_DISPLAY = 33;
+
+ /** The player just completed a call {@link #setWakeMode}.
* @see EventCallback#onCallCompleted
- * @hide
*/
- public static final int CALL_COMPLETED_SET_VIDEO_SCALING_MODE = 32;
+ public static final int CALL_COMPLETED_SET_WAKE_MODE = 34;
- /** The player just completed a call {@link #setDisplay}.
+ /** The player just completed a call {@link #setScreenOnWhilePlaying}.
* @see EventCallback#onCallCompleted
- * @hide
*/
- public static final int CALL_COMPLETED_SET_DISPLAY = 33;
+ public static final int CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING = 35;
/**
* The start of the methods which have separate call complete callback.
@@ -1776,8 +1663,9 @@ public abstract class MediaPlayer2 implements AutoCloseable
CALL_COMPLETED_SKIP_TO_NEXT,
CALL_COMPLETED_CLEAR_NEXT_DATA_SOURCES,
CALL_COMPLETED_SET_BUFFERING_PARAMS,
- CALL_COMPLETED_SET_VIDEO_SCALING_MODE,
CALL_COMPLETED_SET_DISPLAY,
+ CALL_COMPLETED_SET_WAKE_MODE,
+ CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING,
CALL_COMPLETED_NOTIFY_WHEN_COMMAND_LABEL_REACHED,
CALL_COMPLETED_PREPARE_DRM,
})
diff --git a/media/java/android/media/MediaPlayer2Impl.java b/media/java/android/media/MediaPlayer2Impl.java
index ef8db1d4dcba..6697a4f9916c 100644
--- a/media/java/android/media/MediaPlayer2Impl.java
+++ b/media/java/android/media/MediaPlayer2Impl.java
@@ -19,11 +19,11 @@ package android.media;
import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.content.ContentProvider;
+import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
-import android.graphics.SurfaceTexture;
import android.graphics.Rect;
import android.media.MediaPlayer2Proto.PlayerMessage;
import android.media.MediaPlayer2Proto.Value;
@@ -34,8 +34,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.PersistableBundle;
import android.os.PowerManager;
-import android.os.SystemProperties;
-import android.provider.Settings;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Pair;
@@ -78,18 +76,22 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
native_init();
}
+ private static final int NEXT_SOURCE_STATE_ERROR = -1;
+ private static final int NEXT_SOURCE_STATE_INIT = 0;
+ private static final int NEXT_SOURCE_STATE_PREPARING = 1;
+ private static final int NEXT_SOURCE_STATE_PREPARED = 2;
+
private final static String TAG = "MediaPlayer2Impl";
private Context mContext;
- private long mNativeContext; // accessed by native methods
+ private long mNativeContext; // accessed by native methods
private long mNativeSurfaceTexture; // accessed by native methods
- private int mListenerContext; // accessed by native methods
+ private int mListenerContext; // accessed by native methods
private SurfaceHolder mSurfaceHolder;
private PowerManager.WakeLock mWakeLock = null;
private boolean mScreenOnWhilePlaying;
private boolean mStayAwake;
- private int mStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
private final Object mSrcLock = new Object();
//--- guarded by |mSrcLock| start
@@ -134,7 +136,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
/**
* Default constructor.
- * <p>When done with the MediaPlayer2Impl, you should call {@link #close()},
+ * <p>When done with the MediaPlayer2Impl, you should call {@link #close()},
* to free the resources. If not released, too many MediaPlayer2Impl instances may
* result in an exception.</p>
*/
@@ -152,45 +154,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
@Override
- public MediaPlayerBase getMediaPlayerBase() {
- return null;
- }
-
- /**
- * Releases the resources held by this {@code MediaPlayer2} object.
- *
- * It is considered good practice to call this method when you're
- * done using the MediaPlayer2. In particular, whenever an Activity
- * of an application is paused (its onPause() method is called),
- * or stopped (its onStop() method is called), this method should be
- * invoked to release the MediaPlayer2 object, unless the application
- * has a special need to keep the object around. In addition to
- * unnecessary resources (such as memory and instances of codecs)
- * being held, failure to call this method immediately if a
- * MediaPlayer2 object is no longer needed may also lead to
- * continuous battery consumption for mobile devices, and playback
- * failure for other applications if no multiple instances of the
- * same codec are supported on a device. Even if multiple instances
- * of the same codec are supported, some performance degradation
- * may be expected when unnecessary multiple instances are used
- * at the same time.
- *
- * {@code close()} may be safely called after a prior {@code close()}.
- * This class implements the Java {@code AutoCloseable} interface and
- * may be used with try-with-resources.
- */
- @Override
public void close() {
super.close();
release();
}
- /**
- * Starts or resumes playback. If playback had previously been paused,
- * playback will continue from where it was paused. If playback had
- * been stopped, or never started before, playback will start at the
- * beginning.
- */
@Override
public Object play() {
return addTask(new Task(CALL_COMPLETED_PLAY, false) {
@@ -204,14 +172,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private native void _start() throws IllegalStateException;
- /**
- * Prepares the player for playback, asynchronously.
- *
- * After setting the datasource and the display surface, you need to either
- * call prepare(). For streams, you should call prepare(),
- * which returns immediately, rather than blocking until enough data has been
- * buffered.
- */
@Override
public Object prepare() {
return addTask(new Task(CALL_COMPLETED_PREPARE, true) {
@@ -224,9 +184,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
public native void _prepare();
- /**
- * Pauses playback. Call play() to resume.
- */
@Override
public Object pause() {
return addTask(new Task(CALL_COMPLETED_PAUSE, false) {
@@ -241,11 +198,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private native void _pause() throws IllegalStateException;
- /**
- * Tries to play next data source if applicable.
- *
- * @throws IllegalStateException if it is called in an invalid state
- */
@Override
public Object skipToNext() {
return addTask(new Task(CALL_COMPLETED_SKIP_TO_NEXT, false) {
@@ -259,32 +211,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
});
}
- /**
- * Gets the current playback position.
- *
- * @return the current position in milliseconds
- */
@Override
public native long getCurrentPosition();
- /**
- * Gets the duration of the file.
- *
- * @return the duration in milliseconds, if no duration is available
- * (for example, if streaming live content), -1 is returned.
- */
@Override
public native long getDuration();
- /**
- * Gets the current buffered media source position received through progressive downloading.
- * The received buffering percentage indicates how much of the content has been buffered
- * or played. For example a buffering update of 80 percent when half the content
- * has already been played indicates that the next 30 percent of the
- * content to play has been buffered.
- *
- * @return the current buffered media source position in milliseconds
- */
@Override
public long getBufferedPosition() {
// Use cached buffered percent for now.
@@ -298,14 +230,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private native int native_getState();
- /**
- * Sets the audio attributes for this MediaPlayer2.
- * See {@link AudioAttributes} for how to build and configure an instance of this class.
- * You must call this method before {@link #prepare()} in order
- * for the audio attributes to become effective thereafter.
- * @param attributes a non-null set of audio attributes
- * @throws IllegalArgumentException if the attributes are null or invalid.
- */
@Override
public Object setAudioAttributes(@NonNull AudioAttributes attributes) {
return addTask(new Task(CALL_COMPLETED_SET_AUDIO_ATTRIBUTES, false) {
@@ -326,11 +250,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
return attributes;
}
- /**
- * Sets the data source as described by a DataSourceDesc.
- *
- * @param dsd the descriptor of data source you want to play
- */
@Override
public Object setDataSource(@NonNull DataSourceDesc dsd) {
return addTask(new Task(CALL_COMPLETED_SET_DATA_SOURCE, false) {
@@ -351,12 +270,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
});
}
- /**
- * Sets a single data source as described by a DataSourceDesc which will be played
- * after current data source is finished.
- *
- * @param dsd the descriptor of data source you want to play after current one
- */
@Override
public Object setNextDataSource(@NonNull DataSourceDesc dsd) {
return addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCE, false) {
@@ -374,11 +287,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
});
}
- /**
- * Sets a list of data sources to be played sequentially after current data source is done.
- *
- * @param dsds the list of data sources you want to play after current one
- */
@Override
public Object setNextDataSources(@NonNull List<DataSourceDesc> dsds) {
return addTask(new Task(CALL_COMPLETED_SET_NEXT_DATA_SOURCES, false) {
@@ -428,16 +336,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
- /**
- * Configures the player to loop on the current data source.
- * @param loop true if the current data source is meant to loop.
- */
@Override
public Object loopCurrent(boolean loop) {
return addTask(new Task(CALL_COMPLETED_LOOP_CURRENT, false) {
@Override
void process() {
- // TODO: set the looping mode, send notification
setLooping(loop);
}
});
@@ -445,57 +348,29 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private native void setLooping(boolean looping);
- /**
- * Sets the volume of the audio of the media to play, expressed as a linear multiplier
- * on the audio samples.
- * Note that this volume is specific to the player, and is separate from stream volume
- * used across the platform.<br>
- * A value of 0.0f indicates muting, a value of 1.0f is the nominal unattenuated and unamplified
- * gain. See {@link #getMaxPlayerVolume()} for the volume range supported by this player.
- * @param volume a value between 0.0f and {@link #getMaxPlayerVolume()}.
- */
@Override
public Object setPlayerVolume(float volume) {
return addTask(new Task(CALL_COMPLETED_SET_PLAYER_VOLUME, false) {
@Override
void process() {
mVolume = volume;
- _setVolume(volume);
+ native_setVolume(volume);
}
});
}
- private native void _setVolume(float volume);
+ private native void native_setVolume(float volume);
- /**
- * Returns the current volume of this player to this player.
- * Note that it does not take into account the associated stream volume.
- * @return the player volume.
- */
@Override
public float getPlayerVolume() {
return mVolume;
}
- /**
- * @return the maximum volume that can be used in {@link #setPlayerVolume(float)}.
- */
@Override
public float getMaxPlayerVolume() {
return 1.0f;
}
- private static final int NEXT_SOURCE_STATE_ERROR = -1;
- private static final int NEXT_SOURCE_STATE_INIT = 0;
- private static final int NEXT_SOURCE_STATE_PREPARING = 1;
- private static final int NEXT_SOURCE_STATE_PREPARED = 2;
-
- /*
- * Update the MediaPlayer2Impl SurfaceTexture.
- * Call after setting a new display surface.
- */
- private native void _setVideoSurface(Surface surface);
-
/* Do not change these values (starting with INVOKE_ID) without updating
* their counterparts in include/media/mediaplayer2.h!
*/
@@ -504,7 +379,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private static final int INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3;
private static final int INVOKE_ID_SELECT_TRACK = 4;
private static final int INVOKE_ID_DESELECT_TRACK = 5;
- private static final int INVOKE_ID_SET_VIDEO_SCALE_MODE = 6;
private static final int INVOKE_ID_GET_SELECTED_TRACK = 7;
/**
@@ -518,7 +392,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
* native player.
*/
private PlayerMessage invoke(PlayerMessage msg) {
- byte[] ret = _invoke(msg.toByteArray());
+ byte[] ret = native_invoke(msg.toByteArray());
if (ret == null) {
return null;
}
@@ -529,7 +403,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
- private native byte[] _invoke(byte[] request);
+ private native byte[] native_invoke(byte[] request);
@Override
public Object notifyWhenCommandLabelReached(Object label) {
@@ -559,7 +433,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
} else {
surface = null;
}
- _setVideoSurface(surface);
+ native_setVideoSurface(surface);
updateSurfaceScreenOn();
}
});
@@ -574,49 +448,13 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for Surface");
}
mSurfaceHolder = null;
- _setVideoSurface(surface);
+ native_setVideoSurface(surface);
updateSurfaceScreenOn();
}
});
}
- /**
- * Sets video scaling mode. To make the target video scaling mode
- * effective during playback, this method must be called after
- * data source is set. If not called, the default video
- * scaling mode is {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}.
- *
- * <p> The supported video scaling modes are:
- * <ul>
- * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}
- * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
- * </ul>
- *
- * @param mode target video scaling mode. Must be one of the supported
- * video scaling modes; otherwise, IllegalArgumentException will be thrown.
- *
- * @see MediaPlayer2#VIDEO_SCALING_MODE_SCALE_TO_FIT
- * @see MediaPlayer2#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
- * @hide
- */
- @Override
- public Object setVideoScalingMode(int mode) {
- return addTask(new Task(CALL_COMPLETED_SET_VIDEO_SCALING_MODE, false) {
- @Override
- void process() {
- if (!isVideoScalingModeSupported(mode)) {
- final String msg = "Scaling mode " + mode + " is not supported";
- throw new IllegalArgumentException(msg);
- }
- PlayerMessage request = PlayerMessage.newBuilder()
- .addValues(Value.newBuilder()
- .setInt32Value(INVOKE_ID_SET_VIDEO_SCALE_MODE))
- .addValues(Value.newBuilder().setInt32Value(mode))
- .build();
- invoke(request);
- }
- });
- }
+ private native void native_setVideoSurface(Surface surface);
@Override
public boolean cancelCommand(Object token) {
@@ -632,26 +470,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
- private Object addTask(Task task) {
- synchronized (mTaskLock) {
- mPendingTasks.add(task);
- processPendingTask_l();
- }
- return task;
- }
-
- @GuardedBy("mTaskLock")
- private void processPendingTask_l() {
- if (mCurrentTask != null) {
- return;
- }
- if (!mPendingTasks.isEmpty()) {
- Task task = mPendingTasks.remove(0);
- mCurrentTask = task;
- mTaskHandler.post(task);
- }
- }
-
private void handleDataSource(boolean isCurrent, @NonNull DataSourceDesc dsd, long srcId)
throws IOException {
checkArgument(dsd != null, "the DataSourceDesc cannot be null");
@@ -875,9 +693,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
boolean isCurrent, long srcId, Media2DataSource dataSource,
long startPos, long endPos);
- /**
- * @return true if there is a next data source, false otherwise.
- */
+ // return true if there is a next data source, false otherwise.
// This function should be always called on |mHandlerThread|.
private boolean prepareNextDataSource() {
if (Looper.myLooper() != mHandlerThread.getLooper()) {
@@ -975,30 +791,11 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private native void nativePlayNextDataSource(long srcId);
-
- private int getAudioStreamType() {
- if (mStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
- mStreamType = _getAudioStreamType();
- }
- return mStreamType;
- }
-
- private native int _getAudioStreamType() throws IllegalStateException;
-
-
//--------------------------------------------------------------------------
// Explicit Routing
//--------------------
private AudioDeviceInfo mPreferredDevice = null;
- /**
- * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
- * the output from this MediaPlayer2.
- * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink or source.
- * If deviceInfo is null, default routing is restored.
- * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
- * does not correspond to a valid audio device.
- */
@Override
public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
if (deviceInfo != null && !deviceInfo.isSink()) {
@@ -1014,10 +811,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
return status;
}
- /**
- * Returns the selected output specified by {@link #setPreferredDevice}. Note that this
- * is not guaranteed to correspond to the actual device being used for playback.
- */
@Override
public AudioDeviceInfo getPreferredDevice() {
synchronized (this) {
@@ -1025,12 +818,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
- /**
- * Returns an {@link AudioDeviceInfo} identifying the current routing of this MediaPlayer2
- * Note: The query is only valid if the MediaPlayer2 is currently playing.
- * If the player is not playing, the returned device can be null or correspond to previously
- * selected device when the player was last active.
- */
@Override
public AudioDeviceInfo getRoutedDevice() {
int deviceId = native_getRoutedDeviceId();
@@ -1047,9 +834,7 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
return null;
}
- /*
- * Call BEFORE adding a routing callback handler or AFTER removing a routing callback handler.
- */
+ // Call BEFORE adding a routing callback handler or AFTER removing a routing callback handler.
@GuardedBy("mRoutingChangeListeners")
private void enableNativeRoutingCallbacksLocked(boolean enabled) {
if (mRoutingChangeListeners.size() == 0) {
@@ -1057,23 +842,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
- /**
- * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
- * {@link #addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, Handler)}
- * by an app to receive (re)routing notifications.
- */
+ // The list of AudioRouting.OnRoutingChangedListener interfaces added with
+ // addOnRoutingChangedListener by an app to receive (re)routing notifications.
@GuardedBy("mRoutingChangeListeners")
private ArrayMap<AudioRouting.OnRoutingChangedListener,
NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
- /**
- * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
- * changes on this MediaPlayer2.
- * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
- * notifications of rerouting events.
- * @param handler Specifies the {@link Handler} object for the thread on which to execute
- * the callback. If <code>null</code>, the handler on the main looper will be used.
- */
@Override
public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
Handler handler) {
@@ -1087,12 +861,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
- /**
- * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
- * to receive rerouting notifications.
- * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
- * to remove.
- */
@Override
public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
synchronized (mRoutingChangeListeners) {
@@ -1107,70 +875,59 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private native final int native_getRoutedDeviceId();
private native final void native_enableDeviceCallback(boolean enabled);
- /**
- * Set the low-level power management behavior for this MediaPlayer2. This
- * can be used when the MediaPlayer2 is not playing through a SurfaceHolder
- * set with {@link #setDisplay(SurfaceHolder)} and thus can use the
- * high-level {@link #setScreenOnWhilePlaying(boolean)} feature.
- *
- * <p>This function has the MediaPlayer2 access the low-level power manager
- * service to control the device's power usage while playing is occurring.
- * The parameter is a combination of {@link android.os.PowerManager} wake flags.
- * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
- * permission.
- * By default, no attempt is made to keep the device awake during playback.
- *
- * @param context the Context to use
- * @param mode the power/wake mode to set
- * @see android.os.PowerManager
- * @hide
- */
@Override
- public void setWakeMode(Context context, int mode) {
- boolean washeld = false;
+ public Object setWakeMode(Context context, int mode) {
+ return addTask(new Task(CALL_COMPLETED_SET_WAKE_MODE, false) {
+ @Override
+ void process() {
+ boolean washeld = false;
- /* Disable persistant wakelocks in media player based on property */
- if (SystemProperties.getBoolean("audio.offload.ignore_setawake", false) == true) {
- Log.w(TAG, "IGNORING setWakeMode " + mode);
- return;
- }
+ if (mWakeLock != null) {
+ if (mWakeLock.isHeld()) {
+ washeld = true;
+ mWakeLock.release();
+ }
+ mWakeLock = null;
+ }
- if (mWakeLock != null) {
- if (mWakeLock.isHeld()) {
- washeld = true;
- mWakeLock.release();
+ PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+ ActivityManager am =
+ (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
+ List<RunningAppProcessInfo> runningAppsProcInfo = am.getRunningAppProcesses();
+ int pid = android.os.Process.myPid();
+ String name = "pid " + String.valueOf(pid);
+ if (runningAppsProcInfo != null) {
+ for (RunningAppProcessInfo procInfo : runningAppsProcInfo) {
+ if (procInfo.pid == pid) {
+ name = procInfo.processName;
+ break;
+ }
+ }
+ }
+ mWakeLock = pm.newWakeLock(mode | PowerManager.ON_AFTER_RELEASE, name);
+ mWakeLock.setReferenceCounted(false);
+ if (washeld) {
+ mWakeLock.acquire();
+ }
}
- mWakeLock = null;
- }
-
- PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
- mWakeLock = pm.newWakeLock(mode|PowerManager.ON_AFTER_RELEASE, MediaPlayer2Impl.class.getName());
- mWakeLock.setReferenceCounted(false);
- if (washeld) {
- mWakeLock.acquire();
- }
+ });
}
- /**
- * Control whether we should use the attached SurfaceHolder to keep the
- * screen on while video playback is occurring. This is the preferred
- * method over {@link #setWakeMode} where possible, since it doesn't
- * require that the application have permission for low-level wake lock
- * access.
- *
- * @param screenOn Supply true to keep the screen on, false to allow it
- * to turn off.
- * @hide
- */
@Override
- public void setScreenOnWhilePlaying(boolean screenOn) {
- if (mScreenOnWhilePlaying != screenOn) {
- if (screenOn && mSurfaceHolder == null) {
- Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder");
+ public Object setScreenOnWhilePlaying(boolean screenOn) {
+ return addTask(new Task(CALL_COMPLETED_SET_SCREEN_ON_WHILE_PLAYING, false) {
+ @Override
+ void process() {
+ if (mScreenOnWhilePlaying != screenOn) {
+ if (screenOn && mSurfaceHolder == null) {
+ Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective"
+ + " without a SurfaceHolder");
+ }
+ mScreenOnWhilePlaying = screenOn;
+ updateSurfaceScreenOn();
+ }
}
- mScreenOnWhilePlaying = screenOn;
- updateSurfaceScreenOn();
- }
+ });
}
private void stayAwake(boolean awake) {
@@ -1191,42 +948,12 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
- /**
- * Returns the width of the video.
- *
- * @return the width of the video, or 0 if there is no video,
- * no display surface was set, or the width has not been determined
- * yet. The {@code EventCallback} can be registered via
- * {@link #setEventCallback(Executor, EventCallback)} to provide a
- * notification {@code EventCallback.onVideoSizeChanged} when the width
- * is available.
- */
@Override
public native int getVideoWidth();
- /**
- * Returns the height of the video.
- *
- * @return the height of the video, or 0 if there is no video,
- * no display surface was set, or the height has not been determined
- * yet. The {@code EventCallback} can be registered via
- * {@link #setEventCallback(Executor, EventCallback)} to provide a
- * notification {@code EventCallback.onVideoSizeChanged} when the height
- * is available.
- */
@Override
public native int getVideoHeight();
- /**
- * Return Metrics data about the current player.
- *
- * @return a {@link PersistableBundle} containing the set of attributes and values
- * available for the media being handled by this instance of MediaPlayer2
- * The attributes are descibed in {@link MetricsConstants}.
- *
- * Additional vendor-specific fields may also be present in
- * the return value.
- */
@Override
public PersistableBundle getMetrics() {
PersistableBundle bundle = native_getMetrics();
@@ -1235,27 +962,9 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
private native PersistableBundle native_getMetrics();
- /**
- * Checks whether the MediaPlayer2 is playing.
- *
- * @return true if currently playing, false otherwise
- * @throws IllegalStateException if the internal player engine has not been
- * initialized or has been released.
- * @hide
- */
@Override
public native boolean isPlaying();
- /**
- * Gets the current buffering management params used by the source component.
- * Calling it only after {@code setDataSource} has been called.
- * Each type of data source might have different set of default params.
- *
- * @return the current buffering management params used by the source component.
- * @throws IllegalStateException if the internal player engine has not been
- * initialized, or {@code setDataSource} has not been called.
- * @hide
- */
@Override
@NonNull
public native BufferingParams getBufferingParams();
@@ -3388,13 +3097,6 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
// Modular DRM end
- /*
- * Test whether a given video scaling mode is supported.
- */
- private boolean isVideoScalingModeSupported(int mode) {
- return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT ||
- mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
- }
private static class TimedTextUtil {
// These keys must be in sync with the keys in TextDescription2.h
@@ -3450,6 +3152,26 @@ public final class MediaPlayer2Impl extends MediaPlayer2 {
}
}
+ private Object addTask(Task task) {
+ synchronized (mTaskLock) {
+ mPendingTasks.add(task);
+ processPendingTask_l();
+ }
+ return task;
+ }
+
+ @GuardedBy("mTaskLock")
+ private void processPendingTask_l() {
+ if (mCurrentTask != null) {
+ return;
+ }
+ if (!mPendingTasks.isEmpty()) {
+ Task task = mPendingTasks.remove(0);
+ mCurrentTask = task;
+ mTaskHandler.post(task);
+ }
+ }
+
private abstract class Task implements Runnable {
private final int mMediaCallType;
private final boolean mNeedToWaitForEventToComplete;
diff --git a/media/jni/android_media_MediaDrm.cpp b/media/jni/android_media_MediaDrm.cpp
index 7cf8828c0623..8637adae3aa5 100644
--- a/media/jni/android_media_MediaDrm.cpp
+++ b/media/jni/android_media_MediaDrm.cpp
@@ -543,7 +543,7 @@ static String8 JStringToString8(JNIEnv *env, jstring const &jstr) {
import jav.util.Iterator;
HashMap<k, v> hm;
- Set<Entry<k, v> > s = hm.entrySet();
+ Set<Entry<k, v>> s = hm.entrySet();
Iterator i = s.iterator();
Entry e = s.next();
*/
@@ -613,10 +613,10 @@ static jobject KeyedVectorToHashMap (JNIEnv *env, KeyedVector<String8, String8>
}
static jobject ListOfVectorsToArrayListOfByteArray(JNIEnv *env,
- List<Vector<uint8_t> > list) {
+ List<Vector<uint8_t>> list) {
jclass clazz = gFields.arraylistClassId;
jobject arrayList = env->NewObject(clazz, gFields.arraylist.init);
- List<Vector<uint8_t> >::iterator iter = list.begin();
+ List<Vector<uint8_t>>::iterator iter = list.begin();
while (iter != list.end()) {
jbyteArray byteArray = VectorToJByteArray(env, *iter);
env->CallBooleanMethod(arrayList, gFields.arraylist.add, byteArray);
@@ -1216,7 +1216,7 @@ static jobject android_media_MediaDrm_getSecureStops(
return NULL;
}
- List<Vector<uint8_t> > secureStops;
+ List<Vector<uint8_t>> secureStops;
status_t err = drm->getSecureStops(secureStops);
@@ -1237,7 +1237,7 @@ static jobject android_media_MediaDrm_getSecureStopIds(
return NULL;
}
- List<Vector<uint8_t> > secureStopIds;
+ List<Vector<uint8_t>> secureStopIds;
status_t err = drm->getSecureStopIds(secureStopIds);
diff --git a/media/jni/android_media_MediaPlayer2.cpp b/media/jni/android_media_MediaPlayer2.cpp
index 61c28eddfeac..f60e7dae4b26 100644
--- a/media/jni/android_media_MediaPlayer2.cpp
+++ b/media/jni/android_media_MediaPlayer2.cpp
@@ -893,20 +893,6 @@ android_media_MediaPlayer2_reset(JNIEnv *env, jobject thiz)
process_media_player_call( env, thiz, mp->reset(), NULL, NULL );
}
-static jint
-android_media_MediaPlayer2_getAudioStreamType(JNIEnv *env, jobject thiz)
-{
- sp<MediaPlayer2> mp = getMediaPlayer(env, thiz);
- if (mp == NULL ) {
- jniThrowException(env, "java/lang/IllegalStateException", NULL);
- return 0;
- }
- audio_stream_type_t streamtype;
- process_media_player_call( env, thiz, mp->getAudioStreamType(&streamtype), NULL, NULL );
- ALOGV("getAudioStreamType: %d (streamtype)", streamtype);
- return (jint) streamtype;
-}
-
static jboolean
android_media_MediaPlayer2_setParameter(JNIEnv *env, jobject thiz, jint key, jobject)
{
@@ -1467,7 +1453,7 @@ static const JNINativeMethod gMethods[] = {
(void *)android_media_MediaPlayer2_handleDataSourceCallback
},
{"nativePlayNextDataSource", "(J)V", (void *)android_media_MediaPlayer2_playNextDataSource},
- {"_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer2_setVideoSurface},
+ {"native_setVideoSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaPlayer2_setVideoSurface},
{"getBufferingParams", "()Landroid/media/BufferingParams;", (void *)android_media_MediaPlayer2_getBufferingParams},
{"_setBufferingParams", "(Landroid/media/BufferingParams;)V", (void *)android_media_MediaPlayer2_setBufferingParams},
{"_prepare", "()V", (void *)android_media_MediaPlayer2_prepare},
@@ -1487,13 +1473,12 @@ static const JNINativeMethod gMethods[] = {
{"getDuration", "()J", (void *)android_media_MediaPlayer2_getDuration},
{"_release", "()V", (void *)android_media_MediaPlayer2_release},
{"_reset", "()V", (void *)android_media_MediaPlayer2_reset},
- {"_getAudioStreamType", "()I", (void *)android_media_MediaPlayer2_getAudioStreamType},
{"setParameter", "(ILjava/lang/Object;)Z", (void *)android_media_MediaPlayer2_setParameter},
{"getParameter", "(I)Ljava/lang/Object;", (void *)android_media_MediaPlayer2_getParameter},
{"setLooping", "(Z)V", (void *)android_media_MediaPlayer2_setLooping},
{"isLooping", "()Z", (void *)android_media_MediaPlayer2_isLooping},
- {"_setVolume", "(F)V", (void *)android_media_MediaPlayer2_setVolume},
- {"_invoke", "([B)[B", (void *)android_media_MediaPlayer2_invoke},
+ {"native_setVolume", "(F)V", (void *)android_media_MediaPlayer2_setVolume},
+ {"native_invoke", "([B)[B", (void *)android_media_MediaPlayer2_invoke},
{"native_init", "()V", (void *)android_media_MediaPlayer2_native_init},
{"native_setup", "(Ljava/lang/Object;)V", (void *)android_media_MediaPlayer2_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaPlayer2_native_finalize},
diff --git a/packages/CarSystemUI/Android.bp b/packages/CarSystemUI/Android.bp
index 1b1bf8d4b34a..8f13497b2673 100644
--- a/packages/CarSystemUI/Android.bp
+++ b/packages/CarSystemUI/Android.bp
@@ -30,7 +30,7 @@ android_app {
"SystemUIPluginLib",
"SystemUISharedLib",
"SettingsLib",
- "android.car.user",
+ "android.car.userlib",
"androidx.car_car",
"androidx.legacy_legacy-support-v4",
"androidx.recyclerview_recyclerview",
diff --git a/packages/ExtServices/src/android/ext/services/notification/Assistant.java b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
index ddc00e37b8dc..11366848874a 100644
--- a/packages/ExtServices/src/android/ext/services/notification/Assistant.java
+++ b/packages/ExtServices/src/android/ext/services/notification/Assistant.java
@@ -236,13 +236,13 @@ public class Assistant extends NotificationAssistantService {
@NonNull ArrayList<CharSequence> smartReplies) {
Bundle signals = new Bundle();
+ if (!smartActions.isEmpty()) {
+ signals.putParcelableArrayList(Adjustment.KEY_SMART_ACTIONS, smartActions);
+ }
+ if (!smartReplies.isEmpty()) {
+ signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies);
+ }
if (AUTO_DEMOTE_NOTIFICATIONS) {
- if (!smartActions.isEmpty()) {
- signals.putParcelableArrayList(Adjustment.KEY_SMART_ACTIONS, smartActions);
- }
- if (!smartReplies.isEmpty()) {
- signals.putCharSequenceArrayList(Adjustment.KEY_SMART_REPLIES, smartReplies);
- }
if (mNotificationCategorizer.shouldSilence(entry)) {
final int importance = entry.getImportance() < IMPORTANCE_LOW
? entry.getImportance() : IMPORTANCE_LOW;
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java
index 1eb423e53267..74c7b5809337 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstalledReceiver.java
@@ -20,6 +20,7 @@ import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
+import android.provider.Settings;
import android.util.Log;
/**
@@ -29,11 +30,11 @@ public class PackageInstalledReceiver extends BroadcastReceiver {
private static final String TAG = PackageInstalledReceiver.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final boolean APP_INSTALLED_NOTIFICATION_ENABLED = false;
@Override
public void onReceive(Context context, Intent intent) {
- if (!APP_INSTALLED_NOTIFICATION_ENABLED) {
+ if (Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED, 0) == 0) {
return;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
index 2d43762b6863..b46c288bdb00 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProtoDumpUtil.java
@@ -1120,6 +1120,9 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.Global.SHOW_FIRST_CRASH_DIALOG,
GlobalSettingsProto.SHOW_FIRST_CRASH_DIALOG);
+ dumpSetting(s, p,
+ Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED,
+ GlobalSettingsProto.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED);
// Settings.Global.SHOW_PROCESSES intentionally excluded since it's deprecated.
dumpSetting(s, p,
Settings.Global.SHOW_RESTART_IN_CRASH_DIALOG,
@@ -1127,6 +1130,9 @@ class SettingsProtoDumpUtil {
dumpSetting(s, p,
Settings.Global.SHOW_MUTE_IN_CRASH_DIALOG,
GlobalSettingsProto.SHOW_MUTE_IN_CRASH_DIALOG);
+ dumpSetting(s, p,
+ Settings.Global.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED,
+ GlobalSettingsProto.SHOW_NEW_APP_INSTALLED_NOTIFICATION_ENABLED);
final long smartSelectToken = p.start(GlobalSettingsProto.SMART_SELECTION);
dumpSetting(s, p,
diff --git a/packages/SimAppDialog/res/drawable/illo_sim_app_dialog.xml b/packages/SimAppDialog/res/drawable/illo_sim_app_dialog.xml
new file mode 100644
index 000000000000..8dd88b4bc0b0
--- /dev/null
+++ b/packages/SimAppDialog/res/drawable/illo_sim_app_dialog.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<!-- Empty drawable as this is not displayed by default. Must be provided by resource overlay. -->
+<shape xmlns:android="http://schemas.android.com/apk/res/android" />
diff --git a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
index 5bcce4d108a8..12f9bb6b13ea 100644
--- a/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
+++ b/packages/SimAppDialog/res/layout/install_carrier_app_activity.xml
@@ -37,6 +37,22 @@
android:text="@string/install_carrier_app_description_default"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
- </LinearLayout>
+
+ <com.android.setupwizardlib.view.FillContentLayout
+ android:id="@+id/illo_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:visibility="gone">
+
+ <ImageView
+ android:src="@drawable/illo_sim_app_dialog"
+ style="@style/SuwContentIllustration"
+ android:contentDescription="@string/install_carrier_app_image_content_description"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"/>
+
+ </com.android.setupwizardlib.view.FillContentLayout>
+</LinearLayout>
</com.android.setupwizardlib.GlifLayout>
diff --git a/packages/SimAppDialog/res/values/bools.xml b/packages/SimAppDialog/res/values/bools.xml
new file mode 100644
index 000000000000..4953d5e3816b
--- /dev/null
+++ b/packages/SimAppDialog/res/values/bools.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!--
+ Whether to show an illustration on the screen asking the user to download the carrier app.
+ May be set to true in a resource overlay as long as a drawable asset with ID
+ illo_sim_app_dialog is provided, along with a content description for accessibility with
+ string ID install_carrier_app_image_content_description.
+ -->
+ <bool name="show_sim_app_dialog_illo">false</bool>
+</resources>
diff --git a/packages/SimAppDialog/res/values/strings.xml b/packages/SimAppDialog/res/values/strings.xml
index 87941cb25396..9e8359c7d62e 100644
--- a/packages/SimAppDialog/res/values/strings.xml
+++ b/packages/SimAppDialog/res/values/strings.xml
@@ -32,4 +32,6 @@
<string name="install_carrier_app_defer_action">Not now</string>
<!-- Name of the button for downloading the carrier app [CHAR LIMIT=25] -->
<string name="install_carrier_app_download_action">Download app</string>
-</resources> \ No newline at end of file
+ <!-- Empty placeholder string for an illustration content description that is supplied via resource overlay. [DO NOT TRANSLATE] -->
+ <string name="install_carrier_app_image_content_description" translatable="false" />
+</resources>
diff --git a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
index 9e9b80d39ed7..8e8d9f741a81 100644
--- a/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
+++ b/packages/SimAppDialog/src/com/android/simappdialog/InstallCarrierAppActivity.java
@@ -65,6 +65,11 @@ public class InstallCarrierAppActivity extends Activity implements View.OnClickL
Button downloadButton = findViewById(R.id.download_button);
downloadButton.setOnClickListener(this);
+ // Show/hide illo depending on whether one was provided in a resource overlay
+ boolean showIllo = getResources().getBoolean(R.bool.show_sim_app_dialog_illo);
+ View illoContainer = findViewById(R.id.illo_container);
+ illoContainer.setVisibility(showIllo ? View.VISIBLE : View.GONE);
+
// Include carrier name in description text if its present in the intent
Intent intent = getIntent();
if (intent != null) {
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index b770d5c88324..a00baaddb4b1 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -66,7 +66,7 @@ android_library {
libs: [
"telephony-common",
"android.car",
- "android.car.user",
+ "android.car.userlib",
],
aaptflags: [
@@ -120,7 +120,7 @@ android_library {
"android.test.runner",
"telephony-common",
"android.car",
- "android.car.user",
+ "android.car.userlib",
"android.test.base",
],
aaptflags: [
@@ -146,7 +146,7 @@ android_app {
libs: [
"telephony-common",
"android.car",
- "android.car.user",
+ "android.car.userlib",
],
dxflags: ["--multi-dex"],
@@ -183,7 +183,7 @@ android_app {
libs: [
"telephony-common",
"android.car",
- "android.car.user",
+ "android.car.userlib",
],
srcs: [
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index 33c5551605c0..a8ce196cc359 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -164,7 +164,7 @@ Draws decorations about the screen in software (e.g. rounded corners, cutouts).
### [com.android.systemui.biometrics.BiometricDialogImpl](/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogImpl.java)
-Fingerprint UI.
+Biometric UI.
---
diff --git a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/RecentsView.java
index 0d758df11efc..dfa38babd63b 100644
--- a/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/legacy/recents/src/com/android/systemui/recents/views/RecentsView.java
@@ -497,7 +497,7 @@ public class RecentsView extends FrameLayout {
@Override
public WindowInsets onApplyWindowInsets(WindowInsets insets) {
- mSystemInsets.set(insets.getSystemWindowInsets());
+ mSystemInsets.set(insets.getSystemWindowInsetsAsRect());
mTaskStackView.setSystemInsets(mSystemInsets);
requestLayout();
return insets;
diff --git a/packages/SystemUI/res-keyguard/values/styles.xml b/packages/SystemUI/res-keyguard/values/styles.xml
index 04623478804c..9baeaaac9b38 100644
--- a/packages/SystemUI/res-keyguard/values/styles.xml
+++ b/packages/SystemUI/res-keyguard/values/styles.xml
@@ -64,6 +64,7 @@
<item name="android:paddingBottom">@dimen/bottom_text_spacing_digital</item>
<item name="android:fontFamily">@*android:string/config_headlineFontFamilyLight</item>
<item name="android:fontFeatureSettings">@*android:string/config_headlineFontFeatureSettings</item>
+ <item name="android:ellipsize">none</item>
</style>
<style name="BouncerSecurityContainer">
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 7d09c0079ae8..6f5d6577f700 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2131,7 +2131,7 @@
<string name="app_info">App info</string>
<!-- Action label for switching to a browser for an instant app [CHAR LIMIT=20] -->
- <string name="go_to_web">Go to web</string>
+ <string name="go_to_web">Go to browser</string>
<!-- Quick settings tile for toggling mobile data [CHAR LIMIT=20] -->
<string name="mobile_data">Mobile data</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
index 2bc0e45c725d..e051317b96b6 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardDisplayManager.java
@@ -15,54 +15,164 @@
*/
package com.android.keyguard;
-import static android.view.Display.INVALID_DISPLAY;
+import static android.view.Display.DEFAULT_DISPLAY;
+import android.annotation.Nullable;
import android.app.Presentation;
import android.content.Context;
-import android.content.DialogInterface;
-import android.content.DialogInterface.OnDismissListener;
import android.graphics.Point;
+import android.hardware.display.DisplayManager;
import android.media.MediaRouter;
import android.media.MediaRouter.RouteInfo;
import android.os.Bundle;
-import android.util.Slog;
+import android.util.Log;
+import android.util.SparseArray;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
+import java.util.function.BooleanSupplier;
+
// TODO(multi-display): Support multiple external displays
public class KeyguardDisplayManager {
protected static final String TAG = "KeyguardDisplayManager";
private static boolean DEBUG = KeyguardConstants.DEBUG;
private final ViewMediatorCallback mCallback;
+
private final MediaRouter mMediaRouter;
+ private final DisplayManager mDisplayService;
private final Context mContext;
- Presentation mPresentation;
private boolean mShowing;
+ private final SparseArray<Presentation> mPresentations = new SparseArray<>();
+
+ private final DisplayManager.DisplayListener mDisplayListener =
+ new DisplayManager.DisplayListener() {
+
+ @Override
+ public void onDisplayAdded(int displayId) {
+ final Display display = mDisplayService.getDisplay(displayId);
+ if (mShowing) {
+ notifyIfChanged(() -> showPresentation(display));
+ }
+ }
+
+ @Override
+ public void onDisplayChanged(int displayId) {
+ if (displayId == DEFAULT_DISPLAY) return;
+ final Display display = mDisplayService.getDisplay(displayId);
+ if (display != null && mShowing) {
+ final Presentation presentation = mPresentations.get(displayId);
+ if (presentation != null && !presentation.getDisplay().equals(display)) {
+ hidePresentation(displayId);
+ showPresentation(display);
+ }
+ }
+ }
+
+ @Override
+ public void onDisplayRemoved(int displayId) {
+ notifyIfChanged(() -> hidePresentation(displayId));
+ }
+ };
+
public KeyguardDisplayManager(Context context, ViewMediatorCallback callback) {
mContext = context;
mCallback = callback;
- mMediaRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mMediaRouter = mContext.getSystemService(MediaRouter.class);
+ mDisplayService = mContext.getSystemService(DisplayManager.class);
+ mDisplayService.registerDisplayListener(mDisplayListener, null /* handler */);
+ }
+
+ /**
+ * @param display The display to show the presentation on.
+ * @return {@code true} if a presentation was added.
+ * {@code false} if the presentation cannot be added on that display or the presentation
+ * was already there.
+ */
+ private boolean showPresentation(Display display) {
+ if (display == null || display.getDisplayId() == DEFAULT_DISPLAY) return false;
+ if (DEBUG) Log.i(TAG, "Keyguard enabled on display: " + display);
+ final int displayId = display.getDisplayId();
+ Presentation presentation = mPresentations.get(displayId);
+ if (presentation == null) {
+ presentation = new KeyguardPresentation(mContext, display);
+ presentation.setOnDismissListener(dialog -> {
+ if (null != mPresentations.get(displayId)) {
+ mPresentations.remove(displayId);
+ }
+ });
+ try {
+ presentation.show();
+ } catch (WindowManager.InvalidDisplayException ex) {
+ Log.w(TAG, "Invalid display:", ex);
+ presentation = null;
+ }
+ if (presentation != null) {
+ mPresentations.append(displayId, presentation);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @param displayId The id of the display to hide the presentation off.
+ * @return {@code true} if the a presentation was removed.
+ * {@code false} if the presentation was not added before.
+ */
+ private boolean hidePresentation(int displayId) {
+ final Presentation presentation = mPresentations.get(displayId);
+ if (presentation != null) {
+ presentation.dismiss();
+ mPresentations.remove(displayId);
+ return true;
+ }
+ return false;
+ }
+
+ private void notifyIfChanged(BooleanSupplier updateMethod) {
+ if (updateMethod.getAsBoolean()) {
+ final int[] displayList = getPresentationDisplayIds();
+ mCallback.onSecondaryDisplayShowingChanged(displayList);
+ }
+ }
+
+ /**
+ * @return An array of displayId's on which a {@link KeyguardPresentation} is showing on.
+ */
+ @Nullable
+ private int[] getPresentationDisplayIds() {
+ final int size = mPresentations.size();
+ if (size == 0) return null;
+
+ final int[] displayIds = new int[size];
+ for (int i = mPresentations.size() - 1; i >= 0; i--) {
+ final Presentation presentation = mPresentations.valueAt(i);
+ if (presentation != null) {
+ displayIds[i] = presentation.getDisplay().getDisplayId();
+ }
+ }
+ return displayIds;
}
public void show() {
if (!mShowing) {
- if (DEBUG) Slog.v(TAG, "show");
+ if (DEBUG) Log.v(TAG, "show");
mMediaRouter.addCallback(MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY,
mMediaRouterCallback, MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY);
- updateDisplays(true);
+ notifyIfChanged(() -> updateDisplays(true /* showing */));
}
mShowing = true;
}
public void hide() {
if (mShowing) {
- if (DEBUG) Slog.v(TAG, "hide");
+ if (DEBUG) Log.v(TAG, "hide");
mMediaRouter.removeCallback(mMediaRouterCallback);
- updateDisplays(false);
+ notifyIfChanged(() -> updateDisplays(false /* showing */));
}
mShowing = false;
}
@@ -71,71 +181,38 @@ public class KeyguardDisplayManager {
new MediaRouter.SimpleCallback() {
@Override
public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
- if (DEBUG) Slog.d(TAG, "onRouteSelected: type=" + type + ", info=" + info);
- updateDisplays(mShowing);
+ if (DEBUG) Log.d(TAG, "onRouteSelected: type=" + type + ", info=" + info);
+ notifyIfChanged(() -> updateDisplays(mShowing));
}
@Override
public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
- if (DEBUG) Slog.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info);
- updateDisplays(mShowing);
+ if (DEBUG) Log.d(TAG, "onRouteUnselected: type=" + type + ", info=" + info);
+ notifyIfChanged(() -> updateDisplays(mShowing));
}
@Override
public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
- if (DEBUG) Slog.d(TAG, "onRoutePresentationDisplayChanged: info=" + info);
- updateDisplays(mShowing);
- }
- };
-
- private OnDismissListener mOnDismissListener = new OnDismissListener() {
-
- @Override
- public void onDismiss(DialogInterface dialog) {
- mPresentation = null;
+ if (DEBUG) Log.d(TAG, "onRoutePresentationDisplayChanged: info=" + info);
+ notifyIfChanged(() -> updateDisplays(mShowing));
}
};
- protected void updateDisplays(boolean showing) {
- Presentation originalPresentation = mPresentation;
+ protected boolean updateDisplays(boolean showing) {
+ boolean changed = false;
if (showing) {
- MediaRouter.RouteInfo route = mMediaRouter.getSelectedRoute(
- MediaRouter.ROUTE_TYPE_REMOTE_DISPLAY);
- boolean useDisplay = route != null
- && route.getPlaybackType() == MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE;
- Display presentationDisplay = useDisplay ? route.getPresentationDisplay() : null;
-
- if (mPresentation != null && mPresentation.getDisplay() != presentationDisplay) {
- if (DEBUG) Slog.v(TAG, "Display gone: " + mPresentation.getDisplay());
- mPresentation.dismiss();
- mPresentation = null;
- }
-
- if (mPresentation == null && presentationDisplay != null) {
- if (DEBUG) Slog.i(TAG, "Keyguard enabled on display: " + presentationDisplay);
- mPresentation = new KeyguardPresentation(mContext, presentationDisplay,
- R.style.keyguard_presentation_theme);
- mPresentation.setOnDismissListener(mOnDismissListener);
- try {
- mPresentation.show();
- } catch (WindowManager.InvalidDisplayException ex) {
- Slog.w(TAG, "Invalid display:", ex);
- mPresentation = null;
- }
+ final Display[] displays = mDisplayService.getDisplays();
+ for (Display display : displays) {
+ changed |= showPresentation(display);
}
} else {
- if (mPresentation != null) {
- mPresentation.dismiss();
- mPresentation = null;
+ changed = mPresentations.size() > 0;
+ for (int i = mPresentations.size() - 1; i >= 0; i--) {
+ mPresentations.valueAt(i).dismiss();
}
+ mPresentations.clear();
}
-
- // mPresentation is only updated when the display changes
- if (mPresentation != originalPresentation) {
- final int displayId = mPresentation != null
- ? mPresentation.getDisplay().getDisplayId() : INVALID_DISPLAY;
- mCallback.onSecondaryDisplayShowingChanged(displayId);
- }
+ return changed;
}
private final static class KeyguardPresentation extends Presentation {
@@ -157,9 +234,10 @@ public class KeyguardDisplayManager {
}
};
- public KeyguardPresentation(Context context, Display display, int theme) {
- super(context, display, theme);
+ KeyguardPresentation(Context context, Display display) {
+ super(context, display, R.style.keyguard_presentation_theme);
getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
+ setCancelable(false);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 50b98a10b7f0..79966f78373c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -17,6 +17,8 @@
package com.android.keyguard;
import static android.app.slice.Slice.HINT_LIST_ITEM;
+import static android.view.Display.DEFAULT_DISPLAY;
+import static android.view.Display.INVALID_DISPLAY;
import android.animation.LayoutTransition;
import android.animation.ObjectAnimator;
@@ -80,6 +82,7 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
private float mDarkAmount = 0;
private LiveData<Slice> mLiveData;
+ private int mDisplayId = INVALID_DISPLAY;
private int mIconSize;
/**
* Runnable called whenever the view contents change.
@@ -129,6 +132,7 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ mDisplayId = getDisplay().getDisplayId();
// Make sure we always have the most current slice
mLiveData.observeForever(this);
Dependency.get(ConfigurationController.class).addCallback(this);
@@ -138,7 +142,10 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
- mLiveData.removeObserver(this);
+ // TODO(b/117344873) Remove below work around after this issue be fixed.
+ if (mDisplayId == DEFAULT_DISPLAY) {
+ mLiveData.removeObserver(this);
+ }
Dependency.get(ConfigurationController.class).removeCallback(this);
}
diff --git a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
index 41b86a7450a3..a07c5cbde956 100644
--- a/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
+++ b/packages/SystemUI/src/com/android/keyguard/ViewMediatorCallback.java
@@ -96,9 +96,9 @@ public interface ViewMediatorCallback {
int getBouncerPromptReason();
/**
- * Invoked when the secondary display showing a keyguard window changes.
+ * Invoked when the secondary displays showing a keyguard window changes.
*/
- void onSecondaryDisplayShowingChanged(int displayId);
+ void onSecondaryDisplayShowingChanged(int[] displayId);
/**
* Consumes a message that was enqueued to be displayed on the next time the bouncer shows up.
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 3fe99445f49d..e3584cf7493e 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -33,10 +33,11 @@ import android.view.VelocityTracker;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityEvent;
+
import com.android.systemui.classifier.FalsingManager;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
public class SwipeHelper implements Gefingerpoken {
static final String TAG = "com.android.systemui.SwipeHelper";
@@ -604,13 +605,15 @@ public class SwipeHelper implements Gefingerpoken {
}
// don't let items that can't be dismissed be dragged more than
// maxScrollDistance
- if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissed(mCurrView)) {
+ if (CONSTRAIN_SWIPE && !mCallback.canChildBeDismissedInDirection(mCurrView,
+ delta > 0)) {
float size = getSize(mCurrView);
float maxScrollDistance = MAX_SCROLL_SIZE_FRACTION * size;
if (absDelta >= size) {
delta = delta > 0 ? maxScrollDistance : -maxScrollDistance;
} else {
- delta = maxScrollDistance * (float) Math.sin((delta/size)*(Math.PI/2));
+ delta = maxScrollDistance * (float) Math.sin(
+ (delta / size) * (Math.PI / 2));
}
}
@@ -674,9 +677,11 @@ public class SwipeHelper implements Gefingerpoken {
}
public boolean isDismissGesture(MotionEvent ev) {
+ float translation = getTranslation(mCurrView);
return ev.getActionMasked() == MotionEvent.ACTION_UP
+ && !mFalsingManager.isUnlockingDisabled()
&& !isFalseGesture(ev) && (swipedFastEnough() || swipedFarEnough())
- && mCallback.canChildBeDismissed(mCurrView);
+ && mCallback.canChildBeDismissedInDirection(mCurrView, translation > 0);
}
public boolean isFalseGesture(MotionEvent ev) {
@@ -707,6 +712,16 @@ public class SwipeHelper implements Gefingerpoken {
boolean canChildBeDismissed(View v);
+ /**
+ * Returns true if the provided child can be dismissed by a swipe in the given direction.
+ *
+ * @param isRightOrDown {@code true} if the swipe direction is right or down,
+ * {@code false} if it is left or up.
+ */
+ default boolean canChildBeDismissedInDirection(View v, boolean isRightOrDown) {
+ return canChildBeDismissed(v);
+ }
+
boolean isAntiFalsingNeeded();
void onBeginDrag(View v);
diff --git a/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java b/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java
index 69e347c9476d..4010c43f675e 100644
--- a/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java
+++ b/packages/SystemUI/src/com/android/systemui/analytics/DataCollector.java
@@ -16,6 +16,9 @@
package com.android.systemui.analytics;
+import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session;
+import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent;
+
import android.content.Context;
import android.database.ContentObserver;
import android.hardware.Sensor;
@@ -36,9 +39,6 @@ import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session;
-import static com.android.systemui.statusbar.phone.nano.TouchAnalyticsProto.Session.PhoneEvent;
-
/**
* Tracks touch, sensor and phone events when the lockscreen is on. If the phone is unlocked
* the data containing these events is saved to a file. This data is collected
@@ -53,6 +53,8 @@ public class DataCollector implements SensorEventListener {
private static final String COLLECT_BAD_TOUCHES = "data_collector_collect_bad_touches";
private static final String ALLOW_REJECTED_TOUCH_REPORTS =
"data_collector_allow_rejected_touch_reports";
+ private static final String DISABLE_UNLOCKING_FOR_FALSING_COLLECTION =
+ "data_collector_disable_unlocking";
private static final long TIMEOUT_MILLIS = 11000; // 11 seconds.
public static final boolean DEBUG = false;
@@ -65,11 +67,11 @@ public class DataCollector implements SensorEventListener {
private SensorLoggerSession mCurrentSession = null;
private boolean mEnableCollector = false;
- private boolean mTimeoutActive = false;
private boolean mCollectBadTouches = false;
private boolean mCornerSwiping = false;
private boolean mTrackingStarted = false;
private boolean mAllowReportRejectedTouch = false;
+ private boolean mDisableUnlocking = false;
private static DataCollector sInstance = null;
@@ -98,6 +100,11 @@ public class DataCollector implements SensorEventListener {
mSettingsObserver,
UserHandle.USER_ALL);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Secure.getUriFor(DISABLE_UNLOCKING_FOR_FALSING_COLLECTION), false,
+ mSettingsObserver,
+ UserHandle.USER_ALL);
+
updateConfiguration();
}
@@ -118,6 +125,9 @@ public class DataCollector implements SensorEventListener {
mAllowReportRejectedTouch = Build.IS_DEBUGGABLE && 0 != Settings.Secure.getInt(
mContext.getContentResolver(),
ALLOW_REJECTED_TOUCH_REPORTS, 0);
+ mDisableUnlocking = mEnableCollector && Build.IS_DEBUGGABLE && 0 != Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ DISABLE_UNLOCKING_FOR_FALSING_COLLECTION, 0);
}
private boolean sessionEntrypoint() {
@@ -144,7 +154,7 @@ public class DataCollector implements SensorEventListener {
SensorLoggerSession session = mCurrentSession;
mCurrentSession = null;
- if (mEnableCollector) {
+ if (mEnableCollector || mDisableUnlocking) {
session.end(System.currentTimeMillis(), result);
queueSession(session);
}
@@ -183,11 +193,11 @@ public class DataCollector implements SensorEventListener {
byte[] b = Session.toByteArray(currentSession.toProto());
String dir = mContext.getFilesDir().getAbsolutePath();
if (currentSession.getResult() != Session.SUCCESS) {
- if (!mCollectBadTouches) {
+ if (!mDisableUnlocking && !mCollectBadTouches) {
return;
}
dir += "/bad_touches";
- } else {
+ } else if (!mDisableUnlocking) {
dir += "/good_touches";
}
@@ -208,19 +218,6 @@ public class DataCollector implements SensorEventListener {
public synchronized void onSensorChanged(SensorEvent event) {
if (isEnabled() && mCurrentSession != null) {
mCurrentSession.addSensorEvent(event, System.nanoTime());
- enforceTimeout();
- }
- }
-
- private void enforceTimeout() {
- if (mTimeoutActive) {
- if (System.currentTimeMillis() - mCurrentSession.getStartTimestampMillis()
- > TIMEOUT_MILLIS) {
- onSessionEnd(Session.UNKNOWN);
- if (DEBUG) {
- Log.i(TAG, "Analytics timed out.");
- }
- }
}
}
@@ -233,9 +230,12 @@ public class DataCollector implements SensorEventListener {
* rejected touch report.
*/
public boolean isEnabled() {
- return mEnableCollector || mAllowReportRejectedTouch;
+ return mEnableCollector || mAllowReportRejectedTouch || mDisableUnlocking;
}
+ public boolean isUnlockingDisabled() {
+ return mDisableUnlocking;
+ }
/**
* @return true if the full data set for data gathering should be collected - including
* extensive sensor data, which is is not normally included with rejected touch reports.
@@ -450,7 +450,6 @@ public class DataCollector implements SensorEventListener {
}
mCurrentSession.addMotionEvent(event);
mCurrentSession.setTouchArea(width, height);
- enforceTimeout();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
index 3d578c39d3c4..2c61da343763 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManager.java
@@ -201,6 +201,9 @@ public class FalsingManager implements SensorEventListener {
return mHumanInteractionClassifier.isEnabled() || mDataCollector.isEnabled();
}
+ public boolean isUnlockingDisabled() {
+ return mDataCollector.isUnlockingDisabled();
+ }
/**
* @return true if the classifier determined that this is not a human interacting with the phone
*/
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4988f07ca3f3..fe1b35609ae5 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -17,7 +17,6 @@
package com.android.systemui.keyguard;
import static android.provider.Settings.System.SCREEN_OFF_TIMEOUT;
-import static android.view.Display.INVALID_DISPLAY;
import static com.android.internal.telephony.IccCardConstants.State.ABSENT;
import static com.android.internal.telephony.IccCardConstants.State.PIN_REQUIRED;
@@ -95,6 +94,7 @@ import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* Mediates requests related to the keyguard. This includes queries about the
@@ -246,8 +246,8 @@ public class KeyguardViewMediator extends SystemUI {
// AOD is enabled and status bar is in AOD state.
private boolean mAodShowing;
- // display id of the secondary display on which we have put a keyguard window
- private int mSecondaryDisplayShowing = INVALID_DISPLAY;
+ // display ids of the external display on which we have put a keyguard window
+ private int[] mSecondaryDisplaysShowing;
/** Cached value of #isInputRestricted */
private boolean mInputRestricted;
@@ -700,9 +700,9 @@ public class KeyguardViewMediator extends SystemUI {
}
@Override
- public void onSecondaryDisplayShowingChanged(int displayId) {
+ public void onSecondaryDisplayShowingChanged(int[] displayIds) {
synchronized (KeyguardViewMediator.this) {
- setShowingLocked(mShowing, mAodShowing, displayId, false);
+ setShowingLocked(mShowing, mAodShowing, displayIds, false);
}
}
};
@@ -749,10 +749,10 @@ public class KeyguardViewMediator extends SystemUI {
setShowingLocked(!shouldWaitForProvisioning()
&& !mLockPatternUtils.isLockScreenDisabled(
KeyguardUpdateMonitor.getCurrentUser()),
- mAodShowing, mSecondaryDisplayShowing, true /* forceCallbacks */);
+ mAodShowing, mSecondaryDisplaysShowing, true /* forceCallbacks */);
} else {
// The system's keyguard is disabled or missing.
- setShowingLocked(false, mAodShowing, mSecondaryDisplayShowing, true);
+ setShowingLocked(false, mAodShowing, mSecondaryDisplaysShowing, true);
}
mStatusBarKeyguardViewManager =
@@ -1776,11 +1776,11 @@ public class KeyguardViewMediator extends SystemUI {
}
private void updateActivityLockScreenState(boolean showing, boolean aodShowing,
- int secondaryDisplayShowing) {
+ int[] secondaryDisplaysShowing) {
mUiOffloadThread.submit(() -> {
try {
ActivityTaskManager.getService().setLockScreenShown(showing, aodShowing,
- secondaryDisplayShowing);
+ secondaryDisplaysShowing);
} catch (RemoteException e) {
}
});
@@ -1895,7 +1895,8 @@ public class KeyguardViewMediator extends SystemUI {
if (!mHiding) {
// Tell ActivityManager that we canceled the keyguardExitAnimation.
- setShowingLocked(mShowing, mAodShowing, mSecondaryDisplayShowing, true /* force */);
+ setShowingLocked(mShowing, mAodShowing, mSecondaryDisplaysShowing,
+ true /* force */);
return;
}
mHiding = false;
@@ -2164,22 +2165,23 @@ public class KeyguardViewMediator extends SystemUI {
}
private void setShowingLocked(boolean showing, boolean aodShowing) {
- setShowingLocked(showing, aodShowing, mSecondaryDisplayShowing,
+ setShowingLocked(showing, aodShowing, mSecondaryDisplaysShowing,
false /* forceCallbacks */);
}
- private void setShowingLocked(boolean showing, boolean aodShowing, int secondaryDisplayShowing,
- boolean forceCallbacks) {
+ private void setShowingLocked(boolean showing, boolean aodShowing,
+ int[] secondaryDisplaysShowing, boolean forceCallbacks) {
final boolean notifyDefaultDisplayCallbacks = showing != mShowing
|| aodShowing != mAodShowing || forceCallbacks;
- if (notifyDefaultDisplayCallbacks || secondaryDisplayShowing != mSecondaryDisplayShowing) {
+ if (notifyDefaultDisplayCallbacks
+ || !Arrays.equals(secondaryDisplaysShowing, mSecondaryDisplaysShowing)) {
mShowing = showing;
mAodShowing = aodShowing;
- mSecondaryDisplayShowing = secondaryDisplayShowing;
+ mSecondaryDisplaysShowing = secondaryDisplaysShowing;
if (notifyDefaultDisplayCallbacks) {
notifyDefaultDisplayCallbacks(showing);
}
- updateActivityLockScreenState(showing, aodShowing, secondaryDisplayShowing);
+ updateActivityLockScreenState(showing, aodShowing, secondaryDisplaysShowing);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
index 8526afd34514..8a86826cd01d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/DragDownHelper.java
@@ -128,7 +128,8 @@ public class DragDownHelper implements Gefingerpoken {
}
return true;
case MotionEvent.ACTION_UP:
- if (!isFalseTouch() && mDragDownCallback.onDraggedDown(mStartingChild,
+ if (!mFalsingManager.isUnlockingDisabled() && !isFalseTouch()
+ && mDragDownCallback.onDraggedDown(mStartingChild,
(int) (y - mInitialTouchY))) {
if (mStartingChild == null) {
cancelExpansion();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index a00eac4adea0..960d22185652 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -51,6 +51,7 @@ import com.android.settingslib.Utils;
import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.LockIcon;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -66,7 +67,7 @@ import java.util.IllegalFormatConversionException;
/**
* Controls the indications and error messages shown on the Keyguard
*/
-public class KeyguardIndicationController {
+public class KeyguardIndicationController implements StateListener {
private static final String TAG = "KeyguardIndication";
private static final boolean DEBUG_CHARGING_SPEED = false;
@@ -154,6 +155,19 @@ public class KeyguardIndicationController {
mContext.registerReceiverAsUser(mTickReceiver, UserHandle.SYSTEM,
new IntentFilter(Intent.ACTION_TIME_TICK), null,
Dependency.get(Dependency.TIME_TICK_HANDLER));
+
+ Dependency.get(StatusBarStateController.class).addListener(this);
+ }
+
+ /**
+ * Used by {@link com.android.systemui.statusbar.phone.StatusBar} to give the indication
+ * controller a chance to unregister itself as a receiver.
+ *
+ * //TODO: This can probably be converted to a fragment and not have to be manually recreated
+ */
+ public void destroy() {
+ mContext.unregisterReceiver(mTickReceiver);
+ Dependency.get(StatusBarStateController.class).removeListener(this);
}
/**
@@ -518,6 +532,16 @@ public class KeyguardIndicationController {
updateAlphas();
}
+ @Override
+ public void onStateChanged(int newState) {
+ // don't care
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ setDozing(isDozing);
+ }
+
protected class BaseKeyguardCallback extends KeyguardUpdateMonitorCallback {
public static final int HIDE_DELAY_MS = 5000;
private int mLastSuccessiveErrorMessage = -1;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
index b5fbde136c87..5dfd5d0da4af 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/logging/NotificationLogger.java
@@ -29,9 +29,11 @@ import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dependency;
import com.android.systemui.UiOffloadThread;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import java.util.ArrayList;
@@ -42,7 +44,7 @@ import java.util.Collections;
* Handles notification logging, in particular, logging which notifications are visible and which
* are not.
*/
-public class NotificationLogger {
+public class NotificationLogger implements StateListener {
private static final String TAG = "NotificationLogger";
/** The minimum delay in ms between reports of notification visibility. */
@@ -63,7 +65,7 @@ public class NotificationLogger {
protected IStatusBarService mBarService;
private long mLastVisibilityReportUptimeMs;
private NotificationListContainer mListContainer;
- private Object mDozingLock = new Object();
+ private final Object mDozingLock = new Object();
private boolean mDozing;
protected final OnChildLocationsChangedListener mNotificationLocationsChangedListener =
@@ -146,6 +148,8 @@ public class NotificationLogger {
public NotificationLogger() {
mBarService = IStatusBarService.Stub.asInterface(
ServiceManager.getService(Context.STATUS_BAR_SERVICE));
+ // Not expected to be destroyed, don't need to unsubscribe
+ Dependency.get(StatusBarStateController.class).addListener(this);
}
public void setUpWithContainer(NotificationListContainer listContainer) {
@@ -175,7 +179,7 @@ public class NotificationLogger {
mNotificationLocationsChangedListener.onChildLocationsChanged();
}
- public void setDozing(boolean dozing) {
+ private void setDozing(boolean dozing) {
synchronized (mDozingLock) {
mDozing = dozing;
}
@@ -258,6 +262,16 @@ public class NotificationLogger {
return mVisibilityReporter;
}
+ @Override
+ public void onStateChanged(int newState) {
+ // don't care about state change
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ setDozing(isDozing);
+ }
+
/**
* A listener that is notified when some child locations might have changed.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index 003f158d7822..c3bf16e0f796 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -1107,7 +1107,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mIsClipped = clipped;
}
- if (mAmbientState.isDarkAtAll()) {
+ if (mPulsing) {
+ setClipBounds(null);
+ } else if (mAmbientState.isDarkAtAll()) {
setClipBounds(mBackgroundAnimationRect);
} else if (clipped) {
setClipBounds(mRequestedClipBounds);
@@ -5641,6 +5643,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
public boolean canChildBeDismissed(View v) {
return NotificationStackScrollLayout.this.canChildBeDismissed(v);
}
+
+ @Override
+ public boolean canChildBeDismissedInDirection(View v, boolean isRightOrDown) {
+ return (isLayoutRtl() ? !isRightOrDown : isRightOrDown) && canChildBeDismissed(v);
+ }
};
// ---------------------- DragDownHelper.OnDragDownListener ------------------------------------
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
index a0597dc66d14..94b2cdeea898 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeScrimController.java
@@ -20,13 +20,17 @@ import android.annotation.NonNull;
import android.os.Handler;
import android.util.Log;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.systemui.Dependency;
import com.android.systemui.doze.DozeHost;
import com.android.systemui.doze.DozeLog;
+import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.StatusBarStateController.StateListener;
/**
* Controller which handles all the doze animations of the scrims.
*/
-public class DozeScrimController {
+public class DozeScrimController implements StateListener {
private static final String TAG = "DozeScrimController";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -83,8 +87,11 @@ public class DozeScrimController {
public DozeScrimController(DozeParameters dozeParameters) {
mDozeParameters = dozeParameters;
+ //Never expected to be destroyed
+ Dependency.get(StatusBarStateController.class).addListener(this);
}
+ @VisibleForTesting
public void setDozing(boolean dozing) {
if (mDozing == dozing) return;
mDozing = dozing;
@@ -181,4 +188,14 @@ public class DozeScrimController {
public ScrimController.Callback getScrimCallback() {
return mScrimCallback;
}
+
+ @Override
+ public void onStateChanged(int newState) {
+ // don't care
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ setDozing(isDozing);
+ }
} \ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
index 462201c6dac2..b3d0bf8abf62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardDismissUtil.java
@@ -35,7 +35,7 @@ public class KeyguardDismissUtil implements KeyguardDismissHandler {
}
/**
- * Executes an action that requres the screen to be unlocked.
+ * Executes an action that requires the screen to be unlocked.
*
* <p>Must be called after {@link #setDismissHandler}.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
index c08366a95f08..6b12dd9519e4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationGroupManager.java
@@ -16,22 +16,24 @@
package com.android.systemui.statusbar.phone;
-import android.annotation.NonNull;
import android.app.Notification;
import android.os.SystemClock;
import android.service.notification.StatusBarNotification;
-import androidx.annotation.Nullable;
import android.util.Log;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.AlertingNotificationManager;
import com.android.systemui.statusbar.AmbientPulseManager;
import com.android.systemui.statusbar.AmbientPulseManager.OnAmbientChangedListener;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.StatusBarStateController.StateListener;
-import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.NotificationData;
-import com.android.systemui.statusbar.StatusBarStateController;
+import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.policy.HeadsUpManager;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;
@@ -48,7 +50,7 @@ import java.util.Objects;
* A class to handle notifications and their corresponding groups.
*/
public class NotificationGroupManager implements OnHeadsUpChangedListener,
- OnAmbientChangedListener {
+ OnAmbientChangedListener, StateListener {
private static final String TAG = "NotificationGroupManager";
private static final long ALERT_TRANSFER_TIMEOUT = 300;
@@ -62,10 +64,8 @@ public class NotificationGroupManager implements OnHeadsUpChangedListener,
private boolean mIsUpdatingUnchangedGroup;
private HashMap<String, NotificationData.Entry> mPendingNotifications;
- private final StateListener mStateListener = this::setStatusBarState;
-
public NotificationGroupManager() {
- Dependency.get(StatusBarStateController.class).addListener(mStateListener);
+ Dependency.get(StatusBarStateController.class).addListener(this);
}
public void setOnGroupChangeListener(OnGroupChangeListener listener) {
@@ -185,6 +185,7 @@ public class NotificationGroupManager implements OnHeadsUpChangedListener,
* specific alert state logic based off when the state changes.
* @param isDozing if the device is dozing.
*/
+ @VisibleForTesting
public void setDozing(boolean isDozing) {
if (mIsDozing != isDozing) {
for (NotificationGroup group : mGroupMap.values()) {
@@ -732,6 +733,16 @@ public class NotificationGroupManager implements OnHeadsUpChangedListener,
mPendingNotifications = pendingNotifications;
}
+ @Override
+ public void onStateChanged(int newState) {
+ setStatusBarState(newState);
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ setDozing(isDozing);
+ }
+
public static class NotificationGroup {
public final HashMap<String, NotificationData.Entry> children = new HashMap<>();
public NotificationData.Entry summary;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 31facb79045e..f4c2e27ca272 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -582,7 +582,7 @@ public class NotificationPanelView extends PanelView implements
int stackScrollerPadding;
if (mBarState != StatusBarState.KEYGUARD) {
stackScrollerPadding = (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight
- + mQsNotificationTopPadding;
+ + mQsNotificationTopPadding;
} else {
int totalHeight = getHeight();
int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding);
@@ -754,7 +754,7 @@ public class NotificationPanelView extends PanelView implements
mQsExpandImmediate = true;
mNotificationStackScroller.setShouldShowShelfOnly(true);
}
- if (isFullyCollapsed()){
+ if (isFullyCollapsed()) {
expand(true /* animate */);
} else {
flingSettings(0 /* velocity */, FLING_EXPAND);
@@ -921,7 +921,7 @@ public class NotificationPanelView extends PanelView implements
}
private boolean flingExpandsQs(float vel) {
- if (isFalseTouch()) {
+ if (mFalsingManager.isUnlockingDisabled() || isFalseTouch()) {
return false;
}
if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
@@ -1046,11 +1046,11 @@ public class NotificationPanelView extends PanelView implements
final boolean stylusButtonClickDrag = action == MotionEvent.ACTION_DOWN
&& (event.isButtonPressed(MotionEvent.BUTTON_STYLUS_PRIMARY)
- || event.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY));
+ || event.isButtonPressed(MotionEvent.BUTTON_STYLUS_SECONDARY));
final boolean mouseButtonClickDrag = action == MotionEvent.ACTION_DOWN
&& (event.isButtonPressed(MotionEvent.BUTTON_SECONDARY)
- || event.isButtonPressed(MotionEvent.BUTTON_TERTIARY));
+ || event.isButtonPressed(MotionEvent.BUTTON_TERTIARY));
return twoFingerDrag || stylusButtonClickDrag || mouseButtonClickDrag;
}
@@ -1321,12 +1321,12 @@ public class NotificationPanelView extends PanelView implements
private final ValueAnimator.AnimatorUpdateListener mStatusBarAnimateAlphaListener =
new ValueAnimator.AnimatorUpdateListener() {
- @Override
- public void onAnimationUpdate(ValueAnimator animation) {
- mKeyguardStatusBarAnimateAlpha = (float) animation.getAnimatedValue();
- updateHeaderKeyguardAlpha();
- }
- };
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mKeyguardStatusBarAnimateAlpha = (float) animation.getAnimatedValue();
+ updateHeaderKeyguardAlpha();
+ }
+ };
private void animateKeyguardStatusBarIn(long duration) {
mKeyguardStatusBar.setVisibility(View.VISIBLE);
@@ -1382,7 +1382,7 @@ public class NotificationPanelView extends PanelView implements
if (keyguardFadingAway) {
mKeyguardStatusView.animate()
.setStartDelay(mKeyguardMonitor.getKeyguardFadingAwayDelay())
- .setDuration(mKeyguardMonitor.getKeyguardFadingAwayDuration()/2)
+ .setDuration(mKeyguardMonitor.getKeyguardFadingAwayDuration() / 2)
.start();
}
} else if (mBarState == StatusBarState.SHADE_LOCKED
@@ -1425,8 +1425,8 @@ public class NotificationPanelView extends PanelView implements
updateEmptyShadeView();
mQsNavbarScrim.setVisibility(mBarState == StatusBarState.SHADE && mQsExpanded
&& !mStackScrollerOverscrolling && mQsScrimEnabled
- ? View.VISIBLE
- : View.INVISIBLE);
+ ? View.VISIBLE
+ : View.INVISIBLE);
if (mKeyguardUserSwitcher != null && mQsExpanded && !mStackScrollerOverscrolling) {
mKeyguardUserSwitcher.hideIfNotSimple(true /* animate */);
}
@@ -1459,7 +1459,8 @@ public class NotificationPanelView extends PanelView implements
setAccessibilityPaneTitle(determineAccessibilityPaneTitle());
}
- if (mQsFullyExpanded && mFalsingManager.shouldEnforceBouncer()) {
+ if (!mFalsingManager.isUnlockingDisabled() && mQsFullyExpanded
+ && mFalsingManager.shouldEnforceBouncer()) {
mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */);
}
@@ -2130,8 +2131,7 @@ public class NotificationPanelView extends PanelView implements
}
}, null, true /* dismissShade */, false /* afterKeyguardGone */,
true /* deferred */);
- }
- else {
+ } else {
mKeyguardBottomArea.launchLeftAffordance();
}
} else {
@@ -2588,7 +2588,7 @@ public class NotificationPanelView extends PanelView implements
x = Math.min(rightMost, Math.max(leftMost, x));
setVerticalPanelTranslation(x -
(mNotificationStackScroller.getLeft() + mNotificationStackScroller.getWidth() / 2));
- }
+ }
private void resetVerticalPanelPosition() {
setVerticalPanelTranslation(0f);
@@ -2716,8 +2716,8 @@ public class NotificationPanelView extends PanelView implements
String packageToLaunch = (resolveInfo == null || resolveInfo.activityInfo == null)
? null : resolveInfo.activityInfo.packageName;
return packageToLaunch != null &&
- (keyguardIsShowing || !isForegroundApp(packageToLaunch)) &&
- !mAffordanceHelper.isSwipingInProgress();
+ (keyguardIsShowing || !isForegroundApp(packageToLaunch))
+ && !mAffordanceHelper.isSwipingInProgress();
}
/**
@@ -2884,13 +2884,14 @@ public class NotificationPanelView extends PanelView implements
}
public void setStatusAccessibilityImportance(int mode) {
- mKeyguardStatusView.setImportantForAccessibility(mode);
+ mKeyguardStatusView.setImportantForAccessibility(mode);
}
/**
* TODO: this should be removed.
* It's not correct to pass this view forward because other classes will end up adding
* children to it. Theme will be out of sync.
+ *
* @return bottom area view
*/
public KeyguardBottomAreaView getKeyguardBottomAreaView() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index f29b7cab5cbc..021b4307aca4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -670,6 +670,10 @@ public abstract class PanelView extends FrameLayout {
* @return whether a fling should expands the panel; contracts otherwise
*/
protected boolean flingExpands(float vel, float vectorVel, float x, float y) {
+ if (mFalsingManager.isUnlockingDisabled()) {
+ return true;
+ }
+
if (isFalseTouch(x, y)) {
return true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 2337857eda1e..6279d50a5952 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -586,7 +586,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mNotificationLogger = Dependency.get(NotificationLogger.class);
mRemoteInputManager = Dependency.get(NotificationRemoteInputManager.class);
mNotificationListener = Dependency.get(NotificationListener.class);
- mGroupManager = Dependency.get(NotificationGroupManager.class);
mNetworkController = Dependency.get(NetworkController.class);
mUserSwitcherController = Dependency.get(UserSwitcherController.class);
mScreenLifecycle = Dependency.get(ScreenLifecycle.class);
@@ -1096,6 +1095,9 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void onThemeChanged() {
// Recreate Indication controller because internal references changed
+ if (mKeyguardIndicationController != null) {
+ mKeyguardIndicationController.destroy();
+ }
mKeyguardIndicationController =
SystemUIFactory.getInstance().createKeyguardIndicationController(mContext,
mStatusBarWindow.findViewById(R.id.keyguard_indication_area),
@@ -1104,7 +1106,6 @@ public class StatusBar extends SystemUI implements DemoMode,
mKeyguardIndicationController
.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
mKeyguardIndicationController.setVisible(mState == StatusBarState.KEYGUARD);
- mKeyguardIndicationController.setDozing(mDozing);
if (mStatusBarKeyguardViewManager != null) {
mStatusBarKeyguardViewManager.onThemeChanged();
}
@@ -3247,12 +3248,8 @@ public class StatusBar extends SystemUI implements DemoMode,
boolean animate = (!mDozing && mDozeServiceHost.shouldAnimateWakeup())
|| (mDozing && mDozeServiceHost.shouldAnimateScreenOff() && sleepingFromKeyguard);
- mDozeScrimController.setDozing(mDozing);
- mKeyguardIndicationController.setDozing(mDozing);
mNotificationPanel.setDozing(mDozing, animate, mWakeUpTouchLocation,
mDozeServiceHost.wasPassivelyInterrupted());
- mNotificationLogger.setDozing(mDozing);
- mGroupManager.setDozing(mDozing);
updateQsExpansionEnabled();
Trace.endSection();
}
@@ -3442,13 +3439,6 @@ public class StatusBar extends SystemUI implements DemoMode,
updateQsExpansionEnabled();
mKeyguardViewMediator.setAodShowing(mDozing);
- //TODO: make these folks listeners of StatusBarStateController.onDozingChanged
- mStatusBarWindowController.setDozing(mDozing);
- mStatusBarKeyguardViewManager.setDozing(mDozing);
- if (mAmbientIndicationContainer instanceof DozeReceiver) {
- ((DozeReceiver) mAmbientIndicationContainer).setDozing(mDozing);
- }
-
mEntryManager.updateNotifications();
updateDozingState();
updateScrimController();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index df99a9c13855..484fe110b28a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -59,7 +59,8 @@ import java.util.ArrayList;
* which is in turn, reported to this class by the current
* {@link com.android.keyguard.KeyguardViewBase}.
*/
-public class StatusBarKeyguardViewManager implements RemoteInputController.Callback {
+public class StatusBarKeyguardViewManager implements RemoteInputController.Callback,
+ StatusBarStateController.StateListener {
// When hiding the Keyguard with timing supplied from WindowManager, better be early than late.
private static final long HIDE_TIMING_CORRECTION_MS = - 16 * 3;
@@ -150,6 +151,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mLockPatternUtils = lockPatternUtils;
mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
KeyguardUpdateMonitor.getInstance(context).registerCallback(mUpdateMonitorCallback);
+ Dependency.get(StatusBarStateController.class).addListener(this);
}
public void registerStatusBar(StatusBar statusBar,
@@ -334,7 +336,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
updateStates();
}
- public void setDozing(boolean dozing) {
+ private void setDozing(boolean dozing) {
if (mDozing != dozing) {
mDozing = dozing;
if (dozing || mBouncer.needsFullscreenBouncer() || mOccluded) {
@@ -781,6 +783,16 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
}
}
+ @Override
+ public void onStateChanged(int newState) {
+ // Nothing
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ setDozing(isDozing);
+ }
+
private static class DismissWithActionRequest {
final OnDismissAction dismissAction;
final Runnable cancelAction;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
index 4c24a21fc4b0..f81ffe9ecb76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarSignalPolicy.java
@@ -38,6 +38,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.NetworkController.IconState;
import com.android.systemui.statusbar.policy.NetworkControllerImpl;
import com.android.systemui.statusbar.policy.SecurityController;
+import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import java.util.ArrayList;
import java.util.List;
@@ -88,11 +89,13 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
mNetworkController = Dependency.get(NetworkController.class);
mSecurityController = Dependency.get(SecurityController.class);
+ Dependency.get(TunerService.class).addTunable(this, StatusBarIconController.ICON_BLACKLIST);
mNetworkController.addCallback(this);
mSecurityController.addCallback(this);
}
public void destroy() {
+ Dependency.get(TunerService.class).removeTunable(this);
mNetworkController.removeCallback(this);
mSecurityController.removeCallback(this);
}
@@ -137,6 +140,7 @@ public class StatusBarSignalPolicy implements NetworkControllerImpl.SignalCallba
mBlockWifi = blockWifi || mForceBlockWifi;
// Re-register to get new callbacks.
mNetworkController.removeCallback(this);
+ mNetworkController.addCallback(this);
}
}
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 0d37b550d4e0..11de9413b13f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -76,7 +76,6 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
private final State mCurrentState = new State();
private OtherwisedCollapsedListener mListener;
- private final StateListener mStateListener = this::setStatusBarState;
private final SysuiColorExtractor mColorExtractor = Dependency.get(SysuiColorExtractor.class);
public StatusBarWindowController(Context context) {
@@ -564,6 +563,18 @@ public class StatusBarWindowController implements Callback, Dumpable, Configurat
}
}
+ private final StateListener mStateListener = new StateListener() {
+ @Override
+ public void onStateChanged(int newState) {
+ setStatusBarState(newState);
+ }
+
+ @Override
+ public void onDozingChanged(boolean isDozing) {
+ setDozing(isDozing);
+ }
+ };
+
/**
* Custom listener to pipe data back to plugins about whether or not the status bar would be
* collapsed if not for the plugin.
diff --git a/packages/SystemUI/tests/Android.mk b/packages/SystemUI/tests/Android.mk
index aac37a290edc..b32bf99ad53d 100644
--- a/packages/SystemUI/tests/Android.mk
+++ b/packages/SystemUI/tests/Android.mk
@@ -39,7 +39,7 @@ LOCAL_JAVA_LIBRARIES := \
telephony-common \
android.test.base \
android.car \
- android.car.user
+ android.car.userlib
LOCAL_AAPT_FLAGS := --extra-packages com.android.systemui:com.android.keyguard
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
index b5f67c06b2d1..098fa62f4044 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java
@@ -15,22 +15,13 @@ package com.android.systemui.statusbar.notification.stack;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyLong;
-import static org.mockito.ArgumentMatchers.eq;
-import static org.mockito.Mockito.atLeastOnce;
-import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.mockitoSession;
-import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -38,49 +29,34 @@ import static org.mockito.Mockito.when;
import android.animation.Animator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.content.Context;
-import android.graphics.Rect;
import android.os.Handler;
-import android.os.IPowerManager;
-import android.os.Looper;
-import android.os.PowerManager;
import android.service.notification.StatusBarNotification;
-import android.support.test.annotation.UiThreadTest;
import android.support.test.filters.SmallTest;
import android.support.test.runner.AndroidJUnit4;
-import android.testing.TestableLooper.RunWithLooper;
+import android.testing.UiThreadTest;
import android.view.MotionEvent;
-import android.view.VelocityTracker;
import android.view.View;
-import android.view.MotionEvent;
import com.android.systemui.SwipeHelper;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper.SnoozeOption;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.statusbar.notification.row.NotificationMenuRow;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
-import org.mockito.MockitoSession;
-import org.mockito.invocation.InvocationOnMock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
import org.mockito.stubbing.Answer;
-import java.util.ArrayList;
-
/**
* Tests for {@link NotificationSwipeHelper}.
*/
@SmallTest
@RunWith(AndroidJUnit4.class)
+@UiThreadTest
public class NotificationSwipeHelperTest extends SysuiTestCase {
private NotificationSwipeHelper mSwipeHelper;
@@ -96,7 +72,6 @@ public class NotificationSwipeHelperTest extends SysuiTestCase {
@Rule public MockitoRule mockito = MockitoJUnit.rule();
@Before
- @UiThreadTest
public void setUp() throws Exception {
mCallback = mock(NotificationSwipeHelper.NotificationCallback.class);
mListener = mock(NotificationMenuRowPlugin.OnMenuEventListener.class);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index d3842b74990c..4205ac7d9f86 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -21,14 +21,11 @@ import static android.content.Context.AUTOFILL_MANAGER_SERVICE;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sFullScreenMode;
-import static com.android.server.autofill.Helper.sPartitionMaxCount;
-import static com.android.server.autofill.Helper.sVisibleDatasetsMaxCount;
import static com.android.server.autofill.Helper.sVerbose;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
-import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.ActivityThread;
import android.content.BroadcastReceiver;
@@ -38,13 +35,10 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.graphics.Rect;
-import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
-import android.os.Handler;
import android.os.IBinder;
import android.os.Parcelable;
import android.os.RemoteCallback;
@@ -53,7 +47,6 @@ import android.os.ResultReceiver;
import android.os.ShellCallback;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.UserManagerInternal;
import android.provider.Settings;
import android.service.autofill.FillEventHistory;
import android.service.autofill.UserData;
@@ -63,7 +56,6 @@ import android.util.ArrayMap;
import android.util.LocalLog;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseBooleanArray;
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillManagerInternal;
@@ -73,14 +65,12 @@ import android.view.autofill.IAutoFillManagerClient;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.internal.content.PackageMonitor;
-import com.android.internal.os.BackgroundThread;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.Preconditions;
+import com.android.server.AbstractMasterSystemService;
import com.android.server.FgThread;
import com.android.server.LocalServices;
-import com.android.server.SystemService;
import com.android.server.autofill.ui.AutoFillUI;
import java.io.FileDescriptor;
@@ -98,10 +88,13 @@ import java.util.Objects;
* {@link AutofillManagerServiceImpl} per user; the real work is done by
* {@link AutofillManagerServiceImpl} itself.
*/
-public final class AutofillManagerService extends SystemService {
+public final class AutofillManagerService
+ extends AbstractMasterSystemService<AutofillManagerServiceImpl> {
private static final String TAG = "AutofillManagerService";
+ private static final Object sLock = AutofillManagerService.class;
+
static final String RECEIVER_BUNDLE_EXTRA_SESSIONS = "sessions";
private static final char COMPAT_PACKAGE_DELIMITER = ':';
@@ -109,26 +102,27 @@ public final class AutofillManagerService extends SystemService {
private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_BEGIN = '[';
private static final char COMPAT_PACKAGE_URL_IDS_BLOCK_END = ']';
- private final Context mContext;
- private final AutoFillUI mUi;
-
- private final Object mLock = new Object();
/**
- * Cache of {@link AutofillManagerServiceImpl} per user id.
- * <p>
- * It has to be mapped by user id because the same current user could have simultaneous sessions
- * associated to different user profiles (for example, in a multi-window environment or when
- * device has work profiles).
+ * Maximum number of partitions that can be allowed in a session.
+ *
+ * <p>Can be modified using {@code cmd autofill set max_partitions} or through
+ * {@link android.provider.Settings.Global#AUTOFILL_MAX_PARTITIONS_SIZE}.
*/
- @GuardedBy("mLock")
- private SparseArray<AutofillManagerServiceImpl> mServicesCache = new SparseArray<>();
+ @GuardedBy("sLock")
+ private static int sPartitionMaxCount = AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE;
/**
- * Users disabled due to {@link UserManager} restrictions.
+ * Maximum number of visible datasets in the dataset picker UI, or {@code 0} to use default
+ * value from resources.
+ *
+ * <p>Can be modified using {@code cmd autofill set max_visible_datasets} or through
+ * {@link android.provider.Settings.Global#AUTOFILL_MAX_VISIBLE_DATASETS}.
*/
- @GuardedBy("mLock")
- private final SparseBooleanArray mDisabledUsers = new SparseBooleanArray();
+ @GuardedBy("sLock")
+ private static int sVisibleDatasetsMaxCount = 0;
+
+ private final AutoFillUI mUi;
private final LocalLog mRequestsHistory = new LocalLog(20);
private final LocalLog mUiLatencyHistory = new LocalLog(20);
@@ -148,22 +142,19 @@ public final class AutofillManagerService extends SystemService {
// beneath it is brought back to top. Ideally, we should just hide the UI and
// bring it back when the activity resumes.
synchronized (mLock) {
- for (int i = 0; i < mServicesCache.size(); i++) {
- mServicesCache.valueAt(i).destroyFinishedSessionsLocked();
- }
+ visitServicesLocked((s) -> s.destroyFinishedSessionsLocked());
}
-
mUi.hideAll(null);
}
}
};
+ // TODO(b/117779333): move to superclass / create super-class for ShellCommand
@GuardedBy("mLock")
private boolean mAllowInstantService;
public AutofillManagerService(Context context) {
- super(context);
- mContext = context;
+ super(context, UserManager.DISALLOW_AUTOFILL);
mUi = new AutoFillUI(ActivityThread.currentActivityThread().getSystemUiContext());
setLogLevelFromSettings();
@@ -172,199 +163,91 @@ public final class AutofillManagerService extends SystemService {
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- mContext.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
-
- // Hookup with UserManager to disable service when necessary.
- final UserManager um = context.getSystemService(UserManager.class);
- final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
- final List<UserInfo> users = um.getUsers();
- for (int i = 0; i < users.size(); i++) {
- final int userId = users.get(i).id;
- final boolean disabled = umi.getUserRestriction(userId, UserManager.DISALLOW_AUTOFILL);
- if (disabled) {
- Slog.i(TAG, "Disabling Autofill for user " + userId);
- mDisabledUsers.put(userId, disabled);
- }
- }
- umi.addUserRestrictionsListener((userId, newRestrictions, prevRestrictions) -> {
- final boolean disabledNow =
- newRestrictions.getBoolean(UserManager.DISALLOW_AUTOFILL, false);
- synchronized (mLock) {
- final boolean disabledBefore = mDisabledUsers.get(userId);
- if (disabledBefore == disabledNow) {
- // Nothing changed, do nothing.
- if (sDebug) {
- Slog.d(TAG, "Autofill restriction did not change for user " + userId);
- return;
- }
- }
- Slog.i(TAG, "Updating Autofill for user " + userId + ": disabled=" + disabledNow);
- mDisabledUsers.put(userId, disabledNow);
- updateCachedServiceLocked(userId, disabledNow);
- }
- });
- startTrackingPackageChanges();
+ context.registerReceiver(mBroadcastReceiver, filter, null, FgThread.getHandler());
}
- private void startTrackingPackageChanges() {
- PackageMonitor monitor = new PackageMonitor() {
- @Override
- public void onSomePackagesChanged() {
- synchronized (mLock) {
- updateCachedServiceLocked(getChangingUserId());
- }
- }
-
- @Override
- public void onPackageUpdateFinished(String packageName, int uid) {
- synchronized (mLock) {
- final String activePackageName = getActiveAutofillServicePackageName();
- if (packageName.equals(activePackageName)) {
- removeCachedServiceLocked(getChangingUserId());
- } else {
- handlePackageUpdateLocked(packageName);
- }
- }
- }
+ @Override // from MasterSystemService
+ protected String getServiceSettingsProperty() {
+ return Settings.Secure.AUTOFILL_SERVICE;
+ }
- @Override
- public void onPackageRemoved(String packageName, int uid) {
- synchronized (mLock) {
- final int userId = getChangingUserId();
- final AutofillManagerServiceImpl userState = peekServiceForUserLocked(userId);
- if (userState != null) {
- final ComponentName componentName = userState.getServiceComponentName();
- if (componentName != null) {
- if (packageName.equals(componentName.getPackageName())) {
- handleActiveAutofillServiceRemoved(userId);
- }
- }
- }
- }
- }
+ @Override // from MasterSystemService
+ protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver,
+ @NonNull ContentObserver observer) {
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES), false, observer,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_LOGGING_LEVEL), false, observer,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE), false, observer,
+ UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS), false, observer,
+ UserHandle.USER_ALL);
+ }
- @Override
- public boolean onHandleForceStop(Intent intent, String[] packages,
- int uid, boolean doit) {
+ @Override // from MasterSystemService
+ protected void onSettingsChanged(int userId, @NonNull String property) {
+ switch (property) {
+ case Settings.Global.AUTOFILL_LOGGING_LEVEL:
+ setLogLevelFromSettings();
+ break;
+ case Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE:
+ setMaxPartitionsFromSettings();
+ break;
+ case Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS:
+ setMaxVisibleDatasetsFromSettings();
+ break;
+ default:
+ Slog.w(TAG, "Unexpected property (" + property + "); updating cache instead");
+ // fall through
+ case Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES:
synchronized (mLock) {
- final String activePackageName = getActiveAutofillServicePackageName();
- for (String pkg : packages) {
- if (pkg.equals(activePackageName)) {
- if (!doit) {
- return true;
- }
- removeCachedServiceLocked(getChangingUserId());
- } else {
- handlePackageUpdateLocked(pkg);
- }
- }
+ updateCachedServiceLocked(userId);
}
- return false;
- }
-
- private void handleActiveAutofillServiceRemoved(int userId) {
- removeCachedServiceLocked(userId);
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
- Settings.Secure.AUTOFILL_SERVICE, null, userId);
- }
+ }
+ }
- private String getActiveAutofillServicePackageName() {
- final int userId = getChangingUserId();
- final AutofillManagerServiceImpl userState = peekServiceForUserLocked(userId);
- if (userState == null) {
- return null;
- }
- final ComponentName serviceComponent = userState.getServiceComponentName();
- if (serviceComponent == null) {
- return null;
- }
- return serviceComponent.getPackageName();
- }
+ @Override // from MasterSystemService
+ protected AutofillManagerServiceImpl newServiceLocked(int resolvedUserId, boolean disabled) {
+ return new AutofillManagerServiceImpl(this, mLock, mRequestsHistory,
+ mUiLatencyHistory, mWtfHistory, resolvedUserId, mUi, mAutofillCompatState,
+ disabled);
+ }
- @GuardedBy("mLock")
- private void handlePackageUpdateLocked(String packageName) {
- final int size = mServicesCache.size();
- for (int i = 0; i < size; i++) {
- mServicesCache.valueAt(i).handlePackageUpdateLocked(packageName);
- }
- }
- };
+ @Override // MasterSystemService
+ protected AutofillManagerServiceImpl removeCachedServiceLocked(int userId) {
+ final AutofillManagerServiceImpl service = super.removeCachedServiceLocked(userId);
+ if (service != null) {
+ service.destroyLocked();
+ mAutofillCompatState.removeCompatibilityModeRequests(userId);
+ }
+ return service;
+ }
- // package changes
- monitor.register(mContext, null, UserHandle.ALL, true);
+ @Override // from MasterSystemService
+ protected void onServiceEnabledLocked(@NonNull AutofillManagerServiceImpl service, int userId) {
+ addCompatibilityModeRequestsLocked(service, userId);
}
- @Override
+ @Override // from SystemService
public void onStart() {
publishBinderService(AUTOFILL_MANAGER_SERVICE, new AutoFillManagerServiceStub());
publishLocalService(AutofillManagerInternal.class, mLocalService);
}
- @Override
- public void onBootPhase(int phase) {
- if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
- new SettingsObserver(BackgroundThread.getHandler());
- }
- }
-
- @Override
- public void onUnlockUser(int userId) {
- synchronized (mLock) {
- updateCachedServiceLocked(userId);
- }
- }
-
- @Override
+ @Override // from SystemService
public void onSwitchUser(int userHandle) {
if (sDebug) Slog.d(TAG, "Hiding UI when user switched");
mUi.hideAll(null);
}
- @Override
- public void onCleanupUser(int userId) {
- synchronized (mLock) {
- removeCachedServiceLocked(userId);
- }
- }
-
- /**
- * Gets the service instance for an user.
- *
- * @return service instance.
- */
- @GuardedBy("mLock")
- @NonNull
- AutofillManagerServiceImpl getServiceForUserLocked(int userId) {
- final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userId, false, false, null, null);
- AutofillManagerServiceImpl service = mServicesCache.get(resolvedUserId);
- if (service == null) {
- service = new AutofillManagerServiceImpl(mContext, mLock, mRequestsHistory,
- mUiLatencyHistory, mWtfHistory, resolvedUserId, mUi,
- mAutofillCompatState, mDisabledUsers.get(resolvedUserId));
- mServicesCache.put(userId, service);
- addCompatibilityModeRequestsLocked(service, userId);
- }
- return service;
- }
-
- /**
- * Peeks the service instance for a user.
- *
- * @return service instance or {@code null} if not already present
- */
- @GuardedBy("mLock")
- @Nullable
- AutofillManagerServiceImpl peekServiceForUserLocked(int userId) {
- final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
- Binder.getCallingUid(), userId, false, false, null, null);
- return mServicesCache.get(resolvedUserId);
- }
-
// Called by Shell command.
void destroySessions(int userId, IResultReceiver receiver) {
Slog.i(TAG, "destroySessions() for userId " + userId);
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
synchronized (mLock) {
if (userId != UserHandle.USER_ALL) {
@@ -373,10 +256,7 @@ public final class AutofillManagerService extends SystemService {
service.destroySessionsLocked();
}
} else {
- final int size = mServicesCache.size();
- for (int i = 0; i < size; i++) {
- mServicesCache.valueAt(i).destroySessionsLocked();
- }
+ visitServicesLocked((s) -> s.destroySessionsLocked());
}
}
@@ -390,7 +270,7 @@ public final class AutofillManagerService extends SystemService {
// Called by Shell command.
void listSessions(int userId, IResultReceiver receiver) {
Slog.i(TAG, "listSessions() for userId " + userId);
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
final Bundle resultData = new Bundle();
final ArrayList<String> sessions = new ArrayList<>();
@@ -402,10 +282,7 @@ public final class AutofillManagerService extends SystemService {
service.listSessionsLocked(sessions);
}
} else {
- final int size = mServicesCache.size();
- for (int i = 0; i < size; i++) {
- mServicesCache.valueAt(i).listSessionsLocked(sessions);
- }
+ visitServicesLocked((s) -> s.listSessionsLocked(sessions));
}
}
@@ -420,25 +297,22 @@ public final class AutofillManagerService extends SystemService {
// Called by Shell command.
void reset() {
Slog.i(TAG, "reset()");
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
synchronized (mLock) {
- final int size = mServicesCache.size();
- for (int i = 0; i < size; i++) {
- mServicesCache.valueAt(i).destroyLocked();
- }
- mServicesCache.clear();
+ visitServicesLocked((s) -> s.destroyLocked());
+ clearCacheLocked();
}
}
// Called by Shell command.
void setLogLevel(int level) {
Slog.i(TAG, "setLogLevel(): " + level);
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
final long token = Binder.clearCallingIdentity();
try {
- Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.putInt(getContext().getContentResolver(),
Settings.Global.AUTOFILL_LOGGING_LEVEL, level);
} finally {
Binder.restoreCallingIdentity(token);
@@ -447,7 +321,7 @@ public final class AutofillManagerService extends SystemService {
private void setLogLevelFromSettings() {
final int level = Settings.Global.getInt(
- mContext.getContentResolver(),
+ getContext().getContentResolver(),
Settings.Global.AUTOFILL_LOGGING_LEVEL, AutofillManager.DEFAULT_LOGGING_LEVEL);
boolean debug = false;
boolean verbose = false;
@@ -465,14 +339,13 @@ public final class AutofillManagerService extends SystemService {
+ ", verbose=" + verbose);
}
synchronized (mLock) {
- setDebugLocked(debug);
- setVerboseLocked(verbose);
+ setLoggingLevelsLocked(debug, verbose);
}
}
// Called by Shell command.
int getLogLevel() {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
synchronized (mLock) {
if (sVerbose) return AutofillManager.FLAG_ADD_CLIENT_VERBOSE;
@@ -483,7 +356,7 @@ public final class AutofillManagerService extends SystemService {
// Called by Shell command.
int getMaxPartitions() {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
synchronized (mLock) {
return sPartitionMaxCount;
@@ -492,12 +365,12 @@ public final class AutofillManagerService extends SystemService {
// Called by Shell command.
void setMaxPartitions(int max) {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
Slog.i(TAG, "setMaxPartitions(): " + max);
final long token = Binder.clearCallingIdentity();
try {
- Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.putInt(getContext().getContentResolver(),
Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE, max);
} finally {
Binder.restoreCallingIdentity(token);
@@ -505,33 +378,33 @@ public final class AutofillManagerService extends SystemService {
}
private void setMaxPartitionsFromSettings() {
- final int max = Settings.Global.getInt(mContext.getContentResolver(),
+ final int max = Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE,
AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE);
if (sDebug) Slog.d(TAG, "setMaxPartitionsFromSettings(): " + max);
- synchronized (mLock) {
+ synchronized (sLock) {
sPartitionMaxCount = max;
}
}
// Called by Shell command.
int getMaxVisibleDatasets() {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
- synchronized (mLock) {
+ synchronized (sLock) {
return sVisibleDatasetsMaxCount;
}
}
// Called by Shell command.
void setMaxVisibleDatasets(int max) {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
Slog.i(TAG, "setMaxVisibleDatasets(): " + max);
final long token = Binder.clearCallingIdentity();
try {
- Settings.Global.putInt(mContext.getContentResolver(),
+ Settings.Global.putInt(getContext().getContentResolver(),
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, max);
} finally {
Binder.restoreCallingIdentity(token);
@@ -539,11 +412,11 @@ public final class AutofillManagerService extends SystemService {
}
private void setMaxVisibleDatasetsFromSettings() {
- final int max = Settings.Global.getInt(mContext.getContentResolver(),
+ final int max = Settings.Global.getInt(getContext().getContentResolver(),
Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS, 0);
if (sDebug) Slog.d(TAG, "setMaxVisibleDatasetsFromSettings(): " + max);
- synchronized (mLock) {
+ synchronized (sLock) {
sVisibleDatasetsMaxCount = max;
}
}
@@ -551,10 +424,10 @@ public final class AutofillManagerService extends SystemService {
// Called by Shell command.
void getScore(@Nullable String algorithmName, @NonNull String value1,
@NonNull String value2, @NonNull RemoteCallback callback) {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
final FieldClassificationStrategy strategy =
- new FieldClassificationStrategy(mContext, UserHandle.USER_CURRENT);
+ new FieldClassificationStrategy(getContext(), UserHandle.USER_CURRENT);
strategy.getScores(callback, algorithmName, null,
Arrays.asList(AutofillValue.forText(value1)), new String[] { value2 });
@@ -562,19 +435,19 @@ public final class AutofillManagerService extends SystemService {
// Called by Shell command.
Boolean getFullScreenMode() {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
return sFullScreenMode;
}
// Called by Shell command.
void setFullScreenMode(@Nullable Boolean mode) {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
sFullScreenMode = mode;
}
// Called by Shell command.
boolean getAllowInstantService() {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
synchronized (mLock) {
return mAllowInstantService;
}
@@ -582,59 +455,21 @@ public final class AutofillManagerService extends SystemService {
// Called by Shell command.
void setAllowInstantService(boolean mode) {
- mContext.enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
+ getContext().enforceCallingPermission(MANAGE_AUTO_FILL, TAG);
Slog.i(TAG, "setAllowInstantService(): " + mode);
synchronized (mLock) {
mAllowInstantService = mode;
}
}
- private void setDebugLocked(boolean debug) {
+ private void setLoggingLevelsLocked(boolean debug, boolean verbose) {
com.android.server.autofill.Helper.sDebug = debug;
android.view.autofill.Helper.sDebug = debug;
- }
+ this.debug = debug;
- private void setVerboseLocked(boolean verbose) {
com.android.server.autofill.Helper.sVerbose = verbose;
android.view.autofill.Helper.sVerbose = verbose;
- }
-
- /**
- * Removes a cached service for a given user.
- */
- @GuardedBy("mLock")
- private void removeCachedServiceLocked(int userId) {
- final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
- if (service != null) {
- mServicesCache.delete(userId);
- service.destroyLocked();
- mAutofillCompatState.removeCompatibilityModeRequests(userId);
- }
- }
-
- /**
- * Updates a cached service for a given user.
- */
- @GuardedBy("mLock")
- private void updateCachedServiceLocked(int userId) {
- updateCachedServiceLocked(userId, mDisabledUsers.get(userId));
- }
-
- /**
- * Updates a cached service for a given user.
- */
- @GuardedBy("mLock")
- private void updateCachedServiceLocked(int userId, boolean disabled) {
- AutofillManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
- service.destroySessionsLocked();
- service.updateLocked(disabled);
- if (!service.isEnabledLocked()) {
- removeCachedServiceLocked(userId);
- } else {
- addCompatibilityModeRequestsLocked(service, userId);
- }
- }
+ this.verbose = verbose;
}
private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service
@@ -664,7 +499,7 @@ public final class AutofillManagerService extends SystemService {
private String getWhitelistedCompatModePackagesFromSettings() {
return Settings.Global.getString(
- mContext.getContentResolver(),
+ getContext().getContentResolver(),
Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES);
}
@@ -758,6 +593,24 @@ public final class AutofillManagerService extends SystemService {
return compatPackages;
}
+ /**
+ * Gets the maximum number of partitions / fill requests.
+ */
+ public static int getPartitionMaxCount() {
+ synchronized (sLock) {
+ return sPartitionMaxCount;
+ }
+ }
+
+ /**
+ * Gets the maxium number of datasets visible in the UI.
+ */
+ public static int getVisibleDatasetsMaxCount() {
+ synchronized (sLock) {
+ return sVisibleDatasetsMaxCount;
+ }
+ }
+
private final class LocalService extends AutofillManagerInternal {
@Override
public void onBackKeyPressed() {
@@ -889,20 +742,24 @@ public final class AutofillManagerService extends SystemService {
}
private void dump(String prefix, PrintWriter pw) {
- if (mUserSpecs == null) {
- pw.println("N/A");
- return;
- }
- pw.println();
- final String prefix2 = prefix + " ";
- for (int i = 0; i < mUserSpecs.size(); i++) {
- final int user = mUserSpecs.keyAt(i);
- pw.print(prefix); pw.print("User: "); pw.println(user);
- final ArrayMap<String, PackageCompatState> perUser = mUserSpecs.valueAt(i);
- for (int j = 0; j < perUser.size(); j++) {
- final String packageName = perUser.keyAt(j);
- final PackageCompatState state = perUser.valueAt(j);
- pw.print(prefix2); pw.print(packageName); pw.print(": "); pw.println(state);
+ synchronized (mLock) {
+ if (mUserSpecs == null) {
+ pw.println("N/A");
+ return;
+ }
+ pw.println();
+ final String prefix2 = prefix + " ";
+ for (int i = 0; i < mUserSpecs.size(); i++) {
+ final int user = mUserSpecs.keyAt(i);
+ pw.print(prefix);
+ pw.print("User: ");
+ pw.println(user);
+ final ArrayMap<String, PackageCompatState> perUser = mUserSpecs.valueAt(i);
+ for (int j = 0; j < perUser.size(); j++) {
+ final String packageName = perUser.keyAt(j);
+ final PackageCompatState state = perUser.valueAt(j);
+ pw.print(prefix2); pw.print(packageName); pw.print(": "); pw.println(state);
+ }
}
}
}
@@ -971,7 +828,7 @@ public final class AutofillManagerService extends SystemService {
Preconditions.checkArgument(userId == UserHandle.getUserId(getCallingUid()), "userId");
try {
- mContext.getPackageManager().getPackageInfoAsUser(packageName, 0, userId);
+ getContext().getPackageManager().getPackageInfoAsUser(packageName, 0, userId);
} catch (PackageManager.NameNotFoundException e) {
throw new IllegalArgumentException(packageName + " is not a valid package", e);
}
@@ -1139,7 +996,7 @@ public final class AutofillManagerService extends SystemService {
boolean restored = false;
synchronized (mLock) {
- final AutofillManagerServiceImpl service = mServicesCache.get(userId);
+ final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service != null) {
restored = service.restoreSession(sessionId, getCallingUid(), activityToken,
appCallback);
@@ -1216,7 +1073,7 @@ public final class AutofillManagerService extends SystemService {
public void isServiceSupported(int userId, @NonNull IResultReceiver receiver) {
boolean supported = false;
synchronized (mLock) {
- supported = !mDisabledUsers.get(userId);
+ supported = !isDisabledLocked(userId);
}
send(receiver, supported);
}
@@ -1253,7 +1110,7 @@ public final class AutofillManagerService extends SystemService {
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
boolean showHistory = true;
boolean uiOnly = false;
@@ -1280,102 +1137,48 @@ public final class AutofillManagerService extends SystemService {
return;
}
- boolean oldDebug = sDebug;
final String prefix = " ";
- final String prefix2 = " ";
+ boolean realDebug = sDebug;
+ boolean realVerbose = sVerbose;
try {
+ sDebug = sVerbose = true;
synchronized (mLock) {
- oldDebug = sDebug;
- setDebugLocked(true);
- pw.print("Debug mode: "); pw.println(oldDebug);
- pw.print("Verbose mode: "); pw.println(sVerbose);
- pw.print("Disabled users: "); pw.println(mDisabledUsers);
+ pw.print("sDebug: "); pw.print(realDebug);
+ pw.print(" sVerbose: "); pw.println(realVerbose);
+ // Dump per-user services
+ dumpLocked("", pw);
pw.print("Max partitions per session: "); pw.println(sPartitionMaxCount);
pw.print("Max visible datasets: "); pw.println(sVisibleDatasetsMaxCount);
if (sFullScreenMode != null) {
pw.print("Overridden full-screen mode: "); pw.println(sFullScreenMode);
}
pw.println("User data constraints: "); UserData.dumpConstraints(prefix, pw);
- final int size = mServicesCache.size();
- pw.print("Cached services: ");
- if (size == 0) {
- pw.println("none");
- } else {
- pw.println(size);
- for (int i = 0; i < size; i++) {
- pw.print("\nService at index "); pw.println(i);
- final AutofillManagerServiceImpl impl = mServicesCache.valueAt(i);
- impl.dumpLocked(prefix, pw);
- }
- }
mUi.dump(pw);
pw.print("Autofill Compat State: ");
- mAutofillCompatState.dump(prefix2, pw);
- pw.print(prefix2); pw.print("from settings: ");
+ mAutofillCompatState.dump(prefix, pw);
+ pw.print("from settings: ");
pw.println(getWhitelistedCompatModePackagesFromSettings());
pw.print("Allow instant service: "); pw.println(mAllowInstantService);
- }
- if (showHistory) {
- pw.println(); pw.println("Requests history:"); pw.println();
- mRequestsHistory.reverseDump(fd, pw, args);
- pw.println(); pw.println("UI latency history:"); pw.println();
- mUiLatencyHistory.reverseDump(fd, pw, args);
- pw.println(); pw.println("WTF history:"); pw.println();
- mWtfHistory.reverseDump(fd, pw, args);
+ if (showHistory) {
+ pw.println(); pw.println("Requests history:"); pw.println();
+ mRequestsHistory.reverseDump(fd, pw, args);
+ pw.println(); pw.println("UI latency history:"); pw.println();
+ mUiLatencyHistory.reverseDump(fd, pw, args);
+ pw.println(); pw.println("WTF history:"); pw.println();
+ mWtfHistory.reverseDump(fd, pw, args);
+ }
}
} finally {
- setDebugLocked(oldDebug);
+ sDebug = realDebug;
+ sVerbose = realVerbose;
}
}
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err,
String[] args, ShellCallback callback, ResultReceiver resultReceiver) {
- (new AutofillManagerServiceShellCommand(AutofillManagerService.this)).exec(
+ new AutofillManagerServiceShellCommand(AutofillManagerService.this).exec(
this, in, out, err, args, callback, resultReceiver);
}
}
-
- private final class SettingsObserver extends ContentObserver {
- SettingsObserver(Handler handler) {
- super(handler);
- ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.AUTOFILL_SERVICE), false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Secure.getUriFor(
- Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.AUTOFILL_LOGGING_LEVEL), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE), false, this,
- UserHandle.USER_ALL);
- resolver.registerContentObserver(Settings.Global.getUriFor(
- Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS), false, this,
- UserHandle.USER_ALL);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
- if (sVerbose) Slog.v(TAG, "onChange(): uri=" + uri + ", userId=" + userId);
- switch (uri.getLastPathSegment()) {
- case Settings.Global.AUTOFILL_LOGGING_LEVEL:
- setLogLevelFromSettings();
- break;
- case Settings.Global.AUTOFILL_MAX_PARTITIONS_SIZE:
- setMaxPartitionsFromSettings();
- break;
- case Settings.Global.AUTOFILL_MAX_VISIBLE_DATASETS:
- setMaxVisibleDatasetsFromSettings();
- break;
- default:
- synchronized (mLock) {
- updateCachedServiceLocked(userId);
- }
- }
- }
- }
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index 14d68cb853d6..48103559afb6 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -25,19 +25,14 @@ import static com.android.server.autofill.Helper.sVerbose;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.ActivityTaskManager;
import android.app.ActivityManagerInternal;
-import android.app.AppGlobals;
+import android.app.ActivityTaskManager;
import android.app.IActivityTaskManager;
import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ServiceInfo;
import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
import android.metrics.LogMaker;
import android.os.AsyncTask;
import android.os.Binder;
@@ -49,7 +44,6 @@ import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings;
import android.service.autofill.AutofillService;
import android.service.autofill.AutofillServiceInfo;
@@ -60,7 +54,6 @@ import android.service.autofill.FillEventHistory.Event;
import android.service.autofill.FillResponse;
import android.service.autofill.IAutoFillService;
import android.service.autofill.UserData;
-import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.DebugUtils;
@@ -77,6 +70,7 @@ import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
+import com.android.server.AbstractPerUserSystemService;
import com.android.server.LocalServices;
import com.android.server.autofill.AutofillManagerService.AutofillCompatState;
import com.android.server.autofill.ui.AutoFillUI;
@@ -91,7 +85,8 @@ import java.util.Random;
* app's {@link IAutoFillService} implementation.
*
*/
-final class AutofillManagerServiceImpl {
+final class AutofillManagerServiceImpl
+ extends AbstractPerUserSystemService<AutofillManagerServiceImpl> {
private static final String TAG = "AutofillManagerServiceImpl";
private static final int MAX_SESSION_ID_CREATE_TRIES = 2048;
@@ -99,9 +94,6 @@ final class AutofillManagerServiceImpl {
/** Minimum interval to prune abandoned sessions */
private static final int MAX_ABANDONED_SESSION_MILLIS = 30000;
- private final int mUserId;
- private final Context mContext;
- private final Object mLock;
private final AutoFillUI mUi;
private final MetricsLogger mMetricsLogger = new MetricsLogger();
@@ -132,23 +124,11 @@ final class AutofillManagerServiceImpl {
private ArrayMap<ComponentName, Long> mDisabledActivities;
/**
- * Whether service was disabled for user due to {@link UserManager} restrictions.
- */
- @GuardedBy("mLock")
- private boolean mDisabled;
-
- /**
* Data used for field classification.
*/
@GuardedBy("mLock")
private UserData mUserData;
- /**
- * Caches whether the setup completed for the current user.
- */
- @GuardedBy("mLock")
- private boolean mSetupComplete;
-
private final Handler mHandler = new Handler(Looper.getMainLooper(), null, true);
/**
@@ -170,116 +150,27 @@ final class AutofillManagerServiceImpl {
/** When was {@link PruneTask} last executed? */
private long mLastPrune = 0;
- AutofillManagerServiceImpl(Context context, Object lock, LocalLog requestsHistory,
+ AutofillManagerServiceImpl(AutofillManagerService master, Object lock, LocalLog requestsHistory,
LocalLog uiLatencyHistory, LocalLog wtfHistory, int userId, AutoFillUI ui,
AutofillCompatState autofillCompatState, boolean disabled) {
- mContext = context;
- mLock = lock;
+ super(master, lock, userId);
+
mRequestsHistory = requestsHistory;
mUiLatencyHistory = uiLatencyHistory;
mWtfHistory = wtfHistory;
- mUserId = userId;
mUi = ui;
- mFieldClassificationStrategy = new FieldClassificationStrategy(context, userId);
+ mFieldClassificationStrategy = new FieldClassificationStrategy(getContext(), userId);
mAutofillCompatState = autofillCompatState;
updateLocked(disabled);
}
@GuardedBy("mLock")
- private int getServiceUidLocked() {
- if (mInfo == null) {
- Slog.w(TAG, "getServiceUidLocked(): no mInfo");
- return -1;
- }
- return mInfo.getServiceInfo().applicationInfo.uid;
- }
-
-
- @Nullable
- String[] getUrlBarResourceIdsForCompatMode(@NonNull String packageName) {
- return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId);
- }
-
- @Nullable
- String getServicePackageName() {
- final ComponentName serviceComponent = getServiceComponentName();
- if (serviceComponent != null) {
- return serviceComponent.getPackageName();
- }
- return null;
- }
-
- @Nullable
- ComponentName getServiceComponentName() {
- synchronized (mLock) {
- if (mInfo == null) {
- return null;
- }
- return mInfo.getServiceInfo().getComponentName();
- }
- }
-
- int getTargedSdkLocked() {
- if (mInfo == null) {
- return 0;
- }
- return mInfo.getServiceInfo().applicationInfo.targetSdkVersion;
- }
-
- private boolean isSetupCompletedLocked() {
- final String setupComplete = Settings.Secure.getStringForUser(
- mContext.getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
- return "1".equals(setupComplete);
- }
-
- private String getComponentNameFromSettings() {
- return Settings.Secure.getStringForUser(
- mContext.getContentResolver(), Settings.Secure.AUTOFILL_SERVICE, mUserId);
- }
-
- @GuardedBy("mLock")
- void updateLocked(boolean disabled) {
- final boolean wasEnabled = isEnabledLocked();
- if (sVerbose) {
- Slog.v(TAG, "updateLocked(u=" + mUserId + "): wasEnabled=" + wasEnabled
- + ", mSetupComplete= " + mSetupComplete
- + ", disabled=" + disabled + ", mDisabled=" + mDisabled);
- }
- mSetupComplete = isSetupCompletedLocked();
- mDisabled = disabled;
- ComponentName serviceComponent = null;
- ServiceInfo serviceInfo = null;
- final String componentName = getComponentNameFromSettings();
- if (!TextUtils.isEmpty(componentName)) {
- try {
- serviceComponent = ComponentName.unflattenFromString(componentName);
- serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
- 0, mUserId);
- if (serviceInfo == null) {
- Slog.e(TAG, "Bad AutofillService name: " + componentName);
- }
- } catch (RuntimeException | RemoteException e) {
- Slog.e(TAG, "Error getting service info for '" + componentName + "': " + e);
- serviceInfo = null;
- }
- }
- try {
- if (serviceInfo != null) {
- mInfo = new AutofillServiceInfo(mContext, serviceComponent, mUserId);
- if (sDebug) Slog.d(TAG, "Set component for user " + mUserId + " as " + mInfo);
- } else {
- mInfo = null;
- if (sDebug) {
- Slog.d(TAG, "Reset component for user " + mUserId + " (" + componentName + ")");
- }
- }
- } catch (Exception e) {
- Slog.e(TAG, "Bad AutofillServiceInfo for '" + componentName + "': " + e);
- mInfo = null;
- }
- final boolean isEnabled = isEnabledLocked();
- if (wasEnabled != isEnabled) {
- if (!isEnabled) {
+ @Override // from PerUserSystemService
+ protected boolean updateLocked(boolean disabled) {
+ destroySessionsLocked();
+ final boolean enabledChanged = super.updateLocked(disabled);
+ if (enabledChanged) {
+ if (!isEnabledLocked()) {
final int sessionCount = mSessions.size();
for (int i = sessionCount - 1; i >= 0; i--) {
final Session session = mSessions.valueAt(i);
@@ -288,6 +179,19 @@ final class AutofillManagerServiceImpl {
}
sendStateToClients(false);
}
+ return enabledChanged;
+ }
+
+ @Override // from PerUserSystemService
+ protected ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent)
+ throws NameNotFoundException {
+ mInfo = new AutofillServiceInfo(getContext(), serviceComponent, mUserId);
+ return mInfo.getServiceInfo();
+ }
+
+ @Nullable
+ String[] getUrlBarResourceIdsForCompatMode(@NonNull String packageName) {
+ return mAutofillCompatState.getUrlBarResourceIds(packageName, mUserId);
}
@GuardedBy("mLock")
@@ -469,7 +373,7 @@ final class AutofillManagerServiceImpl {
if (componentName.equals(ComponentName.unflattenFromString(autoFillService))) {
mMetricsLogger.action(MetricsEvent.AUTOFILL_SERVICE_DISABLED_SELF,
componentName.getPackageName());
- Settings.Secure.putStringForUser(mContext.getContentResolver(),
+ Settings.Secure.putStringForUser(getContext().getContentResolver(),
Settings.Secure.AUTOFILL_SERVICE, null, mUserId);
destroySessionsLocked();
} else {
@@ -501,7 +405,7 @@ final class AutofillManagerServiceImpl {
assertCallerLocked(componentName, compatMode);
- final Session newSession = new Session(this, mUi, mContext, mHandler, mUserId, mLock,
+ final Session newSession = new Session(this, mUi, getContext(), mHandler, mUserId, mLock,
sessionId, taskId, uid, activityToken, appCallbackToken, hasCallback,
mUiLatencyHistory, mWtfHistory, mInfo.getServiceInfo().getComponentName(),
componentName, compatMode, bindInstantServiceAllowed, flags);
@@ -515,7 +419,7 @@ final class AutofillManagerServiceImpl {
*/
private void assertCallerLocked(@NonNull ComponentName componentName, boolean compatMode) {
final String packageName = componentName.getPackageName();
- final PackageManager pm = mContext.getPackageManager();
+ final PackageManager pm = getContext().getPackageManager();
final int callingUid = Binder.getCallingUid();
final int packageUid;
try {
@@ -651,7 +555,8 @@ final class AutofillManagerServiceImpl {
}
@GuardedBy("mLock")
- void handlePackageUpdateLocked(String packageName) {
+ @Override // from PerUserSystemService
+ protected void handlePackageUpdateLocked(@NonNull String packageName) {
final ServiceInfo serviceInfo = mFieldClassificationStrategy.getServiceInfo();
if (serviceInfo != null && serviceInfo.packageName.equals(packageName)) {
resetExtServiceLocked();
@@ -691,29 +596,6 @@ final class AutofillManagerServiceImpl {
}
/**
- * Gets the user-visibile name of the service this service binds to, or {@code null} if the
- * service is disabled.
- */
- @Nullable
- @GuardedBy("mLock")
- public CharSequence getServiceLabelLocked() {
- return mInfo == null ? null : mInfo.getServiceInfo().loadSafeLabel(
- mContext.getPackageManager(), 0 /* do not ellipsize */,
- PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE | PackageItemInfo.SAFE_LABEL_FLAG_TRIM);
- }
-
- /**
- * Gets the icon of the service this service binds to, or {@code null} if the service is
- * disabled.
- */
- @NonNull
- @Nullable
- @GuardedBy("mLock")
- Drawable getServiceIconLocked() {
- return mInfo == null ? null : mInfo.getServiceInfo().loadIcon(mContext.getPackageManager());
- }
-
- /**
* Initializes the last fill selection after an autofill service returned a new
* {@link FillResponse}.
*/
@@ -941,11 +823,13 @@ final class AutofillManagerServiceImpl {
return true;
}
+ @Override
@GuardedBy("mLock")
- void dumpLocked(String prefix, PrintWriter pw) {
+ protected void dumpLocked(String prefix, PrintWriter pw) {
+ super.dumpLocked(prefix, pw);
+
final String prefix2 = prefix + " ";
- pw.print(prefix); pw.print("User: "); pw.println(mUserId);
pw.print(prefix); pw.print("UID: "); pw.println(getServiceUidLocked());
pw.print(prefix); pw.print("Autofill Service Info: ");
if (mInfo == null) {
@@ -958,9 +842,8 @@ final class AutofillManagerServiceImpl {
}
pw.print(prefix); pw.print("Component from settings: ");
pw.println(getComponentNameFromSettings());
- pw.print(prefix); pw.print("Default component: ");
- pw.println(mContext.getString(R.string.config_defaultAutofillService));
- pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
+ pw.print(prefix); pw.print("Default component: "); pw.println(getContext()
+ .getString(R.string.config_defaultAutofillService));
pw.print(prefix); pw.print("Field classification enabled: ");
pw.println(isFieldClassificationEnabledLocked());
pw.print(prefix); pw.print("Compat pkgs: ");
@@ -970,7 +853,6 @@ final class AutofillManagerServiceImpl {
} else {
pw.println(compatPkgs);
}
- pw.print(prefix); pw.print("Setup complete: "); pw.println(mSetupComplete);
pw.print(prefix); pw.print("Last prune: "); pw.println(mLastPrune);
pw.print(prefix); pw.print("Disabled apps: ");
@@ -1158,11 +1040,6 @@ final class AutofillManagerServiceImpl {
return true;
}
- @GuardedBy("mLock")
- boolean isEnabledLocked() {
- return mSetupComplete && mInfo != null && !mDisabled;
- }
-
/**
* Called by {@link Session} when service asked to disable autofill for an app.
*/
@@ -1270,7 +1147,7 @@ final class AutofillManagerServiceImpl {
// Called by internally, no need to check UID.
boolean isFieldClassificationEnabledLocked() {
return Settings.Secure.getIntForUser(
- mContext.getContentResolver(),
+ getContext().getContentResolver(),
Settings.Secure.AUTOFILL_FEATURE_FIELD_CLASSIFICATION, 1,
mUserId) == 1;
}
diff --git a/services/autofill/java/com/android/server/autofill/Helper.java b/services/autofill/java/com/android/server/autofill/Helper.java
index 420c2be008cb..3c0da7d2d388 100644
--- a/services/autofill/java/com/android/server/autofill/Helper.java
+++ b/services/autofill/java/com/android/server/autofill/Helper.java
@@ -28,20 +28,21 @@ import android.util.ArraySet;
import android.util.Slog;
import android.view.WindowManager;
import android.view.autofill.AutofillId;
-import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;
import java.io.PrintWriter;
+import java.util.ArrayDeque;
import java.util.ArrayList;
-import java.util.LinkedList;
public final class Helper {
private static final String TAG = "AutofillHelper";
+ // TODO(b/117779333): get rid of sDebug / sVerbose and always use the service variables instead
+
/**
* Defines a logging flag that can be dynamically changed at runtime using
* {@code cmd autofill set log_level debug} or through
@@ -57,23 +58,6 @@ public final class Helper {
public static boolean sVerbose = false;
/**
- * Maximum number of partitions that can be allowed in a session.
- *
- * <p>Can be modified using {@code cmd autofill set max_partitions} or through
- * {@link android.provider.Settings.Global#AUTOFILL_MAX_PARTITIONS_SIZE}.
- */
- static int sPartitionMaxCount = AutofillManager.DEFAULT_MAX_PARTITIONS_SIZE;
-
- /**
- * Maximum number of visible datasets in the dataset picker UI, or {@code 0} to use default
- * value from resources.
- *
- * <p>Can be modified using {@code cmd autofill set max_visible_datasets} or through
- * {@link android.provider.Settings.Global#AUTOFILL_MAX_VISIBLE_DATASETS}.
- */
- public static int sVisibleDatasetsMaxCount = 0;
-
- /**
* When non-null, overrides whether the UI should be shown on full-screen mode.
*
* <p>Note: access to this variable is not synchronized because it's "final" on real usage -
@@ -162,7 +146,7 @@ public final class Helper {
private static ViewNode findViewNode(@NonNull AssistStructure structure,
@NonNull ViewNodeFilter filter) {
- final LinkedList<ViewNode> nodesToProcess = new LinkedList<>();
+ final ArrayDeque<ViewNode> nodesToProcess = new ArrayDeque<>();
final int numWindowNodes = structure.getWindowNodeCount();
for (int i = 0; i < numWindowNodes; i++) {
nodesToProcess.add(structure.getWindowNodeAt(i).getRootViewNode());
diff --git a/services/autofill/java/com/android/server/autofill/RemoteFillService.java b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
index d1b09ca1aca8..9aa9d7c52818 100644
--- a/services/autofill/java/com/android/server/autofill/RemoteFillService.java
+++ b/services/autofill/java/com/android/server/autofill/RemoteFillService.java
@@ -18,7 +18,6 @@ package com.android.server.autofill;
import static android.service.autofill.FillRequest.INVALID_REQUEST_ID;
-import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sVerbose;
@@ -26,17 +25,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.content.IntentSender;
-import android.content.ServiceConnection;
-import android.os.Build;
-import android.os.Handler;
import android.os.IBinder;
-import android.os.IBinder.DeathRecipient;
import android.os.ICancellationSignal;
+import android.os.IInterface;
import android.os.RemoteException;
-import android.os.SystemClock;
-import android.os.UserHandle;
import android.service.autofill.AutofillService;
import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
@@ -47,59 +40,17 @@ import android.service.autofill.SaveRequest;
import android.text.format.DateUtils;
import android.util.Slog;
-import com.android.internal.annotations.GuardedBy;
-import com.android.server.FgThread;
+import com.android.server.AbstractRemoteService;
-import java.io.PrintWriter;
-import java.lang.ref.WeakReference;
+final class RemoteFillService extends AbstractRemoteService {
-/**
- * This class represents a remote fill service. It abstracts away the binding
- * and unbinding from the remote implementation.
- *
- * <p>Clients can call methods of this class without worrying about when and
- * how to bind/unbind/timeout. All state of this class is modified on a handler
- * thread.
- */
-final class RemoteFillService implements DeathRecipient {
- private static final String LOG_TAG = "RemoteFillService";
- // How long after the last interaction with the service we would unbind
private static final long TIMEOUT_IDLE_BIND_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
-
- // How long after we make a remote request to a fill service we timeout
private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 5 * DateUtils.SECOND_IN_MILLIS;
- private static final int MSG_UNBIND = 3;
-
- private final Context mContext;
-
- private final ComponentName mComponentName;
-
- private final Intent mIntent;
-
private final FillServiceCallbacks mCallbacks;
-
- private final int mUserId;
-
- private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
-
- private final Handler mHandler;
-
- private final boolean mBindInstantServiceAllowed;
-
private IAutoFillService mAutoFillService;
- private boolean mBinding;
-
- private boolean mDestroyed;
-
- private boolean mServiceDied;
-
- private boolean mCompleted;
-
- private PendingRequest mPendingRequest;
-
- public interface FillServiceCallbacks {
+ public interface FillServiceCallbacks extends VultureCallback {
void onFillRequestSuccess(int requestId, @Nullable FillResponse response,
@NonNull String servicePackageName, int requestFlags);
void onFillRequestFailure(int requestId, @Nullable CharSequence message);
@@ -109,48 +60,42 @@ final class RemoteFillService implements DeathRecipient {
// TODO(b/80093094): add timeout here too?
void onSaveRequestFailure(@Nullable CharSequence message,
@NonNull String servicePackageName);
- void onServiceDied(RemoteFillService service);
}
- public RemoteFillService(Context context, ComponentName componentName,
- int userId, FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
- mContext = context;
+ RemoteFillService(Context context, ComponentName componentName, int userId,
+ FillServiceCallbacks callbacks, boolean bindInstantServiceAllowed) {
+ super(context, AutofillService.SERVICE_INTERFACE, componentName, userId, callbacks,
+ bindInstantServiceAllowed, sVerbose);
mCallbacks = callbacks;
- mComponentName = componentName;
- mIntent = new Intent(AutofillService.SERVICE_INTERFACE).setComponent(mComponentName);
- mUserId = userId;
- mHandler = new Handler(FgThread.getHandler().getLooper());
- mBindInstantServiceAllowed = bindInstantServiceAllowed;
}
- public void destroy() {
- mHandler.sendMessage(obtainMessage(RemoteFillService::handleDestroy, this));
+ @Override
+ protected void onConnectedStateChanged(boolean state) {
+ if (mAutoFillService == null) {
+ Slog.w(mTag, "onConnectedStateChanged(): null service");
+ return;
+ }
+ try {
+ mAutoFillService.onConnectedStateChanged(state);
+ } catch (Exception e) {
+ Slog.w(mTag, "Exception calling onConnectedStateChanged(): " + e);
+ }
}
- private void handleDestroy() {
- if (checkIfDestroyed()) return;
- if (mPendingRequest != null) {
- mPendingRequest.cancel();
- mPendingRequest = null;
- }
- ensureUnbound();
- mDestroyed = true;
+ @Override
+ protected IInterface getServiceInterface(IBinder service) {
+ mAutoFillService = IAutoFillService.Stub.asInterface(service);
+ return mAutoFillService;
}
@Override
- public void binderDied() {
- mHandler.sendMessage(obtainMessage(
- RemoteFillService::handleBinderDied, this));
+ protected long getTimeoutIdleBindMillis() {
+ return TIMEOUT_IDLE_BIND_MILLIS;
}
- private void handleBinderDied() {
- if (checkIfDestroyed()) return;
- if (mAutoFillService != null) {
- mAutoFillService.asBinder().unlinkToDeath(this, 0);
- }
- mAutoFillService = null;
- mServiceDied = true;
- mCallbacks.onServiceDied(this);
+ @Override
+ protected long getRemoteRequestMillis() {
+ return TIMEOUT_REMOTE_REQUEST_MILLIS;
}
/**
@@ -162,8 +107,9 @@ final class RemoteFillService implements DeathRecipient {
* @return the id of the canceled request, or {@link FillRequest#INVALID_REQUEST_ID} if no
* {@link PendingFillRequest} was canceled.
*/
+ // TODO(b/117779333): move this logic to super class (and make mPendingRequest private)
public int cancelCurrentRequest() {
- if (mDestroyed) {
+ if (isDestroyed()) {
return INVALID_REQUEST_ID;
}
@@ -190,118 +136,6 @@ final class RemoteFillService implements DeathRecipient {
scheduleRequest(new PendingSaveRequest(request, this));
}
- private void scheduleRequest(PendingRequest pendingRequest) {
- mHandler.sendMessage(obtainMessage(
- RemoteFillService::handlePendingRequest, this, pendingRequest));
- }
-
- // Note: we are dumping without a lock held so this is a bit racy but
- // adding a lock to a class that offloads to a handler thread would
- // mean adding a lock adding overhead to normal runtime operation.
- public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
- String tab = " ";
- pw.append(prefix).append("service:").println();
- pw.append(prefix).append(tab).append("userId=")
- .append(String.valueOf(mUserId)).println();
- pw.append(prefix).append(tab).append("componentName=")
- .append(mComponentName.flattenToString()).println();
- pw.append(prefix).append(tab).append("destroyed=")
- .append(String.valueOf(mDestroyed)).println();
- pw.append(prefix).append(tab).append("bound=")
- .append(String.valueOf(isBound())).println();
- pw.append(prefix).append(tab).append("hasPendingRequest=")
- .append(String.valueOf(mPendingRequest != null)).println();
- pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
- pw.println();
- }
-
- private void cancelScheduledUnbind() {
- mHandler.removeMessages(MSG_UNBIND);
- }
-
- private void scheduleUnbind() {
- cancelScheduledUnbind();
- mHandler.sendMessageDelayed(
- obtainMessage(RemoteFillService::handleUnbind, this)
- .setWhat(MSG_UNBIND),
- TIMEOUT_IDLE_BIND_MILLIS);
- }
-
- private void handleUnbind() {
- if (checkIfDestroyed()) return;
- ensureUnbound();
- }
-
- private void handlePendingRequest(PendingRequest pendingRequest) {
- if (checkIfDestroyed()) return;
- if (mCompleted) {
- return;
- }
- if (!isBound()) {
- if (mPendingRequest != null) {
- mPendingRequest.cancel();
- }
- mPendingRequest = pendingRequest;
- ensureBound();
- } else {
- if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] handlePendingRequest()");
- pendingRequest.run();
- if (pendingRequest.isFinal()) {
- mCompleted = true;
- }
- }
- }
-
- private boolean isBound() {
- return mAutoFillService != null;
- }
-
- private void ensureBound() {
- if (isBound() || mBinding) {
- return;
- }
- if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] ensureBound()");
- mBinding = true;
-
- int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
- if (mBindInstantServiceAllowed) {
- flags |= Context.BIND_ALLOW_INSTANT;
- }
-
- final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
- new UserHandle(mUserId));
-
- if (!willBind) {
- Slog.w(LOG_TAG, "[user: " + mUserId + "] could not bind to " + mIntent + " using flags "
- + flags);
- mBinding = false;
-
- if (!mServiceDied) {
- handleBinderDied();
- }
- }
- }
-
- private void ensureUnbound() {
- if (!isBound() && !mBinding) {
- return;
- }
- if (sVerbose) Slog.v(LOG_TAG, "[user: " + mUserId + "] ensureUnbound()");
- mBinding = false;
- if (isBound()) {
- try {
- mAutoFillService.onConnectedStateChanged(false);
- } catch (Exception e) {
- Slog.w(LOG_TAG, "Exception calling onDisconnected(): " + e);
- }
- if (mAutoFillService != null) {
- mAutoFillService.asBinder().unlinkToDeath(this, 0);
- mAutoFillService = null;
- }
- }
- mContext.unbindService(mServiceConnection);
- }
-
private void dispatchOnFillRequestSuccess(@NonNull PendingFillRequest pendingRequest,
@Nullable FillResponse response, int requestFlags) {
mHandler.post(() -> {
@@ -334,12 +168,12 @@ final class RemoteFillService implements DeathRecipient {
try {
cancellationSignal.cancel();
} catch (RemoteException e) {
- Slog.w(LOG_TAG, "Error calling cancellation signal: " + e);
+ Slog.w(mTag, "Error calling cancellation signal: " + e);
}
});
}
- private void dispatchOnSaveRequestSuccess(PendingRequest pendingRequest,
+ private void dispatchOnSaveRequestSuccess(PendingSaveRequest pendingRequest,
IntentSender intentSender) {
mHandler.post(() -> {
if (handleResponseCallbackCommon(pendingRequest)) {
@@ -348,7 +182,7 @@ final class RemoteFillService implements DeathRecipient {
});
}
- private void dispatchOnSaveRequestFailure(PendingRequest pendingRequest,
+ private void dispatchOnSaveRequestFailure(PendingSaveRequest pendingRequest,
@Nullable CharSequence message) {
mHandler.post(() -> {
if (handleResponseCallbackCommon(pendingRequest)) {
@@ -357,162 +191,7 @@ final class RemoteFillService implements DeathRecipient {
});
}
- private boolean handleResponseCallbackCommon(PendingRequest pendingRequest) {
- if (mDestroyed) {
- return false;
- }
- if (mPendingRequest == pendingRequest) {
- mPendingRequest = null;
- }
- if (mPendingRequest == null) {
- scheduleUnbind();
- }
- return true;
- }
-
- private class RemoteServiceConnection implements ServiceConnection {
- @Override
- public void onServiceConnected(ComponentName name, IBinder service) {
- if (mDestroyed || !mBinding) {
- // This is abnormal. Unbinding the connection has been requested already.
- Slog.wtf(LOG_TAG, "onServiceConnected was dispatched after unbindService.");
- return;
- }
- mBinding = false;
- mAutoFillService = IAutoFillService.Stub.asInterface(service);
- try {
- service.linkToDeath(RemoteFillService.this, 0);
- } catch (RemoteException re) {
- handleBinderDied();
- return;
- }
- try {
- mAutoFillService.onConnectedStateChanged(true);
- } catch (RemoteException e) {
- Slog.w(LOG_TAG, "Exception calling onConnected(): " + e);
- }
-
- if (mPendingRequest != null) {
- PendingRequest pendingRequest = mPendingRequest;
- mPendingRequest = null;
- handlePendingRequest(pendingRequest);
- }
-
- mServiceDied = false;
- }
-
- @Override
- public void onServiceDisconnected(ComponentName name) {
- mBinding = true;
- mAutoFillService = null;
- }
- }
-
- private boolean checkIfDestroyed() {
- if (mDestroyed) {
- if (sVerbose) {
- Slog.v(LOG_TAG, "Not handling operation as service for "
- + mComponentName + " is already destroyed");
- }
- }
- return mDestroyed;
- }
-
- private static abstract class PendingRequest implements Runnable {
- protected final Object mLock = new Object();
- private final WeakReference<RemoteFillService> mWeakService;
-
- private final Runnable mTimeoutTrigger;
- private final Handler mServiceHandler;
-
- @GuardedBy("mLock")
- private boolean mCancelled;
-
- @GuardedBy("mLock")
- private boolean mCompleted;
-
- PendingRequest(RemoteFillService service) {
- mWeakService = new WeakReference<>(service);
- mServiceHandler = service.mHandler;
- mTimeoutTrigger = () -> {
- synchronized (mLock) {
- if (mCancelled) {
- return;
- }
- mCompleted = true;
- }
-
- Slog.w(LOG_TAG, getClass().getSimpleName() + " timed out");
- final RemoteFillService remoteService = mWeakService.get();
- if (remoteService != null) {
- Slog.w(LOG_TAG, getClass().getSimpleName() + " timed out after "
- + TIMEOUT_REMOTE_REQUEST_MILLIS + " ms");
- onTimeout(remoteService);
- }
- };
- mServiceHandler.postAtTime(mTimeoutTrigger,
- SystemClock.uptimeMillis() + TIMEOUT_REMOTE_REQUEST_MILLIS);
- }
-
- protected RemoteFillService getService() {
- return mWeakService.get();
- }
-
- /**
- * Sub-classes must call this method when the remote service finishes, i.e., when it
- * called {@code onFill...} or {@code onSave...}.
- *
- * @return {@code false} in the service is already finished, {@code true} otherwise.
- */
- protected final boolean finish() {
- synchronized (mLock) {
- if (mCompleted || mCancelled) {
- return false;
- }
- mCompleted = true;
- }
- mServiceHandler.removeCallbacks(mTimeoutTrigger);
- return true;
- }
-
- @GuardedBy("mLock")
- protected boolean isCancelledLocked() {
- return mCancelled;
- }
-
- /**
- * Cancels the service.
- *
- * @return {@code false} if service is already canceled, {@code true} otherwise.
- */
- boolean cancel() {
- synchronized (mLock) {
- if (mCancelled || mCompleted) {
- return false;
- }
- mCancelled = true;
- }
-
- mServiceHandler.removeCallbacks(mTimeoutTrigger);
- return true;
- }
-
- /**
- * Called by the self-destructure timeout when the AutofilllService didn't reply to the
- * request on time.
- */
- abstract void onTimeout(RemoteFillService remoteService);
-
- /**
- * @return whether this request leads to a final state where no
- * other requests can be made.
- */
- boolean isFinal() {
- return false;
- }
- }
-
- private static final class PendingFillRequest extends PendingRequest {
+ private static final class PendingFillRequest extends PendingRequest<RemoteFillService> {
private final FillRequest mRequest;
private final IFillCallback mCallback;
private ICancellationSignal mCancellation;
@@ -534,7 +213,7 @@ final class RemoteFillService implements DeathRecipient {
try {
cancellation.cancel();
} catch (RemoteException e) {
- Slog.e(LOG_TAG, "Error requesting a cancellation", e);
+ Slog.e(mTag, "Error requesting a cancellation", e);
}
}
}
@@ -565,7 +244,7 @@ final class RemoteFillService implements DeathRecipient {
}
@Override
- void onTimeout(RemoteFillService remoteService) {
+ protected void onTimeout(RemoteFillService remoteService) {
// NOTE: Must make these 2 calls asynchronously, because the cancellation signal is
// handled by the service, which could block.
final ICancellationSignal cancellation;
@@ -582,17 +261,17 @@ final class RemoteFillService implements DeathRecipient {
public void run() {
synchronized (mLock) {
if (isCancelledLocked()) {
- if (sDebug) Slog.d(LOG_TAG, "run() called after canceled: " + mRequest);
+ if (sDebug) Slog.d(mTag, "run() called after canceled: " + mRequest);
return;
}
}
final RemoteFillService remoteService = getService();
if (remoteService != null) {
- if (sVerbose) Slog.v(LOG_TAG, "calling onFillRequest() for id=" + mRequest.getId());
+ if (sVerbose) Slog.v(mTag, "calling onFillRequest() for id=" + mRequest.getId());
try {
remoteService.mAutoFillService.onFillRequest(mRequest, mCallback);
} catch (RemoteException e) {
- Slog.e(LOG_TAG, "Error calling on fill request", e);
+ Slog.e(mTag, "Error calling on fill request", e);
remoteService.dispatchOnFillRequestFailure(PendingFillRequest.this, null);
}
@@ -611,14 +290,14 @@ final class RemoteFillService implements DeathRecipient {
try {
cancellation.cancel();
} catch (RemoteException e) {
- Slog.e(LOG_TAG, "Error cancelling a fill request", e);
+ Slog.e(mTag, "Error cancelling a fill request", e);
}
}
return true;
}
}
- private static final class PendingSaveRequest extends PendingRequest {
+ private static final class PendingSaveRequest extends PendingRequest<RemoteFillService> {
private final SaveRequest mRequest;
private final ISaveCallback mCallback;
@@ -653,7 +332,7 @@ final class RemoteFillService implements DeathRecipient {
}
@Override
- void onTimeout(RemoteFillService remoteService) {
+ protected void onTimeout(RemoteFillService remoteService) {
remoteService.dispatchOnSaveRequestFailure(PendingSaveRequest.this, null);
}
@@ -661,11 +340,11 @@ final class RemoteFillService implements DeathRecipient {
public void run() {
final RemoteFillService remoteService = getService();
if (remoteService != null) {
- if (sVerbose) Slog.v(LOG_TAG, "calling onSaveRequest()");
+ if (sVerbose) Slog.v(mTag, "calling onSaveRequest()");
try {
remoteService.mAutoFillService.onSaveRequest(mRequest, mCallback);
} catch (RemoteException e) {
- Slog.e(LOG_TAG, "Error calling on save request", e);
+ Slog.e(mTag, "Error calling on save request", e);
remoteService.dispatchOnSaveRequestFailure(PendingSaveRequest.this, null);
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index f85749af54fd..09f915e252ee 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -27,7 +27,6 @@ import static android.view.autofill.AutofillManager.ACTION_VIEW_EXITED;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
import static com.android.server.autofill.Helper.getNumericValue;
import static com.android.server.autofill.Helper.sDebug;
-import static com.android.server.autofill.Helper.sPartitionMaxCount;
import static com.android.server.autofill.Helper.sVerbose;
import static com.android.server.autofill.Helper.toArray;
import static com.android.server.autofill.ViewState.STATE_RESTARTED_SESSION;
@@ -65,7 +64,6 @@ import android.service.autofill.AutofillService;
import android.service.autofill.Dataset;
import android.service.autofill.FieldClassification;
import android.service.autofill.FieldClassification.Match;
-import android.text.TextUtils;
import android.service.autofill.FillContext;
import android.service.autofill.FillRequest;
import android.service.autofill.FillResponse;
@@ -75,10 +73,10 @@ import android.service.autofill.SaveInfo;
import android.service.autofill.SaveRequest;
import android.service.autofill.UserData;
import android.service.autofill.ValueFinder;
+import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LocalLog;
-import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TimeUtils;
@@ -94,6 +92,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.ArrayUtils;
+import com.android.server.AbstractRemoteService;
import com.android.server.autofill.ui.AutoFillUI;
import com.android.server.autofill.ui.PendingUi;
@@ -903,9 +902,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
this, authenticationId, intent, fillInIntent));
}
- // FillServiceCallbacks
+ // VultureCallback
@Override
- public void onServiceDied(RemoteFillService service) {
+ public void onServiceDied(AbstractRemoteService service) {
Slog.w(TAG, "removing session because service died");
forceRemoveSelfLocked();
}
@@ -2095,9 +2094,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
}
final int numResponses = mResponses.size();
- if (numResponses >= sPartitionMaxCount) {
+ if (numResponses >= AutofillManagerService.getPartitionMaxCount()) {
Slog.e(TAG, "Not starting a new partition on " + id + " because session " + this.id
- + " reached maximum of " + sPartitionMaxCount);
+ + " reached maximum of " + AutofillManagerService.getPartitionMaxCount());
return false;
}
@@ -2289,7 +2288,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
requestNewFillResponseOnViewEnteredIfNecessaryLocked(id, viewState, flags);
// Remove the UI if the ViewState has changed.
- if (mCurrentViewId != viewState.id) {
+ if (!Objects.equals(mCurrentViewId, viewState.id)) {
mUi.hideFillUi(this);
mCurrentViewId = viewState.id;
}
@@ -2298,7 +2297,7 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
viewState.update(value, virtualBounds, flags);
break;
case ACTION_VIEW_EXITED:
- if (mCurrentViewId == viewState.id) {
+ if (Objects.equals(mCurrentViewId, viewState.id)) {
if (sVerbose) Slog.d(TAG, "Exiting view " + id);
mUi.hideFillUi(this);
mCurrentViewId = null;
@@ -3077,7 +3076,9 @@ final class Session implements RemoteFillService.FillServiceCallbacks, ViewState
private void wtf(@Nullable Exception e, String fmt, Object...args) {
final String message = String.format(fmt, args);
- mWtfHistory.log(message);
+ synchronized (mLock) {
+ mWtfHistory.log(message);
+ }
if (e != null) {
Slog.wtf(TAG, message, e);
diff --git a/services/autofill/java/com/android/server/autofill/ui/FillUi.java b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
index f79f6ff73d29..d1fe970c0783 100644
--- a/services/autofill/java/com/android/server/autofill/ui/FillUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/FillUi.java
@@ -19,25 +19,22 @@ import static com.android.server.autofill.Helper.paramsToString;
import static com.android.server.autofill.Helper.sDebug;
import static com.android.server.autofill.Helper.sFullScreenMode;
import static com.android.server.autofill.Helper.sVerbose;
-import static com.android.server.autofill.Helper.sVisibleDatasetsMaxCount;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.app.PendingIntent;
import android.content.Context;
-import android.graphics.drawable.Drawable;
-import android.view.ContextThemeWrapper;
-import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.PackageManager;
import android.graphics.Point;
import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
import android.service.autofill.Dataset;
import android.service.autofill.Dataset.DatasetFieldFilter;
import android.service.autofill.FillResponse;
import android.text.TextUtils;
import android.util.Slog;
import android.util.TypedValue;
+import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
@@ -60,6 +57,7 @@ import android.widget.TextView;
import com.android.internal.R;
import com.android.server.UiThread;
+import com.android.server.autofill.AutofillManagerService;
import com.android.server.autofill.Helper;
import java.io.PrintWriter;
@@ -193,8 +191,8 @@ final class FillUi {
}
});
- if (sVisibleDatasetsMaxCount > 0) {
- mVisibleDatasetsMaxCount = sVisibleDatasetsMaxCount;
+ if (AutofillManagerService.getVisibleDatasetsMaxCount() > 0) {
+ mVisibleDatasetsMaxCount = AutofillManagerService.getVisibleDatasetsMaxCount();
if (sVerbose) {
Slog.v(TAG, "overriding maximum visible datasets to " + mVisibleDatasetsMaxCount);
}
diff --git a/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java b/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java
new file mode 100644
index 000000000000..9cab1ed15b9e
--- /dev/null
+++ b/services/autofill/java/com/android/server/intelligence/ContentCaptureSession.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.intelligence;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.service.intelligence.IntelligenceService;
+import android.service.intelligence.InteractionContext;
+import android.service.intelligence.InteractionSessionId;
+import android.util.Slog;
+import android.view.intelligence.ContentCaptureEvent;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+import com.android.server.AbstractRemoteService;
+import com.android.server.intelligence.RemoteIntelligenceService.RemoteIntelligenceServiceCallbacks;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+final class ContentCaptureSession implements RemoteIntelligenceServiceCallbacks {
+
+ private static final String TAG = "ContentCaptureSession";
+
+ private final Object mLock;
+ private final IBinder mActivityToken;
+
+ private final IntelligencePerUserService mService;
+ private final RemoteIntelligenceService mRemoteService;
+ private final InteractionContext mInterationContext;
+ private final InteractionSessionId mId;
+
+ ContentCaptureSession(@NonNull Context context, int userId, @NonNull Object lock,
+ @NonNull IBinder activityToken, @NonNull IntelligencePerUserService service,
+ @NonNull ComponentName serviceComponentName, @NonNull ComponentName appComponentName,
+ int taskId, int displayId, @NonNull InteractionSessionId sessionId, int flags,
+ boolean bindInstantServiceAllowed, boolean verbose) {
+ mLock = lock;
+ mActivityToken = activityToken;
+ mService = service;
+ mId = Preconditions.checkNotNull(sessionId);
+ mRemoteService = new RemoteIntelligenceService(context,
+ IntelligenceService.SERVICE_INTERFACE, serviceComponentName, userId, this,
+ bindInstantServiceAllowed, verbose);
+ mInterationContext = new InteractionContext(appComponentName, taskId, displayId, flags);
+ }
+
+ /**
+ * Notifies the {@link IntelligenceService} that the service started.
+ */
+ @GuardedBy("mLock")
+ public void notifySessionStartedLocked() {
+ mRemoteService.onSessionLifecycleRequest(mInterationContext, mId);
+ }
+
+ /**
+ * Notifies the {@link IntelligenceService} of a batch of events.
+ */
+ public void sendEventsLocked(List<ContentCaptureEvent> events) {
+ mRemoteService.onContentCaptureEventsRequest(mId, events);
+ }
+
+ /**
+ * Cleans up the session and remove itself from the service.
+ *
+ * @param notifyRemoteService whether it should trigger a {@link
+ * IntelligenceService#onDestroyInteractionSession(InteractionSessionId)}
+ * request.
+ */
+ @GuardedBy("mLock")
+ public void removeSelfLocked(boolean notifyRemoteService) {
+ try {
+ if (notifyRemoteService) {
+ mRemoteService.onSessionLifecycleRequest(/* context= */ null, mId);
+ }
+ } finally {
+ mService.removeSessionLocked(mId);
+ }
+ }
+
+ @Override // from RemoteScreenObservationServiceCallbacks
+ public void onServiceDied(AbstractRemoteService service) {
+ // TODO(b/111276913): implement (remove session from PerUserSession?)
+ if (mService.isDebug()) {
+ Slog.d(TAG, "onServiceDied() for " + mId);
+ }
+ synchronized (mLock) {
+ removeSelfLocked(/* notifyRemoteService= */ false);
+ }
+ }
+
+ @Override // from RemoteScreenObservationServiceCallbacks
+ public void onFailureOrTimeout(boolean timedOut) {
+ // TODO(b/111276913): log metrics on whether timed out or not
+ if (mService.isDebug()) {
+ Slog.d(TAG, "onFailureOrTimeout(" + mId + "): timed out=" + timedOut);
+ }
+ synchronized (mLock) {
+ removeSelfLocked(/* notifyRemoteService= */ false);
+ }
+ }
+
+ @GuardedBy("mLock")
+ public void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
+ pw.print(prefix); pw.print("id: "); mId.dump(pw); pw.println();
+ pw.print(prefix); pw.print("context: "); mInterationContext.dump(pw); pw.println();
+ pw.print(prefix); pw.print("activity token: "); pw.println(mActivityToken);
+ }
+
+ @Override
+ public String toString() {
+ return "ContentCaptureSession[id=" + mId.getValue() + ", act=" + mActivityToken + "]";
+ }
+}
diff --git a/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java b/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java
new file mode 100644
index 000000000000..43d4a4476c11
--- /dev/null
+++ b/services/autofill/java/com/android/server/intelligence/IntelligenceManagerService.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.intelligence;
+
+import static android.content.Context.INTELLIGENCE_MANAGER_SERVICE;
+
+import android.annotation.NonNull;
+import android.app.ActivityManagerInternal;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.UserManager;
+import android.service.intelligence.InteractionSessionId;
+import android.view.intelligence.ContentCaptureEvent;
+import android.view.intelligence.IIntelligenceManager;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.IResultReceiver;
+import com.android.internal.util.DumpUtils;
+import com.android.internal.util.Preconditions;
+import com.android.server.AbstractMasterSystemService;
+import com.android.server.LocalServices;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * A service used to observe the contents of the screen.
+ *
+ * <p>The data collected by this service can be analyzed and combined with other sources to provide
+ * contextual data in other areas of the system such as Autofill.
+ */
+public final class IntelligenceManagerService
+ extends AbstractMasterSystemService<IntelligencePerUserService> {
+
+ private static final String TAG = "IntelligenceManagerService";
+
+ @GuardedBy("mLock")
+ private ActivityManagerInternal mAm;
+
+ public IntelligenceManagerService(Context context) {
+ super(context, UserManager.DISALLOW_INTELLIGENCE_CAPTURE);
+ }
+
+ @Override // from MasterSystemService
+ protected String getServiceSettingsProperty() {
+ // TODO(b/111276913): STOPSHIP temporary settings, until it's set by resourcs + cmd
+ return "intel_service";
+ }
+
+ @Override // from MasterSystemService
+ protected IntelligencePerUserService newServiceLocked(int resolvedUserId,
+ boolean disabled) {
+ return new IntelligencePerUserService(this, mLock, resolvedUserId);
+ }
+
+ @Override // from SystemService
+ public void onStart() {
+ publishBinderService(INTELLIGENCE_MANAGER_SERVICE,
+ new IntelligenceManagerServiceStub());
+ }
+
+ private ActivityManagerInternal getAmInternal() {
+ synchronized (mLock) {
+ if (mAm == null) {
+ mAm = LocalServices.getService(ActivityManagerInternal.class);
+ }
+ }
+ return mAm;
+ }
+
+ final class IntelligenceManagerServiceStub extends IIntelligenceManager.Stub {
+
+ @Override
+ public void startSession(int userId, @NonNull IBinder activityToken,
+ @NonNull ComponentName componentName, @NonNull InteractionSessionId sessionId,
+ int flags, @NonNull IResultReceiver result) {
+ Preconditions.checkNotNull(activityToken);
+ Preconditions.checkNotNull(componentName);
+ Preconditions.checkNotNull(sessionId);
+
+ // TODO(b/111276913): refactor getTaskIdForActivity() to also return ComponentName,
+ // so we don't pass it on startSession (same for Autofill)
+ final int taskId = getAmInternal().getTaskIdForActivity(activityToken, false);
+
+ // TODO(b/111276913): get from AM as well
+ final int displayId = 0;
+
+ synchronized (mLock) {
+ final IntelligencePerUserService service = getServiceForUserLocked(userId);
+ service.startSessionLocked(activityToken, componentName, taskId, displayId,
+ sessionId, flags, result);
+ }
+ }
+
+ @Override
+ public void sendEvents(int userId, @NonNull InteractionSessionId sessionId,
+ @NonNull List<ContentCaptureEvent> events) {
+ Preconditions.checkNotNull(sessionId);
+ Preconditions.checkNotNull(events);
+
+ synchronized (mLock) {
+ final IntelligencePerUserService service = getServiceForUserLocked(userId);
+ service.sendEventsLocked(sessionId, events);
+ }
+ }
+
+ @Override
+ public void finishSession(int userId, @NonNull InteractionSessionId sessionId) {
+ Preconditions.checkNotNull(sessionId);
+
+ synchronized (mLock) {
+ final IntelligencePerUserService service = getServiceForUserLocked(userId);
+ service.finishSessionLocked(sessionId);
+ }
+ }
+
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
+
+ synchronized (mLock) {
+ dumpLocked("", pw);
+ }
+ }
+ }
+}
diff --git a/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java b/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java
new file mode 100644
index 000000000000..584b872c64d0
--- /dev/null
+++ b/services/autofill/java/com/android/server/intelligence/IntelligencePerUserService.java
@@ -0,0 +1,185 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.intelligence;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.service.intelligence.InteractionSessionId;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.view.intelligence.ContentCaptureEvent;
+import android.view.intelligence.IntelligenceManager;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.IResultReceiver;
+import com.android.server.AbstractPerUserSystemService;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Per-user instance of {@link IntelligenceManagerService}.
+ */
+final class IntelligencePerUserService
+ extends AbstractPerUserSystemService<IntelligencePerUserService> {
+
+ private static final String TAG = "IntelligencePerUserService";
+
+ @GuardedBy("mLock")
+ private final ArrayMap<InteractionSessionId, ContentCaptureSession> mSessions =
+ new ArrayMap<>();
+
+ // TODO(b/111276913): add mechanism to prune stale sessions, similar to Autofill's
+
+ protected IntelligencePerUserService(
+ IntelligenceManagerService master, Object lock, int userId) {
+ super(master, lock, userId);
+ }
+
+ @Override // from PerUserSystemService
+ protected ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent)
+ throws NameNotFoundException {
+
+ ServiceInfo si;
+ try {
+ // TODO(b/111276913): must check that either the service is from a system component,
+ // or it matches a service set by shell cmd (so it can be used on CTS tests and when
+ // OEMs are implementing the real service
+ si = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
+ PackageManager.GET_META_DATA, mUserId);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Could not get service for " + serviceComponent + ": " + e);
+ return null;
+ }
+ if (!Manifest.permission.BIND_INTELLIGENCE_SERVICE.equals(si.permission)) {
+ Slog.w(TAG, "IntelligenceService from '" + si.packageName
+ + "' does not require permission "
+ + Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+ throw new SecurityException("Service does not require permission "
+ + Manifest.permission.BIND_INTELLIGENCE_SERVICE);
+ }
+ return si;
+ }
+
+ // TODO(b/111276913): log metrics
+ @GuardedBy("mLock")
+ public void startSessionLocked(@NonNull IBinder activityToken,
+ @NonNull ComponentName componentName, int taskId, int displayId,
+ @NonNull InteractionSessionId sessionId, int flags,
+ @NonNull IResultReceiver resultReceiver) {
+ final ComponentName serviceComponentName = getServiceComponentName();
+ if (serviceComponentName == null) {
+ // TODO(b/111276913): this happens when the system service is starting, we should
+ // probably handle it in a more elegant way (like waiting for boot_complete or
+ // something like that
+ Slog.w(TAG, "startSession(" + activityToken + "): hold your horses");
+ return;
+ }
+
+ ContentCaptureSession session = mSessions.get(sessionId);
+ if (session != null) {
+ if (mMaster.debug) {
+ Slog.d(TAG, "startSession(): reusing session " + sessionId + " for "
+ + componentName);
+ }
+ // TODO(b/111276913): check if local ids match and decide what to do if they don't
+ // TODO(b/111276913): should we call session.notifySessionStartedLocked() again??
+ // if not, move notifySessionStartedLocked() into session constructor
+ sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
+ return;
+ }
+
+ // TODO(b/117779333): get from mMaster once it's moved to superclass
+ final boolean bindInstantServiceAllowed = false;
+
+ session = new ContentCaptureSession(getContext(), mUserId, mLock, activityToken,
+ this, serviceComponentName, componentName, taskId, displayId, sessionId, flags,
+ bindInstantServiceAllowed, mMaster.verbose);
+ if (mMaster.verbose) {
+ Slog.v(TAG, "startSession(): new session for " + componentName + " and id "
+ + sessionId);
+ }
+ mSessions.put(sessionId, session);
+ session.notifySessionStartedLocked();
+ sendToClient(resultReceiver, IntelligenceManager.STATE_ACTIVE);
+ }
+
+ // TODO(b/111276913): log metrics
+ @GuardedBy("mLock")
+ public void finishSessionLocked(@NonNull InteractionSessionId sessionId) {
+ final ContentCaptureSession session = mSessions.get(sessionId);
+ if (session == null) {
+ Slog.w(TAG, "finishSession(): no session with id" + sessionId);
+ return;
+ }
+ if (mMaster.verbose) {
+ Slog.v(TAG, "finishSession(): " + session);
+ }
+ session.removeSelfLocked(true);
+ }
+
+ @GuardedBy("mLock")
+ public void sendEventsLocked(@NonNull InteractionSessionId sessionId,
+ @NonNull List<ContentCaptureEvent> events) {
+ final ContentCaptureSession session = mSessions.get(sessionId);
+ if (session == null) {
+ Slog.w(TAG, "sendEvents(): no session for " + sessionId);
+ return;
+ }
+ if (mMaster.verbose) {
+ Slog.v(TAG, "sendEvents(): id=" + sessionId + "; events =" + events.size());
+ }
+ session.sendEventsLocked(events);
+ }
+
+ @GuardedBy("mLock")
+ public void removeSessionLocked(@NonNull InteractionSessionId sessionId) {
+ mSessions.remove(sessionId);
+ }
+
+ @Override
+ protected void dumpLocked(String prefix, PrintWriter pw) {
+ super.dumpLocked(prefix, pw);
+ if (mSessions.isEmpty()) {
+ pw.print(prefix); pw.println("no sessions");
+ } else {
+ final int size = mSessions.size();
+ pw.print(prefix); pw.print("number sessions: "); pw.println(size);
+ final String prefix2 = prefix + " ";
+ for (int i = 0; i < size; i++) {
+ pw.print(prefix); pw.print("session@"); pw.println(i);
+ final ContentCaptureSession session = mSessions.valueAt(i);
+ session.dumpLocked(prefix2, pw);
+ }
+ }
+ }
+
+ private static void sendToClient(@NonNull IResultReceiver resultReceiver, int value) {
+ try {
+ resultReceiver.send(value, null);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Error async reporting result to client: " + e);
+ }
+ }
+}
diff --git a/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java b/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java
new file mode 100644
index 000000000000..9d241fbf820d
--- /dev/null
+++ b/services/autofill/java/com/android/server/intelligence/RemoteIntelligenceService.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.intelligence;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.service.intelligence.IIntelligenceService;
+import android.service.intelligence.InteractionContext;
+import android.service.intelligence.InteractionSessionId;
+import android.text.format.DateUtils;
+import android.util.Slog;
+import android.view.intelligence.ContentCaptureEvent;
+
+import com.android.server.AbstractRemoteService;
+
+import java.util.List;
+
+final class RemoteIntelligenceService extends AbstractRemoteService {
+
+ private static final String TAG = "RemoteIntelligenceService";
+
+ private static final long TIMEOUT_IDLE_BIND_MILLIS = 2 * DateUtils.MINUTE_IN_MILLIS;
+ private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.MINUTE_IN_MILLIS;
+
+ private final RemoteIntelligenceServiceCallbacks mCallbacks;
+ private IIntelligenceService mService;
+
+ RemoteIntelligenceService(Context context, String serviceInterface,
+ ComponentName componentName, int userId,
+ RemoteIntelligenceServiceCallbacks callbacks, boolean bindInstantServiceAllowed,
+ boolean verbose) {
+ super(context, serviceInterface, componentName, userId, callbacks,
+ bindInstantServiceAllowed, verbose);
+ mCallbacks = callbacks;
+ }
+
+ @Override // from RemoteService
+ protected IInterface getServiceInterface(@NonNull IBinder service) {
+ mService = IIntelligenceService.Stub.asInterface(service);
+ return mService;
+ }
+
+ // TODO(b/111276913): modify super class to allow permanent binding when value is 0 or negative
+ @Override // from RemoteService
+ protected long getTimeoutIdleBindMillis() {
+ // TODO(b/111276913): read from Settings so it can be changed in the field
+ return TIMEOUT_IDLE_BIND_MILLIS;
+ }
+
+ @Override // from RemoteService
+ protected long getRemoteRequestMillis() {
+ // TODO(b/111276913): read from Settings so it can be changed in the field
+ return TIMEOUT_REMOTE_REQUEST_MILLIS;
+ }
+
+ /**
+ * Called by {@link ContentCaptureSession} to generate a call to the
+ * {@link RemoteIntelligenceService} to indicate the session was created (when {@code context}
+ * is not {@code null} or destroyed (when {@code context} is {@code null}).
+ */
+ public void onSessionLifecycleRequest(@Nullable InteractionContext context,
+ @NonNull InteractionSessionId sessionId) {
+ cancelScheduledUnbind();
+ scheduleRequest(new PendingSessionLifecycleRequest(this, context, sessionId));
+ }
+
+ /**
+ * Called by {@link ContentCaptureSession} to send a batch of events to the service.
+ */
+ public void onContentCaptureEventsRequest(@NonNull InteractionSessionId sessionId,
+ @NonNull List<ContentCaptureEvent> events) {
+ cancelScheduledUnbind();
+ scheduleRequest(new PendingOnContentCaptureEventsRequest(this, sessionId, events));
+ }
+
+
+ private abstract static class MyPendingRequest
+ extends PendingRequest<RemoteIntelligenceService> {
+ protected final InteractionSessionId mSessionId;
+
+ private MyPendingRequest(@NonNull RemoteIntelligenceService service,
+ @NonNull InteractionSessionId sessionId) {
+ super(service);
+ mSessionId = sessionId;
+ }
+
+ @Override // from PendingRequest
+ protected final void onTimeout(RemoteIntelligenceService remoteService) {
+ Slog.w(TAG, "timed out handling " + getClass().getSimpleName() + " for "
+ + mSessionId);
+ remoteService.mCallbacks.onFailureOrTimeout(/* timedOut= */ true);
+ }
+
+ @Override // from PendingRequest
+ public final void run() {
+ final RemoteIntelligenceService remoteService = getService();
+ if (remoteService != null) {
+ try {
+ myRun(remoteService);
+ // We don't expect the service to call us back, so we finish right away.
+ finish();
+ } catch (RemoteException e) {
+ Slog.w(TAG, "exception handling " + getClass().getSimpleName() + " for "
+ + mSessionId + ": " + e);
+ remoteService.mCallbacks.onFailureOrTimeout(/* timedOut= */ false);
+ }
+ }
+ }
+
+ protected abstract void myRun(@NonNull RemoteIntelligenceService service)
+ throws RemoteException;
+
+ }
+
+ private static final class PendingSessionLifecycleRequest extends MyPendingRequest {
+
+ private final InteractionContext mContext;
+
+ protected PendingSessionLifecycleRequest(@NonNull RemoteIntelligenceService service,
+ @Nullable InteractionContext context, @NonNull InteractionSessionId sessionId) {
+ super(service, sessionId);
+ mContext = context;
+ }
+
+ @Override // from MyPendingRequest
+ public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException {
+ remoteService.mService.onSessionLifecycle(mContext, mSessionId);
+ }
+ }
+
+ private static final class PendingOnContentCaptureEventsRequest extends MyPendingRequest {
+
+ private final List<ContentCaptureEvent> mEvents;
+
+ protected PendingOnContentCaptureEventsRequest(@NonNull RemoteIntelligenceService service,
+ @NonNull InteractionSessionId sessionId,
+ @NonNull List<ContentCaptureEvent> events) {
+ super(service, sessionId);
+ mEvents = events;
+ }
+
+ @Override // from MyPendingRequest
+ public void myRun(@NonNull RemoteIntelligenceService remoteService) throws RemoteException {
+ remoteService.mService.onContentCaptureEvents(mSessionId, mEvents);
+ }
+ }
+
+ public interface RemoteIntelligenceServiceCallbacks extends VultureCallback {
+ // To keep it simple, we use the same callback for all failures / timeouts.
+ void onFailureOrTimeout(boolean timedOut);
+ }
+}
diff --git a/services/core/java/com/android/server/AbstractMasterSystemService.java b/services/core/java/com/android/server/AbstractMasterSystemService.java
new file mode 100644
index 000000000000..c955daf2fae4
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractMasterSystemService.java
@@ -0,0 +1,507 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.UserInfo;
+import android.database.ContentObserver;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.os.UserManagerInternal;
+import android.provider.Settings;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.content.PackageMonitor;
+import com.android.internal.os.BackgroundThread;
+
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Base class for {@link SystemService SystemServices} that support multi user.
+ *
+ * <p>Subclasses of this service are just a facade for the service binder calls - the "real" work
+ * is done by the {@link AbstractPerUserSystemService} subclasses, which are automatically managed
+ * through an user -> service cache.
+ *
+ * <p>It also takes care of other plumbing tasks such as:
+ *
+ * <ul>
+ * <li>Disabling the service when {@link UserManager} restrictions change.
+ * <li>Refreshing the service when its underlying
+ * {@link #getServiceSettingsProperty() Settings property} changed.
+ * <li>Calling the service when other Settings properties changed.
+ * </ul>
+ *
+ * <p>See {@code com.android.server.autofill.AutofillManagerService} for a concrete
+ * (no pun intended) example of how to use it.
+ *
+ * @param <S> "real" service class.
+ *
+ * @hide
+ */
+// TODO(b/117779333): improve javadoc above instead of using Autofill as an example
+public abstract class AbstractMasterSystemService<S extends AbstractPerUserSystemService<S>>
+ extends SystemService {
+
+ /**
+ * Log tag
+ */
+ protected final String mTag = getClass().getSimpleName();
+
+ /**
+ * Lock used to synchronize access to internal state; should be acquired before calling a
+ * method whose name ends with {@code locked}.
+ */
+ protected final Object mLock = new Object();
+
+ /**
+ * Whether the service should log debug statements.
+ */
+ public boolean verbose = false;
+
+ /**
+ * Whether the service should log verbose statements.
+ */
+ public boolean debug = false;
+
+ /**
+ * Users disabled due to {@link UserManager} restrictions, or {@code null} if the service cannot
+ * be disabled through {@link UserManager}.
+ */
+ @GuardedBy("mLock")
+ @Nullable
+ private final SparseBooleanArray mDisabledUsers;
+
+ /**
+ * Cache of services per user id.
+ */
+ @GuardedBy("mLock")
+ private final SparseArray<S> mServicesCache = new SparseArray<>();
+
+ /**
+ * Default constructor.
+ *
+ * @param context system context.
+ * @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
+ * disables the service.
+ */
+ protected AbstractMasterSystemService(@NonNull Context context,
+ @Nullable String disallowProperty) {
+ super(context);
+
+ if (disallowProperty == null) {
+ mDisabledUsers = null;
+ } else {
+ mDisabledUsers = new SparseBooleanArray();
+ // Hookup with UserManager to disable service when necessary.
+ final UserManager um = context.getSystemService(UserManager.class);
+ final UserManagerInternal umi = LocalServices.getService(UserManagerInternal.class);
+ final List<UserInfo> users = um.getUsers();
+ for (int i = 0; i < users.size(); i++) {
+ final int userId = users.get(i).id;
+ final boolean disabled = umi.getUserRestriction(userId, disallowProperty);
+ if (disabled) {
+ Slog.i(mTag, "Disabling for user " + userId);
+ mDisabledUsers.put(userId, disabled);
+ }
+ }
+ umi.addUserRestrictionsListener((userId, newRestrictions, prevRestrictions) -> {
+ final boolean disabledNow =
+ newRestrictions.getBoolean(disallowProperty, false);
+ synchronized (mLock) {
+ final boolean disabledBefore = mDisabledUsers.get(userId);
+ if (disabledBefore == disabledNow) {
+ // Nothing changed, do nothing.
+ if (debug) {
+ Slog.d(mTag, "Restriction did not change for user " + userId);
+ return;
+ }
+ }
+ Slog.i(mTag, "Updating for user " + userId + ": disabled=" + disabledNow);
+ mDisabledUsers.put(userId, disabledNow);
+ updateCachedServiceLocked(userId, disabledNow);
+ }
+ });
+ }
+ startTrackingPackageChanges();
+ }
+
+ @Override // from SystemService
+ public void onBootPhase(int phase) {
+ if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
+ new SettingsObserver(BackgroundThread.getHandler());
+ }
+ }
+
+ @Override // from SystemService
+ public void onUnlockUser(int userId) {
+ synchronized (mLock) {
+ updateCachedServiceLocked(userId);
+ }
+ }
+
+ @Override // from SystemService
+ public void onCleanupUser(int userId) {
+ synchronized (mLock) {
+ removeCachedServiceLocked(userId);
+ }
+ }
+
+ /**
+ * Creates a new service that will be added to the cache.
+ *
+ * @param resolvedUserId the resolved user id for the service.
+ * @param disabled whether the service is currently disabled (due to {@link UserManager}
+ * restrictions).
+ *
+ * @return a new instance.
+ */
+ protected abstract S newServiceLocked(@UserIdInt int resolvedUserId, boolean disabled);
+
+ /**
+ * Register the service for extra Settings changes (i.e., other than
+ * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
+ * {@link #getServiceSettingsProperty()}, which are automatically handled).
+ *
+ * <p> Example:
+ *
+ * <pre><code>
+ * resolver.registerContentObserver(Settings.Global.getUriFor(
+ * Settings.Global.AUTOFILL_COMPAT_MODE_ALLOWED_PACKAGES), false, observer,
+ * UserHandle.USER_ALL);
+ * </code></pre>
+ *
+ * <p><b>NOTE: </p>it doesn't need to register for
+ * {@link android.provider.Settings.Secure#USER_SETUP_COMPLETE} or
+ * {@link #getServiceSettingsProperty()}.
+ *
+ */
+ @SuppressWarnings("unused")
+ protected void registerForExtraSettingsChanges(@NonNull ContentResolver resolver,
+ @NonNull ContentObserver observer) {
+ }
+
+ /**
+ * Callback for Settings changes that were registered though
+ * {@link #registerForExtraSettingsChanges(ContentResolver, ContentObserver)}.
+ *
+ * @param userId user associated with the change
+ * @param property Settings property changed.
+ */
+ protected void onSettingsChanged(@UserIdInt int userId, @NonNull String property) {
+ }
+
+ /**
+ * Gets the service instance for an user, creating an instance if not present in the cache.
+ */
+ @GuardedBy("mLock")
+ @NonNull
+ protected S getServiceForUserLocked(@UserIdInt int userId) {
+ final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, false, null, null);
+ S service = mServicesCache.get(resolvedUserId);
+ if (service == null) {
+ final boolean disabled = isDisabledLocked(userId);
+ service = newServiceLocked(resolvedUserId, disabled);
+ if (!disabled) {
+ onServiceEnabledLocked(service, resolvedUserId);
+ }
+ mServicesCache.put(userId, service);
+ }
+ return service;
+ }
+
+ /**
+ * Gets the <b>existing</b> service instance for a user, returning {@code null} if not already
+ * present in the cache.
+ */
+ @GuardedBy("mLock")
+ @Nullable
+ protected S peekServiceForUserLocked(int userId) {
+ final int resolvedUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
+ Binder.getCallingUid(), userId, false, false, null, null);
+ return mServicesCache.get(resolvedUserId);
+ }
+
+ /**
+ * Updates a cached service for a given user.
+ */
+ @GuardedBy("mLock")
+ protected void updateCachedServiceLocked(int userId) {
+ updateCachedServiceLocked(userId, isDisabledLocked(userId));
+ }
+
+ /**
+ * Checks whether the service is disabled (through {@link UserManager} restrictions) for the
+ * given user.
+ */
+ protected boolean isDisabledLocked(int userId) {
+ return mDisabledUsers == null ? false : mDisabledUsers.get(userId);
+ }
+
+ /**
+ * Updates a cached service for a given user.
+ *
+ * @param userId user handle.
+ * @param disabled whether the user is disabled.
+ * @return service for the user.
+ */
+ @GuardedBy("mLock")
+ protected S updateCachedServiceLocked(int userId, boolean disabled) {
+ final S service = getServiceForUserLocked(userId);
+ if (service != null) {
+ service.updateLocked(disabled);
+ if (!service.isEnabledLocked()) {
+ removeCachedServiceLocked(userId);
+ } else {
+ onServiceEnabledLocked(service, userId);
+ }
+ }
+ return service;
+ }
+
+ /**
+ * Gets the Settings property that defines the name of the component name used to bind this
+ * service to an external service, or {@code null} when the service is not defined by such
+ * property (for example, if it's a system service defined by framework resources).
+ */
+ @Nullable
+ protected String getServiceSettingsProperty() {
+ return null;
+ }
+
+ /**
+ * Callback called after a new service was added to the cache, or an existing service that was
+ * previously disabled gets enabled.
+ *
+ * <p>By default doesn't do anything, but can be overridden by subclasses.
+ */
+ @SuppressWarnings("unused")
+ protected void onServiceEnabledLocked(S service, @UserIdInt int userId) {
+ }
+
+ /**
+ * Removes a cached service for a given user.
+ *
+ * @return the removed service;
+ */
+ @GuardedBy("mLock")
+ @NonNull
+ protected S removeCachedServiceLocked(@UserIdInt int userId) {
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ mServicesCache.delete(userId);
+ }
+ return service;
+ }
+
+ /**
+ * Visits all services in the cache.
+ */
+ @GuardedBy("mLock")
+ protected void visitServicesLocked(@NonNull Visitor<S> visitor) {
+ final int size = mServicesCache.size();
+ for (int i = 0; i < size; i++) {
+ visitor.visit(mServicesCache.valueAt(i));
+ }
+ }
+
+ /**
+ * Clear the cache by removing all services.
+ */
+ @GuardedBy("mLock")
+ protected void clearCacheLocked() {
+ mServicesCache.clear();
+ }
+
+ // TODO(b/117779333): support proto
+ protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
+ boolean realDebug = debug;
+ boolean realVerbose = verbose;
+
+ try {
+ // Temporarily turn on full logging;
+ debug = verbose = true;
+ final int size = mServicesCache.size();
+ pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
+ pw.print(" Verbose: "); pw.println(realVerbose);
+ pw.print(prefix); pw.print("Disabled users: "); pw.println(mDisabledUsers);
+ pw.print(prefix); pw.print("Settings property: "); pw.println(
+ getServiceSettingsProperty());
+ pw.print(prefix); pw.print("Cached services: ");
+ if (size == 0) {
+ pw.println("none");
+ } else {
+ pw.println(size);
+ final String prefix2 = " ";
+ for (int i = 0; i < size; i++) {
+ pw.print(prefix); pw.print("Service at "); pw.print(i); pw.println(": ");
+ final S service = mServicesCache.valueAt(i);
+ service.dumpLocked(prefix2, pw);
+ pw.println();
+ }
+ }
+ } finally {
+ debug = realDebug;
+ verbose = realVerbose;
+ }
+ }
+
+ private void startTrackingPackageChanges() {
+ PackageMonitor monitor = new PackageMonitor() {
+ @Override
+ public void onSomePackagesChanged() {
+ synchronized (mLock) {
+ updateCachedServiceLocked(getChangingUserId());
+ }
+ }
+
+ @Override
+ public void onPackageUpdateFinished(String packageName, int uid) {
+ synchronized (mLock) {
+ final String activePackageName = getActiveServicePackageName();
+ if (packageName.equals(activePackageName)) {
+ removeCachedServiceLocked(getChangingUserId());
+ } else {
+ handlePackageUpdateLocked(packageName);
+ }
+ }
+ }
+
+ @Override
+ public void onPackageRemoved(String packageName, int uid) {
+ synchronized (mLock) {
+ final int userId = getChangingUserId();
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ final ComponentName componentName = service.getServiceComponentName();
+ if (componentName != null) {
+ if (packageName.equals(componentName.getPackageName())) {
+ handleActiveServiceRemoved(userId);
+ }
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean onHandleForceStop(Intent intent, String[] packages,
+ int uid, boolean doit) {
+ synchronized (mLock) {
+ final String activePackageName = getActiveServicePackageName();
+ for (String pkg : packages) {
+ if (pkg.equals(activePackageName)) {
+ if (!doit) {
+ return true;
+ }
+ removeCachedServiceLocked(getChangingUserId());
+ } else {
+ handlePackageUpdateLocked(pkg);
+ }
+ }
+ }
+ return false;
+ }
+
+ private void handleActiveServiceRemoved(@UserIdInt int userId) {
+ removeCachedServiceLocked(userId);
+ final String serviceSettingsProperty = getServiceSettingsProperty();
+ if (serviceSettingsProperty != null) {
+ Settings.Secure.putStringForUser(getContext().getContentResolver(),
+ serviceSettingsProperty, null, userId);
+ }
+ }
+
+ private String getActiveServicePackageName() {
+ final int userId = getChangingUserId();
+ final S service = peekServiceForUserLocked(userId);
+ if (service == null) {
+ return null;
+ }
+ final ComponentName serviceComponent = service.getServiceComponentName();
+ if (serviceComponent == null) {
+ return null;
+ }
+ return serviceComponent.getPackageName();
+ }
+
+ @GuardedBy("mLock")
+ private void handlePackageUpdateLocked(String packageName) {
+ visitServicesLocked((s) -> s.handlePackageUpdateLocked(packageName));
+ }
+ };
+
+ // package changes
+ monitor.register(getContext(), null, UserHandle.ALL, true);
+ }
+
+ /**
+ * Visitor pattern.
+ *
+ * @param <S> visited class.
+ */
+ public interface Visitor<S> {
+ /**
+ * Visits a service.
+ *
+ * @param service the service to be visited.
+ */
+ void visit(@NonNull S service);
+ }
+
+ private final class SettingsObserver extends ContentObserver {
+ SettingsObserver(Handler handler) {
+ super(handler);
+ ContentResolver resolver = getContext().getContentResolver();
+ final String serviceProperty = getServiceSettingsProperty();
+ if (serviceProperty != null) {
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ serviceProperty), false, this, UserHandle.USER_ALL);
+ }
+ resolver.registerContentObserver(Settings.Secure.getUriFor(
+ Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL);
+ registerForExtraSettingsChanges(resolver, this);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onChange(): uri=" + uri + ", userId=" + userId);
+ final String property = uri.getLastPathSegment();
+ if (property.equals(getServiceSettingsProperty())
+ || property.equals(Settings.Secure.USER_SETUP_COMPLETE)) {
+ synchronized (mLock) {
+ updateCachedServiceLocked(userId);
+ }
+ } else {
+ onSettingsChanged(userId, property);
+ }
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/AbstractPerUserSystemService.java b/services/core/java/com/android/server/AbstractPerUserSystemService.java
new file mode 100644
index 000000000000..201abe689283
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractPerUserSystemService.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server;
+
+import android.annotation.CallSuper;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.UserIdInt;
+import android.app.AppGlobals;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ServiceInfo;
+import android.graphics.drawable.Drawable;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.UserManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.PrintWriter;
+
+/**
+ * Companion for {@link AbstractMasterSystemService}, it's the base class for the "real" service
+ * implementation.
+ *
+ * @param <S> itself
+ *
+ * @hide
+ */
+public abstract class AbstractPerUserSystemService<S extends AbstractPerUserSystemService<S>> {
+
+ protected final @UserIdInt int mUserId;
+ protected final Object mLock;
+ protected final String mTag = getClass().getSimpleName();
+
+ protected final AbstractMasterSystemService<S> mMaster;
+
+ /**
+ * Whether service was disabled for user due to {@link UserManager} restrictions.
+ */
+ @GuardedBy("mLock")
+ private boolean mDisabled;
+
+ /**
+ * Caches whether the setup completed for the current user.
+ */
+ @GuardedBy("mLock")
+ private boolean mSetupComplete;
+
+ @GuardedBy("mLock")
+ private ServiceInfo mServiceInfo;
+
+ protected AbstractPerUserSystemService(@NonNull AbstractMasterSystemService<S> master,
+ @NonNull Object lock, @UserIdInt int userId) {
+ mMaster = master;
+ mLock = lock;
+ mUserId = userId;
+ }
+
+ /**
+ * Creates a new {@link ServiceInfo} for the given service name.
+ *
+ * @throws NameNotFoundException if the service does not exist.
+ * @throws SecurityException if the service does not have the proper permissions to be bound to.
+ */
+ protected abstract ServiceInfo newServiceInfo(@NonNull ComponentName serviceComponent)
+ throws NameNotFoundException;
+
+ /**
+ * Callback called when an app has been updated.
+ *
+ * @param packageName package of the app being updated.
+ */
+ protected void handlePackageUpdateLocked(@NonNull String packageName) {
+ }
+
+ /**
+ * Gets whether the service is enabled and ready.
+ */
+ @GuardedBy("mLock")
+ protected boolean isEnabledLocked() {
+ return mSetupComplete && mServiceInfo != null && !mDisabled;
+ }
+
+ /**
+ * Updates the state of this service.
+ *
+ * <p>Typically called when the service {@link Settings} property or {@link UserManager}
+ * restriction changed, which includes the initial creation of the service.
+ *
+ * <p>Subclasses can extend this method to provide extra initialization.
+ *
+ * @param disabled whether the service is disabled (due to {@link UserManager} restrictions).
+ *
+ * @return whether the disabled state changed.
+ */
+ @GuardedBy("mLock")
+ @CallSuper
+ protected boolean updateLocked(boolean disabled) {
+
+ final boolean wasEnabled = isEnabledLocked();
+ if (mMaster.verbose) {
+ Slog.v(mTag, "updateLocked(u=" + mUserId + "): wasEnabled=" + wasEnabled
+ + ", mSetupComplete=" + mSetupComplete
+ + ", disabled=" + disabled + ", mDisabled=" + mDisabled);
+ }
+
+ mSetupComplete = isSetupCompletedLocked();
+ mDisabled = disabled;
+ ComponentName serviceComponent = null;
+ ServiceInfo serviceInfo = null;
+ final String componentName = getComponentNameFromSettings();
+ if (!TextUtils.isEmpty(componentName)) {
+ try {
+ serviceComponent = ComponentName.unflattenFromString(componentName);
+ serviceInfo = AppGlobals.getPackageManager().getServiceInfo(serviceComponent,
+ 0, mUserId);
+ if (serviceInfo == null) {
+ Slog.e(mTag, "Bad service name: " + componentName);
+ }
+ } catch (RuntimeException | RemoteException e) {
+ Slog.e(mTag, "Error getting service info for '" + componentName + "': " + e);
+ serviceInfo = null;
+ }
+ }
+ try {
+ if (serviceInfo != null) {
+ mServiceInfo = newServiceInfo(serviceComponent);
+ if (mMaster.debug) {
+ Slog.d(mTag, "Set component for user " + mUserId + " as " + mServiceInfo);
+ }
+ } else {
+ mServiceInfo = null;
+ if (mMaster.debug) {
+ Slog.d(mTag, "Reset component for user " + mUserId + ":" + componentName);
+ }
+ }
+ } catch (Exception e) {
+ Slog.e(mTag, "Bad ServiceInfo for '" + componentName + "': " + e);
+ mServiceInfo = null;
+ }
+ return wasEnabled != isEnabledLocked();
+ }
+
+ /**
+ * Gets this UID of the remote service this service binds to, or {@code -1} if the service is
+ * disabled.
+ */
+ @GuardedBy("mLock")
+ protected final int getServiceUidLocked() {
+ if (mServiceInfo == null) {
+ Slog.w(mTag, "getServiceUidLocked(): no mServiceInfo");
+ return Process.INVALID_UID;
+ }
+ return mServiceInfo.applicationInfo.uid;
+ }
+
+ /**
+ * Gets this name of the remote service this service binds to as defined by {@link Settings}.
+ */
+ @Nullable
+ protected final String getComponentNameFromSettings() {
+ final String property = mMaster.getServiceSettingsProperty();
+ return property == null ? null : Settings.Secure
+ .getStringForUser(getContext().getContentResolver(), property, mUserId);
+ }
+
+ /**
+ * Gets the {@link ComponentName} of the remote service this service binds to, or {@code null}
+ * if the service is disabled.
+ */
+ @Nullable
+ public final ComponentName getServiceComponentName() {
+ synchronized (mLock) {
+ return mServiceInfo == null ? null : mServiceInfo.getComponentName();
+ }
+ }
+ /**
+ * Gets the name of the of the app this service binds to, or {@code null} if the service is
+ * disabled.
+ */
+ @Nullable
+ public final String getServicePackageName() {
+ final ComponentName serviceComponent = getServiceComponentName();
+ return serviceComponent == null ? null : serviceComponent.getPackageName();
+ }
+
+ /**
+ * Gets the user-visibile name of the service this service binds to, or {@code null} if the
+ * service is disabled.
+ */
+ @Nullable
+ @GuardedBy("mLock")
+ public final CharSequence getServiceLabelLocked() {
+ return mServiceInfo == null ? null : mServiceInfo.loadSafeLabel(
+ getContext().getPackageManager(), 0 /* do not ellipsize */,
+ PackageItemInfo.SAFE_LABEL_FLAG_FIRST_LINE | PackageItemInfo.SAFE_LABEL_FLAG_TRIM);
+ }
+
+ /**
+ * Gets the icon the service this service binds to, or {@code null} if the service is disabled.
+ */
+ @Nullable
+ @GuardedBy("mLock")
+ public final Drawable getServiceIconLocked() {
+ return mServiceInfo == null ? null
+ : mServiceInfo.loadIcon(getContext().getPackageManager());
+ }
+
+ /**
+ * Whether the service should log debug statements.
+ */
+ public final boolean isDebug() {
+ return mMaster.debug;
+ }
+
+ /**
+ * Whether the service should log verbose statements.
+ */
+ public final boolean isVerbose() {
+ return mMaster.verbose;
+ }
+
+ /**
+ * Gets the target SDK level of the service this service binds to,
+ * or {@code 0} if the service is disabled.
+ */
+ public final int getTargedSdkLocked() {
+ return mServiceInfo == null ? 0 : mServiceInfo.applicationInfo.targetSdkVersion;
+ }
+
+ /**
+ * Gets whether the device already finished setup.
+ */
+ protected final boolean isSetupCompletedLocked() {
+ final String setupComplete = Settings.Secure.getStringForUser(
+ getContext().getContentResolver(), Settings.Secure.USER_SETUP_COMPLETE, mUserId);
+ return "1".equals(setupComplete);
+ }
+
+ /**
+ * Gets the context associated with this service.
+ */
+ protected final Context getContext() {
+ return mMaster.getContext();
+ }
+
+ // TODO(b/117779333): support proto
+ @GuardedBy("mLock")
+ protected void dumpLocked(@NonNull String prefix, @NonNull PrintWriter pw) {
+ pw.print(prefix); pw.print("User: "); pw.println(mUserId);
+ pw.print(prefix); pw.print("Disabled: "); pw.println(mDisabled);
+ pw.print(prefix); pw.print("Setup complete: "); pw.println(mSetupComplete);
+ pw.print(prefix); pw.print("Service name: "); pw.println(getComponentNameFromSettings());
+ }
+}
diff --git a/services/core/java/com/android/server/AbstractRemoteService.java b/services/core/java/com/android/server/AbstractRemoteService.java
new file mode 100644
index 000000000000..181d7fde1fb8
--- /dev/null
+++ b/services/core/java/com/android/server/AbstractRemoteService.java
@@ -0,0 +1,443 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
+import android.os.IInterface;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.PrintWriter;
+import java.lang.ref.WeakReference;
+
+/**
+ * Base class representing a remote service.
+ *
+ * <p>It abstracts away the binding and unbinding from the remote implementation, so clients can
+ * call its methods without worrying about when and how to bind/unbind/timeout.
+ *
+ * <p>All state of this class is modified on a handler thread.
+ *
+ * <p>See {@code com.android.server.autofill.RemoteFillService} for a concrete
+ * (no pun intended) example of how to use it.
+ *
+ * @hide
+ */
+//TODO(b/117779333): improve javadoc above instead of using Autofill as an example
+public abstract class AbstractRemoteService implements DeathRecipient {
+
+ private static final int MSG_UNBIND = 1;
+
+ protected static final int LAST_PRIVATE_MSG = MSG_UNBIND;
+
+ // TODO(b/117779333): convert all booleans into an integer / flags
+ public final boolean mVerbose;
+
+ protected final String mTag = getClass().getSimpleName();
+ protected final Handler mHandler;
+ protected final ComponentName mComponentName;
+
+ protected PendingRequest<? extends AbstractRemoteService> mPendingRequest;
+
+ private final Context mContext;
+ private final Intent mIntent;
+ private final VultureCallback mVultureCallback;
+ private final int mUserId;
+ private final ServiceConnection mServiceConnection = new RemoteServiceConnection();
+ private final boolean mBindInstantServiceAllowed;
+ private IInterface mServiceInterface;
+
+ private boolean mBinding;
+ private boolean mDestroyed;
+ private boolean mServiceDied;
+ private boolean mCompleted;
+
+ /**
+ * Callback called when the service dies.
+ */
+ public interface VultureCallback {
+ /**
+ * Called when the service dies.
+ *
+ * @param service service that died!
+ */
+ void onServiceDied(AbstractRemoteService service);
+ }
+
+ public AbstractRemoteService(@NonNull Context context, @NonNull String serviceInterface,
+ @NonNull ComponentName componentName, int userId, @NonNull VultureCallback callback,
+ boolean bindInstantServiceAllowed, boolean verbose) {
+ mContext = context;
+ mVultureCallback = callback;
+ mVerbose = verbose;
+ mComponentName = componentName;
+ mIntent = new Intent(serviceInterface).setComponent(mComponentName);
+ mUserId = userId;
+ mHandler = new Handler(FgThread.getHandler().getLooper());
+ mBindInstantServiceAllowed = bindInstantServiceAllowed;
+ }
+
+ /**
+ * Destroys this service.
+ */
+ public final void destroy() {
+ mHandler.sendMessage(obtainMessage(AbstractRemoteService::handleDestroy, this));
+ }
+
+ /**
+ * Checks whether this service is destroyed.
+ */
+ public final boolean isDestroyed() {
+ return mDestroyed;
+ }
+
+ /**
+ * Callback called when the system connected / disconnected to the service.
+ *
+ * @param state {@code true} when connected, {@code false} when disconnected.
+ */
+ protected void onConnectedStateChanged(boolean state) {
+ }
+
+ /**
+ * Gets the base Binder interface from the service.
+ */
+ @NonNull
+ protected abstract IInterface getServiceInterface(@NonNull IBinder service);
+
+ /**
+ * Defines How long after the last interaction with the service we would unbind.
+ */
+ protected abstract long getTimeoutIdleBindMillis();
+
+ /**
+ * Defines how long after we make a remote request to a fill service we timeout.
+ */
+ protected abstract long getRemoteRequestMillis();
+
+ private void handleDestroy() {
+ if (checkIfDestroyed()) return;
+ if (mPendingRequest != null) {
+ mPendingRequest.cancel();
+ mPendingRequest = null;
+ }
+ ensureUnbound();
+ mDestroyed = true;
+ }
+
+ @Override // from DeathRecipient
+ public void binderDied() {
+ mHandler.sendMessage(obtainMessage(AbstractRemoteService::handleBinderDied, this));
+ }
+
+ private void handleBinderDied() {
+ if (checkIfDestroyed()) return;
+ if (mServiceInterface != null) {
+ mServiceInterface.asBinder().unlinkToDeath(this, 0);
+ }
+ mServiceInterface = null;
+ mServiceDied = true;
+ mVultureCallback.onServiceDied(this);
+ }
+
+ // Note: we are dumping without a lock held so this is a bit racy but
+ // adding a lock to a class that offloads to a handler thread would
+ // mean adding a lock adding overhead to normal runtime operation.
+ /**
+ * Dump it!
+ */
+ public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+ String tab = " ";
+ pw.append(prefix).append("service:").println();
+ pw.append(prefix).append(tab).append("userId=")
+ .append(String.valueOf(mUserId)).println();
+ pw.append(prefix).append(tab).append("componentName=")
+ .append(mComponentName.flattenToString()).println();
+ pw.append(prefix).append(tab).append("destroyed=")
+ .append(String.valueOf(mDestroyed)).println();
+ pw.append(prefix).append(tab).append("bound=")
+ .append(String.valueOf(isBound())).println();
+ pw.append(prefix).append(tab).append("hasPendingRequest=")
+ .append(String.valueOf(mPendingRequest != null)).println();
+ pw.append(prefix).append("mBindInstantServiceAllowed=").println(mBindInstantServiceAllowed);
+ pw.append(prefix).append("idleTimeout=")
+ .append(Long.toString(getTimeoutIdleBindMillis() / 1000)).append("s").println();
+ pw.append(prefix).append("requestTimeout=")
+ .append(Long.toString(getRemoteRequestMillis() / 1000)).append("s").println();
+ pw.println();
+ }
+
+ protected void scheduleRequest(PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+ mHandler.sendMessage(obtainMessage(
+ AbstractRemoteService::handlePendingRequest, this, pendingRequest));
+ }
+
+ protected void cancelScheduledUnbind() {
+ mHandler.removeMessages(MSG_UNBIND);
+ }
+
+ protected void scheduleUnbind() {
+ cancelScheduledUnbind();
+ mHandler.sendMessageDelayed(obtainMessage(AbstractRemoteService::handleUnbind, this)
+ .setWhat(MSG_UNBIND), getTimeoutIdleBindMillis());
+ }
+
+ private void handleUnbind() {
+ if (checkIfDestroyed()) return;
+
+ ensureUnbound();
+ }
+
+ private void handlePendingRequest(
+ PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+ if (checkIfDestroyed() || mCompleted) return;
+
+ if (!isBound()) {
+ if (mPendingRequest != null) {
+ mPendingRequest.cancel();
+ }
+ mPendingRequest = pendingRequest;
+ ensureBound();
+ } else {
+ if (mVerbose) Slog.v(mTag, "handlePendingRequest(): " + pendingRequest);
+ pendingRequest.run();
+ if (pendingRequest.isFinal()) {
+ mCompleted = true;
+ }
+ }
+ }
+
+ private boolean isBound() {
+ return mServiceInterface != null;
+ }
+
+ private void ensureBound() {
+ if (isBound() || mBinding) return;
+
+ if (mVerbose) Slog.v(mTag, "ensureBound()");
+ mBinding = true;
+
+ int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+ if (mBindInstantServiceAllowed) {
+ flags |= Context.BIND_ALLOW_INSTANT;
+ }
+
+ final boolean willBind = mContext.bindServiceAsUser(mIntent, mServiceConnection, flags,
+ new UserHandle(mUserId));
+
+ if (!willBind) {
+ Slog.w(mTag, "could not bind to " + mIntent + " using flags " + flags);
+ mBinding = false;
+
+ if (!mServiceDied) {
+ handleBinderDied();
+ }
+ }
+ }
+
+ private void ensureUnbound() {
+ if (!isBound() && !mBinding) return;
+
+ if (mVerbose) Slog.v(mTag, "ensureUnbound()");
+ mBinding = false;
+ if (isBound()) {
+ onConnectedStateChanged(false);
+ if (mServiceInterface != null) {
+ mServiceInterface.asBinder().unlinkToDeath(this, 0);
+ mServiceInterface = null;
+ }
+ }
+ mContext.unbindService(mServiceConnection);
+ }
+
+ private class RemoteServiceConnection implements ServiceConnection {
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ if (mDestroyed || !mBinding) {
+ // This is abnormal. Unbinding the connection has been requested already.
+ Slog.wtf(mTag, "onServiceConnected() was dispatched after unbindService.");
+ return;
+ }
+ mBinding = false;
+ mServiceInterface = getServiceInterface(service);
+ try {
+ service.linkToDeath(AbstractRemoteService.this, 0);
+ } catch (RemoteException re) {
+ handleBinderDied();
+ return;
+ }
+ onConnectedStateChanged(true);
+
+ if (mPendingRequest != null) {
+ final PendingRequest<? extends AbstractRemoteService> pendingRequest =
+ mPendingRequest;
+ mPendingRequest = null;
+ handlePendingRequest(pendingRequest);
+ }
+
+ mServiceDied = false;
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ mBinding = true;
+ mServiceInterface = null;
+ }
+ }
+
+ private boolean checkIfDestroyed() {
+ if (mDestroyed) {
+ if (mVerbose) {
+ Slog.v(mTag, "Not handling operation as service for " + mComponentName
+ + " is already destroyed");
+ }
+ }
+ return mDestroyed;
+ }
+
+ protected boolean handleResponseCallbackCommon(
+ PendingRequest<? extends AbstractRemoteService> pendingRequest) {
+ if (isDestroyed()) return false;
+
+ if (mPendingRequest == pendingRequest) {
+ mPendingRequest = null;
+ }
+ if (mPendingRequest == null) {
+ scheduleUnbind();
+ }
+ return true;
+ }
+
+ /**
+ * Base class for the requests serviced by the remote service.
+ *
+ * @param <S> the remote service class
+ */
+ public abstract static class PendingRequest<S extends AbstractRemoteService>
+ implements Runnable {
+ protected final String mTag = getClass().getSimpleName();
+ protected final Object mLock = new Object();
+
+ private final WeakReference<S> mWeakService;
+ private final Runnable mTimeoutTrigger;
+ private final Handler mServiceHandler;
+
+ @GuardedBy("mLock")
+ private boolean mCancelled;
+
+ @GuardedBy("mLock")
+ private boolean mCompleted;
+
+ protected PendingRequest(S service) {
+ mWeakService = new WeakReference<>(service);
+ mServiceHandler = service.mHandler;
+ mTimeoutTrigger = () -> {
+ synchronized (mLock) {
+ if (mCancelled) {
+ return;
+ }
+ mCompleted = true;
+ }
+
+ final S remoteService = mWeakService.get();
+ if (remoteService != null) {
+ Slog.w(mTag, "timed out after " + service.getRemoteRequestMillis() + " ms");
+ onTimeout(remoteService);
+ } else {
+ Slog.w(mTag, "timed out (no service)");
+ }
+ };
+ mServiceHandler.postAtTime(mTimeoutTrigger,
+ SystemClock.uptimeMillis() + service.getRemoteRequestMillis());
+ }
+
+ /**
+ * Gets a reference to the remote service.
+ */
+ protected final S getService() {
+ return mWeakService.get();
+ }
+
+ /**
+ * Subclasses must call this method when the remote service finishes, i.e., when the service
+ * finishes processing a request.
+ *
+ * @return {@code false} in the service is already finished, {@code true} otherwise.
+ */
+ protected final boolean finish() {
+ synchronized (mLock) {
+ if (mCompleted || mCancelled) {
+ return false;
+ }
+ mCompleted = true;
+ }
+ mServiceHandler.removeCallbacks(mTimeoutTrigger);
+ return true;
+ }
+
+ /**
+ * Checks whether this request was cancelled.
+ */
+ @GuardedBy("mLock")
+ protected final boolean isCancelledLocked() {
+ return mCancelled;
+ }
+
+ /**
+ * Cancels the service.
+ *
+ * @return {@code false} if service is already canceled, {@code true} otherwise.
+ */
+ public boolean cancel() {
+ synchronized (mLock) {
+ if (mCancelled || mCompleted) {
+ return false;
+ }
+ mCancelled = true;
+ }
+
+ mServiceHandler.removeCallbacks(mTimeoutTrigger);
+ return true;
+ }
+
+ /**
+ * Called by the self-destruct timeout when the remote service didn't reply to the
+ * request on time.
+ */
+ protected abstract void onTimeout(S remoteService);
+
+ /**
+ * Checks whether this request leads to a final state where no other requests can be made.
+ */
+ protected boolean isFinal() {
+ return false;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 793a1778f900..26e22bf6f8a2 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -1258,8 +1258,6 @@ public class VibratorService extends IVibratorService.Stub
private final class VibratorShellCommand extends ShellCommand {
- private static final long MAX_VIBRATION_MS = 200;
-
private final IBinder mToken;
private VibratorShellCommand(IBinder token) {
@@ -1303,9 +1301,6 @@ public class VibratorService extends IVibratorService.Stub
}
final long duration = Long.parseLong(getNextArgRequired());
- if (duration > MAX_VIBRATION_MS) {
- throw new IllegalArgumentException("maximum duration is " + MAX_VIBRATION_MS);
- }
String description = getNextArg();
if (description == null) {
description = "Shell command";
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d631fa87c11e..7ea7e1a8241e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -127,6 +127,11 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
+import static com.android.server.am.MemoryStatUtil.hasMemcg;
+import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
+import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
+import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CLEANUP;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_CONFIGURATION;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH;
@@ -144,11 +149,6 @@ import static com.android.server.wm.ActivityTaskManagerService.DUMP_STARTER_CMD;
import static com.android.server.wm.ActivityTaskManagerService.KEY_DISPATCHING_TIMEOUT_MS;
import static com.android.server.wm.ActivityTaskManagerService.RELAUNCH_REASON_NONE;
import static com.android.server.wm.ActivityTaskManagerService.relaunchReasonToString;
-import static com.android.server.am.MemoryStatUtil.MEMORY_STAT_INTERESTING_NATIVE_PROCESSES;
-import static com.android.server.am.MemoryStatUtil.hasMemcg;
-import static com.android.server.am.MemoryStatUtil.readCmdlineFromProcfs;
-import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
-import static com.android.server.am.MemoryStatUtil.readMemoryStatFromProcfs;
import android.Manifest;
import android.Manifest.permission;
@@ -7320,13 +7320,6 @@ public class ActivityManagerService extends IActivityManager.Stub
}
@Override
- public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
- int secondaryDisplayShowing) {
- mActivityTaskManager.setLockScreenShown(
- keyguardShowing, aodShowing, secondaryDisplayShowing);
- }
-
- @Override
public void notifyLockedProfile(@UserIdInt int userId) {
mAtmInternal.notifyLockedProfile(userId, mUserController.getCurrentUserId());
}
@@ -17355,8 +17348,6 @@ public class ActivityManagerService extends IActivityManager.Stub
}
}
- mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
-
incrementProcStateSeqAndNotifyAppsLocked();
mNumServiceProcs = mNewNumServiceProcs;
@@ -17618,6 +17609,9 @@ public class ActivityManagerService extends IActivityManager.Stub
mHandler.post(new ProcStatsRunnable(ActivityManagerService.this, mProcessStats));
}
+ // Run this after making sure all procstates are updated.
+ mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, now);
+
if (DEBUG_OOM_ADJ) {
final long duration = SystemClock.uptimeMillis() - now;
if (false) {
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index 5d4263b13903..bc3cc3bd383c 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -70,7 +70,7 @@ import java.util.List;
/**
* A service to manage multiple clients that want to access the face HAL API.
* The service is responsible for maintaining a list of clients and dispatching all
- * face -related events.
+ * face-related events.
*
* @hide
*/
diff --git a/services/core/java/com/android/server/biometrics/iris/IrisService.java b/services/core/java/com/android/server/biometrics/iris/IrisService.java
new file mode 100644
index 000000000000..37cdc2a4f07a
--- /dev/null
+++ b/services/core/java/com/android/server/biometrics/iris/IrisService.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.biometrics.iris;
+
+import android.content.Context;
+
+import com.android.server.biometrics.BiometricServiceBase;
+import com.android.server.biometrics.BiometricUtils;
+import com.android.server.biometrics.Metrics;
+
+/**
+ * A service to manage multiple clients that want to access the Iris HAL API.
+ * The service is responsible for maintaining a list of clients and dispatching all
+ * iris-related events.
+ *
+ * TODO: The vendor is expected to fill in the service. See
+ * {@link com.android.server.biometrics.fingerprint.FingerprintService}
+ *
+ * @hide
+ */
+public class IrisService extends BiometricServiceBase {
+
+ private static final String TAG = "IrisService";
+
+ /**
+ * Initializes the system service.
+ * <p>
+ * Subclasses must define a single argument constructor that accepts the context
+ * and passes it to super.
+ * </p>
+ *
+ * @param context The system server context.
+ */
+ public IrisService(Context context) {
+ super(context);
+ }
+
+ @Override
+ public void onStart() {
+ super.onStart();
+ }
+
+ @Override
+ protected String getTag() {
+ return TAG;
+ }
+
+ @Override
+ protected BiometricUtils getBiometricUtils() {
+ return null;
+ }
+
+ @Override
+ protected int getFailedAttemptsLockoutTimed() {
+ return 0;
+ }
+
+ @Override
+ protected int getFailedAttemptsLockoutPermanent() {
+ return 0;
+ }
+
+ @Override
+ protected Metrics getMetrics() {
+ return null;
+ }
+
+ @Override
+ protected boolean hasReachedEnrollmentLimit(int userId) {
+ return false;
+ }
+
+ @Override
+ protected void updateActiveGroup(int userId, String clientPackage) {
+
+ }
+
+ @Override
+ protected String getLockoutResetIntent() {
+ return null;
+ }
+
+ @Override
+ protected String getLockoutBroadcastPermission() {
+ return null;
+ }
+
+ @Override
+ protected long getHalDeviceId() {
+ return 0;
+ }
+
+ @Override
+ protected void handleUserSwitching(int userId) {
+
+ }
+
+ @Override
+ protected boolean hasEnrolledBiometrics(int userId) {
+ return false;
+ }
+
+ @Override
+ protected String getManageBiometricPermission() {
+ return null;
+ }
+
+ @Override
+ protected void checkUseBiometricPermission() {
+
+ }
+
+ @Override
+ protected boolean checkAppOps(int uid, String opPackageName) {
+ return false;
+ }
+}
diff --git a/services/core/java/com/android/server/location/ContextHubClientBroker.java b/services/core/java/com/android/server/location/ContextHubClientBroker.java
index 60f70c70b8e0..642347021201 100644
--- a/services/core/java/com/android/server/location/ContextHubClientBroker.java
+++ b/services/core/java/com/android/server/location/ContextHubClientBroker.java
@@ -159,25 +159,12 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
/* package */ ContextHubClientBroker(
Context context, IContexthub contextHubProxy, ContextHubClientManager clientManager,
- ContextHubInfo contextHubInfo, short hostEndPointId,
- IContextHubClientCallback callback) {
+ ContextHubInfo contextHubInfo, short hostEndPointId) {
mContext = context;
mContextHubProxy = contextHubProxy;
mClientManager = clientManager;
mAttachedContextHubInfo = contextHubInfo;
mHostEndPointId = hostEndPointId;
- mCallbackInterface = callback;
- }
-
- /**
- * Attaches a death recipient for this client
- *
- * @throws RemoteException if the client has already died
- */
- /* package */ synchronized void attachDeathRecipient() throws RemoteException {
- if (mCallbackInterface != null) {
- mCallbackInterface.asBinder().linkToDeath(this, 0 /* flags */);
- }
}
/**
@@ -245,9 +232,15 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
public boolean unregisterIntent(PendingIntent pendingIntent) {
ContextHubServiceUtil.checkPermissions(mContext);
+ boolean success = false;
synchronized (this) {
- return mPendingIntentRequest.unregister(pendingIntent);
+ success = mPendingIntentRequest.unregister(pendingIntent);
+ if (mCallbackInterface == null) {
+ close();
+ }
}
+
+ return success;
}
/**
@@ -276,6 +269,37 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
}
/**
+ * Sets the callback interface for this client, only if the callback is currently unregistered.
+ *
+ * Also attaches a death recipient to a ContextHubClientBroker object. If unsuccessful, the
+ * connection is closed.
+ *
+ * @param callback the callback interface
+ * @return true if the callback was successfully set, false otherwise
+ *
+ * @throws IllegalStateException if the client has already been registered to a callback
+ */
+ /* package */
+ synchronized boolean setCallback(IContextHubClientCallback callback) {
+ boolean success = false;
+ if (mCallbackInterface != null) {
+ throw new IllegalStateException("Client is already registered with a callback");
+ } else {
+ mCallbackInterface = callback;
+ try {
+ mCallbackInterface.asBinder().linkToDeath(this, 0 /* flags */);
+ success = true;
+ } catch (RemoteException e) {
+ // The client process has died, so we close the connection.
+ Log.e(TAG, "Failed to attach death recipient to client");
+ close();
+ }
+ }
+
+ return success;
+ }
+
+ /**
* @return the ID of the context hub this client is attached to
*/
/* package */ int getAttachedContextHubId() {
@@ -347,6 +371,18 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
}
/**
+ * @param intent the PendingIntent to compare to
+ * @return true if the given PendingIntent is currently registered, false otherwise
+ */
+ /* package */ boolean hasPendingIntent(PendingIntent intent) {
+ PendingIntent pendingIntent = null;
+ synchronized (this) {
+ pendingIntent = mPendingIntentRequest.getPendingIntent();
+ }
+ return (pendingIntent != null) && pendingIntent.equals(intent);
+ }
+
+ /**
* Helper function to invoke a specified client callback, if the connection is open.
*
* @param consumer the consumer specifying the callback to invoke
@@ -407,6 +443,9 @@ public class ContextHubClientBroker extends IContextHubClient.Stub
Log.w(TAG, "PendingIntent has been canceled, unregistering from client"
+ " (host endpoint ID " + mHostEndPointId + ")");
mPendingIntentRequest.clear();
+ if (mCallbackInterface == null) {
+ close();
+ }
}
}
}
diff --git a/services/core/java/com/android/server/location/ContextHubClientManager.java b/services/core/java/com/android/server/location/ContextHubClientManager.java
index eda8c6f8b418..72879ddc2018 100644
--- a/services/core/java/com/android/server/location/ContextHubClientManager.java
+++ b/services/core/java/com/android/server/location/ContextHubClientManager.java
@@ -16,6 +16,7 @@
package com.android.server.location;
+import android.app.PendingIntent;
import android.content.Context;
import android.hardware.contexthub.V1_0.ContextHubMsg;
import android.hardware.contexthub.V1_0.IContexthub;
@@ -88,15 +89,9 @@ import java.util.function.Consumer;
*/
/* package */ IContextHubClient registerClient(
IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
- ContextHubClientBroker broker = createNewClientBroker(clientCallback, contextHubInfo);
-
- try {
- broker.attachDeathRecipient();
- } catch (RemoteException e) {
- // The client process has died, so we close the connection and return null.
- Log.e(TAG, "Failed to attach death recipient to client");
- broker.close();
- return null;
+ ContextHubClientBroker broker = createNewClientBroker(contextHubInfo);
+ if (!broker.setCallback(clientCallback)) {
+ return null; // Client process has died, so we return null
}
Log.d(TAG, "Registered client with host endpoint ID " + broker.getHostEndPointId());
@@ -104,6 +99,36 @@ import java.util.function.Consumer;
}
/**
+ * Binds a existing and registered client with a new callback interface, provided a previously
+ * registered PendingIntent.
+ *
+ * @param pendingIntent a previously registered PendingIntent for a registered client
+ * @param clientCallback the callback interface of the client to bind to
+ * @param contextHubId the ID of the hub this client is attached to
+ *
+ * @return the client interface
+ *
+ * @throws IllegalArgumentException if no matching client is found
+ * @throws IllegalStateException if the client has already been registered to a callback
+ */
+ /* package */ IContextHubClient bindClient(
+ PendingIntent pendingIntent, IContextHubClientCallback clientCallback,
+ int contextHubId) {
+ ContextHubClientBroker broker = getClientBroker(pendingIntent, contextHubId);
+ if (broker == null) {
+ throw new IllegalArgumentException("Could not find client of Context Hub (ID = "
+ + contextHubId + ") with PendingIntent");
+ }
+
+ if (!broker.setCallback(clientCallback)) {
+ return null; // Client process has died, so we return null
+ }
+
+ Log.d(TAG, "Re-registered client with host endpoint ID " + broker.getHostEndPointId());
+ return IContextHubClient.Stub.asInterface(broker);
+ }
+
+ /**
* Handles a message sent from a nanoapp.
*
* @param contextHubId the ID of the hub where the nanoapp sent the message from
@@ -182,7 +207,6 @@ import java.util.function.Consumer;
* Creates a new ContextHubClientBroker object for a client and registers it with the client
* manager.
*
- * @param clientCallback the callback interface of the client to register
* @param contextHubInfo the object describing the hub this client is attached to
*
* @return the ContextHubClientBroker object
@@ -190,7 +214,7 @@ import java.util.function.Consumer;
* @throws IllegalStateException if max number of clients have already registered
*/
private synchronized ContextHubClientBroker createNewClientBroker(
- IContextHubClientCallback clientCallback, ContextHubInfo contextHubInfo) {
+ ContextHubInfo contextHubInfo) {
if (mHostEndPointIdToClientMap.size() == MAX_CLIENT_ID + 1) {
throw new IllegalStateException("Could not register client - max limit exceeded");
}
@@ -200,8 +224,7 @@ import java.util.function.Consumer;
for (int i = 0; i <= MAX_CLIENT_ID; i++) {
if (!mHostEndPointIdToClientMap.containsKey((short) id)) {
broker = new ContextHubClientBroker(
- mContext, mContextHubProxy, this, contextHubInfo, (short) id,
- clientCallback);
+ mContext, mContextHubProxy, this, contextHubInfo, (short) id);
mHostEndPointIdToClientMap.put((short) id, broker);
mNextHostEndpointId = (id == MAX_CLIENT_ID) ? 0 : id + 1;
break;
@@ -236,4 +259,22 @@ import java.util.function.Consumer;
}
}
}
+
+ /**
+ * Retrieves a ContextHubClientBroker object with a matching PendingIntent and Context Hub ID.
+ *
+ * @param pendingIntent the PendingIntent to match
+ * @param contextHubId the ID of the Context Hub the client is attached to
+ * @return the matching ContextHubClientBroker, null if not found
+ */
+ private ContextHubClientBroker getClientBroker(PendingIntent pendingIntent, int contextHubId) {
+ for (ContextHubClientBroker broker : mHostEndPointIdToClientMap.values()) {
+ if (broker.hasPendingIntent(pendingIntent)
+ && broker.getAttachedContextHubId() == contextHubId) {
+ return broker;
+ }
+ }
+
+ return null;
+ }
}
diff --git a/services/core/java/com/android/server/location/ContextHubService.java b/services/core/java/com/android/server/location/ContextHubService.java
index e3c2863e7c72..215e67c0884f 100644
--- a/services/core/java/com/android/server/location/ContextHubService.java
+++ b/services/core/java/com/android/server/location/ContextHubService.java
@@ -16,6 +16,7 @@
package com.android.server.location;
+import android.app.PendingIntent;
import android.content.Context;
import android.hardware.contexthub.V1_0.AsyncEventType;
import android.hardware.contexthub.V1_0.ContextHub;
@@ -631,6 +632,37 @@ public class ContextHubService extends IContextHubService.Stub {
}
/**
+ * Recreates and binds a IContextHubClientCallback interface to an existing and registered
+ * client at the service for the specified Context Hub, provided a previously registered
+ * PendingIntent.
+ *
+ * @param pendingIntent the PendingIntent previously registered for the client
+ * @param clientCallback the client interface to register with the service
+ * @param contextHubId the ID of the hub this client is attached to
+ * @return the generated client interface, null if registration was unsuccessful
+ *
+ * @throws IllegalArgumentException if contextHubId is not a valid ID
+ * @throws NullPointerException if clientCallback or pendingIntent is null
+ */
+ @Override
+ public IContextHubClient bindClient(
+ PendingIntent pendingIntent, IContextHubClientCallback clientCallback,
+ int contextHubId) throws RemoteException {
+ checkPermissions();
+ if (!isValidContextHubId(contextHubId)) {
+ throw new IllegalArgumentException("Invalid context hub ID " + contextHubId);
+ }
+ if (pendingIntent == null) {
+ throw new NullPointerException("Cannot create client with null pending intent");
+ }
+ if (clientCallback == null) {
+ throw new NullPointerException("Cannot create client with null callback");
+ }
+
+ return mClientManager.bindClient(pendingIntent, clientCallback, contextHubId);
+ }
+
+ /**
* Loads a nanoapp binary at the specified Context hub.
*
* @param contextHubId the ID of the hub to load the binary
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index fc9bd37a0f80..f279af03753e 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -96,7 +96,7 @@ public class ZenModeHelper {
private final SettingsObserver mSettingsObserver;
@VisibleForTesting protected final AppOpsManager mAppOps;
@VisibleForTesting protected final NotificationManager mNotificationManager;
- protected ZenModeConfig mDefaultConfig;
+ @VisibleForTesting protected ZenModeConfig mDefaultConfig;
private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
private final ZenModeFiltering mFiltering;
protected final RingerModeDelegate mRingerModeDelegate = new
@@ -309,9 +309,6 @@ public class ZenModeHelper {
newConfig = mConfig.copy();
ZenRule rule = new ZenRule();
populateZenRule(automaticZenRule, rule, true);
- if (newConfig.automaticRules.put(rule.id, rule) != null) {
- rule.modified = true;
- }
if (setConfigLocked(newConfig, reason, rule.component, true)) {
return rule.id;
} else {
@@ -341,9 +338,6 @@ public class ZenModeHelper {
}
}
populateZenRule(automaticZenRule, rule, false);
- if (newConfig.automaticRules.put(ruleId, rule) != null) {
- rule.modified = true;
- }
return setConfigLocked(newConfig, reason, rule.component, true);
}
}
@@ -431,13 +425,16 @@ public class ZenModeHelper {
updateDefaultAutomaticRuleNames();
for (ZenRule defaultRule : mDefaultConfig.automaticRules.values()) {
ZenRule currRule = mConfig.automaticRules.get(defaultRule.id);
- // if default rule wasn't modified, use localized name instead of previous
- if (currRule != null && !currRule.modified && !defaultRule.name.equals(currRule.name)) {
- if (canManageAutomaticZenRule(defaultRule)) {
+ // if default rule wasn't user-modified nor enabled, use localized name
+ // instead of previous system name
+ if (currRule != null && !currRule.modified && !currRule.enabled
+ && !defaultRule.name.equals(currRule.name)) {
+ if (canManageAutomaticZenRule(currRule)) {
if (DEBUG) Slog.d(TAG, "Locale change - updating default zen rule name "
+ "from " + currRule.name + " to " + defaultRule.name);
// update default rule (if locale changed, name of rule will change)
- updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(defaultRule),
+ currRule.name = defaultRule.name;
+ updateAutomaticZenRule(defaultRule.id, createAutomaticZenRule(currRule),
"locale changed");
}
}
@@ -481,6 +478,7 @@ public class ZenModeHelper {
rule.condition = null;
rule.conditionId = automaticZenRule.getConditionId();
rule.enabled = automaticZenRule.isEnabled();
+ rule.modified = automaticZenRule.isModified();
if (automaticZenRule.getZenPolicy() != null) {
rule.zenPolicy = automaticZenRule.getZenPolicy();
}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 404f152bb8d1..275f3dcdb6d2 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -77,7 +77,6 @@ import java.util.List;
*/
public class LauncherAppsService extends SystemService {
- private static final boolean SHOW_HIDDEN_APP_ENABLED = false;
private final LauncherAppsImpl mLauncherAppsImpl;
public LauncherAppsService(Context context) {
@@ -310,22 +309,28 @@ public class LauncherAppsService extends SystemService {
.addCategory(Intent.CATEGORY_LAUNCHER)
.setPackage(packageName),
user);
- if (!SHOW_HIDDEN_APP_ENABLED) {
+ if (Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.SHOW_HIDDEN_LAUNCHER_ICON_APPS_ENABLED, 0) == 0) {
return launcherActivities;
}
final int callingUid = injectBinderCallingUid();
final ArrayList<ResolveInfo> result = new ArrayList<>(launcherActivities.getList());
+ final PackageManagerInternal pmInt =
+ LocalServices.getService(PackageManagerInternal.class);
if (packageName != null) {
- // If target package has launcher activities, then return those launcher
- // activities. Otherwise, return hidden activity that forwards user to app
- // details page.
+ // If this hidden app should not be shown, return the original list.
+ // Otherwise, inject hidden activity that forwards user to app details page.
if (result.size() > 0) {
return launcherActivities;
}
- ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user);
- if (info != null) {
- result.add(info);
+ ApplicationInfo appInfo = pmInt.getApplicationInfo(packageName, /*flags*/ 0,
+ callingUid, user.getIdentifier());
+ if (shouldShowHiddenApp(appInfo)) {
+ ResolveInfo info = getHiddenAppActivityInfo(packageName, callingUid, user);
+ if (info != null) {
+ result.add(info);
+ }
}
return new ParceledListSlice<>(result);
}
@@ -336,8 +341,6 @@ public class LauncherAppsService extends SystemService {
for (ResolveInfo info : result) {
visiblePackages.add(info.activityInfo.packageName);
}
- final PackageManagerInternal pmInt =
- LocalServices.getService(PackageManagerInternal.class);
List<ApplicationInfo> installedPackages = pmInt.getInstalledApplications(0,
user.getIdentifier(), callingUid);
for (ApplicationInfo applicationInfo : installedPackages) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 0b32d1a5d69b..6ccd0406bfcc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -58,7 +58,6 @@ import android.os.Process;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SELinux;
-import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -646,8 +645,8 @@ public class PackageInstallerService extends IPackageInstaller.Stub {
}
try {
- Os.mkdir(stageDir.getAbsolutePath(), 0755);
- Os.chmod(stageDir.getAbsolutePath(), 0755);
+ Os.mkdir(stageDir.getAbsolutePath(), 0775);
+ Os.chmod(stageDir.getAbsolutePath(), 0775);
} catch (ErrnoException e) {
// This purposefully throws if directory already exists
throw new IOException("Failed to prepare session dir: " + stageDir, e);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 51225a77b005..249edab2be94 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -43,6 +43,7 @@ import static com.android.server.pm.PackageInstallerService.prepareStageDir;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.apex.IApexService;
import android.app.admin.DeviceAdminInfo;
import android.app.admin.DevicePolicyManagerInternal;
import android.content.Context;
@@ -75,6 +76,7 @@ import android.os.ParcelableException;
import android.os.Process;
import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
+import android.os.ServiceManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.storage.StorageManager;
@@ -838,12 +840,15 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
resolveStageDirLocked();
mSealed = true;
-
- // Verify that stage looks sane with respect to existing application.
- // This currently only ensures packageName, versionCode, and certificate
- // consistency.
try {
- validateInstallLocked(pkgInfo);
+ if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+ validateApexInstallLocked(pkgInfo);
+ } else {
+ // Verify that stage looks sane with respect to existing application.
+ // This currently only ensures packageName, versionCode, and certificate
+ // consistency.
+ validateApkInstallLocked(pkgInfo);
+ }
} catch (PackageManagerException e) {
throw e;
} catch (Throwable e) {
@@ -926,6 +931,31 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
Preconditions.checkNotNull(mSigningDetails);
Preconditions.checkNotNull(mResolvedBaseFile);
+ if ((params.installFlags & PackageManager.INSTALL_APEX) != 0) {
+ commitApexLocked();
+ } else {
+ commitApkLocked();
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void commitApexLocked() throws PackageManagerException {
+ try {
+ IApexService apex = IApexService.Stub.asInterface(
+ ServiceManager.getService("apexservice"));
+ apex.stagePackage(mResolvedBaseFile.toString());
+ } catch (Throwable e) {
+ // Convert all exceptions into package manager exceptions as only those are handled
+ // in the code above
+ throw new PackageManagerException(e);
+ } finally {
+ destroyInternal();
+ dispatchSessionFinished(PackageManager.INSTALL_SUCCEEDED, "APEX installed", null);
+ }
+ }
+
+ @GuardedBy("mLock")
+ private void commitApkLocked() throws PackageManagerException {
if (needToAskForPermissionsLocked()) {
// User needs to confirm installation; give installer an intent they can use to involve
// user.
@@ -1047,6 +1077,57 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
(params.installFlags & PackageManager.DONT_KILL_APP) != 0;
}
+ @GuardedBy("mLock")
+ private void validateApexInstallLocked(@Nullable PackageInfo pkgInfo)
+ throws PackageManagerException {
+ mResolvedStagedFiles.clear();
+ mResolvedInheritedFiles.clear();
+
+ try {
+ resolveStageDirLocked();
+ } catch (IOException e) {
+ throw new PackageManagerException(INSTALL_FAILED_CONTAINER_ERROR,
+ "Failed to resolve stage location", e);
+ }
+
+ final File[] addedFiles = mResolvedStageDir.listFiles(sAddedFilter);
+ if (ArrayUtils.isEmpty(addedFiles)) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK, "No packages staged");
+ }
+
+ if (addedFiles.length > 1) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Only one APEX file at a time might be installed");
+ }
+ File addedFile = addedFiles[0];
+ final ApkLite apk;
+ try {
+ apk = PackageParser.parseApkLite(
+ addedFile, PackageParser.PARSE_COLLECT_CERTIFICATES);
+ } catch (PackageParserException e) {
+ throw PackageManagerException.from(e);
+ }
+
+ mPackageName = apk.packageName;
+ mVersionCode = apk.getLongVersionCode();
+ mSigningDetails = apk.signingDetails;
+ mResolvedBaseFile = addedFile;
+
+ assertApkConsistentLocked(String.valueOf(addedFile), apk);
+
+ if (mSigningDetails == PackageParser.SigningDetails.UNKNOWN) {
+ try {
+ // STOPSHIP: For APEX we should also implement proper APK Signature verification.
+ mSigningDetails = ApkSignatureVerifier.plsCertsNoVerifyOnlyCerts(
+ pkgInfo.applicationInfo.sourceDir,
+ PackageParser.SigningDetails.SignatureSchemeVersion.JAR);
+ } catch (PackageParserException e) {
+ throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
+ "Couldn't obtain signatures from base APK");
+ }
+ }
+ }
+
/**
* Validate install by confirming that all application packages are have
* consistent package name, version code, and signing certificates.
@@ -1060,7 +1141,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
* {@link PackageManagerService}.
*/
@GuardedBy("mLock")
- private void validateInstallLocked(@Nullable PackageInfo pkgInfo)
+ private void validateApkInstallLocked(@Nullable PackageInfo pkgInfo)
throws PackageManagerException {
ApkLite baseApk = null;
mPackageName = null;
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9210d46c1476..0e37bcafe5d0 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -85,6 +85,11 @@ import static android.content.pm.PackageManager.MOVE_FAILED_SYSTEM_PACKAGE;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.content.pm.PackageParser.isApkFile;
+import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE;
+import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER;
+import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE;
+import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK;
+import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
import static android.os.storage.StorageManager.FLAG_STORAGE_DE;
@@ -366,6 +371,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.BiConsumer;
import java.util.function.Predicate;
/**
@@ -2090,6 +2096,28 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ @GuardedBy("mPackages")
+ private void setupBuiltinSharedLibraryDependenciesLocked() {
+ // Builtin libraries don't have versions.
+ long version = SharedLibraryInfo.VERSION_UNDEFINED;
+
+ SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(ANDROID_HIDL_MANAGER, version);
+ if (libraryInfo != null) {
+ libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_HIDL_BASE, version));
+ }
+
+ libraryInfo = getSharedLibraryInfoLPr(ANDROID_TEST_RUNNER, version);
+ if (libraryInfo != null) {
+ libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_TEST_MOCK, version));
+ libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_TEST_BASE, version));
+ }
+
+ libraryInfo = getSharedLibraryInfoLPr(ANDROID_TEST_MOCK, version);
+ if (libraryInfo != null) {
+ libraryInfo.addDependency(getSharedLibraryInfoLPr(ANDROID_TEST_BASE, version));
+ }
+ }
+
public PackageManagerService(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
LockGuard.installLock(mPackages, LockGuard.INDEX_PACKAGES);
@@ -2205,6 +2233,9 @@ public class PackageManagerService extends IPackageManager.Stub
addSharedLibraryLPw(path, null, name, SharedLibraryInfo.VERSION_UNDEFINED,
SharedLibraryInfo.TYPE_BUILTIN, PLATFORM_PACKAGE_NAME, 0);
}
+ // Builtin libraries cannot encode their dependency where they are
+ // defined, so fix that now.
+ setupBuiltinSharedLibraryDependenciesLocked();
SELinuxMMAC.readInstallPolicy();
@@ -4867,7 +4898,10 @@ public class PackageManagerService extends IPackageManager.Stub
SharedLibraryInfo resLibInfo = new SharedLibraryInfo(libInfo.getPath(),
libInfo.getPackageName(), libInfo.getName(), libInfo.getLongVersion(),
libInfo.getType(), libInfo.getDeclaringPackage(),
- getPackagesUsingSharedLibraryLPr(libInfo, flags, userId));
+ getPackagesUsingSharedLibraryLPr(libInfo, flags, userId),
+ (libInfo.getDependencies() == null
+ ? null
+ : new ArrayList(libInfo.getDependencies())));
if (result == null) {
result = new ArrayList<>();
@@ -9598,16 +9632,34 @@ public class PackageManagerService extends IPackageManager.Stub
}
@GuardedBy("mPackages")
- private void addSharedLibraryLPr(Set<String> usesLibraryFiles,
- SharedLibraryInfo file,
- PackageParser.Package changingLib) {
+ private void applyDefiningSharedLibraryUpdateLocked(
+ PackageParser.Package pkg, SharedLibraryInfo libInfo,
+ BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
+ if (pkg.isLibrary()) {
+ if (pkg.staticSharedLibName != null) {
+ SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
+ pkg.staticSharedLibName, pkg.staticSharedLibVersion);
+ action.accept(definedLibrary, libInfo);
+ } else {
+ for (String libraryName : pkg.libraryNames) {
+ SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
+ libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
+ action.accept(definedLibrary, libInfo);
+ }
+ }
+ }
+ }
+
+ @GuardedBy("mPackages")
+ private void addSharedLibraryLPr(PackageParser.Package pkg, Set<String> usesLibraryFiles,
+ SharedLibraryInfo libInfo, PackageParser.Package changingLib) {
- if (file.getPath() != null) {
- usesLibraryFiles.add(file.getPath());
+ if (libInfo.getPath() != null) {
+ usesLibraryFiles.add(libInfo.getPath());
return;
}
- PackageParser.Package p = mPackages.get(file.getPackageName());
- if (changingLib != null && changingLib.packageName.equals(file.getPackageName())) {
+ PackageParser.Package p = mPackages.get(libInfo.getPackageName());
+ if (changingLib != null && changingLib.packageName.equals(libInfo.getPackageName())) {
// If we are doing this while in the middle of updating a library apk,
// then we need to make sure to use that new apk for determining the
// dependencies here. (We haven't yet finished committing the new apk
@@ -9618,6 +9670,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
if (p != null) {
usesLibraryFiles.addAll(p.getAllCodePaths());
+ // If the package provides libraries, add the dependency to them.
+ applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, (definingLibrary, dependency) -> {
+ definingLibrary.addDependency(dependency);
+ });
if (p.usesLibraryFiles != null) {
Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
}
@@ -9630,6 +9686,12 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkg == null) {
return;
}
+
+ // If the package provides libraries, clear their old dependencies.
+ // This method will set them up again.
+ applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
+ definingLibrary.clearDependencies();
+ });
// The collection used here must maintain the order of addition (so
// that libraries are searched in the correct order) and must have no
// duplicates.
@@ -9656,7 +9718,7 @@ public class PackageManagerService extends IPackageManager.Stub
// usesLibraryFiles while eliminating duplicates.
Set<String> usesLibraryFiles = new LinkedHashSet<>();
for (SharedLibraryInfo libInfo : usesLibraryInfos) {
- addSharedLibraryLPr(usesLibraryFiles, libInfo, changingLib);
+ addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib);
}
pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
} else {
@@ -11201,7 +11263,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
SharedLibraryInfo libraryInfo = new SharedLibraryInfo(path, apk, name,
version, type, new VersionedPackage(declaringPackageName, declaringVersionCode),
- null);
+ null, null);
versionedLib.put(version, libraryInfo);
return true;
}
@@ -15153,14 +15215,8 @@ public class PackageManagerService extends IPackageManager.Stub
pkgList.add(oldPackage.applicationInfo.packageName);
sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
}
-
- clearAppDataLIF(pkg, UserHandle.USER_ALL, StorageManager.FLAG_STORAGE_DE
- | StorageManager.FLAG_STORAGE_CE
- | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
-
-
// Update the in-memory copy of the previous code paths.
PackageSetting ps1 = mSettings.mPackages.get(
reconciledPkg.prepareResult.existingPackage.packageName);
@@ -15364,7 +15420,8 @@ public class PackageManagerService extends IPackageManager.Stub
/**
* On successful install, executes remaining steps after commit completes and the package lock
- * is released.
+ * is released. These are typically more expensive or require calls to installd, which often
+ * locks on {@link #mPackages}.
*/
private void executePostCommitSteps(CommitRequest commitRequest) {
for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
@@ -16093,7 +16150,6 @@ public class PackageManagerService extends IPackageManager.Stub
try {
final PackageParser.Package existingPackage;
String renamedPackage = null;
- boolean clearCodeCache = false;
boolean sysPkg = false;
String targetVolumeUuid = volumeUuid;
int targetScanFlags = scanFlags;
@@ -16314,7 +16370,6 @@ public class PackageManagerService extends IPackageManager.Stub
Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
+ ", old=" + oldPackage);
}
- clearCodeCache = true;
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
@@ -16370,7 +16425,7 @@ public class PackageManagerService extends IPackageManager.Stub
shouldCloseFreezerBeforeReturn = false;
return new PrepareResult(args.installReason, targetVolumeUuid, installerPackageName,
args.user, replace, targetScanFlags, targetParseFlags, existingPackage, pkg,
- clearCodeCache, sysPkg, renamedPackage, freezer);
+ replace /* clearCodeCache */, sysPkg, renamedPackage, freezer);
} finally {
if (shouldCloseFreezerBeforeReturn) {
freezer.close();
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index e25cca43e8da..38bd1722e61f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -920,7 +920,10 @@ class PackageManagerShellCommand extends ShellCommand {
pw.println("Error: must either specify a package size or an APK file");
return 1;
}
- if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, "base.apk",
+ final boolean isApex =
+ (params.sessionParams.installFlags & PackageManager.INSTALL_APEX) != 0;
+ String splitName = "base." + (isApex ? "apex" : "apk");
+ if (doWriteSplit(sessionId, inPath, params.sessionParams.sizeBytes, splitName,
false /*logSuccess*/) != PackageInstaller.STATUS_SUCCESS) {
return 1;
}
@@ -2262,6 +2265,9 @@ class PackageManagerShellCommand extends ShellCommand {
case "--force-sdk":
sessionParams.installFlags |= PackageManager.INSTALL_FORCE_SDK;
break;
+ case "--apex":
+ sessionParams.installFlags |= PackageManager.INSTALL_APEX;
+ break;
default:
throw new IllegalArgumentException("Unknown option " + opt);
}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index 392d4d839c45..753c2833b056 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -30,6 +30,7 @@ import android.os.storage.StorageManager;
import android.os.SystemProperties;
import android.os.UserHandle;
import android.provider.Settings.Global;
+import android.util.Log;
import android.util.Slog;
import android.util.jar.StrictJarFile;
@@ -74,7 +75,7 @@ public class DexManager {
private static final String PROPERTY_NAME_PM_DEXOPT_PRIV_APPS_OOB_LIST =
"pm.dexopt.priv-apps-oob-list";
- private static final boolean DEBUG = false;
+ private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private final Context mContext;
@@ -192,6 +193,16 @@ public class DexManager {
String[] classLoaderContexts = DexoptUtils.processContextForDexLoad(
classLoaderNames, classPaths);
+ // A null classLoaderContexts means that there are unsupported class loaders in the
+ // chain.
+ if (classLoaderContexts == null) {
+ if (DEBUG) {
+ Slog.i(TAG, loadingAppInfo.packageName +
+ " uses unsupported class loader in " + classLoaderNames);
+ }
+ return;
+ }
+
int dexPathIndex = 0;
for (String dexPath : dexPathsToRegister) {
// Find the owning package name.
@@ -219,14 +230,10 @@ public class DexManager {
}
// Record dex file usage. If the current usage is a new pattern (e.g. new secondary,
- // or UsedBytOtherApps), record will return true and we trigger an async write
+ // or UsedByOtherApps), record will return true and we trigger an async write
// to disk to make sure we don't loose the data in case of a reboot.
- // A null classLoaderContexts means that there are unsupported class loaders in the
- // chain.
- String classLoaderContext = classLoaderContexts == null
- ? PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT
- : classLoaderContexts[dexPathIndex];
+ String classLoaderContext = classLoaderContexts[dexPathIndex];
if (mPackageDexUsage.record(searchResult.mOwningPackageName,
dexPath, loaderUserId, loaderIsa, isUsedByOtherApps, primaryOrSplit,
loadingAppInfo.packageName, classLoaderContext)) {
diff --git a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
index 602ce3b2a0c1..86f7380e331b 100644
--- a/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
+++ b/services/core/java/com/android/server/pm/dex/PackageDexUsage.java
@@ -21,6 +21,7 @@ import android.util.Slog;
import android.os.Build;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FastPrintWriter;
import com.android.server.pm.AbstractStatsBase;
import com.android.server.pm.PackageManagerServiceUtils;
@@ -78,14 +79,16 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
// skip optimizations on that dex files.
/*package*/ static final String VARIABLE_CLASS_LOADER_CONTEXT =
"=VariableClassLoaderContext=";
- // The marker used for unsupported class loader contexts.
- /*package*/ static final String UNSUPPORTED_CLASS_LOADER_CONTEXT =
- "=UnsupportedClassLoaderContext=";
// The markers used for unknown class loader contexts. This can happen if the dex file was
// recorded in a previous version and we didn't have a chance to update its usage.
/*package*/ static final String UNKNOWN_CLASS_LOADER_CONTEXT =
"=UnknownClassLoaderContext=";
+ // The marker used for unsupported class loader contexts (no longer written, may occur in old
+ // files so discarded on read).
+ private static final String UNSUPPORTED_CLASS_LOADER_CONTEXT =
+ "=UnsupportedClassLoaderContext=";
+
// Map which structures the information we have on a package.
// Maps package name to package data (which stores info about UsedByOtherApps and
// secondary dex files.).
@@ -365,6 +368,12 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
Set<String> loadingPackages = maybeReadLoadingPackages(in, version);
String classLoaderContext = maybeReadClassLoaderContext(in, version);
+ if (UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(classLoaderContext)) {
+ // We used to record use of unsupported class loaders, but we no longer do.
+ // Discard such entries; they will be deleted when we next write the file.
+ continue;
+ }
+
int ownerUserId = Integer.parseInt(elems[0]);
boolean isUsedByOtherApps = readBoolean(elems[1]);
DexUseInfo dexUseInfo = new DexUseInfo(isUsedByOtherApps, ownerUserId,
@@ -709,13 +718,13 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
// the compiled code will be private.
private boolean mUsedByOtherAppsBeforeUpgrade;
- public PackageUseInfo() {
+ /*package*/ PackageUseInfo() {
mCodePathsUsedByOtherApps = new HashMap<>();
mDexUseInfoMap = new HashMap<>();
}
// Creates a deep copy of the `other`.
- public PackageUseInfo(PackageUseInfo other) {
+ private PackageUseInfo(PackageUseInfo other) {
mCodePathsUsedByOtherApps = new HashMap<>();
for (Map.Entry<String, Set<String>> e : other.mCodePathsUsedByOtherApps.entrySet()) {
mCodePathsUsedByOtherApps.put(e.getKey(), new HashSet<>(e.getValue()));
@@ -796,8 +805,9 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
// Packages who load this dex file.
private final Set<String> mLoadingPackages;
- public DexUseInfo(boolean isUsedByOtherApps, int ownerUserId, String classLoaderContext,
- String loaderIsa) {
+ @VisibleForTesting
+ /* package */ DexUseInfo(boolean isUsedByOtherApps, int ownerUserId,
+ String classLoaderContext, String loaderIsa) {
mIsUsedByOtherApps = isUsedByOtherApps;
mOwnerUserId = ownerUserId;
mClassLoaderContext = classLoaderContext;
@@ -809,7 +819,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
}
// Creates a deep copy of the `other`.
- public DexUseInfo(DexUseInfo other) {
+ private DexUseInfo(DexUseInfo other) {
mIsUsedByOtherApps = other.mIsUsedByOtherApps;
mOwnerUserId = other.mOwnerUserId;
mClassLoaderContext = other.mClassLoaderContext;
@@ -827,11 +837,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
if (UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext)) {
// Can happen if we read a previous version.
mClassLoaderContext = dexUseInfo.mClassLoaderContext;
- } else if (UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(dexUseInfo.mClassLoaderContext)) {
- // We detected an unsupported context.
- mClassLoaderContext = UNSUPPORTED_CLASS_LOADER_CONTEXT;
- } else if (!UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext) &&
- !Objects.equals(mClassLoaderContext, dexUseInfo.mClassLoaderContext)) {
+ } else if (!Objects.equals(mClassLoaderContext, dexUseInfo.mClassLoaderContext)) {
// We detected a context change.
mClassLoaderContext = VARIABLE_CLASS_LOADER_CONTEXT;
}
@@ -846,7 +852,7 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
return mIsUsedByOtherApps;
}
- public int getOwnerUserId() {
+ /* package */ int getOwnerUserId() {
return mOwnerUserId;
}
@@ -860,17 +866,15 @@ public class PackageDexUsage extends AbstractStatsBase<Void> {
public String getClassLoaderContext() { return mClassLoaderContext; }
- public boolean isUnsupportedClassLoaderContext() {
- return UNSUPPORTED_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
- }
-
- public boolean isUnknownClassLoaderContext() {
+ @VisibleForTesting
+ /* package */ boolean isUnknownClassLoaderContext() {
// The class loader context may be unknown if we loaded the data from a previous version
// which didn't save the context.
return UNKNOWN_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
}
- public boolean isVariableClassLoaderContext() {
+ @VisibleForTesting
+ /* package */ boolean isVariableClassLoaderContext() {
return VARIABLE_CLASS_LOADER_CONTEXT.equals(mClassLoaderContext);
}
}
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index aae7b95f2dd4..9d1a30107d35 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -40,7 +40,6 @@ import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.media.RingtoneManager;
import android.net.Uri;
-import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.os.Handler;
@@ -880,9 +879,8 @@ public final class DefaultPermissionGrantPolicy {
}
private String getDefaultSystemHandlerActivityPackage(Intent intent, int userId) {
- ResolveInfo handler = mServiceInternal.resolveIntent(intent,
- intent.resolveType(mContext.getContentResolver()), DEFAULT_INTENT_QUERY_FLAGS,
- userId, false, Binder.getCallingUid());
+ ResolveInfo handler = mContext.getPackageManager().resolveActivityAsUser(
+ intent, DEFAULT_INTENT_QUERY_FLAGS, userId);
if (handler == null || handler.activityInfo == null) {
return null;
}
@@ -899,8 +897,8 @@ public final class DefaultPermissionGrantPolicy {
private String getDefaultSystemHandlerServicePackage(
Intent intent, int userId) {
- List<ResolveInfo> handlers = mServiceInternal.queryIntentServices(
- intent, DEFAULT_INTENT_QUERY_FLAGS, Binder.getCallingUid(), userId);
+ List<ResolveInfo> handlers = mContext.getPackageManager().queryIntentServicesAsUser(
+ intent, DEFAULT_INTENT_QUERY_FLAGS, userId);
if (handlers == null) {
return null;
}
@@ -924,10 +922,8 @@ public final class DefaultPermissionGrantPolicy {
for (String syncAdapterPackageName : syncAdapterPackageNames) {
homeIntent.setPackage(syncAdapterPackageName);
- ResolveInfo homeActivity = mServiceInternal.resolveIntent(homeIntent,
- homeIntent.resolveType(mContext.getContentResolver()),
- DEFAULT_INTENT_QUERY_FLAGS,
- userId, false, Binder.getCallingUid());
+ ResolveInfo homeActivity = mContext.getPackageManager().resolveActivityAsUser(
+ homeIntent, DEFAULT_INTENT_QUERY_FLAGS, userId);
if (homeActivity != null) {
continue;
}
@@ -941,7 +937,7 @@ public final class DefaultPermissionGrantPolicy {
}
private String getDefaultProviderAuthorityPackage(String authority, int userId) {
- ProviderInfo provider = mServiceInternal.resolveContentProvider(
+ ProviderInfo provider = mContext.getPackageManager().resolveContentProviderAsUser(
authority, DEFAULT_INTENT_QUERY_FLAGS, userId);
if (provider != null) {
return provider.packageName;
@@ -980,8 +976,9 @@ public final class DefaultPermissionGrantPolicy {
continue;
}
- final int flags = mServiceInternal.getPermissionFlagsTEMP(
- permission, packageName, userId);
+ UserHandle user = UserHandle.of(userId);
+ final int flags = mContext.getPackageManager()
+ .getPermissionFlags(permission, packageName, user);
// We didn't get this through the default grant policy. Move along.
if ((flags & PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT) == 0) {
@@ -997,7 +994,7 @@ public final class DefaultPermissionGrantPolicy {
if ((flags & PackageManager.FLAG_PERMISSION_SYSTEM_FIXED) != 0 && !systemFixed) {
continue;
}
- mServiceInternal.revokeRuntimePermission(packageName, permission, userId, false);
+ mContext.getPackageManager().revokeRuntimePermission(packageName, permission, user);
if (DEBUG) {
Log.i(TAG, "revoked " + (systemFixed ? "fixed " : "not fixed ")
@@ -1007,8 +1004,8 @@ public final class DefaultPermissionGrantPolicy {
// Remove the GRANTED_BY_DEFAULT flag without touching the others.
// Note that we do not revoke FLAG_PERMISSION_SYSTEM_FIXED. That bit remains
// sticky once set.
- mServiceInternal.updatePermissionFlagsTEMP(permission, packageName,
- PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, userId);
+ mContext.getPackageManager().updatePermissionFlags(permission, packageName,
+ PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT, 0, user);
}
}
@@ -1077,8 +1074,9 @@ public final class DefaultPermissionGrantPolicy {
}
if (permissions.contains(permission)) {
- final int flags = mServiceInternal.getPermissionFlagsTEMP(
- permission, pkg.packageName, userId);
+ UserHandle user = UserHandle.of(userId);
+ final int flags = mContext.getPackageManager().getPermissionFlags(
+ permission, pkg.packageName, user);
// If any flags are set to the permission, then it is either set in
// its current state by the system or device/profile owner or the user.
@@ -1094,8 +1092,8 @@ public final class DefaultPermissionGrantPolicy {
continue;
}
- mServiceInternal.grantRuntimePermission(
- pkg.packageName, permission, userId, false);
+ mContext.getPackageManager()
+ .grantRuntimePermission(pkg.packageName, permission, user);
if (DEBUG) {
Log.i(TAG, "Granted " + (systemFixed ? "fixed " : "not fixed ")
+ permission + " to default handler " + pkg);
@@ -1106,8 +1104,8 @@ public final class DefaultPermissionGrantPolicy {
newFlags |= PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
}
- mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
- newFlags, newFlags, userId);
+ mContext.getPackageManager().updatePermissionFlags(permission, pkg.packageName,
+ newFlags, newFlags, user);
}
// If a component gets a permission for being the default handler A
@@ -1119,8 +1117,8 @@ public final class DefaultPermissionGrantPolicy {
Log.i(TAG, "Granted not fixed " + permission + " to default handler "
+ pkg);
}
- mServiceInternal.updatePermissionFlagsTEMP(permission, pkg.packageName,
- PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, 0, userId);
+ mContext.getPackageManager().updatePermissionFlags(permission, pkg.packageName,
+ PackageManager.FLAG_PERMISSION_SYSTEM_FIXED, 0, user);
}
}
}
@@ -1137,10 +1135,12 @@ public final class DefaultPermissionGrantPolicy {
private PackageInfo getPackageInfo(String pkg,
@PackageManager.PackageInfoFlags int extraFlags) {
- return mServiceInternal.getPackageInfo(pkg,
- DEFAULT_PACKAGE_INFO_QUERY_FLAGS | extraFlags,
- //TODO is this the right filterCallingUid?
- UserHandle.USER_SYSTEM, UserHandle.USER_SYSTEM);
+ try {
+ return mContext.getPackageManager().getPackageInfo(pkg,
+ DEFAULT_PACKAGE_INFO_QUERY_FLAGS | extraFlags);
+ } catch (NameNotFoundException e) {
+ return null;
+ }
}
private boolean isSysComponentOrPersistentPlatformSignedPrivApp(PackageInfo pkg) {
diff --git a/services/core/java/com/android/server/pm/permission/OWNERS b/services/core/java/com/android/server/pm/permission/OWNERS
index ffc4731feadd..88b97ea2cb49 100644
--- a/services/core/java/com/android/server/pm/permission/OWNERS
+++ b/services/core/java/com/android/server/pm/permission/OWNERS
@@ -1,8 +1,9 @@
per-file DefaultPermissionGrantPolicy.java = bpoiesz@google.com
-per-file DefaultPermissionGrantPolicy.java = fkupolov@google.com
per-file DefaultPermissionGrantPolicy.java = hackbod@android.com
per-file DefaultPermissionGrantPolicy.java = jsharkey@android.com
per-file DefaultPermissionGrantPolicy.java = svetoslavganov@google.com
per-file DefaultPermissionGrantPolicy.java = toddke@google.com
per-file DefaultPermissionGrantPolicy.java = yamasani@google.com
per-file DefaultPermissionGrantPolicy.java = patb@google.com
+per-file DefaultPermissionGrantPolicy.java = eugenesusla@google.com
+per-file DefaultPermissionGrantPolicy.java = moltmann@google.com
diff --git a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
index 1e0b52adb2f4..ae1090cfb045 100644
--- a/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
+++ b/services/core/java/com/android/server/policy/keyguard/KeyguardServiceDelegate.java
@@ -1,13 +1,11 @@
package com.android.server.policy.keyguard;
-import static android.view.Display.INVALID_DISPLAY;
import static com.android.server.wm.KeyguardServiceDelegateProto.INTERACTIVE_STATE;
import static com.android.server.wm.KeyguardServiceDelegateProto.OCCLUDED;
import static com.android.server.wm.KeyguardServiceDelegateProto.SCREEN_STATE;
import static com.android.server.wm.KeyguardServiceDelegateProto.SECURE;
import static com.android.server.wm.KeyguardServiceDelegateProto.SHOWING;
-import android.app.ActivityManager;
import android.app.ActivityTaskManager;
import android.content.ComponentName;
import android.content.Context;
@@ -212,10 +210,10 @@ public class KeyguardServiceDelegate {
mHandler.post(() -> {
try {
// There are no longer any keyguard windows on secondary displays, so pass
- // INVALID_DISPLAY. All that means is that showWhenLocked activities on
- // secondary displays now get to show.
+ // {@code null}. All that means is that showWhenLocked activities on
+ // external displays now get to show.
ActivityTaskManager.getService().setLockScreenShown(true /* keyguardShowing */,
- false /* aodShowing */, INVALID_DISPLAY);
+ false /* aodShowing */, null /* secondaryDisplaysShowing */);
} catch (RemoteException e) {
// Local call.
}
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLaunchObserver.java b/services/core/java/com/android/server/wm/ActivityMetricsLaunchObserver.java
new file mode 100644
index 000000000000..e3133efb890c
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLaunchObserver.java
@@ -0,0 +1,182 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Intent;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Observe activity manager launch sequences.
+ *
+ * The activity manager can have at most 1 concurrent launch sequences. Calls to this interface
+ * are ordered by a happens-before relation for each defined state transition (see below).
+ *
+ * When a new launch sequence is made, that sequence is in the {@code INTENT_STARTED} state which
+ * is communicated by the {@link #onIntentStarted} callback. This is a transient state.
+ *
+ * The intent can fail to launch the activity, in which case the sequence's state transitions to
+ * {@code INTENT_FAILED} via {@link #onIntentFailed}. This is a terminal state.
+ *
+ * If an activity is successfully started, the launch sequence's state will transition into
+ * {@code STARTED} via {@link #onActivityLaunched}. This is a transient state.
+ *
+ * It must then transition to either {@code CANCELLED} with {@link #onActivityLaunchCancelled}
+ * or into {@code FINISHED} with {@link #onActivityLaunchFinished}. These are terminal states.
+ *
+ * Note that the {@link ActivityRecord} provided as a parameter to some state transitions isn't
+ * necessarily the same within a single launch sequence: it is only the top-most activity at the
+ * time (if any). Trampoline activities coalesce several activity starts into a single launch
+ * sequence.
+ *
+ * Upon reaching a terminal state, it is considered that there are no active launch sequences
+ * until a subsequent transition into {@code INTENT_STARTED} initiates a new launch sequence.
+ *
+ * <pre>
+ * ┌⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯┐ ┌⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯┐ ╔══════════════════════════╗
+ * ╴╴▶ ⋮ INTENT_STARTED ⋮ ──▶ ⋮ ACTIVITY_LAUNCHED ⋮ ──▶ ║ ACTIVITY_LAUNCH_FINISHED ║
+ * └⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯┘ └⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯⋯┘ ╚══════════════════════════╝
+ * : :
+ * : :
+ * ▼ ▼
+ * ╔════════════════╗ ╔═══════════════════════════╗
+ * ║ INTENT_FAILED ║ ║ ACTIVITY_LAUNCH_CANCELLED ║
+ * ╚════════════════╝ ╚═══════════════════════════╝
+ * </pre>
+ */
+public interface ActivityMetricsLaunchObserver {
+ /**
+ * The 'temperature' at which a launch sequence had started.
+ *
+ * The lower the temperature the more work has to be done during start-up.
+ * A 'cold' temperature means that a new process has been started and likely
+ * nothing is cached.
+ *
+ * A hot temperature means the existing activity is brought to the foreground.
+ * It may need to regenerate some objects as a result of {@code onTrimMemory}.
+ *
+ * A warm temperature is in the middle; an existing process is used, but the activity
+ * has to be created from scratch with {@code #onCreate}.
+ *
+ * @see https://developer.android.com/topic/performance/vitals/launch-time
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({
+ TEMPERATURE_COLD,
+ TEMPERATURE_WARM,
+ TEMPERATURE_HOT
+ })
+ @interface Temperature {}
+
+ /** Cold launch sequence: a new process has started. */
+ public static final int TEMPERATURE_COLD = 1;
+ /** Warm launch sequence: process reused, but activity has to be created. */
+ public static final int TEMPERATURE_WARM = 2;
+ /** Hot launch sequence: process reused, activity brought-to-top. */
+ public static final int TEMPERATURE_HOT = 3;
+
+ /**
+ * Notifies the observer that a new launch sequence has begun as a result of a new intent.
+ *
+ * Once a launch sequence begins, the resolved activity will either subsequently start with
+ * {@link #onActivityLaunched} or abort early (for example due to a resolution error or due to
+ * a security error) with {@link #onIntentFailed}.
+ *
+ * Multiple calls to this method cannot occur without first terminating the current
+ * launch sequence.
+ */
+ public void onIntentStarted(@NonNull Intent intent);
+
+ /**
+ * Notifies the observer that the current launch sequence has failed to launch an activity.
+ *
+ * This function call terminates the current launch sequence. The next method call, if any,
+ * must be {@link #onIntentStarted}.
+ *
+ * Examples of this happening:
+ * - Failure to resolve to an activity
+ * - Calling package did not have the security permissions to call the requested activity
+ * - Resolved activity was already running and only needed to be brought to the top
+ *
+ * Multiple calls to this method cannot occur without first terminating the current
+ * launch sequence.
+ */
+ public void onIntentFailed();
+
+ /**
+ * Notifies the observer that the current launch sequence had begun starting an activity.
+ *
+ * This is an intermediate state: once an activity begins starting, the entire launch sequence
+ * will later terminate by either finishing or cancelling.
+ *
+ * The initial activity is the first activity to be started as part of a launch sequence:
+ * it is represented by {@param activity} However, it isn't
+ * necessarily the activity which will be considered as displayed when the activity
+ * finishes launching (e.g. {@code activity} in {@link #onActivityLaunchFinished}).
+ *
+ * Multiple calls to this method cannot occur without first terminating the current
+ * launch sequence.
+ */
+ public void onActivityLaunched(@NonNull ActivityRecord activity,
+ @Temperature int temperature);
+
+ /**
+ * Notifies the observer that the current launch sequence has been aborted.
+ *
+ * This function call terminates the current launch sequence. The next method call, if any,
+ * must be {@link #onIntentStarted}.
+ *
+ * This can happen for many reasons, for example the user switches away to another app
+ * prior to the launch sequence completing, or the application being killed.
+ *
+ * Multiple calls to this method cannot occur without first terminating the current
+ * launch sequence.
+ *
+ * @param abortingActivity the last activity that had the top-most window during abort
+ * (this can be {@code null} in rare situations its unknown).
+ *
+ * @apiNote The aborting activity isn't necessarily the same as the starting activity;
+ * in the case of a trampoline, multiple activities could've been started
+ * and only the latest activity is reported here.
+ */
+ public void onActivityLaunchCancelled(@Nullable ActivityRecord abortingActivity);
+
+ /**
+ * Notifies the observer that the current launch sequence has been successfully finished.
+ *
+ * This function call terminates the current launch sequence. The next method call, if any,
+ * must be {@link #onIntentStarted}.
+ *
+ * A launch sequence is considered to be successfully finished when a frame is fully
+ * drawn for the first time: the top-most activity at the time is what's reported here.
+ *
+ * @param finalActivity the top-most activity whose windows were first to fully draw
+ *
+ * Multiple calls to this method cannot occur without first terminating the current
+ * launch sequence.
+ *
+ * @apiNote The finishing activity isn't necessarily the same as the starting activity;
+ * in the case of a trampoline, multiple activities could've been started
+ * and only the latest activity that was top-most during first-frame drawn
+ * is reported here.
+ */
+ public void onActivityLaunchFinished(@NonNull ActivityRecord finalActivity);
+}
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 8bde7dd92ed3..9b01dfd8852c 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -80,6 +80,7 @@ import static com.android.server.am.MemoryStatUtil.MemoryStat;
import static com.android.server.am.MemoryStatUtil.readMemoryStatFromFilesystem;
import static com.android.server.wm.ActivityTaskManagerInternal.APP_TRANSITION_TIMEOUT;
+import android.app.WindowConfiguration.WindowingMode;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
@@ -141,15 +142,21 @@ class ActivityMetricsLogger {
private final Context mContext;
private final MetricsLogger mMetricsLogger = new MetricsLogger();
+ // set to INVALID_START_TIME in reset.
+ // set to valid value in notifyActivityLaunching
private long mCurrentTransitionStartTime = INVALID_START_TIME;
private long mLastTransitionStartTime = INVALID_START_TIME;
private int mCurrentTransitionDeviceUptime;
private int mCurrentTransitionDelayMs;
+
+ /** If the any app transitions have been logged as starting, after the latest reset. */
private boolean mLoggedTransitionStarting;
+ /** Map : @WindowingMode int => WindowingModeTransitionInfo */
private final SparseArray<WindowingModeTransitionInfo> mWindowingModeTransitionInfo =
new SparseArray<>();
+ /** Map : @WindowingMode int => WindowingModeTransitionInfo */
private final SparseArray<WindowingModeTransitionInfo> mLastWindowingModeTransitionInfo =
new SparseArray<>();
private final H mHandler;
@@ -157,6 +164,12 @@ class ActivityMetricsLogger {
private ArtManagerInternal mArtManagerInternal;
private final StringBuilder mStringBuilder = new StringBuilder();
+ /**
+ * Due to the global single concurrent launch sequence, all calls to this observer must be made
+ * in-order on the same thread to fulfill the "happens-before" guarantee in LaunchObserver.
+ */
+ private final ActivityMetricsLaunchObserver mLaunchObserver = null;
+
private final class H extends Handler {
public H(Looper looper) {
@@ -175,6 +188,7 @@ class ActivityMetricsLogger {
}
private final class WindowingModeTransitionInfo {
+ /** The latest activity to have been launched. */
private ActivityRecord launchedActivity;
private int startResult;
private boolean currentTransitionProcessRunning;
@@ -273,7 +287,7 @@ class ActivityMetricsLogger {
return;
}
- int windowingMode = stack.getWindowingMode();
+ @WindowingMode int windowingMode = stack.getWindowingMode();
if (windowingMode == WINDOWING_MODE_PINNED) {
stack = mSupervisor.findStackBehind(stack);
windowingMode = stack.getWindowingMode();
@@ -301,11 +315,19 @@ class ActivityMetricsLogger {
* Notifies the tracker at the earliest possible point when we are starting to launch an
* activity.
*/
- void notifyActivityLaunching() {
+ void notifyActivityLaunching(Intent intent) {
+ if (DEBUG_METRICS) {
+ Slog.i(TAG, String.format("notifyActivityLaunching: active:%b, intent:%s",
+ isAnyTransitionActive(),
+ intent));
+ }
+
if (!isAnyTransitionActive()) {
- if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunching");
+
mCurrentTransitionStartTime = SystemClock.uptimeMillis();
mLastTransitionStartTime = mCurrentTransitionStartTime;
+
+ launchObserverNotifyIntentStarted(intent);
}
}
@@ -350,7 +372,9 @@ class ActivityMetricsLogger {
+ " processRunning=" + processRunning
+ " processSwitch=" + processSwitch);
- final int windowingMode = launchedActivity != null
+ // If we are already in an existing transition, only update the activity name, but not the
+ // other attributes.
+ final @WindowingMode int windowingMode = launchedActivity != null
? launchedActivity.getWindowingMode()
: WINDOWING_MODE_UNDEFINED;
final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
@@ -361,13 +385,15 @@ class ActivityMetricsLogger {
if (launchedActivity != null && launchedActivity.nowVisible) {
// Launched activity is already visible. We cannot measure windows drawn delay.
- reset(true /* abort */, info);
+ reset(true /* abort */, info, "launched activity already visible");
return;
}
if (launchedActivity != null && info != null) {
// If we are already in an existing transition, only update the activity name, but not
// the other attributes.
+
+ // Coalesce multiple (trampoline) activities from a single sequence together.
info.launchedActivity = launchedActivity;
return;
}
@@ -377,7 +403,7 @@ class ActivityMetricsLogger {
if ((!isLoggableResultCode(resultCode) || launchedActivity == null || !processSwitch
|| windowingMode == WINDOWING_MODE_UNDEFINED) && !otherWindowModesLaunching) {
// Failed to launch or it was not a process switch, so we don't care about the timing.
- reset(true /* abort */, info);
+ reset(true /* abort */, info, "failed to launch or not a process switch");
return;
} else if (otherWindowModesLaunching) {
// Don't log this windowing mode but continue with the other windowing modes.
@@ -386,6 +412,8 @@ class ActivityMetricsLogger {
if (DEBUG_METRICS) Slog.i(TAG, "notifyActivityLaunched successful");
+ // A new launch sequence [with the windowingMode] has begun.
+ // Start tracking it.
final WindowingModeTransitionInfo newInfo = new WindowingModeTransitionInfo();
newInfo.launchedActivity = launchedActivity;
newInfo.currentTransitionProcessRunning = processRunning;
@@ -394,6 +422,7 @@ class ActivityMetricsLogger {
mLastWindowingModeTransitionInfo.put(windowingMode, newInfo);
mCurrentTransitionDeviceUptime = (int) (SystemClock.uptimeMillis() / 1000);
startTraces(newInfo);
+ launchObserverNotifyActivityLaunched(newInfo);
}
/**
@@ -407,7 +436,8 @@ class ActivityMetricsLogger {
/**
* Notifies the tracker that all windows of the app have been drawn.
*/
- WindowingModeTransitionInfoSnapshot notifyWindowsDrawn(int windowingMode, long timestamp) {
+ WindowingModeTransitionInfoSnapshot notifyWindowsDrawn(@WindowingMode int windowingMode,
+ long timestamp) {
if (DEBUG_METRICS) Slog.i(TAG, "notifyWindowsDrawn windowingMode=" + windowingMode);
final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
@@ -419,7 +449,7 @@ class ActivityMetricsLogger {
final WindowingModeTransitionInfoSnapshot infoSnapshot =
new WindowingModeTransitionInfoSnapshot(info);
if (allWindowsDrawn() && mLoggedTransitionStarting) {
- reset(false /* abort */, info);
+ reset(false /* abort */, info, "notifyWindowsDrawn - all windows drawn");
}
return infoSnapshot;
}
@@ -427,7 +457,7 @@ class ActivityMetricsLogger {
/**
* Notifies the tracker that the starting window was drawn.
*/
- void notifyStartingWindowDrawn(int windowingMode, long timestamp) {
+ void notifyStartingWindowDrawn(@WindowingMode int windowingMode, long timestamp) {
final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(windowingMode);
if (info == null || info.loggedStartingWindowDrawn) {
return;
@@ -444,22 +474,28 @@ class ActivityMetricsLogger {
*/
void notifyTransitionStarting(SparseIntArray windowingModeToReason, long timestamp) {
if (!isAnyTransitionActive() || mLoggedTransitionStarting) {
+ // Ignore calls to this made after a reset and prior to notifyActivityLaunching.
+
+ // Ignore any subsequent notifyTransitionStarting until the next reset.
return;
}
if (DEBUG_METRICS) Slog.i(TAG, "notifyTransitionStarting");
mCurrentTransitionDelayMs = calculateDelay(timestamp);
mLoggedTransitionStarting = true;
+
+ WindowingModeTransitionInfo foundInfo = null;
for (int index = windowingModeToReason.size() - 1; index >= 0; index--) {
- final int windowingMode = windowingModeToReason.keyAt(index);
+ final @WindowingMode int windowingMode = windowingModeToReason.keyAt(index);
final WindowingModeTransitionInfo info = mWindowingModeTransitionInfo.get(
windowingMode);
if (info == null) {
continue;
}
info.reason = windowingModeToReason.valueAt(index);
+ foundInfo = info;
}
if (allWindowsDrawn()) {
- reset(false /* abort */, null /* WindowingModeTransitionInfo */);
+ reset(false /* abort */, foundInfo, "notifyTransitionStarting - all windows drawn");
}
}
@@ -498,7 +534,7 @@ class ActivityMetricsLogger {
logAppTransitionCancel(info);
mWindowingModeTransitionInfo.remove(r.getWindowingMode());
if (mWindowingModeTransitionInfo.size() == 0) {
- reset(true /* abort */, info);
+ reset(true /* abort */, info, "notifyVisibilityChanged to invisible");
}
}
}
@@ -534,12 +570,25 @@ class ActivityMetricsLogger {
&& mWindowingModeTransitionInfo.size() > 0;
}
- private void reset(boolean abort, WindowingModeTransitionInfo info) {
- if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort);
+ private void reset(boolean abort, WindowingModeTransitionInfo info, String cause) {
+ if (DEBUG_METRICS) Slog.i(TAG, "reset abort=" + abort + ",cause=" + cause);
if (!abort && isAnyTransitionActive()) {
logAppTransitionMultiEvents();
}
stopLaunchTrace(info);
+
+ // Ignore reset-after reset.
+ if (isAnyTransitionActive()) {
+ // LaunchObserver callbacks.
+ if (abort) {
+ launchObserverNotifyActivityLaunchCancelled(info);
+ } else {
+ launchObserverNotifyActivityLaunchFinished(info);
+ }
+ } else {
+ launchObserverNotifyIntentFailed();
+ }
+
mCurrentTransitionStartTime = INVALID_START_TIME;
mCurrentTransitionDelayMs = INVALID_DELAY;
mLoggedTransitionStarting = false;
@@ -572,6 +621,13 @@ class ActivityMetricsLogger {
info.launchedActivity.packageName,
convertAppStartTransitionType(type),
info.launchedActivity.info.name);
+ if (DEBUG_METRICS) {
+ Slog.i(TAG, String.format("APP_START_CANCELED(%s, %s, %s, %s)",
+ info.launchedActivity.appInfo.uid,
+ info.launchedActivity.packageName,
+ convertAppStartTransitionType(type),
+ info.launchedActivity.info.name));
+ }
}
private void logAppTransitionMultiEvents() {
@@ -656,6 +712,17 @@ class ActivityMetricsLogger {
launchToken,
packageOptimizationInfo.getCompilationReason(),
packageOptimizationInfo.getCompilationFilter());
+
+ if (DEBUG_METRICS) {
+ Slog.i(TAG, String.format("APP_START_OCCURRED(%s, %s, %s, %s, %s)",
+ info.applicationInfo.uid,
+ info.packageName,
+ convertAppStartTransitionType(info.type),
+ info.launchedActivityName,
+ info.launchedActivityLaunchedFromPackage));
+ }
+
+
logAppStartMemoryStateCapture(info);
}
@@ -923,4 +990,76 @@ class ActivityMetricsLogger {
info.launchTraceActive = false;
}
}
+
+ /** Notify the {@link ActivityMetricsLaunchObserver} that a new launch sequence has begun. */
+ private void launchObserverNotifyIntentStarted(Intent intent) {
+ if (mLaunchObserver != null) {
+ // Beginning a launch is timing sensitive and so should be observed as soon as possible.
+ mLaunchObserver.onIntentStarted(intent);
+ }
+ }
+
+ /**
+ * Notify the {@link ActivityMetricsLaunchObserver} that the previous launch sequence has
+ * aborted due to intent failure (e.g. intent resolve failed or security error, etc) or
+ * intent being delivered to the top running activity.
+ */
+ private void launchObserverNotifyIntentFailed() {
+ if (mLaunchObserver != null) {
+ mLaunchObserver.onIntentFailed();
+ }
+ }
+
+ /**
+ * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence's activity
+ * has started.
+ */
+ private void launchObserverNotifyActivityLaunched(WindowingModeTransitionInfo info) {
+ @ActivityMetricsLaunchObserver.Temperature int temperature =
+ convertTransitionTypeToLaunchObserverTemperature(getTransitionType(info));
+
+ if (mLaunchObserver != null) {
+ // Beginning a launch is timing sensitive and so should be observed as soon as possible.
+ mLaunchObserver.onActivityLaunched(info.launchedActivity,
+ temperature);
+ }
+ }
+
+ /**
+ * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence is
+ * cancelled.
+ */
+ private void launchObserverNotifyActivityLaunchCancelled(WindowingModeTransitionInfo info) {
+ final ActivityRecord launchedActivity = info != null ? info.launchedActivity : null;
+
+ if (mLaunchObserver != null) {
+ mLaunchObserver.onActivityLaunchCancelled(launchedActivity);
+ }
+ }
+
+ /**
+ * Notify the {@link ActivityMetricsLaunchObserver} that the current launch sequence's activity
+ * has fully finished (successfully).
+ */
+ private void launchObserverNotifyActivityLaunchFinished(WindowingModeTransitionInfo info) {
+ final ActivityRecord launchedActivity = info.launchedActivity;
+
+ if (mLaunchObserver != null) {
+ mLaunchObserver.onActivityLaunchFinished(launchedActivity);
+ }
+ }
+
+ private static @ActivityMetricsLaunchObserver.Temperature int
+ convertTransitionTypeToLaunchObserverTemperature(int transitionType) {
+ switch (transitionType) {
+ case TYPE_TRANSITION_WARM_LAUNCH:
+ return ActivityMetricsLaunchObserver.TEMPERATURE_WARM;
+ case TYPE_TRANSITION_HOT_LAUNCH:
+ return ActivityMetricsLaunchObserver.TEMPERATURE_HOT;
+ case TYPE_TRANSITION_COLD_LAUNCH:
+ return ActivityMetricsLaunchObserver.TEMPERATURE_COLD;
+ default:
+ return -1;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 77b331e6c4a9..9bcee8a3ab23 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -59,6 +59,13 @@ import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.TYPE_VIRTUAL;
import static android.view.WindowManager.TRANSIT_DOCK_TASK_FROM_RECENTS;
+import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
+import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
+import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
+import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
+import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
+import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
+import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
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;
@@ -67,13 +74,6 @@ 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;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
-import static com.android.server.am.ActivityStackSupervisorProto.CONFIGURATION_CONTAINER;
-import static com.android.server.am.ActivityStackSupervisorProto.DISPLAYS;
-import static com.android.server.am.ActivityStackSupervisorProto.FOCUSED_STACK_ID;
-import static com.android.server.am.ActivityStackSupervisorProto.IS_HOME_RECENTS_COMPONENT;
-import static com.android.server.am.ActivityStackSupervisorProto.KEYGUARD_CONTROLLER;
-import static com.android.server.am.ActivityStackSupervisorProto.PENDING_ACTIVITIES;
-import static com.android.server.am.ActivityStackSupervisorProto.RESUMED_ACTIVITY;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
@@ -1976,8 +1976,9 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
//Slog.i(TAG, "IDLE: mBooted=" + mBooted + ", fromTimeout=" + fromTimeout);
- // Make sure we can finish booting when all resumed activities are idle.
- if ((!mService.isBooted() && allResumedActivitiesIdle()) || fromTimeout) {
+ // Check if able to finish booting when device is booting and all resumed activities
+ // are idle.
+ if ((mService.isBooting() && allResumedActivitiesIdle()) || fromTimeout) {
booting = checkFinishBootingLocked();
}
@@ -4136,7 +4137,12 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
if (DEBUG_STACK) Slog.v(TAG, "Display added displayId=" + displayId);
synchronized (mService.mGlobalLock) {
getActivityDisplayOrCreateLocked(displayId);
- startHomeOnDisplay(mCurrentUser, "displayAdded", displayId);
+ // Do not start home before booting, or it may accidentally finish booting before it
+ // starts. Instead, we expect home activities to be launched when the system is ready
+ // (ActivityManagerService#systemReady).
+ if (mService.isBooted() || mService.isBooting()) {
+ startHomeOnDisplay(mCurrentUser, "displayAdded", displayId);
+ }
}
}
@@ -4745,7 +4751,7 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
final ActivityRecord targetActivity = task.getTopActivity();
sendPowerHintForLaunchStartIfNeeded(true /* forceSend */, targetActivity);
- mActivityMetricsLogger.notifyActivityLaunching();
+ mActivityMetricsLogger.notifyActivityLaunching(task.intent);
try {
mService.moveTaskToFrontLocked(task.taskId, 0, options,
true /* fromRecents */);
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index e43a79ac59d5..afc946b5deb0 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -996,7 +996,7 @@ class ActivityStarter {
if (intent != null && intent.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Intent");
}
- mSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
+ mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
boolean componentSpecified = intent.getComponent() != null;
final int realCallingPid = Binder.getCallingPid();
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 3ede8bc818e0..3359eac880c7 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -114,17 +114,17 @@ import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_SWITC
import static com.android.server.wm.ActivityTaskManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
-import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
-import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
-import static com.android.server.wm.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
-import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
-import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
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_RECEIVER_EXTRAS;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_STRUCTURE;
+import static com.android.server.wm.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
+import static com.android.server.wm.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
+import static com.android.server.wm.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
+import static com.android.server.wm.TaskRecord.REPARENT_KEEP_STACK_AT_FRONT;
+import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import android.Manifest;
import android.annotation.NonNull;
@@ -2885,7 +2885,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
- int secondaryDisplayShowing) {
+ int[] secondaryDisplaysShowing) {
if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
@@ -2903,7 +2903,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
try {
mKeyguardController.setKeyguardShown(keyguardShowing, aodShowing,
- secondaryDisplayShowing);
+ secondaryDisplaysShowing);
} finally {
Binder.restoreCallingIdentity(ident);
}
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 3560635ced09..c91af73dc6dd 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -18,7 +18,6 @@ package com.android.server.wm;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
-import static android.view.Display.INVALID_DISPLAY;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_NO_ANIMATION;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_TO_SHADE;
import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_GOING_AWAY_WITH_WALLPAPER;
@@ -30,13 +29,13 @@ import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_TO_SHADE;
import static android.view.WindowManagerPolicyConstants.KEYGUARD_GOING_AWAY_FLAG_WITH_WALLPAPER;
-import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
-import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.KeyguardControllerProto.KEYGUARD_OCCLUDED_STATES;
import static com.android.server.am.KeyguardControllerProto.KEYGUARD_SHOWING;
import static com.android.server.am.KeyguardOccludedProto.DISPLAY_ID;
import static com.android.server.am.KeyguardOccludedProto.KEYGUARD_OCCLUDED;
+import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
+import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import android.os.IBinder;
import android.os.RemoteException;
@@ -50,6 +49,7 @@ import com.android.server.policy.WindowManagerPolicy;
import com.android.server.wm.ActivityTaskManagerInternal.SleepToken;
import java.io.PrintWriter;
+import java.util.Arrays;
/**
* Controls Keyguard occluding, dismissing and transitions depending on what kind of activities are
@@ -67,10 +67,9 @@ class KeyguardController {
private boolean mAodShowing;
private boolean mKeyguardGoingAway;
private boolean mDismissalRequested;
+ private int[] mSecondaryDisplayIdsShowing;
private int mBeforeUnoccludeTransit;
private int mVisibilityTransactionDepth;
- // TODO(b/111955725): Support multiple external displays
- private int mSecondaryDisplayShowing = INVALID_DISPLAY;
private final SparseArray<KeyguardDisplayState> mDisplayStates = new SparseArray<>();
private final ActivityTaskManagerService mService;
@@ -90,7 +89,9 @@ class KeyguardController {
*/
boolean isKeyguardOrAodShowing(int displayId) {
return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway
- && !isDisplayOccluded(displayId);
+ && (displayId == DEFAULT_DISPLAY
+ ? !isDisplayOccluded(DEFAULT_DISPLAY)
+ : isShowingOnSecondaryDisplay(displayId));
}
/**
@@ -98,7 +99,10 @@ class KeyguardController {
* display, false otherwise
*/
boolean isKeyguardShowing(int displayId) {
- return mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId);
+ return mKeyguardShowing && !mKeyguardGoingAway
+ && (displayId == DEFAULT_DISPLAY
+ ? !isDisplayOccluded(DEFAULT_DISPLAY)
+ : isShowingOnSecondaryDisplay(displayId));
}
/**
@@ -120,16 +124,17 @@ class KeyguardController {
* Update the Keyguard showing state.
*/
void setKeyguardShown(boolean keyguardShowing, boolean aodShowing,
- int secondaryDisplayShowing) {
+ int[] secondaryDisplaysShowing) {
boolean showingChanged = keyguardShowing != mKeyguardShowing || aodShowing != mAodShowing;
// If keyguard is going away, but SystemUI aborted the transition, need to reset state.
showingChanged |= mKeyguardGoingAway && keyguardShowing;
- if (!showingChanged && secondaryDisplayShowing == mSecondaryDisplayShowing) {
+ if (!showingChanged && Arrays.equals(secondaryDisplaysShowing,
+ mSecondaryDisplayIdsShowing)) {
return;
}
mKeyguardShowing = keyguardShowing;
mAodShowing = aodShowing;
- mSecondaryDisplayShowing = secondaryDisplayShowing;
+ mSecondaryDisplayIdsShowing = secondaryDisplaysShowing;
mWindowManager.setAodShowing(aodShowing);
if (showingChanged) {
dismissDockedStackIfNeeded();
@@ -145,6 +150,14 @@ class KeyguardController {
updateKeyguardSleepToken();
}
+ private boolean isShowingOnSecondaryDisplay(int displayId) {
+ if (mSecondaryDisplayIdsShowing == null) return false;
+ for (int showingId : mSecondaryDisplayIdsShowing) {
+ if (displayId == showingId) return true;
+ }
+ return false;
+ }
+
/**
* Called when Keyguard is going away.
*
@@ -386,16 +399,18 @@ class KeyguardController {
}
private KeyguardDisplayState getDisplay(int displayId) {
- if (mDisplayStates.get(displayId) == null) {
- mDisplayStates.append(displayId,
- new KeyguardDisplayState(mService, displayId));
+ KeyguardDisplayState state = mDisplayStates.get(displayId);
+ if (state == null) {
+ state = new KeyguardDisplayState(mService, displayId);
+ mDisplayStates.append(displayId, state);
}
- return mDisplayStates.get(displayId);
+ return state;
}
void onDisplayRemoved(int displayId) {
- if (mDisplayStates.get(displayId) != null) {
- mDisplayStates.get(displayId).onRemoved();
+ final KeyguardDisplayState state = mDisplayStates.get(displayId);
+ if (state != null) {
+ state.onRemoved();
mDisplayStates.remove(displayId);
}
}
@@ -456,7 +471,8 @@ class KeyguardController {
mOccluded |= controller.mWindowManager.isShowingDream();
}
- // TODO(b/113840485): Handle app transition for individual display.
+ // TODO(b/113840485): Handle app transition for individual display, and apply occluded
+ // state change to secondary displays.
// For now, only default display can change occluded.
if (lastOccluded != mOccluded && mDisplayId == DEFAULT_DISPLAY) {
controller.handleOccludedChanged();
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 7a1ebf2b51b3..9aeb0253250a 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -122,7 +122,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
targetActivity);
}
- mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching();
+ mStackSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
mService.mAmInternal.setRunningRemoteAnimation(mCallingPid, true);
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 49f410d98289..54a140dec713 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -16,6 +16,12 @@
package com.android.server;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
+import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
+import static android.os.IServiceManager.DUMP_FLAG_PROTO;
+import static android.view.Display.DEFAULT_DISPLAY;
+
import android.app.ActivityThread;
import android.app.INotificationManager;
import android.app.usage.UsageStatsManagerInternal;
@@ -64,10 +70,12 @@ import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.EmergencyAffordanceManager;
import com.android.internal.widget.ILockSettings;
import com.android.server.am.ActivityManagerService;
-import com.android.server.wm.ActivityTaskManagerService;
import com.android.server.appbinding.AppBindingService;
import com.android.server.audio.AudioService;
import com.android.server.biometrics.BiometricService;
+import com.android.server.biometrics.face.FaceService;
+import com.android.server.biometrics.fingerprint.FingerprintService;
+import com.android.server.biometrics.iris.IrisService;
import com.android.server.broadcastradio.BroadcastRadioService;
import com.android.server.camera.CameraServiceProxy;
import com.android.server.clipboard.ClipboardService;
@@ -78,8 +86,6 @@ import com.android.server.display.ColorDisplayService;
import com.android.server.display.DisplayManagerService;
import com.android.server.dreams.DreamManagerService;
import com.android.server.emergency.EmergencyAffordanceService;
-import com.android.server.biometrics.face.FaceService;
-import com.android.server.biometrics.fingerprint.FingerprintService;
import com.android.server.hdmi.HdmiControlService;
import com.android.server.input.InputManagerService;
import com.android.server.inputmethod.InputMethodManagerService;
@@ -87,8 +93,8 @@ import com.android.server.job.JobSchedulerService;
import com.android.server.lights.LightsService;
import com.android.server.media.MediaResourceMonitorService;
import com.android.server.media.MediaRouterService;
-import com.android.server.media.MediaUpdateService;
import com.android.server.media.MediaSessionService;
+import com.android.server.media.MediaUpdateService;
import com.android.server.media.projection.MediaProjectionManagerService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
@@ -127,6 +133,7 @@ import com.android.server.uri.UriGrantsManagerService;
import com.android.server.usage.UsageStatsService;
import com.android.server.vr.VrManagerService;
import com.android.server.webkit.WebViewUpdateService;
+import com.android.server.wm.ActivityTaskManagerService;
import com.android.server.wm.WindowManagerService;
import dalvik.system.VMRuntime;
@@ -138,12 +145,6 @@ import java.util.Timer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_CRITICAL;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_HIGH;
-import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
-import static android.os.IServiceManager.DUMP_FLAG_PROTO;
-import static android.view.Display.DEFAULT_DISPLAY;
-
public final class SystemServer {
private static final String TAG = "SystemServer";
@@ -229,6 +230,8 @@ public final class SystemServer {
"com.android.server.wallpaper.WallpaperManagerService$Lifecycle";
private static final String AUTO_FILL_MANAGER_SERVICE_CLASS =
"com.android.server.autofill.AutofillManagerService";
+ private static final String INTELLIGENCE_MANAGER_SERVICE_CLASS =
+ "com.android.server.intelligence.IntelligenceManagerService";
private static final String TIME_ZONE_RULES_MANAGER_SERVICE_CLASS =
"com.android.server.timezone.RulesManagerService$Lifecycle";
private static final String IOT_SERVICE_CLASS =
@@ -794,6 +797,8 @@ public final class SystemServer {
boolean disableSystemTextClassifier = SystemProperties.getBoolean(
"config.disable_systemtextclassifier", false);
+ boolean disableIntelligence = SystemProperties.getBoolean(
+ "config.disable_intelligence", false);
boolean disableNetworkTime = SystemProperties.getBoolean("config.disable_networktime",
false);
boolean disableCameraService = SystemProperties.getBoolean("config.disable_cameraservice",
@@ -1589,6 +1594,8 @@ public final class SystemServer {
final boolean hasFeatureFace
= mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE);
+ final boolean hasFeatureIris
+ = mPackageManager.hasSystemFeature(PackageManager.FEATURE_IRIS);
final boolean hasFeatureFingerprint
= mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT);
@@ -1598,13 +1605,19 @@ public final class SystemServer {
traceEnd();
}
+ if (hasFeatureIris) {
+ traceBeginAndSlog("StartIrisSensor");
+ mSystemServiceManager.startService(IrisService.class);
+ traceEnd();
+ }
+
if (hasFeatureFingerprint) {
traceBeginAndSlog("StartFingerprintSensor");
mSystemServiceManager.startService(FingerprintService.class);
traceEnd();
}
- if (hasFeatureFace || hasFeatureFingerprint) {
+ if (hasFeatureFace || hasFeatureIris || hasFeatureFingerprint) {
// Start this service after all biometric services.
traceBeginAndSlog("StartBiometricPromptService");
mSystemServiceManager.startService(BiometricService.class);
@@ -1728,6 +1741,12 @@ public final class SystemServer {
traceEnd();
}
+ if (!disableIntelligence) {
+ traceBeginAndSlog("StartIntelligenceService");
+ mSystemServiceManager.startService(INTELLIGENCE_MANAGER_SERVICE_CLASS);
+ traceEnd();
+ }
+
traceBeginAndSlog("AppServiceManager");
mSystemServiceManager.startService(AppBindingService.Lifecycle.class);
traceEnd();
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 b0b7defe8da6..ebac8fb712be 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -38,12 +38,12 @@ import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import libcore.io.IoUtils;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import libcore.io.IoUtils;
-
import java.io.File;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
@@ -490,7 +490,7 @@ public class PackageParserTest {
pkg.usesLibraryFiles = new String[] { "foo13"};
pkg.usesLibraryInfos = new ArrayList<>();
- pkg.usesLibraryInfos.add(new SharedLibraryInfo(null, null, null, 0L, 0, null, null));
+ pkg.usesLibraryInfos.add(new SharedLibraryInfo(null, null, null, 0L, 0, null, null, null));
pkg.mOriginalPackages = new ArrayList<>();
pkg.mOriginalPackages.add("foo14");
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
index 416a616b0546..bd42b7318158 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexManagerTests.java
@@ -401,15 +401,7 @@ public class DexManagerTests {
List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
- PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
- assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
- assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
- // We expect that all the contexts are unsupported.
- String[] expectedContexts =
- Collections.nCopies(secondaries.size(),
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
- assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
- /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+ assertNoUseInfo(mBarUser0UnsupportedClassLoader);
}
@Test
@@ -438,27 +430,18 @@ public class DexManagerTests {
}
@Test
- public void testNotifyUnsupportedClassLoaderDoesNotChange() {
- List<String> secondaries = mBarUser0UnsupportedClassLoader.getSecondaryDexPaths();
- notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
-
- PackageUseInfo pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
- assertIsUsedByOtherApps(mBarUser0UnsupportedClassLoader, pui, false);
- assertEquals(secondaries.size(), pui.getDexUseInfoMap().size());
- // We expect that all the contexts are unsupported.
- String[] expectedContexts =
- Collections.nCopies(secondaries.size(),
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT).toArray(new String[0]);
- assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
- /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+ public void testNotifyUnsupportedClassLoaderDoesNotChangeExisting() {
+ List<String> secondaries = mBarUser0.getSecondaryDexPaths();
- // Record bar secondaries again with a different class loader. This will change the context.
- // However, because the context was already marked as unsupported we should not chage it.
- notifyDexLoad(mBarUser0DelegateLastClassLoader, secondaries, mUser0);
- pui = getPackageUseInfo(mBarUser0UnsupportedClassLoader);
- assertSecondaryUse(mBarUser0UnsupportedClassLoader, pui, secondaries,
- /*isUsedByOtherApps*/false, mUser0, expectedContexts);
+ notifyDexLoad(mBarUser0, secondaries, mUser0);
+ PackageUseInfo pui = getPackageUseInfo(mBarUser0);
+ assertSecondaryUse(mBarUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0);
+ // Record bar secondaries again with an unsupported class loader. This should not change the
+ // context.
+ notifyDexLoad(mBarUser0UnsupportedClassLoader, secondaries, mUser0);
+ pui = getPackageUseInfo(mBarUser0);
+ assertSecondaryUse(mBarUser0, pui, secondaries, /*isUsedByOtherApps*/false, mUser0);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
index 3e93dcf3ba92..7755e94369af 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/PackageDexUsageTests.java
@@ -399,20 +399,6 @@ public class PackageDexUsageTests {
}
@Test
- public void testRecordClassLoaderContextUnsupportedContext() {
- // Record a secondary dex file.
- assertTrue(record(mFooSecondary1User0));
- // Now update its context.
- TestData unsupportedContext = mFooSecondary1User0.updateClassLoaderContext(
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT);
- assertTrue(record(unsupportedContext));
-
- assertPackageDexUsage(null, unsupportedContext);
- writeAndReadBack();
- assertPackageDexUsage(null, unsupportedContext);
- }
-
- @Test
public void testRecordClassLoaderContextTransitionFromUnknown() {
// Record a secondary dex file.
TestData unknownContext = mFooSecondary1User0.updateClassLoaderContext(
@@ -440,29 +426,41 @@ public class PackageDexUsageTests {
PackageDexUsage.DexUseInfo validContext = new DexUseInfo(isUsedByOtherApps, userId,
"valid_context", "arm");
assertFalse(validContext.isUnknownClassLoaderContext());
- assertFalse(validContext.isUnsupportedClassLoaderContext());
assertFalse(validContext.isVariableClassLoaderContext());
- PackageDexUsage.DexUseInfo unsupportedContext = new DexUseInfo(isUsedByOtherApps, userId,
- PackageDexUsage.UNSUPPORTED_CLASS_LOADER_CONTEXT, "arm");
- assertFalse(unsupportedContext.isUnknownClassLoaderContext());
- assertTrue(unsupportedContext.isUnsupportedClassLoaderContext());
- assertFalse(unsupportedContext.isVariableClassLoaderContext());
-
PackageDexUsage.DexUseInfo variableContext = new DexUseInfo(isUsedByOtherApps, userId,
PackageDexUsage.VARIABLE_CLASS_LOADER_CONTEXT, "arm");
assertFalse(variableContext.isUnknownClassLoaderContext());
- assertFalse(variableContext.isUnsupportedClassLoaderContext());
assertTrue(variableContext.isVariableClassLoaderContext());
PackageDexUsage.DexUseInfo unknownContext = new DexUseInfo(isUsedByOtherApps, userId,
PackageDexUsage.UNKNOWN_CLASS_LOADER_CONTEXT, "arm");
assertTrue(unknownContext.isUnknownClassLoaderContext());
- assertFalse(unknownContext.isUnsupportedClassLoaderContext());
assertFalse(unknownContext.isVariableClassLoaderContext());
}
@Test
+ public void testUnsupportedClassLoaderDiscardedOnRead() throws Exception {
+ String content = "PACKAGE_MANAGER__PACKAGE_DEX_USAGE__2\n"
+ + mBarSecondary1User0.mPackageName + "\n"
+ + "#" + mBarSecondary1User0.mDexFile + "\n"
+ + "0,0," + mBarSecondary1User0.mLoaderIsa + "\n"
+ + "@\n"
+ + "=UnsupportedClassLoaderContext=\n"
+
+ + mFooSecondary1User0.mPackageName + "\n"
+ + "#" + mFooSecondary1User0.mDexFile + "\n"
+ + "0,0," + mFooSecondary1User0.mLoaderIsa + "\n"
+ + "@\n"
+ + mFooSecondary1User0.mClassLoaderContext + "\n";
+
+ mPackageDexUsage.read(new StringReader(content));
+
+ assertPackageDexUsage(mFooBaseUser0, mFooSecondary1User0);
+ assertPackageDexUsage(mBarBaseUser0);
+ }
+
+ @Test
public void testReadVersion1() {
String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
// Equivalent to
diff --git a/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
index b5fe8b159c47..a9071612a725 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AnimatingAppWindowTokenRegistryTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -29,11 +29,9 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -41,12 +39,11 @@ import org.mockito.MockitoAnnotations;
* Tests for the {@link TaskStack} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.AnimatingAppWindowTokenRegistryTest
+ * atest FrameworksServicesTests:AnimatingAppWindowTokenRegistryTest
*/
@SmallTest
@Presubmit
@FlakyTest(detail = "Promote once confirmed non-flaky")
-@RunWith(AndroidJUnit4.class)
public class AnimatingAppWindowTokenRegistryTest extends WindowTestsBase {
@Mock
@@ -56,14 +53,14 @@ public class AnimatingAppWindowTokenRegistryTest extends WindowTestsBase {
Runnable mMockEndDeferFinishCallback1;
@Mock
Runnable mMockEndDeferFinishCallback2;
+
@Before
public void setUp() throws Exception {
- super.setUp();
MockitoAnnotations.initMocks(this);
}
@Test
- public void testDeferring() throws Exception {
+ public void testDeferring() {
final AppWindowToken window1 = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final AppWindowToken window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
@@ -85,7 +82,7 @@ public class AnimatingAppWindowTokenRegistryTest extends WindowTestsBase {
}
@Test
- public void testContainerRemoved() throws Exception {
+ public void testContainerRemoved() {
final AppWindowToken window1 = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final AppWindowToken window2 = createAppWindow(window1.getTask(), ACTIVITY_TYPE_STANDARD,
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java
index fc3ca93df801..5e12a950c560 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -27,28 +27,28 @@ import android.platform.test.annotations.Presubmit;
import android.view.WindowManager;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
+/**
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:AppTransitionControllerTest
+ */
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class AppTransitionControllerTest extends WindowTestsBase {
private AppTransitionController mAppTransitionController;
@Before
public void setUp() throws Exception {
- super.setUp();
- mAppTransitionController = new AppTransitionController(sWm, mDisplayContent);
+ mAppTransitionController = new AppTransitionController(mWm, mDisplayContent);
}
@Test
- public void testTranslucentOpen() throws Exception {
- synchronized (sWm.mGlobalLock) {
+ public void testTranslucentOpen() {
+ synchronized (mWm.mGlobalLock) {
final AppWindowToken behind = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final AppWindowToken translucentOpening = createAppWindowToken(mDisplayContent,
@@ -64,8 +64,8 @@ public class AppTransitionControllerTest extends WindowTestsBase {
}
@Test
- public void testTranslucentClose() throws Exception {
- synchronized (sWm.mGlobalLock) {
+ public void testTranslucentClose() {
+ synchronized (mWm.mGlobalLock) {
final AppWindowToken behind = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
final AppWindowToken translucentClosing = createAppWindowToken(mDisplayContent,
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
index ee6fbac3f19f..f12619c6e337 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppTransitionTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -32,81 +32,75 @@ import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.spy;
-import android.content.Context;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import android.view.Display;
import android.view.IApplicationToken;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link AppTransition}.
*
- * atest AppTransitionTests
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:AppTransitionTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class AppTransitionTests extends WindowTestsBase {
private DisplayContent mDc;
@Before
public void setUp() throws Exception {
- super.setUp();
- final Context context = InstrumentationRegistry.getTargetContext();
- mDc = sWm.getDefaultDisplayContentLocked();
+ mDc = mWm.getDefaultDisplayContentLocked();
// For unit test, we don't need to test performSurfacePlacement to prevent some
// abnormal interaction with surfaceflinger native side.
- sWm.mRoot = spy(sWm.mRoot);
- doNothing().when(sWm.mRoot).performSurfacePlacement(anyBoolean());
+ mWm.mRoot = spy(mWm.mRoot);
+ doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean());
}
@Test
- public void testKeyguardOverride() throws Exception {
- sWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
- sWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+ public void testKeyguardOverride() {
+ mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+ mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mDc.mAppTransition.getAppTransition());
}
@Test
- public void testKeyguardKeep() throws Exception {
- sWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
- sWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+ public void testKeyguardKeep() {
+ mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+ mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mDc.mAppTransition.getAppTransition());
}
@Test
- public void testForceOverride() throws Exception {
- sWm.prepareAppTransition(TRANSIT_KEYGUARD_UNOCCLUDE, false /* alwaysKeepCurrent */);
+ public void testForceOverride() {
+ mWm.prepareAppTransition(TRANSIT_KEYGUARD_UNOCCLUDE, false /* alwaysKeepCurrent */);
mDc.getController().prepareAppTransition(TRANSIT_ACTIVITY_OPEN,
false /* alwaysKeepCurrent */, 0 /* flags */, true /* forceOverride */);
assertEquals(TRANSIT_ACTIVITY_OPEN, mDc.mAppTransition.getAppTransition());
}
@Test
- public void testCrashing() throws Exception {
- sWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
- sWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
+ public void testCrashing() {
+ mWm.prepareAppTransition(TRANSIT_ACTIVITY_OPEN, false /* alwaysKeepCurrent */);
+ mWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
assertEquals(TRANSIT_CRASHING_ACTIVITY_CLOSE, mDc.mAppTransition.getAppTransition());
}
@Test
- public void testKeepKeyguard_withCrashing() throws Exception {
- sWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
- sWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
+ public void testKeepKeyguard_withCrashing() {
+ mWm.prepareAppTransition(TRANSIT_KEYGUARD_GOING_AWAY, false /* alwaysKeepCurrent */);
+ mWm.prepareAppTransition(TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
assertEquals(TRANSIT_KEYGUARD_GOING_AWAY, mDc.mAppTransition.getAppTransition());
}
@Test
- public void testAppTransitionStateForMultiDisplay() throws Exception {
+ public void testAppTransitionStateForMultiDisplay() {
// Create 2 displays & presume both display the state is ON for ready to display & animate.
final DisplayContent dc1 = createNewDisplayWithController(Display.STATE_ON);
final DisplayContent dc2 = createNewDisplayWithController(Display.STATE_ON);
@@ -149,7 +143,7 @@ public class AppTransitionTests extends WindowTestsBase {
}
@Test
- public void testCleanAppTransitionWhenTaskStackReparent() throws Exception {
+ public void testCleanAppTransitionWhenTaskStackReparent() {
// Create 2 displays & presume both display the state is ON for ready to display & animate.
final DisplayContent dc1 = createNewDisplayWithController(Display.STATE_ON);
final DisplayContent dc2 = createNewDisplayWithController(Display.STATE_ON);
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
index fcd8a39e4d07..415b5d93d90e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowContainerControllerTests.java
@@ -21,6 +21,8 @@ import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static android.content.res.Configuration.EMPTY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
@@ -29,10 +31,8 @@ import static org.junit.Assert.fail;
import android.platform.test.annotations.Presubmit;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.WindowTestUtils.TestTaskWindowContainerController;
@@ -41,16 +41,17 @@ import org.junit.Test;
/**
* Test class for {@link AppWindowContainerController}.
*
- * atest FrameworksServicesTests:com.android.server.wm.AppWindowContainerControllerTests
+ * atest FrameworksServicesTests:AppWindowContainerControllerTests
*/
+@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
-@FlakyTest(bugId = 74078662)
-@org.junit.runner.RunWith(AndroidJUnit4.class)
public class AppWindowContainerControllerTests extends WindowTestsBase {
+ private final String mPackageName = getInstrumentation().getTargetContext().getPackageName();
+
@Test
- public void testRemoveContainer() throws Exception {
+ public void testRemoveContainer() {
final WindowTestUtils.TestAppWindowContainerController controller =
createAppWindowController();
@@ -68,7 +69,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testSetOrientation() throws Exception {
+ public void testSetOrientation() {
final WindowTestUtils.TestAppWindowContainerController controller =
createAppWindowController();
@@ -84,7 +85,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, controller.getOrientation());
// Reset display frozen state
- sWm.mDisplayFrozen = false;
+ mWm.mDisplayFrozen = false;
}
private void assertHasStartingWindow(AppWindowToken atoken) {
@@ -103,10 +104,10 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testCreateRemoveStartingWindow() throws Exception {
+ public void testCreateRemoveStartingWindow() {
final WindowTestUtils.TestAppWindowContainerController controller =
createAppWindowController();
- controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+ controller.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
false, false);
waitUntilHandlersIdle();
@@ -118,34 +119,34 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testAddRemoveRace() throws Exception {
-
+ public void testAddRemoveRace() {
// There was once a race condition between adding and removing starting windows
for (int i = 0; i < 1000; i++) {
final WindowTestUtils.TestAppWindowContainerController controller =
createAppWindowController();
- controller.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+ controller.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
false, false);
controller.removeStartingWindow();
waitUntilHandlersIdle();
assertNoStartingWindow(controller.getAppWindowToken(mDisplayContent));
- controller.getAppWindowToken(mDisplayContent).getParent().getParent().removeImmediately();
+ controller.getAppWindowToken(
+ mDisplayContent).getParent().getParent().removeImmediately();
}
}
@Test
- public void testTransferStartingWindow() throws Exception {
+ public void testTransferStartingWindow() {
final WindowTestUtils.TestAppWindowContainerController controller1 =
createAppWindowController();
final WindowTestUtils.TestAppWindowContainerController controller2 =
createAppWindowController();
- controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+ controller1.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
false, false);
waitUntilHandlersIdle();
- controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+ controller2.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
true, true, false, true, false, false);
waitUntilHandlersIdle();
@@ -154,19 +155,19 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testTransferStartingWindowWhileCreating() throws Exception {
+ public void testTransferStartingWindowWhileCreating() {
final WindowTestUtils.TestAppWindowContainerController controller1 =
createAppWindowController();
final WindowTestUtils.TestAppWindowContainerController controller2 =
createAppWindowController();
- ((TestWindowManagerPolicy) sWm.mPolicy).setRunnableWhenAddingSplashScreen(() -> {
+ ((TestWindowManagerPolicy) mWm.mPolicy).setRunnableWhenAddingSplashScreen(() -> {
// Surprise, ...! Transfer window in the middle of the creation flow.
- controller2.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+ controller2.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, controller1.mToken.asBinder(),
true, true, false, true, false, false);
});
- controller1.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+ controller1.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
false, false);
waitUntilHandlersIdle();
@@ -175,7 +176,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testTryTransferStartingWindowFromHiddenAboveToken() throws Exception {
+ public void testTryTransferStartingWindowFromHiddenAboveToken() {
// Add two tasks on top of each other.
TestTaskWindowContainerController taskController =
@@ -186,7 +187,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
createAppWindowController(taskController);
// Add a starting window.
- controllerTop.addStartingWindow(InstrumentationRegistry.getContext().getPackageName(),
+ controllerTop.addStartingWindow(mPackageName,
android.R.style.Theme, null, "Test", 0, 0, 0, 0, null, true, true, false, true,
false, false);
waitUntilHandlersIdle();
@@ -202,7 +203,7 @@ public class AppWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testReparent() throws Exception {
+ public void testReparent() {
final StackWindowController stackController =
createStackControllerOnDisplay(mDisplayContent);
final WindowTestUtils.TestTaskWindowContainerController taskController1 =
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
index e3ab5cf4fc52..4522494349a3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenAnimationTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -26,15 +26,14 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
import android.view.SurfaceControl;
+import androidx.test.filters.SmallTest;
+
import com.android.server.wm.WindowTestUtils.TestAppWindowToken;
+import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -43,10 +42,9 @@ import org.mockito.MockitoAnnotations;
* Animation related tests for the {@link AppWindowToken} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.AppWindowTokenAnimationTests
+ * atest FrameworksServicesTests:AppWindowTokenAnimationTests
*/
@SmallTest
-@RunWith(AndroidJUnit4.class)
public class AppWindowTokenAnimationTests extends WindowTestsBase {
private TestAppWindowToken mToken;
@@ -56,9 +54,8 @@ public class AppWindowTokenAnimationTests extends WindowTestsBase {
@Mock
private AnimationAdapter mSpec;
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
MockitoAnnotations.initMocks(this);
mToken = createTestAppWindowToken(mDisplayContent, WINDOWING_MODE_FULLSCREEN,
@@ -67,7 +64,7 @@ public class AppWindowTokenAnimationTests extends WindowTestsBase {
}
@Test
- public void clipAfterAnim_boundsLayerIsCreated() throws Exception {
+ public void clipAfterAnim_boundsLayerIsCreated() {
mToken.mNeedsAnimationBoundsLayer = true;
mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
@@ -78,7 +75,7 @@ public class AppWindowTokenAnimationTests extends WindowTestsBase {
}
@Test
- public void clipAfterAnim_boundsLayerIsDestroyed() throws Exception {
+ public void clipAfterAnim_boundsLayerIsDestroyed() {
mToken.mNeedsAnimationBoundsLayer = true;
mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
final SurfaceControl leash = mToken.mSurfaceAnimator.mLeash;
@@ -95,7 +92,7 @@ public class AppWindowTokenAnimationTests extends WindowTestsBase {
}
@Test
- public void clipAfterAnimCancelled_boundsLayerIsDestroyed() throws Exception {
+ public void clipAfterAnimCancelled_boundsLayerIsDestroyed() {
mToken.mNeedsAnimationBoundsLayer = true;
mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
final SurfaceControl leash = mToken.mSurfaceAnimator.mLeash;
@@ -108,7 +105,7 @@ public class AppWindowTokenAnimationTests extends WindowTestsBase {
}
@Test
- public void clipNoneAnim_boundsLayerIsNotCreated() throws Exception {
+ public void clipNoneAnim_boundsLayerIsNotCreated() {
mToken.mNeedsAnimationBoundsLayer = false;
mToken.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
diff --git a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
index 7935ec168142..a8e1ed46c166 100644
--- a/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/AppWindowTokenTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -47,31 +47,27 @@ import android.view.WindowManager;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Tests for the {@link AppWindowToken} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.AppWindowTokenTests
+ * atest FrameworksServicesTests:AppWindowTokenTests
*/
+@FlakyTest(bugId = 68267650)
@SmallTest
-// TODO: b/68267650
-// @Presubmit
-@RunWith(AndroidJUnit4.class)
+@Presubmit
public class AppWindowTokenTests extends WindowTestsBase {
TaskStack mStack;
Task mTask;
WindowTestUtils.TestAppWindowToken mToken;
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
-
mStack = createTaskStackOnDisplay(mDisplayContent);
mTask = createTaskInStack(mStack, 0 /* userId */);
mToken = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
@@ -81,7 +77,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
@Test
@Presubmit
- public void testAddWindow_Order() throws Exception {
+ public void testAddWindow_Order() {
assertEquals(0, mToken.getWindowsCount());
final WindowState win1 = createWindow(null, TYPE_APPLICATION, mToken, "win1");
@@ -107,7 +103,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
@Test
@Presubmit
- public void testFindMainWindow() throws Exception {
+ public void testFindMainWindow() {
assertNull(mToken.findMainWindow());
final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
@@ -123,7 +119,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
@Test
@Presubmit
- public void testGetTopFullscreenWindow() throws Exception {
+ public void testGetTopFullscreenWindow() {
assertNull(mToken.getTopFullscreenWindow());
final WindowState window1 = createWindow(null, TYPE_BASE_APPLICATION, mToken, "window1");
@@ -138,10 +134,10 @@ public class AppWindowTokenTests extends WindowTestsBase {
}
@Test
- public void testLandscapeSeascapeRotationByApp() throws Exception {
+ public void testLandscapeSeascapeRotationByApp() {
// Some plumbing to get the service ready for rotation updates.
- sWm.mDisplayReady = true;
- sWm.mDisplayEnabled = true;
+ mWm.mDisplayReady = true;
+ mWm.mDisplayEnabled = true;
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
TYPE_BASE_APPLICATION);
@@ -151,26 +147,26 @@ public class AppWindowTokenTests extends WindowTestsBase {
// Set initial orientation and update.
mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
- sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
+ mWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
mDisplayContent.getDisplayId());
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, mDisplayContent.getLastOrientation());
appWindow.resizeReported = false;
// Update the orientation to perform 180 degree rotation and check that resize was reported.
mToken.setOrientation(SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
- sWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
+ mWm.updateOrientationFromAppTokens(mDisplayContent.getOverrideConfiguration(), null,
mDisplayContent.getDisplayId());
- sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
+ mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
assertEquals(SCREEN_ORIENTATION_REVERSE_LANDSCAPE, mDisplayContent.getLastOrientation());
assertTrue(appWindow.resizeReported);
appWindow.removeImmediately();
}
@Test
- public void testLandscapeSeascapeRotationByPolicy() throws Exception {
+ public void testLandscapeSeascapeRotationByPolicy() {
// Some plumbing to get the service ready for rotation updates.
- sWm.mDisplayReady = true;
- sWm.mDisplayEnabled = true;
+ mWm.mDisplayReady = true;
+ mWm.mDisplayEnabled = true;
final DisplayRotation spiedRotation = spy(mDisplayContent.getDisplayRotation());
mDisplayContent.setDisplayRotation(spiedRotation);
@@ -194,15 +190,15 @@ public class AppWindowTokenTests extends WindowTestsBase {
private void performRotation(DisplayRotation spiedRotation, int rotationToReport) {
doReturn(rotationToReport).when(spiedRotation).rotationForOrientation(anyInt(), anyInt());
- sWm.updateRotation(false, false);
+ mWm.updateRotation(false, false);
// Prevent the next rotation from being deferred by animation.
- sWm.mAnimator.setScreenRotationAnimationLocked(mDisplayContent.getDisplayId(), null);
- sWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
+ mWm.mAnimator.setScreenRotationAnimationLocked(mDisplayContent.getDisplayId(), null);
+ mWm.mRoot.performSurfacePlacement(false /* recoveringMemory */);
}
@Test
@Presubmit
- public void testGetOrientation() throws Exception {
+ public void testGetOrientation() {
mToken.setOrientation(SCREEN_ORIENTATION_LANDSCAPE);
mToken.setFillsParent(false);
@@ -220,7 +216,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
@Test
@Presubmit
- public void testKeyguardFlagsDuringRelaunch() throws Exception {
+ public void testKeyguardFlagsDuringRelaunch() {
final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
TYPE_BASE_APPLICATION);
attrs.flags |= FLAG_SHOW_WHEN_LOCKED | FLAG_DISMISS_KEYGUARD;
@@ -246,7 +242,7 @@ public class AppWindowTokenTests extends WindowTestsBase {
@Test
@FlakyTest(detail = "Promote once confirmed non-flaky")
- public void testStuckExitingWindow() throws Exception {
+ public void testStuckExitingWindow() {
final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
"closingWindow");
closingWindow.mAnimatingExit = true;
diff --git a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
index d65055cf0e07..1c5391ed3a6c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/BoundsAnimationControllerTests.java
@@ -11,12 +11,12 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
-import static android.view.Display.DEFAULT_DISPLAY;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
import static com.android.server.wm.BoundsAnimationController.NO_PIP_MODE_CHANGED_CALLBACKS;
import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_CHANGED_ON_END;
@@ -24,11 +24,11 @@ import static com.android.server.wm.BoundsAnimationController.SCHEDULE_PIP_MODE_
import static com.android.server.wm.BoundsAnimationController.SchedulePipModeChangedState;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
import android.animation.ValueAnimator;
import android.content.Context;
@@ -37,16 +37,14 @@ import android.os.Handler;
import android.os.Looper;
import android.platform.test.annotations.Presubmit;
-import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.BoundsAnimationController.BoundsAnimator;
import com.android.server.wm.WindowManagerInternal.AppTransitionListener;
+import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link BoundsAnimationController} to ensure that it sends the right callbacks
@@ -59,21 +57,20 @@ import org.junit.runner.RunWith;
* appropriately.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.wm.BoundsAnimationControllerTests
+ * atest FrameworksServicesTests:BoundsAnimationControllerTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class BoundsAnimationControllerTests extends WindowTestsBase {
/**
* Mock value animator to simulate updates with.
*/
- private class MockValueAnimator extends ValueAnimator {
+ private static class MockValueAnimator extends ValueAnimator {
private float mFraction;
- public MockValueAnimator getWithValue(float fraction) {
+ MockValueAnimator getWithValue(float fraction) {
mFraction = fraction;
return this;
}
@@ -87,12 +84,12 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
/**
* Mock app transition to fire notifications to the bounds animator.
*/
- private class MockAppTransition extends AppTransition {
+ private static class MockAppTransition extends AppTransition {
private AppTransitionListener mListener;
- MockAppTransition(Context context) {
- super(context, sWm, mDisplayContent);
+ MockAppTransition(Context context, WindowManagerService wm, DisplayContent displayContent) {
+ super(context, wm, displayContent);
}
@Override
@@ -120,7 +117,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
/**
* A test animate bounds user to track callbacks from the bounds animation.
*/
- private class TestBoundsAnimationTarget implements BoundsAnimationTarget {
+ private static class TestBoundsAnimationTarget implements BoundsAnimationTarget {
boolean mAwaitingAnimationStart;
boolean mMovedToFullscreen;
@@ -193,21 +190,23 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
/**
* Drives the animations, makes common assertions along the way.
*/
- private class BoundsAnimationDriver {
+ private static class BoundsAnimationDriver {
- private BoundsAnimationController mController;
- private TestBoundsAnimationTarget mTarget;
- private BoundsAnimator mAnimator;
+ private final BoundsAnimationController mController;
+ private final TestBoundsAnimationTarget mTarget;
+ private final MockValueAnimator mMockAnimator;
+ private BoundsAnimator mAnimator;
private Rect mFrom;
private Rect mTo;
private Rect mLargerBounds;
private Rect mExpectedFinalBounds;
BoundsAnimationDriver(BoundsAnimationController controller,
- TestBoundsAnimationTarget target) {
+ TestBoundsAnimationTarget target, MockValueAnimator mockValueAnimator) {
mController = controller;
mTarget = target;
+ mMockAnimator = mockValueAnimator;
}
BoundsAnimationDriver start(Rect from, Rect to) {
@@ -222,7 +221,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
// Started, not running
assertTrue(mTarget.mAwaitingAnimationStart);
- assertTrue(!mTarget.mAnimationStarted);
+ assertFalse(mTarget.mAnimationStarted);
startImpl(from, to);
@@ -236,7 +235,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
}
// Started and running
- assertTrue(!mTarget.mAwaitingAnimationStart);
+ assertFalse(mTarget.mAwaitingAnimationStart);
assertTrue(mTarget.mAnimationStarted);
return this;
@@ -268,7 +267,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
assertTrue(mTarget.mForcePipModeChangedCallback);
} else {
// No animation start for replacing animation
- assertTrue(!mTarget.mAnimationStarted);
+ assertFalse(mTarget.mAnimationStarted);
}
mTarget.mAnimationStarted = true;
return this;
@@ -297,7 +296,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
// Animating to larger size
if (mFrom.equals(mLargerBounds)) {
- assertTrue(!mAnimator.animatingToLargerSize());
+ assertFalse(mAnimator.animatingToLargerSize());
} else if (mTo.equals(mLargerBounds)) {
assertTrue(mAnimator.animatingToLargerSize());
}
@@ -339,10 +338,10 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
mAnimator.onAnimationUpdate(mMockAnimator.getWithValue(0.5f));
// Not started, not running, cancel reset
- assertTrue(!mTarget.mCancelRequested);
+ assertFalse(mTarget.mCancelRequested);
// Stack/task bounds not updated
- assertTrue(!mTarget.mBoundsUpdated);
+ assertFalse(mTarget.mBoundsUpdated);
// Callback made
assertTrue(mTarget.mAnimationEnded);
@@ -372,14 +371,10 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
return this;
}
- private Rect getLargerBounds(Rect r1, Rect r2) {
+ private static Rect getLargerBounds(Rect r1, Rect r2) {
int r1Area = r1.width() * r1.height();
int r2Area = r2.width() * r2.height();
- if (r1Area <= r2Area) {
- return r2;
- } else {
- return r1;
- }
+ return (r1Area <= r2Area) ? r2 : r1;
}
}
@@ -395,32 +390,29 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
// Common
private MockAppTransition mMockAppTransition;
- private MockValueAnimator mMockAnimator;
private TestBoundsAnimationTarget mTarget;
private BoundsAnimationController mController;
private BoundsAnimationDriver mDriver;
// Temp
- private Rect mTmpRect = new Rect();
+ private static final Rect sTmpRect = new Rect();
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
-
- final Context context = InstrumentationRegistry.getTargetContext();
+ final Context context = getInstrumentation().getTargetContext();
final Handler handler = new Handler(Looper.getMainLooper());
- mMockAppTransition = new MockAppTransition(context);
- mMockAnimator = new MockValueAnimator();
+ mMockAppTransition = new MockAppTransition(context, mWm, mDisplayContent);
mTarget = new TestBoundsAnimationTarget();
mController = new BoundsAnimationController(context, mMockAppTransition, handler, null);
- mDriver = new BoundsAnimationDriver(mController, mTarget);
+ final MockValueAnimator mockValueAnimator = new MockValueAnimator();
+ mDriver = new BoundsAnimationDriver(mController, mTarget, mockValueAnimator);
}
/** BASE TRANSITIONS **/
@UiThreadTest
@Test
- public void testFullscreenToFloatingTransition() throws Exception {
+ public void testFullscreenToFloatingTransition() {
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0f)
@@ -432,7 +424,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToFullscreenTransition() throws Exception {
+ public void testFloatingToFullscreenTransition() {
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
.update(0f)
@@ -444,7 +436,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToSmallerFloatingTransition() throws Exception {
+ public void testFloatingToSmallerFloatingTransition() {
mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0f)
@@ -456,7 +448,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToLargerFloatingTransition() throws Exception {
+ public void testFloatingToLargerFloatingTransition() {
mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0f)
@@ -470,7 +462,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFullscreenToFloatingCancelFromTarget() throws Exception {
+ public void testFullscreenToFloatingCancelFromTarget() {
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -480,7 +472,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFullscreenToFloatingCancelFromAnimationToSameBounds() throws Exception {
+ public void testFullscreenToFloatingCancelFromAnimationToSameBounds() {
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -491,7 +483,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFullscreenToFloatingCancelFromAnimationToFloatingBounds() throws Exception {
+ public void testFullscreenToFloatingCancelFromAnimationToFloatingBounds() {
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -503,7 +495,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFullscreenToFloatingCancelFromAnimationToFullscreenBounds() throws Exception {
+ public void testFullscreenToFloatingCancelFromAnimationToFullscreenBounds() {
// When animating from fullscreen and the animation is interruped, we expect the animation
// start callback to be made, with a forced pip mode change callback
mDriver.start(BOUNDS_FULL, BOUNDS_FLOATING)
@@ -518,7 +510,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToFullscreenCancelFromTarget() throws Exception {
+ public void testFloatingToFullscreenCancelFromTarget() {
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -528,7 +520,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToFullscreenCancelFromAnimationToSameBounds() throws Exception {
+ public void testFloatingToFullscreenCancelFromAnimationToSameBounds() {
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -539,7 +531,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToFullscreenCancelFromAnimationToFloatingBounds() throws Exception {
+ public void testFloatingToFullscreenCancelFromAnimationToFloatingBounds() {
mDriver.start(BOUNDS_FLOATING, BOUNDS_FULL)
.expectStarted(SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -553,7 +545,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToSmallerFloatingCancelFromTarget() throws Exception {
+ public void testFloatingToSmallerFloatingCancelFromTarget() {
mDriver.start(BOUNDS_FLOATING, BOUNDS_SMALLER_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -563,7 +555,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testFloatingToLargerFloatingCancelFromTarget() throws Exception {
+ public void testFloatingToLargerFloatingCancelFromTarget() {
mDriver.start(BOUNDS_SMALLER_FLOATING, BOUNDS_FLOATING)
.expectStarted(!SCHEDULE_PIP_MODE_CHANGED)
.update(0.25f)
@@ -575,7 +567,7 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
@UiThreadTest
@Test
- public void testBoundsAreCopied() throws Exception {
+ public void testBoundsAreCopied() {
Rect from = new Rect(0, 0, 100, 100);
Rect to = new Rect(25, 25, 75, 75);
mDriver.start(from, to)
@@ -588,9 +580,9 @@ public class BoundsAnimationControllerTests extends WindowTestsBase {
/**
* @return whether the task and stack bounds would be the same if they were at the same offset.
*/
- private boolean assertEqualSizeAtOffset(Rect stackBounds, Rect taskBounds) {
- mTmpRect.set(taskBounds);
- mTmpRect.offsetTo(stackBounds.left, stackBounds.top);
- return stackBounds.equals(mTmpRect);
+ private static boolean assertEqualSizeAtOffset(Rect stackBounds, Rect taskBounds) {
+ sTmpRect.set(taskBounds);
+ sTmpRect.offsetTo(stackBounds.left, stackBounds.top);
+ return stackBounds.equals(sTmpRect);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
index 21555e38a7e8..b6a7cfba7dc4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DimmerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -32,26 +32,22 @@ import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
-import androidx.test.runner.AndroidJUnit4;
-
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.DimmerTests;
+ * atest FrameworksServicesTests:DimmerTests;
*/
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class DimmerTests extends WindowTestsBase {
- private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
+ private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
final SurfaceControl mControl = mock(SurfaceControl.class);
final SurfaceControl.Transaction mTransaction = mock(SurfaceControl.Transaction.class);
- TestWindowContainer() {
- super(sWm);
+ TestWindowContainer(WindowManagerService wm) {
+ super(wm);
}
@Override
@@ -65,13 +61,13 @@ public class DimmerTests extends WindowTestsBase {
}
}
- private class MockSurfaceBuildingContainer extends WindowContainer<TestWindowContainer> {
+ private static class MockSurfaceBuildingContainer extends WindowContainer<TestWindowContainer> {
final SurfaceSession mSession = new SurfaceSession();
final SurfaceControl mHostControl = mock(SurfaceControl.class);
final SurfaceControl.Transaction mHostTransaction = mock(SurfaceControl.Transaction.class);
- MockSurfaceBuildingContainer() {
- super(sWm);
+ MockSurfaceBuildingContainer(WindowManagerService wm) {
+ super(wm);
}
class MockSurfaceBuilder extends SurfaceControl.Builder {
@@ -116,15 +112,14 @@ public class DimmerTests extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
- mHost = new MockSurfaceBuildingContainer();
+ mHost = new MockSurfaceBuildingContainer(mWm);
mSurfaceAnimatorStarter = spy(new SurfaceAnimatorStarterImpl());
mTransaction = mock(SurfaceControl.Transaction.class);
mDimmer = new Dimmer(mHost, mSurfaceAnimatorStarter);
}
@Test
- public void testDimAboveNoChildCreatesSurface() throws Exception {
+ public void testDimAboveNoChildCreatesSurface() {
final float alpha = 0.8f;
mDimmer.dimAbove(mTransaction, alpha);
@@ -137,7 +132,7 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testDimAboveNoChildRedundantlyUpdatesAlphaOnExistingSurface() throws Exception {
+ public void testDimAboveNoChildRedundantlyUpdatesAlphaOnExistingSurface() {
float alpha = 0.8f;
mDimmer.dimAbove(mTransaction, alpha);
final SurfaceControl firstSurface = getDimLayer();
@@ -150,7 +145,7 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testUpdateDimsAppliesSize() throws Exception {
+ public void testUpdateDimsAppliesSize() {
mDimmer.dimAbove(mTransaction, 0.8f);
int width = 100;
@@ -163,7 +158,7 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testDimAboveNoChildNotReset() throws Exception {
+ public void testDimAboveNoChildNotReset() {
mDimmer.dimAbove(mTransaction, 0.8f);
SurfaceControl dimLayer = getDimLayer();
mDimmer.resetDimStates();
@@ -174,8 +169,8 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testDimAboveWithChildCreatesSurfaceAboveChild() throws Exception {
- TestWindowContainer child = new TestWindowContainer();
+ public void testDimAboveWithChildCreatesSurfaceAboveChild() {
+ TestWindowContainer child = new TestWindowContainer(mWm);
mHost.addChild(child, 0);
final float alpha = 0.8f;
@@ -189,8 +184,8 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testDimBelowWithChildSurfaceCreatesSurfaceBelowChild() throws Exception {
- TestWindowContainer child = new TestWindowContainer();
+ public void testDimBelowWithChildSurfaceCreatesSurfaceBelowChild() {
+ TestWindowContainer child = new TestWindowContainer(mWm);
mHost.addChild(child, 0);
final float alpha = 0.8f;
@@ -204,8 +199,8 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testDimBelowWithChildSurfaceDestroyedWhenReset() throws Exception {
- TestWindowContainer child = new TestWindowContainer();
+ public void testDimBelowWithChildSurfaceDestroyedWhenReset() {
+ TestWindowContainer child = new TestWindowContainer(mWm);
mHost.addChild(child, 0);
final float alpha = 0.8f;
@@ -220,8 +215,8 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testDimBelowWithChildSurfaceNotDestroyedWhenPersisted() throws Exception {
- TestWindowContainer child = new TestWindowContainer();
+ public void testDimBelowWithChildSurfaceNotDestroyedWhenPersisted() {
+ TestWindowContainer child = new TestWindowContainer(mWm);
mHost.addChild(child, 0);
final float alpha = 0.8f;
@@ -236,9 +231,9 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testDimUpdateWhileDimming() throws Exception {
+ public void testDimUpdateWhileDimming() {
Rect bounds = new Rect();
- TestWindowContainer child = new TestWindowContainer();
+ TestWindowContainer child = new TestWindowContainer(mWm);
mHost.addChild(child, 0);
final float alpha = 0.8f;
@@ -258,8 +253,8 @@ public class DimmerTests extends WindowTestsBase {
}
@Test
- public void testRemoveDimImmediately() throws Exception {
- TestWindowContainer child = new TestWindowContainer();
+ public void testRemoveDimImmediately() {
+ TestWindowContainer child = new TestWindowContainer(mWm);
mHost.addChild(child, 0);
mDimmer.dimAbove(mTransaction, child, 1);
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
index 8b75570a8b29..dd374e959a63 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplayContentTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -53,7 +53,6 @@ import android.graphics.Rect;
import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
-import android.util.SparseIntArray;
import android.view.DisplayCutout;
import android.view.Gravity;
import android.view.MotionEvent;
@@ -61,12 +60,10 @@ import android.view.Surface;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.util.ArrayList;
import java.util.Arrays;
@@ -78,16 +75,15 @@ import java.util.List;
* Tests for the {@link DisplayContent} class.
*
* Build/Install/Run:
- * atest com.android.server.wm.DisplayContentTests
+ * atest FrameworksServicesTests:DisplayContentTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class DisplayContentTests extends WindowTestsBase {
@Test
@FlakyTest(bugId = 77772044)
- public void testForAllWindows() throws Exception {
+ public void testForAllWindows() {
final WindowState exitingAppWindow = createWindow(null, TYPE_BASE_APPLICATION,
mDisplayContent, "exiting app");
final AppWindowToken exitingAppToken = exitingAppWindow.mAppToken;
@@ -108,11 +104,11 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testForAllWindows_WithAppImeTarget() throws Exception {
+ public void testForAllWindows_WithAppImeTarget() {
final WindowState imeAppTarget =
createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "imeAppTarget");
- sWm.mInputMethodTarget = imeAppTarget;
+ mWm.mInputMethodTarget = imeAppTarget;
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
@@ -128,8 +124,8 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testForAllWindows_WithChildWindowImeTarget() throws Exception {
- sWm.mInputMethodTarget = mChildAppWindowAbove;
+ public void testForAllWindows_WithChildWindowImeTarget() {
+ mWm.mInputMethodTarget = mChildAppWindowAbove;
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
@@ -144,8 +140,8 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testForAllWindows_WithStatusBarImeTarget() throws Exception {
- sWm.mInputMethodTarget = mStatusBarWindow;
+ public void testForAllWindows_WithStatusBarImeTarget() {
+ mWm.mInputMethodTarget = mStatusBarWindow;
assertForAllWindowsOrder(Arrays.asList(
mWallpaperWindow,
@@ -160,7 +156,7 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testForAllWindows_WithInBetweenWindowToken() throws Exception {
+ public void testForAllWindows_WithInBetweenWindowToken() {
// This window is set-up to be z-ordered between some windows that go in the same token like
// the nav bar and status bar.
final WindowState voiceInteractionWindow = createWindow(null, TYPE_VOICE_INTERACTION,
@@ -180,7 +176,7 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testComputeImeTarget() throws Exception {
+ public void testComputeImeTarget() {
// Verify that an app window can be an ime target.
final WindowState appWin = createWindow(null, TYPE_APPLICATION, mDisplayContent, "appWin");
appWin.setHasSurface(true);
@@ -203,7 +199,7 @@ public class DisplayContentTests extends WindowTestsBase {
* container references updates.
*/
@Test
- public void testMoveStackBetweenDisplays() throws Exception {
+ public void testMoveStackBetweenDisplays() {
// Create a second display.
final DisplayContent dc = createNewDisplay();
@@ -233,7 +229,7 @@ public class DisplayContentTests extends WindowTestsBase {
* This tests override configuration updates for display content.
*/
@Test
- public void testDisplayOverrideConfigUpdate() throws Exception {
+ public void testDisplayOverrideConfigUpdate() {
final int displayId = mDisplayContent.getDisplayId();
final Configuration currentOverrideConfig = mDisplayContent.getOverrideConfiguration();
@@ -242,7 +238,7 @@ public class DisplayContentTests extends WindowTestsBase {
newOverrideConfig.densityDpi += 120;
newOverrideConfig.fontScale += 0.3;
- sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
+ mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, displayId);
// Check that override config is applied.
assertEquals(newOverrideConfig, mDisplayContent.getOverrideConfiguration());
@@ -252,7 +248,7 @@ public class DisplayContentTests extends WindowTestsBase {
* This tests global configuration updates when default display config is updated.
*/
@Test
- public void testDefaultDisplayOverrideConfigUpdate() throws Exception {
+ public void testDefaultDisplayOverrideConfigUpdate() {
final Configuration currentConfig = mDisplayContent.getConfiguration();
// Create new, slightly changed override configuration and apply it to the display.
@@ -260,16 +256,16 @@ public class DisplayContentTests extends WindowTestsBase {
newOverrideConfig.densityDpi += 120;
newOverrideConfig.fontScale += 0.3;
- sWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
+ mWm.setNewDisplayOverrideConfiguration(newOverrideConfig, DEFAULT_DISPLAY);
// Check that global configuration is updated, as we've updated default display's config.
- Configuration globalConfig = sWm.mRoot.getConfiguration();
+ Configuration globalConfig = mWm.mRoot.getConfiguration();
assertEquals(newOverrideConfig.densityDpi, globalConfig.densityDpi);
assertEquals(newOverrideConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
// Return back to original values.
- sWm.setNewDisplayOverrideConfiguration(currentConfig, DEFAULT_DISPLAY);
- globalConfig = sWm.mRoot.getConfiguration();
+ mWm.setNewDisplayOverrideConfiguration(currentConfig, DEFAULT_DISPLAY);
+ globalConfig = mWm.mRoot.getConfiguration();
assertEquals(currentConfig.densityDpi, globalConfig.densityDpi);
assertEquals(currentConfig.fontScale, globalConfig.fontScale, 0.1 /* delta */);
}
@@ -278,8 +274,8 @@ public class DisplayContentTests extends WindowTestsBase {
* Tests tapping on a stack in different display results in window gaining focus.
*/
@Test
- public void testInputEventBringsCorrectDisplayInFocus() throws Exception {
- DisplayContent dc0 = sWm.getDefaultDisplayContentLocked();
+ public void testInputEventBringsCorrectDisplayInFocus() {
+ DisplayContent dc0 = mWm.getDefaultDisplayContentLocked();
// Create a second display
final DisplayContent dc1 = createNewDisplay();
@@ -303,51 +299,51 @@ public class DisplayContentTests extends WindowTestsBase {
// tap on primary display.
tapOnDisplay(dc0);
// Check focus is on primary display.
- assertEquals(sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
+ assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
dc0.findFocusedWindow());
// Tap on secondary display.
tapOnDisplay(dc1);
// Check focus is on secondary.
- assertEquals(sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
+ assertEquals(mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus,
dc1.findFocusedWindow());
}
@Test
- public void testFocusedWindowMultipleDisplays() throws Exception {
+ public void testFocusedWindowMultipleDisplays() {
// Create a focusable window and check that focus is calculated correctly
final WindowState window1 =
createWindow(null, TYPE_BASE_APPLICATION, mDisplayContent, "window1");
updateFocusedWindow();
assertTrue(window1.isFocused());
- assertEquals(window1, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
+ assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
// Check that a new display doesn't affect focus
final DisplayContent dc = createNewDisplay();
updateFocusedWindow();
assertTrue(window1.isFocused());
- assertEquals(window1, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
+ assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
// Add a window to the second display, and it should be focused
final WindowState window2 = createWindow(null, TYPE_BASE_APPLICATION, dc, "window2");
updateFocusedWindow();
assertTrue(window1.isFocused());
assertTrue(window2.isFocused());
- assertEquals(window2, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
+ assertEquals(window2, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
// Move the first window to the to including parents, and make sure focus is updated
window1.getParent().positionChildAt(POSITION_TOP, window1, true);
updateFocusedWindow();
assertTrue(window1.isFocused());
assertTrue(window2.isFocused());
- assertEquals(window1, sWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
+ assertEquals(window1, mWm.mRoot.getTopFocusedDisplayContent().mCurrentFocus);
}
/**
* This tests setting the maximum ui width on a display.
*/
@Test
- public void testMaxUiWidth() throws Exception {
+ public void testMaxUiWidth() {
// Prevent base display metrics for test from being updated to the value of real display.
final DisplayContent displayContent = createDisplayNoUpdateDisplayInfo();
final int baseWidth = 1440;
@@ -439,8 +435,8 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testDisplayCutout_rot0() throws Exception {
- synchronized (sWm.getWindowManagerLock()) {
+ public void testDisplayCutout_rot0() {
+ synchronized (mWm.getWindowManagerLock()) {
final DisplayContent dc = createNewDisplay();
dc.mInitialDisplayWidth = 200;
dc.mInitialDisplayHeight = 400;
@@ -458,8 +454,8 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testDisplayCutout_rot90() throws Exception {
- synchronized (sWm.getWindowManagerLock()) {
+ public void testDisplayCutout_rot90() {
+ synchronized (mWm.getWindowManagerLock()) {
// Prevent mInitialDisplayCutout from being updated from real display (e.g. null
// if the device has no cutout).
final DisplayContent dc = createDisplayNoUpdateDisplayInfo();
@@ -476,7 +472,8 @@ public class DisplayContentTests extends WindowTestsBase {
final Rect r1 = new Rect(left, top, right, bottom);
final DisplayCutout cutout = new WmDisplayCutout(
- fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP), null)
+ fromBoundingRect(r1.left, r1.top, r1.right, r1.bottom, BOUNDS_POSITION_TOP),
+ null)
.computeSafeInsets(displayWidth, displayHeight).getDisplayCutout();
dc.mInitialDisplayCutout = cutout;
@@ -500,8 +497,8 @@ public class DisplayContentTests extends WindowTestsBase {
}
@Test
- public void testLayoutSeq_assignedDuringLayout() throws Exception {
- synchronized (sWm.getWindowManagerLock()) {
+ public void testLayoutSeq_assignedDuringLayout() {
+ synchronized (mWm.getWindowManagerLock()) {
final DisplayContent dc = createNewDisplay();
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, dc, "w");
@@ -533,7 +530,7 @@ public class DisplayContentTests extends WindowTestsBase {
assertEquals("Visible keyguard must influence device orientation",
SCREEN_ORIENTATION_PORTRAIT, dc.getOrientation());
- sWm.setKeyguardGoingAway(true);
+ mWm.setKeyguardGoingAway(true);
assertEquals("Keyguard that is going away must not influence device orientation",
SCREEN_ORIENTATION_LANDSCAPE, dc.getOrientation());
}
@@ -543,10 +540,10 @@ public class DisplayContentTests extends WindowTestsBase {
final DisplayContent dc = createNewDisplay();
assertTrue(dc.mShouldOverrideDisplayConfiguration);
- sWm.dontOverrideDisplayInfo(dc.getDisplayId());
+ mWm.dontOverrideDisplayInfo(dc.getDisplayId());
assertFalse(dc.mShouldOverrideDisplayConfiguration);
- verify(sWm.mDisplayManagerInternal, times(1))
+ verify(mWm.mDisplayManagerInternal, times(1))
.setDisplayInfoOverrideFromWindowManager(dc.getDisplayId(), null);
}
@@ -572,7 +569,7 @@ public class DisplayContentTests extends WindowTestsBase {
}
private boolean isOptionsPanelAtRight(int displayId) {
- return (sWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
+ return (mWm.getPreferredOptionsPanelGravity(displayId) & Gravity.RIGHT) == Gravity.RIGHT;
}
private static void verifySizes(DisplayContent displayContent, int expectedBaseWidth,
@@ -583,8 +580,8 @@ public class DisplayContentTests extends WindowTestsBase {
}
private void updateFocusedWindow() {
- synchronized (sWm.mGlobalLock) {
- sWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false);
+ synchronized (mWm.mGlobalLock) {
+ mWm.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL, false);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java b/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
index 3be125815d21..f0c49c8ab0b3 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DisplaySettingsTests.java
@@ -12,11 +12,12 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- *
*/
package com.android.server.wm;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
@@ -31,15 +32,13 @@ import android.view.Display;
import android.view.DisplayInfo;
import android.view.Surface;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.policy.WindowManagerPolicy;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.io.File;
@@ -47,14 +46,13 @@ import java.io.File;
* Tests for the {@link DisplaySettings} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.DisplaySettingsTests
+ * atest FrameworksServicesTests:DisplaySettingsTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class DisplaySettingsTests extends WindowTestsBase {
- private File mTestFolder;
+ private static final File TEST_FOLDER = getInstrumentation().getTargetContext().getCacheDir();
private DisplaySettings mTarget;
private DisplayContent mPrimaryDisplay;
@@ -62,21 +60,23 @@ public class DisplaySettingsTests extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
-
- mTestFolder = InstrumentationRegistry.getContext().getCacheDir();
- deleteRecursively(mTestFolder);
+ deleteRecursively(TEST_FOLDER);
- sWm.setSupportsFreeformWindowManagement(false);
- sWm.setIsPc(false);
+ mWm.setSupportsFreeformWindowManagement(false);
+ mWm.setIsPc(false);
- mTarget = new DisplaySettings(sWm, mTestFolder);
+ mTarget = new DisplaySettings(mWm, TEST_FOLDER);
- mPrimaryDisplay = sWm.getDefaultDisplayContentLocked();
+ mPrimaryDisplay = mWm.getDefaultDisplayContentLocked();
mSecondaryDisplay = mDisplayContent;
assertNotEquals(Display.DEFAULT_DISPLAY, mSecondaryDisplay.getDisplayId());
}
+ @After
+ public void tearDown() {
+ deleteRecursively(TEST_FOLDER);
+ }
+
@Test
public void testPrimaryDisplayDefaultToFullscreenWithoutFreeformSupport() {
mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
@@ -87,7 +87,7 @@ public class DisplaySettingsTests extends WindowTestsBase {
@Test
public void testPrimaryDisplayDefaultToFullscreenWithFreeformSupportNonPc() {
- sWm.setSupportsFreeformWindowManagement(true);
+ mWm.setSupportsFreeformWindowManagement(true);
mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
@@ -97,8 +97,8 @@ public class DisplaySettingsTests extends WindowTestsBase {
@Test
public void testPrimaryDisplayDefaultToFreeformWithFreeformIsPc() {
- sWm.setSupportsFreeformWindowManagement(true);
- sWm.setIsPc(true);
+ mWm.setSupportsFreeformWindowManagement(true);
+ mWm.setIsPc(true);
mTarget.applySettingsToDisplayLocked(mPrimaryDisplay);
@@ -116,7 +116,7 @@ public class DisplaySettingsTests extends WindowTestsBase {
@Test
public void testSecondaryDisplayDefaultToFreeformWithFreeformSupportNonPc() {
- sWm.setSupportsFreeformWindowManagement(true);
+ mWm.setSupportsFreeformWindowManagement(true);
mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
@@ -126,8 +126,8 @@ public class DisplaySettingsTests extends WindowTestsBase {
@Test
public void testSecondaryDisplayDefaultToFreeformWithFreeformSupportIsPc() {
- sWm.setSupportsFreeformWindowManagement(true);
- sWm.setIsPc(true);
+ mWm.setSupportsFreeformWindowManagement(true);
+ mWm.setIsPc(true);
mTarget.applySettingsToDisplayLocked(mSecondaryDisplay);
@@ -157,7 +157,7 @@ public class DisplaySettingsTests extends WindowTestsBase {
doAnswer(invocation -> {
((DisplayInfo) invocation.getArguments()[1]).copyFrom(originalInfo);
return null;
- }).when(sWm.mDisplayManagerInternal).getNonOverrideDisplayInfo(anyInt(), any());
+ }).when(mWm.mDisplayManagerInternal).getNonOverrideDisplayInfo(anyInt(), any());
mTarget.setForcedSize(mSecondaryDisplay, 1000 /* width */, 2000 /* height */);
applySettingsToDisplayByNewInstance(mSecondaryDisplay);
@@ -165,7 +165,7 @@ public class DisplaySettingsTests extends WindowTestsBase {
assertEquals(1000 /* width */, mSecondaryDisplay.mBaseDisplayWidth);
assertEquals(2000 /* height */, mSecondaryDisplay.mBaseDisplayHeight);
- sWm.clearForcedDisplaySize(mSecondaryDisplay.getDisplayId());
+ mWm.clearForcedDisplaySize(mSecondaryDisplay.getDisplayId());
assertEquals(mSecondaryDisplay.mInitialDisplayWidth, mSecondaryDisplay.mBaseDisplayWidth);
assertEquals(mSecondaryDisplay.mInitialDisplayHeight, mSecondaryDisplay.mBaseDisplayHeight);
}
@@ -177,7 +177,7 @@ public class DisplaySettingsTests extends WindowTestsBase {
assertEquals(600 /* density */, mSecondaryDisplay.mBaseDisplayDensity);
- sWm.clearForcedDisplayDensityForUser(mSecondaryDisplay.getDisplayId(), 0 /* userId */);
+ mWm.clearForcedDisplayDensityForUser(mSecondaryDisplay.getDisplayId(), 0 /* userId */);
assertEquals(mSecondaryDisplay.mInitialDisplayDensity,
mSecondaryDisplay.mBaseDisplayDensity);
}
@@ -189,7 +189,7 @@ public class DisplaySettingsTests extends WindowTestsBase {
assertTrue(mSecondaryDisplay.mDisplayScalingDisabled);
- sWm.setForcedDisplayScalingMode(mSecondaryDisplay.getDisplayId(),
+ mWm.setForcedDisplayScalingMode(mSecondaryDisplay.getDisplayId(),
DisplayContent.FORCE_SCALING_MODE_AUTO);
assertFalse(mSecondaryDisplay.mDisplayScalingDisabled);
}
@@ -298,20 +298,20 @@ public class DisplaySettingsTests extends WindowTestsBase {
* that also means the previous state must be written correctly.
*/
private void applySettingsToDisplayByNewInstance(DisplayContent display) {
- new DisplaySettings(sWm, mTestFolder).applySettingsToDisplayLocked(display);
+ new DisplaySettings(mWm, TEST_FOLDER).applySettingsToDisplayLocked(display);
}
private static boolean deleteRecursively(File file) {
+ boolean fullyDeleted = true;
if (file.isFile()) {
return file.delete();
+ } else if (file.isDirectory()) {
+ final File[] files = file.listFiles();
+ for (File child : files) {
+ fullyDeleted &= deleteRecursively(child);
+ }
+ fullyDeleted &= file.delete();
}
-
- boolean fullyDeleted = true;
- final File[] files = file.listFiles();
- for (File child : files) {
- fullyDeleted &= deleteRecursively(child);
- }
- fullyDeleted &= file.delete();
return fullyDeleted;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
index 31b2fefed420..55e766da09fc 100644
--- a/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/DragDropControllerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -40,23 +40,24 @@ import android.view.SurfaceControl;
import android.view.SurfaceSession;
import android.view.View;
-import com.android.internal.annotations.GuardedBy;
+import androidx.test.filters.SmallTest;
+
import com.android.server.LocalServices;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
-import androidx.test.filters.SmallTest;
-
/**
* Tests for the {@link DragDropController} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.DragDropControllerTests
+ * atest FrameworksServicesTests:DragDropControllerTests
*/
@SmallTest
@Presubmit
@@ -67,7 +68,6 @@ public class DragDropControllerTests extends WindowTestsBase {
private IBinder mToken;
static class TestDragDropController extends DragDropController {
- @GuardedBy("sWm.mWindowMap")
private Runnable mCloseCallback;
TestDragDropController(WindowManagerService service, Looper looper) {
@@ -107,31 +107,34 @@ public class DragDropControllerTests extends WindowTestsBase {
return window;
}
- @Override
- @Before
- public void setUp() throws Exception {
+ @BeforeClass
+ public static void setUpOnce() {
final UserManagerInternal userManager = mock(UserManagerInternal.class);
LocalServices.addService(UserManagerInternal.class, userManager);
+ }
- super.setUp();
+ @AfterClass
+ public static void tearDownOnce() {
+ LocalServices.removeServiceForTest(UserManagerInternal.class);
+ }
- mTarget = new TestDragDropController(sWm, sWm.mH.getLooper());
+ @Before
+ public void setUp() throws Exception {
+ mTarget = new TestDragDropController(mWm, mWm.mH.getLooper());
mDisplayContent = spy(mDisplayContent);
mWindow = createDropTargetWindow("Drag test window", 0);
doReturn(mWindow).when(mDisplayContent).getTouchableWinAtPointLocked(0, 0);
- when(sWm.mInputManager.transferTouchFocus(any(), any())).thenReturn(true);
+ when(mWm.mInputManager.transferTouchFocus(any(), any())).thenReturn(true);
- synchronized (sWm.mGlobalLock) {
- sWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
+ synchronized (mWm.mGlobalLock) {
+ mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
}
}
- @Override
@After
public void tearDown() throws Exception {
- LocalServices.removeServiceForTest(UserManagerInternal.class);
final CountDownLatch latch;
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
if (!mTarget.dragDropActiveLocked()) {
return;
}
@@ -142,8 +145,6 @@ public class DragDropControllerTests extends WindowTestsBase {
mTarget.setOnClosedCallbackLocked(latch::countDown);
}
assertTrue(latch.await(TIMEOUT_MS, TimeUnit.MILLISECONDS));
-
- super.tearDown();
}
@Test
@@ -174,7 +175,7 @@ public class DragDropControllerTests extends WindowTestsBase {
.setFormat(PixelFormat.TRANSLUCENT)
.build();
- assertTrue(sWm.mInputManager.transferTouchFocus(null, null));
+ assertTrue(mWm.mInputManager.transferTouchFocus(null, null));
mToken = mTarget.performDrag(
new SurfaceSession(), 0, 0, mWindow.mClient, flag, surface, 0, 0, 0, 0, 0,
data);
diff --git a/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
index 7222a999e23c..1fae317f3af8 100644
--- a/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/PinnedStackControllerTest.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.server.wm;
import static android.view.Display.DEFAULT_DISPLAY;
@@ -16,17 +32,18 @@ import android.platform.test.annotations.Presubmit;
import android.view.IPinnedStackListener;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+/**
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:PinnedStackControllerTest
+ */
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class PinnedStackControllerTest extends WindowTestsBase {
@Mock private IPinnedStackListener mIPinnedStackListener;
@@ -34,15 +51,15 @@ public class PinnedStackControllerTest extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
MockitoAnnotations.initMocks(this);
+
when(mIPinnedStackListener.asBinder()).thenReturn(mIPinnedStackListenerStub);
}
@Test
public void setShelfHeight_shelfVisibilityChangedTriggered() throws RemoteException {
- sWm.mSupportsPictureInPicture = true;
- sWm.registerPinnedStackListener(DEFAULT_DISPLAY, mIPinnedStackListener);
+ mWm.mSupportsPictureInPicture = true;
+ mWm.registerPinnedStackListener(DEFAULT_DISPLAY, mIPinnedStackListener);
verify(mIPinnedStackListener).onImeVisibilityChanged(false, 0);
verify(mIPinnedStackListener).onShelfVisibilityChanged(false, 0);
@@ -55,7 +72,7 @@ public class PinnedStackControllerTest extends WindowTestsBase {
final int SHELF_HEIGHT = 300;
- sWm.setShelfHeight(true, SHELF_HEIGHT);
+ mWm.setShelfHeight(true, SHELF_HEIGHT);
verify(mIPinnedStackListener).onShelfVisibilityChanged(true, SHELF_HEIGHT);
verify(mIPinnedStackListener).onMovementBoundsChanged(any(), any(), any(), eq(false),
eq(true), anyInt());
diff --git a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 088e22972cc9..fe5fc068a36b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -24,9 +24,9 @@ import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.server.wm.RecentsAnimationController.REORDER_KEEP_IN_PLACE;
import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_ORIGINAL_POSITION;
-import static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeast;
import static org.mockito.Mockito.verify;
@@ -42,22 +42,20 @@ import android.view.SurfaceControl;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
- * atest FrameworksServicesTests:com.android.server.wm.RecentsAnimationControllerTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:RecentsAnimationControllerTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class RecentsAnimationControllerTest extends WindowTestsBase {
@Mock SurfaceControl mMockLeash;
@@ -69,10 +67,10 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
MockitoAnnotations.initMocks(this);
+
when(mMockRunner.asBinder()).thenReturn(new Binder());
- mController = new RecentsAnimationController(sWm, mMockRunner, mAnimationCallbacks,
+ mController = new RecentsAnimationController(mWm, mMockRunner, mAnimationCallbacks,
DEFAULT_DISPLAY);
}
@@ -96,7 +94,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
}
@Test
- public void testCancelAfterRemove_expectIgnored() throws Exception {
+ public void testCancelAfterRemove_expectIgnored() {
final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
AnimationAdapter adapter = mController.addAnimation(appWindow.getTask(),
@@ -114,10 +112,10 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
}
}
- @Test
@FlakyTest(bugId = 117117823)
- public void testIncludedApps_expectTargetAndVisible() throws Exception {
- sWm.setRecentsAnimationController(mController);
+ @Test
+ public void testIncludedApps_expectTargetAndVisible() {
+ mWm.setRecentsAnimationController(mController);
final AppWindowToken homeAppWindow = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
diff --git a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
index ae92984ebf65..fa5379576e8b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RemoteAnimationControllerTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -39,7 +39,6 @@ import android.view.SurfaceControl;
import android.view.SurfaceControl.Transaction;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.testutils.OffsettableClock;
import com.android.server.testutils.TestHandler;
@@ -47,17 +46,16 @@ import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
/**
- * atest FrameworksServicesTests:com.android.server.wm.RemoteAnimationControllerTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:RemoteAnimationControllerTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class RemoteAnimationControllerTest extends WindowTestsBase {
@Mock SurfaceControl mMockLeash;
@@ -71,15 +69,13 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
MockitoAnnotations.initMocks(this);
+
when(mMockRunner.asBinder()).thenReturn(new Binder());
mAdapter = new RemoteAnimationAdapter(mMockRunner, 100, 50);
mAdapter.setCallingPid(123);
- sWm.mH.runWithScissors(() -> {
- mHandler = new TestHandler(null, mClock);
- }, 0);
- mController = new RemoteAnimationController(sWm, mAdapter, mHandler);
+ mWm.mH.runWithScissors(() -> mHandler = new TestHandler(null, mClock), 0);
+ mController = new RemoteAnimationController(mWm, mAdapter, mHandler);
}
@Test
@@ -91,7 +87,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
new Point(50, 100), new Rect(50, 100, 150, 150));
adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
mController.goodToGo();
- sWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+ mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
@@ -146,7 +142,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
@Test
public void testTimeout_scaled() throws Exception {
- sWm.setAnimationScale(2, 5.0f);
+ mWm.setAnimationScale(2, 5.0f);
try{
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
@@ -165,19 +161,19 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
verify(mMockRunner).onAnimationCancelled();
verify(mFinishedCallback).onAnimationFinished(eq(adapter));
} finally {
- sWm.setAnimationScale(2, 1.0f);
+ mWm.setAnimationScale(2, 1.0f);
}
}
@Test
- public void testZeroAnimations() throws Exception {
+ public void testZeroAnimations() {
mController.goodToGo();
verifyNoMoreInteractionsExceptAsBinder(mMockRunner);
}
@Test
- public void testNotReallyStarted() throws Exception {
+ public void testNotReallyStarted() {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
mController.createAnimationAdapter(win.mAppToken,
new Point(50, 100), new Rect(50, 100, 150, 150));
@@ -195,7 +191,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
new Point(50, 100), new Rect(50, 100, 150, 150));
adapter.startAnimation(mMockLeash, mMockTransaction, mFinishedCallback);
mController.goodToGo();
- sWm.mAnimator.executeAfterPrepareSurfacesRunnables();
+ mWm.mAnimator.executeAfterPrepareSurfacesRunnables();
final ArgumentCaptor<RemoteAnimationTarget[]> appsCaptor =
ArgumentCaptor.forClass(RemoteAnimationTarget[].class);
final ArgumentCaptor<IRemoteAnimationFinishedCallback> finishedCaptor =
@@ -206,7 +202,7 @@ public class RemoteAnimationControllerTest extends WindowTestsBase {
}
@Test
- public void testRemovedBeforeStarted() throws Exception {
+ public void testRemovedBeforeStarted() {
final WindowState win = createWindow(null /* parent */, TYPE_BASE_APPLICATION, "testWin");
final AnimationAdapter adapter = mController.createAnimationAdapter(win.mAppToken,
new Point(50, 100), new Rect(50, 100, 150, 150));
diff --git a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
index 001bed969d8f..62a617d8f20a 100644
--- a/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/RootWindowContainerTests.java
@@ -1,30 +1,43 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.server.wm;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertEquals;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Tests for the {@link RootWindowContainer} class.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.RootWindowContainerTests
+ * atest FrameworksServicesTests:RootWindowContainerTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class RootWindowContainerTests extends WindowTestsBase {
@Test
- public void testSetDisplayOverrideConfigurationIfNeeded() throws Exception {
- synchronized (sWm.mGlobalLock) {
+ public void testSetDisplayOverrideConfigurationIfNeeded() {
+ synchronized (mWm.mGlobalLock) {
// Add first stack we expect to be updated with configuration change.
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
stack.getOverrideConfiguration().windowConfiguration.setBounds(new Rect(0, 0, 5, 5));
@@ -41,12 +54,12 @@ public class RootWindowContainerTests extends WindowTestsBase {
override.windowConfiguration.setBounds(new Rect(0, 0, 10, 10));
// Set display override.
- final int[] results = sWm.mRoot.setDisplayOverrideConfigurationIfNeeded(override,
+ final int[] results = mWm.mRoot.setDisplayOverrideConfigurationIfNeeded(override,
mDisplayContent.getDisplayId());
// Ensure only first stack is returned.
- assertTrue(results.length == 1);
- assertTrue(results[0] == stack.mStackId);
+ assertEquals(1, results.length);
+ assertEquals(stack.mStackId, results[0]);
}
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
index 9f2645cc98ae..ce5b13cab1a7 100644
--- a/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/StackWindowControllerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -25,10 +25,8 @@ import android.graphics.Rect;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link StackWindowController}.
@@ -38,10 +36,9 @@ import org.junit.runner.RunWith;
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class StackWindowControllerTests extends WindowTestsBase {
@Test
- public void testRemoveContainer() throws Exception {
+ public void testRemoveContainer() {
final StackWindowController stackController =
createStackControllerOnDisplay(mDisplayContent);
final WindowTestUtils.TestTaskWindowContainerController taskController =
@@ -61,7 +58,7 @@ public class StackWindowControllerTests extends WindowTestsBase {
}
@Test
- public void testRemoveContainer_deferRemoval() throws Exception {
+ public void testRemoveContainer_deferRemoval() {
final StackWindowController stackController =
createStackControllerOnDisplay(mDisplayContent);
final WindowTestUtils.TestTaskWindowContainerController taskController =
@@ -87,7 +84,7 @@ public class StackWindowControllerTests extends WindowTestsBase {
}
@Test
- public void testReparent() throws Exception {
+ public void testReparent() {
// Create first stack on primary display.
final StackWindowController stack1Controller =
createStackControllerOnDisplay(mDisplayContent);
diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
index 4551c3611102..584f2695891b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimationRunnerTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -27,6 +27,8 @@ import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
import android.animation.AnimationHandler.AnimationFrameCallbackProvider;
import android.animation.ValueAnimator;
import android.graphics.Matrix;
@@ -42,30 +44,27 @@ import android.view.animation.TranslateAnimation;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.LocalAnimationAdapter.AnimationSpec;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;
-import static java.util.concurrent.TimeUnit.SECONDS;
-
import java.util.concurrent.CountDownLatch;
/**
* Test class for {@link SurfaceAnimationRunner}.
*
- * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimationRunnerTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:SurfaceAnimationRunnerTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class SurfaceAnimationRunnerTest extends WindowTestsBase {
@Mock SurfaceControl mMockSurface;
@@ -79,7 +78,8 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
+ MockitoAnnotations.initMocks(this);
+
mFinishCallbackLatch = new CountDownLatch(1);
mSurfaceAnimationRunner = new SurfaceAnimationRunner(null /* callbackProvider */, null,
mMockTransaction, mMockPowerManager);
@@ -112,7 +112,7 @@ public class SurfaceAnimationRunnerTest extends WindowTestsBase {
}
@Test
- public void testCancel_notStarted() throws Exception {
+ public void testCancel_notStarted() {
mSurfaceAnimationRunner = new SurfaceAnimationRunner(new NoOpFrameCallbackProvider(), null,
mMockTransaction, mMockPowerManager);
mSurfaceAnimationRunner
diff --git a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
index 7b5e8deeeb65..6833dc5f0497 100644
--- a/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/SurfaceAnimatorTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -35,14 +35,13 @@ import android.view.SurfaceSession;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.SurfaceAnimator.Animatable;
import com.android.server.wm.SurfaceAnimator.OnAnimationFinishedCallback;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -50,11 +49,11 @@ import org.mockito.MockitoAnnotations;
/**
* Test class for {@link SurfaceAnimatorTest}.
*
- * atest FrameworksServicesTests:com.android.server.wm.SurfaceAnimatorTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:SurfaceAnimatorTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class SurfaceAnimatorTest extends WindowTestsBase {
@Mock AnimationAdapter mSpec;
@@ -68,15 +67,24 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
MockitoAnnotations.initMocks(this);
- mAnimatable = new MyAnimatable();
- mAnimatable2 = new MyAnimatable();
- mDeferFinishAnimatable = new DeferFinishAnimatable();
+
+ mAnimatable = new MyAnimatable(mWm, mSession, mTransaction);
+ mAnimatable2 = new MyAnimatable(mWm, mSession, mTransaction);
+ mDeferFinishAnimatable = new DeferFinishAnimatable(mWm, mSession, mTransaction);
+ }
+
+ @After
+ public void tearDown() {
+ mAnimatable = null;
+ mAnimatable2 = null;
+ mDeferFinishAnimatable = null;
+ mSession.kill();
+ mSession = null;
}
@Test
- public void testRunAnimation() throws Exception {
+ public void testRunAnimation() {
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
OnAnimationFinishedCallback.class);
@@ -92,7 +100,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
}
@Test
- public void testOverrideAnimation() throws Exception {
+ public void testOverrideAnimation() {
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
final SurfaceControl firstLeash = mAnimatable.mLeash;
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec2, true /* hidden */);
@@ -117,7 +125,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
}
@Test
- public void testCancelAnimation() throws Exception {
+ public void testCancelAnimation() {
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
assertAnimating(mAnimatable);
mAnimatable.mSurfaceAnimator.cancelAnimation();
@@ -128,7 +136,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
}
@Test
- public void testDelayingAnimationStart() throws Exception {
+ public void testDelayingAnimationStart() {
mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
verifyZeroInteractions(mSpec);
@@ -139,7 +147,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
}
@Test
- public void testDelayingAnimationStartAndCancelled() throws Exception {
+ public void testDelayingAnimationStartAndCancelled() {
mAnimatable.mSurfaceAnimator.startDelayingAnimationStart();
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
mAnimatable.mSurfaceAnimator.cancelAnimation();
@@ -150,7 +158,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
}
@Test
- public void testTransferAnimation() throws Exception {
+ public void testTransferAnimation() {
mAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec, true /* hidden */);
final ArgumentCaptor<OnAnimationFinishedCallback> callbackCaptor = ArgumentCaptor.forClass(
@@ -171,7 +179,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
@Test
@FlakyTest(detail = "Promote once confirmed non-flaky")
- public void testDeferFinish() throws Exception {
+ public void testDeferFinish() {
// Start animation
mDeferFinishAnimatable.mSurfaceAnimator.startAnimation(mTransaction, mSpec,
@@ -186,7 +194,7 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
assertAnimating(mDeferFinishAnimatable);
// Now end defer finishing.
- mDeferFinishAnimatable.endDeferFinishCallback.run();
+ mDeferFinishAnimatable.mEndDeferFinishCallback.run();
assertNotAnimating(mAnimatable2);
assertTrue(mDeferFinishAnimatable.mFinishedCallbackCalled);
verify(mTransaction).destroy(eq(mDeferFinishAnimatable.mLeash));
@@ -202,26 +210,30 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
assertNull(animatable.mSurfaceAnimator.getAnimation());
}
- private class MyAnimatable implements Animatable {
+ private static class MyAnimatable implements Animatable {
+ private final SurfaceSession mSession;
+ private final Transaction mTransaction;
final SurfaceControl mParent;
final SurfaceControl mSurface;
final SurfaceAnimator mSurfaceAnimator;
SurfaceControl mLeash;
boolean mFinishedCallbackCalled;
- MyAnimatable() {
- mParent = sWm.makeSurfaceBuilder(mSession)
+ MyAnimatable(WindowManagerService wm, SurfaceSession session, Transaction transaction) {
+ mSession = session;
+ mTransaction = transaction;
+ mParent = wm.makeSurfaceBuilder(mSession)
.setName("test surface parent")
.setSize(3000, 3000)
.build();
- mSurface = sWm.makeSurfaceBuilder(mSession)
+ mSurface = wm.makeSurfaceBuilder(mSession)
.setName("test surface")
.setSize(1, 1)
.build();
mFinishedCallbackCalled = false;
mLeash = null;
- mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, sWm);
+ mSurfaceAnimator = new SurfaceAnimator(this, mFinishedCallback, wm);
}
@Override
@@ -281,13 +293,18 @@ public class SurfaceAnimatorTest extends WindowTestsBase {
private final Runnable mFinishedCallback = () -> mFinishedCallbackCalled = true;
}
- private class DeferFinishAnimatable extends MyAnimatable {
+ private static class DeferFinishAnimatable extends MyAnimatable {
- Runnable endDeferFinishCallback;
+ Runnable mEndDeferFinishCallback;
+
+ DeferFinishAnimatable(WindowManagerService wm, SurfaceSession session,
+ Transaction transaction) {
+ super(wm, session, transaction);
+ }
@Override
public boolean shouldDeferAnimationFinish(Runnable endDeferFinishCallback) {
- this.endDeferFinishCallback = endDeferFinishCallback;
+ mEndDeferFinishCallback = endDeferFinishCallback;
return true;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
index 17b7fc1fd0f0..785b955863db 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositionerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -35,24 +35,22 @@ import android.util.Log;
import android.view.Display;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
import org.mockito.Mockito;
/**
* Tests for the {@link TaskPositioner} class.
*
- * runtest frameworks-services -c com.android.server.wm.TaskPositionerTests
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:TaskPositionerTests
*/
@SmallTest
-@RunWith(AndroidJUnit4.class)
public class TaskPositionerTests extends WindowTestsBase {
- private final boolean DEBUGGING = false;
- private final String TAG = "TaskPositionerTest";
+ private static final boolean DEBUGGING = false;
+ private static final String TAG = "TaskPositionerTest";
private final static int MOUSE_DELTA_X = 5;
private final static int MOUSE_DELTA_Y = 5;
@@ -65,8 +63,6 @@ public class TaskPositionerTests extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
-
TaskPositioner.setFactory(null);
final Display display = mDisplayContent.getDisplay();
@@ -77,7 +73,7 @@ public class TaskPositionerTests extends WindowTestsBase {
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, dm);
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, dm);
- mPositioner = new TaskPositioner(sWm, Mockito.mock(IActivityTaskManager.class));
+ mPositioner = new TaskPositioner(mWm, Mockito.mock(IActivityTaskManager.class));
mPositioner.register(mDisplayContent);
mWindow = Mockito.spy(createWindow(null, TYPE_BASE_APPLICATION, "window"));
@@ -94,7 +90,7 @@ public class TaskPositionerTests extends WindowTestsBase {
}
@Test
- public void testOverrideFactory() throws Exception {
+ public void testOverrideFactory() {
final boolean[] created = new boolean[1];
created[0] = false;
TaskPositioner.setFactory(new TaskPositioner.Factory() {
@@ -105,7 +101,7 @@ public class TaskPositionerTests extends WindowTestsBase {
}
});
- assertNull(TaskPositioner.create(sWm));
+ assertNull(TaskPositioner.create(mWm));
assertTrue(created[0]);
}
@@ -114,7 +110,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* as does some basic tests (e.g. dragging in Y only will keep X stable).
*/
@Test
- public void testBasicFreeWindowResizing() throws Exception {
+ public void testBasicFreeWindowResizing() {
final Rect r = new Rect(100, 220, 700, 520);
final int midY = (r.top + r.bottom) / 2;
mDimBounds.set(r);
@@ -175,7 +171,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* This tests that by dragging any edge, the fixed / opposite edge(s) remains anchored.
*/
@Test
- public void testFreeWindowResizingTestAllEdges() throws Exception {
+ public void testFreeWindowResizingTestAllEdges() {
final Rect r = new Rect(100, 220, 700, 520);
final int midX = (r.left + r.right) / 2;
final int midY = (r.top + r.bottom) / 2;
@@ -260,7 +256,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* right things upon resizing when dragged from the top left corner.
*/
@Test
- public void testLandscapePreservedWindowResizingDragTopLeft() throws Exception {
+ public void testLandscapePreservedWindowResizingDragTopLeft() {
final Rect r = new Rect(100, 220, 700, 520);
mDimBounds.set(r);
@@ -298,7 +294,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* right things upon resizing when dragged from the left corner.
*/
@Test
- public void testLandscapePreservedWindowResizingDragLeft() throws Exception {
+ public void testLandscapePreservedWindowResizingDragLeft() {
final Rect r = new Rect(100, 220, 700, 520);
final int midY = (r.top + r.bottom) / 2;
mDimBounds.set(r);
@@ -339,7 +335,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* right things upon resizing when dragged from the top corner.
*/
@Test
- public void testLandscapePreservedWindowResizingDragTop() throws Exception {
+ public void testLandscapePreservedWindowResizingDragTop() {
final Rect r = new Rect(100, 220, 700, 520);
final int midX = (r.left + r.right) / 2;
mDimBounds.set(r);
@@ -376,7 +372,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* right things upon resizing when dragged from the top left corner.
*/
@Test
- public void testPortraitPreservedWindowResizingDragTopLeft() throws Exception {
+ public void testPortraitPreservedWindowResizingDragTopLeft() {
final Rect r = new Rect(330, 100, 630, 600);
mDimBounds.set(r);
@@ -409,7 +405,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* right things upon resizing when dragged from the left corner.
*/
@Test
- public void testPortraitPreservedWindowResizingDragLeft() throws Exception {
+ public void testPortraitPreservedWindowResizingDragLeft() {
final Rect r = new Rect(330, 100, 630, 600);
final int midY = (r.top + r.bottom) / 2;
mDimBounds.set(r);
@@ -452,7 +448,7 @@ public class TaskPositionerTests extends WindowTestsBase {
* right things upon resizing when dragged from the top corner.
*/
@Test
- public void testPortraitPreservedWindowResizingDragTop() throws Exception {
+ public void testPortraitPreservedWindowResizingDragTop() {
final Rect r = new Rect(330, 100, 630, 600);
final int midX = (r.left + r.right) / 2;
mDimBounds.set(r);
@@ -485,7 +481,7 @@ public class TaskPositionerTests extends WindowTestsBase {
mPositioner.getWindowDragBounds());
}
- private void assertBoundsEquals(Rect expected, Rect actual) {
+ private static void assertBoundsEquals(Rect expected, Rect actual) {
if (DEBUGGING) {
if (!expected.equals(actual)) {
Log.e(TAG, "rect(" + actual.toString() + ") != isRect(" + actual.toString()
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
index d1480c5865cf..00b462954bd9 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskPositioningControllerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -32,70 +32,66 @@ import android.view.InputChannel;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Tests for the {@link TaskPositioningController} class.
*
- * atest com.android.server.wm.TaskPositioningControllerTests
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:TaskPositioningControllerTests
*/
-@SmallTest
@FlakyTest(bugId = 117924387)
-@RunWith(AndroidJUnit4.class)
+@SmallTest
@Presubmit
public class TaskPositioningControllerTests extends WindowTestsBase {
private static final int TIMEOUT_MS = 1000;
+
private TaskPositioningController mTarget;
private WindowState mWindow;
@Before
public void setUp() throws Exception {
- super.setUp();
+ assertNotNull(mWm.mTaskPositioningController);
+ mTarget = mWm.mTaskPositioningController;
- assertNotNull(sWm.mTaskPositioningController);
- mTarget = sWm.mTaskPositioningController;
-
- when(sWm.mInputManager.transferTouchFocus(
+ when(mWm.mInputManager.transferTouchFocus(
any(InputChannel.class),
any(InputChannel.class))).thenReturn(true);
mWindow = createWindow(null, TYPE_BASE_APPLICATION, "window");
mWindow.mInputChannel = new InputChannel();
- synchronized (sWm.mGlobalLock) {
- sWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
+ synchronized (mWm.mGlobalLock) {
+ mWm.mWindowMap.put(mWindow.mClient.asBinder(), mWindow);
}
}
@Test
- public void testStartAndFinishPositioning() throws Exception {
- synchronized (sWm.mGlobalLock) {
+ public void testStartAndFinishPositioning() {
+ synchronized (mWm.mGlobalLock) {
assertFalse(mTarget.isPositioningLocked());
assertNull(mTarget.getDragWindowHandleLocked());
}
assertTrue(mTarget.startMovingTask(mWindow.mClient, 0, 0));
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
assertTrue(mTarget.isPositioningLocked());
assertNotNull(mTarget.getDragWindowHandleLocked());
}
mTarget.finishTaskPositioning();
// Wait until the looper processes finishTaskPositioning.
- assertTrue(sWm.mH.runWithScissors(() -> {}, TIMEOUT_MS));
+ assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
assertFalse(mTarget.isPositioningLocked());
assertNull(mTarget.getDragWindowHandleLocked());
}
@Test
- public void testHandleTapOutsideTask() throws Exception {
- synchronized (sWm.mGlobalLock) {
-
+ public void testHandleTapOutsideTask() {
+ synchronized (mWm.mGlobalLock) {
assertFalse(mTarget.isPositioningLocked());
assertNull(mTarget.getDragWindowHandleLocked());
}
@@ -106,16 +102,16 @@ public class TaskPositioningControllerTests extends WindowTestsBase {
mTarget.handleTapOutsideTask(content, 0, 0);
// Wait until the looper processes finishTaskPositioning.
- assertTrue(sWm.mH.runWithScissors(() -> {}, TIMEOUT_MS));
+ assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
assertTrue(mTarget.isPositioningLocked());
assertNotNull(mTarget.getDragWindowHandleLocked());
}
mTarget.finishTaskPositioning();
// Wait until the looper processes finishTaskPositioning.
- assertTrue(sWm.mH.runWithScissors(() -> {}, TIMEOUT_MS));
+ assertTrue(mWm.mH.runWithScissors(() -> { }, TIMEOUT_MS));
assertFalse(mTarget.isPositioningLocked());
assertNull(mTarget.getDragWindowHandleLocked());
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
index c9d800449ff9..1c6afd545b1f 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotCacheTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -24,32 +24,32 @@ import static junit.framework.Assert.assertNull;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link TaskSnapshotCache}.
*
- * runtest frameworks-services -c com.android.server.wm.TaskSnapshotCacheTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:TaskSnapshotCacheTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase {
private TaskSnapshotCache mCache;
+ @Override
@Before
- public void setUp() throws Exception {
+ public void setUp() {
super.setUp();
- mCache = new TaskSnapshotCache(sWm, mLoader);
+
+ mCache = new TaskSnapshotCache(mWm, mLoader);
}
@Test
- public void testAppRemoved() throws Exception {
+ public void testAppRemoved() {
final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
mCache.putSnapshot(window.getTask(), createSnapshot());
assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
@@ -60,7 +60,7 @@ public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase {
}
@Test
- public void testAppDied() throws Exception {
+ public void testAppDied() {
final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
mCache.putSnapshot(window.getTask(), createSnapshot());
assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
@@ -71,7 +71,7 @@ public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase {
}
@Test
- public void testTaskRemoved() throws Exception {
+ public void testTaskRemoved() {
final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
mCache.putSnapshot(window.getTask(), createSnapshot());
assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, 0 /* userId */,
@@ -82,32 +82,32 @@ public class TaskSnapshotCacheTest extends TaskSnapshotPersisterTestBase {
}
@Test
- public void testReduced_notCached() throws Exception {
+ public void testReduced_notCached() {
final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
- mPersister.persistSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId, createSnapshot());
+ mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot());
mPersister.waitForQueueEmpty();
- assertNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+ assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
false /* restoreFromDisk */, false /* reducedResolution */));
// Load it from disk
- assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+ assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
true /* restoreFromDisk */, true /* reducedResolution */));
// Make sure it's not in the cache now.
- assertNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+ assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
false /* restoreFromDisk */, false /* reducedResolution */));
}
@Test
- public void testRestoreFromDisk() throws Exception {
+ public void testRestoreFromDisk() {
final WindowState window = createWindow(null, FIRST_APPLICATION_WINDOW, "window");
- mPersister.persistSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId, createSnapshot());
+ mPersister.persistSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId, createSnapshot());
mPersister.waitForQueueEmpty();
- assertNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+ assertNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
false /* restoreFromDisk */, false /* reducedResolution */));
// Load it from disk
- assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, sWm.mCurrentUserId,
+ assertNotNull(mCache.getSnapshot(window.getTask().mTaskId, mWm.mCurrentUserId,
true /* restoreFromDisk */, false /* reducedResolution */));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
index efce063c8fca..d2c07651d83c 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotControllerTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -20,7 +20,8 @@ import static android.view.WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW;
import static android.view.WindowManager.LayoutParams.FLAG_SECURE;
import static android.view.WindowManager.TRANSIT_UNSET;
-import static com.android.server.wm.TaskSnapshotController.*;
+import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_APP_THEME;
+import static com.android.server.wm.TaskSnapshotController.SNAPSHOT_MODE_REAL;
import static junit.framework.Assert.assertEquals;
@@ -28,25 +29,23 @@ import android.platform.test.annotations.Presubmit;
import android.util.ArraySet;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.google.android.collect.Sets;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link TaskSnapshotController}.
*
- * runtest frameworks-services -c com.android.server.wm.TaskSnapshotControllerTest
+ * Build/Install/Run:
+ * * atest FrameworksServicesTests:TaskSnapshotControllerTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class TaskSnapshotControllerTest extends WindowTestsBase {
@Test
- public void testGetClosingApps_closing() throws Exception {
+ public void testGetClosingApps_closing() {
final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
"closingWindow");
closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET,
@@ -54,13 +53,13 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
final ArraySet<AppWindowToken> closingApps = new ArraySet<>();
closingApps.add(closingWindow.mAppToken);
final ArraySet<Task> closingTasks = new ArraySet<>();
- sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+ mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
assertEquals(1, closingTasks.size());
assertEquals(closingWindow.mAppToken.getTask(), closingTasks.valueAt(0));
}
@Test
- public void testGetClosingApps_notClosing() throws Exception {
+ public void testGetClosingApps_notClosing() {
final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
"closingWindow");
final WindowState openingWindow = createAppWindow(closingWindow.getTask(),
@@ -72,12 +71,12 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
final ArraySet<AppWindowToken> closingApps = new ArraySet<>();
closingApps.add(closingWindow.mAppToken);
final ArraySet<Task> closingTasks = new ArraySet<>();
- sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+ mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
assertEquals(0, closingTasks.size());
}
@Test
- public void testGetClosingApps_skipClosingAppsSnapshotTasks() throws Exception {
+ public void testGetClosingApps_skipClosingAppsSnapshotTasks() {
final WindowState closingWindow = createWindow(null, FIRST_APPLICATION_WINDOW,
"closingWindow");
closingWindow.mAppToken.setVisibility(null, false /* visible */, TRANSIT_UNSET,
@@ -85,29 +84,29 @@ public class TaskSnapshotControllerTest extends WindowTestsBase {
final ArraySet<AppWindowToken> closingApps = new ArraySet<>();
closingApps.add(closingWindow.mAppToken);
final ArraySet<Task> closingTasks = new ArraySet<>();
- sWm.mTaskSnapshotController.addSkipClosingAppSnapshotTasks(
+ mWm.mTaskSnapshotController.addSkipClosingAppSnapshotTasks(
Sets.newArraySet(closingWindow.mAppToken.getTask()));
- sWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
+ mWm.mTaskSnapshotController.getClosingTasks(closingApps, closingTasks);
assertEquals(0, closingTasks.size());
}
@Test
- public void testGetSnapshotMode() throws Exception {
+ public void testGetSnapshotMode() {
final WindowState disabledWindow = createWindow(null,
FIRST_APPLICATION_WINDOW, mDisplayContent, "disabledWindow");
disabledWindow.mAppToken.setDisablePreviewScreenshots(true);
assertEquals(SNAPSHOT_MODE_APP_THEME,
- sWm.mTaskSnapshotController.getSnapshotMode(disabledWindow.getTask()));
+ mWm.mTaskSnapshotController.getSnapshotMode(disabledWindow.getTask()));
final WindowState normalWindow = createWindow(null,
FIRST_APPLICATION_WINDOW, mDisplayContent, "normalWindow");
assertEquals(SNAPSHOT_MODE_REAL,
- sWm.mTaskSnapshotController.getSnapshotMode(normalWindow.getTask()));
+ mWm.mTaskSnapshotController.getSnapshotMode(normalWindow.getTask()));
final WindowState secureWindow = createWindow(null,
FIRST_APPLICATION_WINDOW, mDisplayContent, "secureWindow");
secureWindow.mAttrs.flags |= FLAG_SECURE;
assertEquals(SNAPSHOT_MODE_APP_THEME,
- sWm.mTaskSnapshotController.getSnapshotMode(secureWindow.getTask()));
+ mWm.mTaskSnapshotController.getSnapshotMode(secureWindow.getTask()));
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
index 600b2e52b083..b0eafeeae043 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterLoaderTest.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -34,23 +34,22 @@ import android.util.ArraySet;
import android.view.View;
import androidx.test.filters.MediumTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.TaskSnapshotPersister.RemoveObsoleteFilesQueueItem;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.io.File;
+import java.util.function.Predicate;
/**
* Test class for {@link TaskSnapshotPersister} and {@link TaskSnapshotLoader}
*
- * atest FrameworksServicesTests:TaskSnapshotPersisterLoaderTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:TaskSnapshotPersisterLoaderTest
*/
@MediumTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBase {
private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
@@ -59,9 +58,9 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
public void testPersistAndLoadSnapshot() {
mPersister.persistSnapshot(1 , mTestUserId, createSnapshot());
mPersister.waitForQueueEmpty();
- final File[] files = new File[] { new File(sFilesDir.getPath() + "/snapshots/1.proto"),
- new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
- new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg")};
+ final File[] files = new File[] { new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
+ new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg")};
assertTrueForFiles(files, File::exists, " must exist");
final TaskSnapshot snapshot = mLoader.loadTask(1, mTestUserId, false /* reduced */);
assertNotNull(snapshot);
@@ -70,9 +69,10 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
assertEquals(Configuration.ORIENTATION_PORTRAIT, snapshot.getOrientation());
}
- private void assertTrueForFiles(File[] files, Predicate<File> predicate, String message) {
+ private static void assertTrueForFiles(File[] files, Predicate<File> predicate,
+ String message) {
for (File file : files) {
- assertTrue(file.getName() + message, predicate.apply(file));
+ assertTrue(file.getName() + message, predicate.test(file));
}
}
@@ -81,9 +81,9 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
mPersister.persistSnapshot(1, mTestUserId, createSnapshot());
mPersister.onTaskRemovedFromRecents(1, mTestUserId);
mPersister.waitForQueueEmpty();
- assertFalse(new File(sFilesDir.getPath() + "/snapshots/1.proto").exists());
- assertFalse(new File(sFilesDir.getPath() + "/snapshots/1.jpg").exists());
- assertFalse(new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg").exists());
+ assertFalse(new File(FILES_DIR.getPath() + "/snapshots/1.proto").exists());
+ assertFalse(new File(FILES_DIR.getPath() + "/snapshots/1.jpg").exists());
+ assertFalse(new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg").exists());
}
/**
@@ -120,12 +120,12 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
// Make sure 1,2 were purged but removeObsoleteFiles wasn't.
final File[] existsFiles = new File[] {
- new File(sFilesDir.getPath() + "/snapshots/3.proto"),
- new File(sFilesDir.getPath() + "/snapshots/4.proto")};
+ new File(FILES_DIR.getPath() + "/snapshots/3.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/4.proto")};
final File[] nonExistsFiles = new File[] {
- new File(sFilesDir.getPath() + "/snapshots/100.proto"),
- new File(sFilesDir.getPath() + "/snapshots/1.proto"),
- new File(sFilesDir.getPath() + "/snapshots/1.proto")};
+ new File(FILES_DIR.getPath() + "/snapshots/100.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/1.proto")};
assertTrueForFiles(existsFiles, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
}
@@ -149,10 +149,10 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
assertTrue(a.isReducedResolution());
mPersister.persistSnapshot(1 , mTestUserId, a);
mPersister.waitForQueueEmpty();
- final File[] files = new File[] { new File(sFilesDir.getPath() + "/snapshots/1.proto"),
- new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg")};
+ final File[] files = new File[] { new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg")};
final File[] nonExistsFiles = new File[] {
- new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
+ new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
};
assertTrueForFiles(files, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
@@ -195,8 +195,8 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
TaskSnapshot b = new TaskSnapshotBuilder()
.setWindowingMode(WINDOWING_MODE_PINNED)
.build();
- assertTrue(a.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
- assertTrue(b.getWindowingMode() == WINDOWING_MODE_PINNED);
+ assertEquals(WINDOWING_MODE_FULLSCREEN, a.getWindowingMode());
+ assertEquals(WINDOWING_MODE_PINNED, b.getWindowingMode());
mPersister.persistSnapshot(1, mTestUserId, a);
mPersister.persistSnapshot(2, mTestUserId, b);
mPersister.waitForQueueEmpty();
@@ -204,8 +204,8 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
assertNotNull(snapshotA);
assertNotNull(snapshotB);
- assertTrue(snapshotA.getWindowingMode() == WINDOWING_MODE_FULLSCREEN);
- assertTrue(snapshotB.getWindowingMode() == WINDOWING_MODE_PINNED);
+ assertEquals(WINDOWING_MODE_FULLSCREEN, snapshotA.getWindowingMode());
+ assertEquals(WINDOWING_MODE_PINNED, snapshotB.getWindowingMode());
}
@Test
@@ -239,8 +239,8 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
TaskSnapshot b = new TaskSnapshotBuilder()
.setSystemUiVisibility(lightBarFlags)
.build();
- assertTrue(a.getSystemUiVisibility() == 0);
- assertTrue(b.getSystemUiVisibility() == lightBarFlags);
+ assertEquals(0, a.getSystemUiVisibility());
+ assertEquals(lightBarFlags, b.getSystemUiVisibility());
mPersister.persistSnapshot(1, mTestUserId, a);
mPersister.persistSnapshot(2, mTestUserId, b);
mPersister.waitForQueueEmpty();
@@ -248,8 +248,8 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
final TaskSnapshot snapshotB = mLoader.loadTask(2, mTestUserId, false /* reduced */);
assertNotNull(snapshotA);
assertNotNull(snapshotB);
- assertTrue(snapshotA.getSystemUiVisibility() == 0);
- assertTrue(snapshotB.getSystemUiVisibility() == lightBarFlags);
+ assertEquals(0, snapshotA.getSystemUiVisibility());
+ assertEquals(lightBarFlags, snapshotB.getSystemUiVisibility());
}
@Test
@@ -261,13 +261,13 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
mPersister.removeObsoleteFiles(taskIds, new int[] { mTestUserId });
mPersister.waitForQueueEmpty();
final File[] existsFiles = new File[] {
- new File(sFilesDir.getPath() + "/snapshots/1.proto"),
- new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
- new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg") };
+ new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
+ new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg") };
final File[] nonExistsFiles = new File[] {
- new File(sFilesDir.getPath() + "/snapshots/2.proto"),
- new File(sFilesDir.getPath() + "/snapshots/2.jpg"),
- new File(sFilesDir.getPath() + "/snapshots/2_reduced.jpg")};
+ new File(FILES_DIR.getPath() + "/snapshots/2.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/2.jpg"),
+ new File(FILES_DIR.getPath() + "/snapshots/2_reduced.jpg")};
assertTrueForFiles(existsFiles, File::exists, " must exist");
assertTrueForFiles(nonExistsFiles, file -> !file.exists(), " must not exist");
}
@@ -281,24 +281,12 @@ public class TaskSnapshotPersisterLoaderTest extends TaskSnapshotPersisterTestBa
mPersister.persistSnapshot(2, mTestUserId, createSnapshot());
mPersister.waitForQueueEmpty();
final File[] existsFiles = new File[] {
- new File(sFilesDir.getPath() + "/snapshots/1.proto"),
- new File(sFilesDir.getPath() + "/snapshots/1.jpg"),
- new File(sFilesDir.getPath() + "/snapshots/1_reduced.jpg"),
- new File(sFilesDir.getPath() + "/snapshots/2.proto"),
- new File(sFilesDir.getPath() + "/snapshots/2.jpg"),
- new File(sFilesDir.getPath() + "/snapshots/2_reduced.jpg")};
+ new File(FILES_DIR.getPath() + "/snapshots/1.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/1.jpg"),
+ new File(FILES_DIR.getPath() + "/snapshots/1_reduced.jpg"),
+ new File(FILES_DIR.getPath() + "/snapshots/2.proto"),
+ new File(FILES_DIR.getPath() + "/snapshots/2.jpg"),
+ new File(FILES_DIR.getPath() + "/snapshots/2_reduced.jpg")};
assertTrueForFiles(existsFiles, File::exists, " must exist");
}
-
- /**
- * Private predicate definition.
- *
- * This is needed because com.android.internal.util.Predicate is deprecated
- * and can only be used with classes fron android.test.runner. This cannot
- * use java.util.function.Predicate because that is not present on all API
- * versions that this test must run on.
- */
- private interface Predicate<T> {
- boolean apply(T t);
- }
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
index 33b137ef33e2..0f9b82586e0e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotPersisterTestBase.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -21,6 +21,8 @@ import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.graphics.GraphicBuffer.USAGE_HW_TEXTURE;
import static android.graphics.GraphicBuffer.USAGE_SW_READ_RARELY;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import android.app.ActivityManager.TaskSnapshot;
import android.graphics.Canvas;
import android.graphics.Color;
@@ -31,51 +33,37 @@ import android.os.UserManager;
import org.junit.After;
import org.junit.Before;
-import org.junit.BeforeClass;
import java.io.File;
-import androidx.test.InstrumentationRegistry;
-
/**
* Base class for tests that use a {@link TaskSnapshotPersister}.
*/
class TaskSnapshotPersisterTestBase extends WindowTestsBase {
private static final Rect TEST_INSETS = new Rect(10, 20, 30, 40);
+ static final File FILES_DIR = getInstrumentation().getTargetContext().getFilesDir();
TaskSnapshotPersister mPersister;
TaskSnapshotLoader mLoader;
int mTestUserId;
- static File sFilesDir;
-
- @BeforeClass
- public static void setUpUser() {
- sFilesDir = InstrumentationRegistry.getContext().getFilesDir();
- }
- @Override
@Before
- public void setUp() throws Exception {
- super.setUp();
-
- final UserManager um = UserManager.get(InstrumentationRegistry.getContext());
+ public void setUp() {
+ final UserManager um = UserManager.get(getInstrumentation().getTargetContext());
mTestUserId = um.getUserHandle();
- mPersister = new TaskSnapshotPersister(userId -> sFilesDir);
+ mPersister = new TaskSnapshotPersister(userId -> FILES_DIR);
mLoader = new TaskSnapshotLoader(mPersister);
mPersister.start();
}
- @Override
@After
- public void tearDown() throws Exception {
+ public void tearDown() {
cleanDirectory();
-
- super.tearDown();
}
private void cleanDirectory() {
- final File[] files = new File(sFilesDir, "snapshots").listFiles();
+ final File[] files = new File(FILES_DIR, "snapshots").listFiles();
if (files == null) {
return;
}
@@ -99,7 +87,7 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
/**
* Builds a TaskSnapshot.
*/
- class TaskSnapshotBuilder {
+ static class TaskSnapshotBuilder {
private float mScale = 1f;
private boolean mIsRealSnapshot = true;
@@ -107,32 +95,32 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
private int mWindowingMode = WINDOWING_MODE_FULLSCREEN;
private int mSystemUiVisibility = 0;
- public TaskSnapshotBuilder setScale(float scale) {
+ TaskSnapshotBuilder setScale(float scale) {
mScale = scale;
return this;
}
- public TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) {
+ TaskSnapshotBuilder setIsRealSnapshot(boolean isRealSnapshot) {
mIsRealSnapshot = isRealSnapshot;
return this;
}
- public TaskSnapshotBuilder setIsTranslucent(boolean isTranslucent) {
+ TaskSnapshotBuilder setIsTranslucent(boolean isTranslucent) {
mIsTranslucent = isTranslucent;
return this;
}
- public TaskSnapshotBuilder setWindowingMode(int windowingMode) {
+ TaskSnapshotBuilder setWindowingMode(int windowingMode) {
mWindowingMode = windowingMode;
return this;
}
- public TaskSnapshotBuilder setSystemUiVisibility(int systemUiVisibility) {
+ TaskSnapshotBuilder setSystemUiVisibility(int systemUiVisibility) {
mSystemUiVisibility = systemUiVisibility;
return this;
}
- public TaskSnapshot build() {
+ TaskSnapshot build() {
final GraphicBuffer buffer = GraphicBuffer.create(100, 100, PixelFormat.RGBA_8888,
USAGE_HW_TEXTURE | USAGE_SW_READ_RARELY | USAGE_SW_READ_RARELY);
Canvas c = buffer.lockCanvas();
@@ -142,6 +130,5 @@ class TaskSnapshotPersisterTestBase extends WindowTestsBase {
mScale < 1f /* reducedResolution */, mScale, mIsRealSnapshot, mWindowingMode,
mSystemUiVisibility, mIsTranslucent);
}
-
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
index 91074b9db081..7c16191efec4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskSnapshotSurfaceTest.java
@@ -39,21 +39,19 @@ import android.platform.test.annotations.Presubmit;
import android.view.Surface;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.TaskSnapshotSurface.Window;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link TaskSnapshotSurface}.
*
- * runtest frameworks-services -c com.android.server.wm.TaskSnapshotSurfaceTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:TaskSnapshotSurfaceTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class TaskSnapshotSurfaceTest extends WindowTestsBase {
private TaskSnapshotSurface mSurface;
@@ -65,7 +63,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
final TaskSnapshot snapshot = new TaskSnapshot(buffer,
ORIENTATION_PORTRAIT, contentInsets, false, 1.0f, true /* isRealSnapshot */,
WINDOWING_MODE_FULLSCREEN, 0 /* systemUiVisibility */, false /* isTranslucent */);
- mSurface = new TaskSnapshotSurface(sWm, new Window(), new Surface(), snapshot, "Test",
+ mSurface = new TaskSnapshotSurface(mWm, new Window(), new Surface(), snapshot, "Test",
Color.WHITE, Color.RED, Color.BLUE, sysuiVis, windowFlags, 0, taskBounds,
ORIENTATION_PORTRAIT);
}
@@ -76,7 +74,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
}
@Test
- public void fillEmptyBackground_fillHorizontally() throws Exception {
+ public void fillEmptyBackground_fillHorizontally() {
setupSurface(200, 100);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(200);
@@ -86,7 +84,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
}
@Test
- public void fillEmptyBackground_fillVertically() throws Exception {
+ public void fillEmptyBackground_fillVertically() {
setupSurface(100, 200);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
@@ -96,7 +94,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
}
@Test
- public void fillEmptyBackground_fillBoth() throws Exception {
+ public void fillEmptyBackground_fillBoth() {
setupSurface(200, 200);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(200);
@@ -107,7 +105,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
}
@Test
- public void fillEmptyBackground_dontFill_sameSize() throws Exception {
+ public void fillEmptyBackground_dontFill_sameSize() {
setupSurface(100, 100);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
@@ -117,7 +115,7 @@ public class TaskSnapshotSurfaceTest extends WindowTestsBase {
}
@Test
- public void fillEmptyBackground_dontFill_bitmapLarger() throws Exception {
+ public void fillEmptyBackground_dontFill_bitmapLarger() {
setupSurface(100, 100);
final Canvas mockCanvas = mock(Canvas.class);
when(mockCanvas.getWidth()).thenReturn(100);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
index 0e9a63ce728b..f01e9f0662c9 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackContainersTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -27,17 +27,17 @@ import static org.junit.Assert.assertTrue;
import android.platform.test.annotations.Presubmit;
+import androidx.test.filters.SmallTest;
+
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
-import androidx.test.filters.SmallTest;
-
/**
* Tests for the {@link DisplayContent.TaskStackContainers} container in {@link DisplayContent}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.TaskStackContainersTests
+ * atest FrameworksServicesTests:TaskStackContainersTests
*/
@SmallTest
@Presubmit
@@ -45,11 +45,8 @@ public class TaskStackContainersTests extends WindowTestsBase {
private TaskStack mPinnedStack;
- @Override
@Before
public void setUp() throws Exception {
- super.setUp();
-
mPinnedStack = createStackControllerOnStackOnDisplay(
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, mDisplayContent).mContainer;
// Stack should contain visible app window to be considered visible.
@@ -61,12 +58,9 @@ public class TaskStackContainersTests extends WindowTestsBase {
assertTrue(mPinnedStack.isVisible());
}
- @Override
@After
public void tearDown() throws Exception {
mPinnedStack.removeImmediately();
-
- super.tearDown();
}
@Test
@@ -121,14 +115,14 @@ public class TaskStackContainersTests extends WindowTestsBase {
final Task task = createTaskInStack(stack, 0 /* userId */);
// Add another display at top.
- sWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(),
+ mWm.mRoot.positionChildAt(WindowContainer.POSITION_TOP, createNewDisplay(),
false /* includingParents */);
// Move the task of {@code mDisplayContent} to top.
stack.positionChildAt(WindowContainer.POSITION_TOP, task, true /* includingParents */);
- final int indexOfDisplayWithPinnedStack = sWm.mRoot.mChildren.indexOf(mDisplayContent);
+ final int indexOfDisplayWithPinnedStack = mWm.mRoot.mChildren.indexOf(mDisplayContent);
assertEquals("The testing DisplayContent should be moved to top with task",
- sWm.mRoot.getChildCount() - 1, indexOfDisplayWithPinnedStack);
+ mWm.mRoot.getChildCount() - 1, indexOfDisplayWithPinnedStack);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
index cb5c1cd67092..7ac331829fb1 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskStackTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -25,24 +25,21 @@ import static org.junit.Assert.assertNull;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Tests for the {@link TaskStack} class.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.wm.TaskStackTests
+ * atest FrameworksServicesTests:TaskStackTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class TaskStackTests extends WindowTestsBase {
@Test
- public void testStackPositionChildAt() throws Exception {
+ public void testStackPositionChildAt() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task1 = createTaskInStack(stack, 0 /* userId */);
final Task task2 = createTaskInStack(stack, 1 /* userId */);
@@ -59,7 +56,7 @@ public class TaskStackTests extends WindowTestsBase {
}
@Test
- public void testClosingAppDifferentStackOrientation() throws Exception {
+ public void testClosingAppDifferentStackOrientation() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task1 = createTaskInStack(stack, 0 /* userId */);
WindowTestUtils.TestAppWindowToken appWindowToken1 =
@@ -79,7 +76,7 @@ public class TaskStackTests extends WindowTestsBase {
}
@Test
- public void testMoveTaskToBackDifferentStackOrientation() throws Exception {
+ public void testMoveTaskToBackDifferentStackOrientation() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task1 = createTaskInStack(stack, 0 /* userId */);
WindowTestUtils.TestAppWindowToken appWindowToken1 =
@@ -99,7 +96,7 @@ public class TaskStackTests extends WindowTestsBase {
}
@Test
- public void testStackRemoveImmediately() throws Exception {
+ public void testStackRemoveImmediately() {
final TaskStack stack = createTaskStackOnDisplay(mDisplayContent);
final Task task = createTaskInStack(stack, 0 /* userId */);
assertEquals(stack, task.mStack);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
index edd76647f4a8..1af79e41fe37 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TaskWindowContainerControllerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -24,24 +24,21 @@ import static org.junit.Assert.assertTrue;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link TaskWindowContainerController}.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.wm.TaskWindowContainerControllerTests
+ * atest FrameworksServicesTests:TaskWindowContainerControllerTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class TaskWindowContainerControllerTests extends WindowTestsBase {
@Test
- public void testRemoveContainer() throws Exception {
+ public void testRemoveContainer() {
final WindowTestUtils.TestTaskWindowContainerController taskController =
new WindowTestUtils.TestTaskWindowContainerController(this);
final WindowTestUtils.TestAppWindowContainerController appController =
@@ -54,7 +51,7 @@ public class TaskWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testRemoveContainer_deferRemoval() throws Exception {
+ public void testRemoveContainer_deferRemoval() {
final WindowTestUtils.TestTaskWindowContainerController taskController =
new WindowTestUtils.TestTaskWindowContainerController(this);
final WindowTestUtils.TestAppWindowContainerController appController =
@@ -79,7 +76,7 @@ public class TaskWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testReparent() throws Exception {
+ public void testReparent() {
final StackWindowController stackController1 =
createStackControllerOnDisplay(mDisplayContent);
final WindowTestUtils.TestTaskWindowContainerController taskController =
@@ -116,7 +113,7 @@ public class TaskWindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testReparent_BetweenDisplays() throws Exception {
+ public void testReparent_BetweenDisplays() {
// Create first stack on primary display.
final StackWindowController stack1Controller =
createStackControllerOnDisplay(mDisplayContent);
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
index 353aa7deb534..e8d0a066dade 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestIWindow.java
@@ -11,13 +11,11 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
-import com.android.internal.os.IResultReceiver;
-
import android.graphics.Rect;
import android.os.Bundle;
import android.os.ParcelFileDescriptor;
@@ -27,87 +25,71 @@ import android.view.DisplayCutout;
import android.view.DragEvent;
import android.view.IWindow;
+import com.android.internal.os.IResultReceiver;
+
public class TestIWindow extends IWindow.Stub {
@Override
public void executeCommand(String command, String parameters,
- ParcelFileDescriptor descriptor)
- throws RemoteException {
-
+ ParcelFileDescriptor descriptor) throws RemoteException {
}
@Override
public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
Rect stableInsets, Rect outsets, boolean reportDraw, MergedConfiguration mergedConfig,
Rect backDropFrame, boolean forceLayout, boolean alwaysConsumeNavBar, int displayId,
- DisplayCutout.ParcelableWrapper displayCutout)
- throws RemoteException {
-
+ DisplayCutout.ParcelableWrapper displayCutout) throws RemoteException {
}
@Override
public void moved(int newX, int newY) throws RemoteException {
-
}
@Override
public void dispatchAppVisibility(boolean visible) throws RemoteException {
-
}
@Override
public void dispatchGetNewSurface() throws RemoteException {
-
}
@Override
- public void windowFocusChanged(boolean hasFocus, boolean inTouchMode)
- throws RemoteException {
-
+ public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) throws RemoteException {
}
@Override
public void closeSystemDialogs(String reason) throws RemoteException {
-
}
@Override
- public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep,
- boolean sync)
+ public void dispatchWallpaperOffsets(float x, float y, float xStep, float yStep, boolean sync)
throws RemoteException {
-
}
@Override
public void dispatchWallpaperCommand(String action, int x, int y, int z, Bundle extras,
boolean sync) throws RemoteException {
-
}
@Override
public void dispatchDragEvent(DragEvent event) throws RemoteException {
-
}
@Override
public void updatePointerIcon(float x, float y) throws RemoteException {
-
}
@Override
public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility, int localValue,
int localChanges) throws RemoteException {
-
}
@Override
public void dispatchWindowShown() throws RemoteException {
-
}
@Override
public void requestAppKeyboardShortcuts(IResultReceiver receiver, int deviceId)
throws RemoteException {
-
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 19abd9e8dac9..0165e7d4e84b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/servicestests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -46,8 +46,6 @@ import java.io.PrintWriter;
import java.util.function.Supplier;
class TestWindowManagerPolicy implements WindowManagerPolicy {
- private static final String TAG = "TestWindowManagerPolicy";
-
private final Supplier<WindowManagerService> mWmSupplier;
int rotationToReport = 0;
@@ -55,21 +53,18 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
private Runnable mRunnableWhenAddingSplashScreen;
- public TestWindowManagerPolicy(Supplier<WindowManagerService> wmSupplier) {
-
+ TestWindowManagerPolicy(Supplier<WindowManagerService> wmSupplier) {
mWmSupplier = wmSupplier;
}
@Override
public void registerShortcutKey(long shortcutCode, IShortcutService shortcutKeyReceiver)
throws RemoteException {
-
}
@Override
public void init(Context context, IWindowManager windowManager,
WindowManagerFuncs windowManagerFuncs) {
-
}
public void setDefaultDisplay(DisplayContentInfo displayContentInfo) {
@@ -93,7 +88,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void adjustConfigurationLw(Configuration config, int keyboardPresence,
int navigationPresence) {
-
}
@Override
@@ -179,7 +173,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void removeWindowLw(WindowState win) {
-
}
@Override
@@ -189,7 +182,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void selectRotationAnimationLw(int[] anim) {
-
}
@Override
@@ -220,14 +212,12 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
}
@Override
- public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event,
- int policyFlags) {
+ public long interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) {
return 0;
}
@Override
- public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event,
- int policyFlags) {
+ public KeyEvent dispatchUnhandledKey(WindowState win, KeyEvent event, int policyFlags) {
return null;
}
@@ -238,12 +228,11 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) {
-
}
@Override
- public void applyPostLayoutPolicyLw(WindowState win,
- WindowManager.LayoutParams attrs, WindowState attached, WindowState imeTarget) {
+ public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
+ WindowState attached, WindowState imeTarget) {
}
@Override
@@ -257,49 +246,40 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
}
@Override
- public int focusChangedLw(WindowState lastFocus,
- WindowState newFocus) {
+ public int focusChangedLw(WindowState lastFocus, WindowState newFocus) {
return 0;
}
@Override
public void startedWakingUp() {
-
}
@Override
public void finishedWakingUp() {
-
}
@Override
public void startedGoingToSleep(int why) {
-
}
@Override
public void finishedGoingToSleep(int why) {
-
}
@Override
public void screenTurningOn(ScreenOnListener screenOnListener) {
-
}
@Override
public void screenTurnedOn() {
-
}
@Override
public void screenTurningOff(ScreenOffListener screenOffListener) {
-
}
@Override
public void screenTurnedOff() {
-
}
@Override
@@ -314,22 +294,18 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void notifyLidSwitchChanged(long whenNanos, boolean lidOpen) {
-
}
@Override
public void notifyCameraLensCoverSwitchChanged(long whenNanos, boolean lensCovered) {
-
}
@Override
public void enableKeyguard(boolean enabled) {
-
}
@Override
public void exitKeyguardSecurely(OnKeyguardExitResult callback) {
-
}
@Override
@@ -382,53 +358,44 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
}
public void setSafeMode(boolean safeMode) {
-
}
@Override
public void systemReady() {
-
}
@Override
public void systemBooted() {
-
}
@Override
public void showBootMessage(CharSequence msg, boolean always) {
-
}
@Override
public void hideBootMessages() {
-
}
@Override
public void userActivity() {
-
}
@Override
public void enableScreenAfterBoot() {
-
}
@Override
- public boolean performHapticFeedbackLw(WindowState win, int effectId,
- boolean always, String reason) {
+ public boolean performHapticFeedbackLw(WindowState win, int effectId, boolean always,
+ String reason) {
return false;
}
@Override
public void keepScreenOnStartedLw() {
-
}
@Override
public void keepScreenOnStoppedLw() {
-
}
@Override
@@ -443,37 +410,30 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void lockNow(Bundle options) {
-
}
@Override
public void showRecentApps() {
-
}
@Override
public void showGlobalActions() {
-
}
@Override
public void setCurrentUserLw(int newUserId) {
-
}
@Override
public void setSwitchingUser(boolean switching) {
-
}
@Override
public void writeToProto(ProtoOutputStream proto, long fieldId) {
-
}
@Override
public void dump(String prefix, PrintWriter writer, String[] args) {
-
}
@Override
@@ -483,13 +443,11 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void startKeyguardExitAnimation(long startTime, long fadeoutDuration) {
-
}
@Override
public void getStableInsetsLw(int displayRotation, int displayWidth, int displayHeight,
DisplayCutout cutout, Rect outInsets) {
-
}
@Override
@@ -506,7 +464,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void getNonDecorInsetsLw(int displayRotation, int displayWidth, int displayHeight,
DisplayCutout cutout, Rect outInsets) {
-
}
@Override
@@ -517,7 +474,6 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void onConfigurationChanged(DisplayContentInfo displayContentInfo) {
-
}
@Override
@@ -528,12 +484,10 @@ class TestWindowManagerPolicy implements WindowManagerPolicy {
@Override
public void setPipVisibilityLw(boolean visible) {
-
}
@Override
public void setRecentsVisibilityLw(boolean visible) {
-
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
index 54456fbd6f3b..9e22c0a86d96 100644
--- a/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/UnknownAppVisibilityControllerTest.java
@@ -11,52 +11,50 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
import static junit.framework.Assert.assertTrue;
+import android.os.SystemClock;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Test class for {@link AppTransition}.
*
- * runtest frameworks-services -c com.android.server.wm.UnknownAppVisibilityControllerTest
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:UnknownAppVisibilityControllerTest
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
mDisplayContent.mUnknownAppVisibilityController.clear();
}
@Test
- public void testFlow() throws Exception {
+ public void testFlow() {
final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token);
mDisplayContent.mUnknownAppVisibilityController.notifyAppResumedFinished(token);
mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token);
// Make sure our handler processed the message.
- Thread.sleep(100);
+ SystemClock.sleep(100);
assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
@Test
- public void testMultiple() throws Exception {
+ public void testMultiple() {
final AppWindowToken token1 = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
final AppWindowToken token2 = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token1);
@@ -67,12 +65,12 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
mDisplayContent.mUnknownAppVisibilityController.notifyRelayouted(token2);
// Make sure our handler processed the message.
- Thread.sleep(100);
+ SystemClock.sleep(100);
assertTrue(mDisplayContent.mUnknownAppVisibilityController.allResolved());
}
@Test
- public void testClear() throws Exception {
+ public void testClear() {
final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token);
mDisplayContent.mUnknownAppVisibilityController.clear();;
@@ -80,7 +78,7 @@ public class UnknownAppVisibilityControllerTest extends WindowTestsBase {
}
@Test
- public void testAppRemoved() throws Exception {
+ public void testAppRemoved() {
final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
mDisplayContent.mUnknownAppVisibilityController.notifyLaunched(token);
mDisplayContent.mUnknownAppVisibilityController.appRemovedOrHidden(token);
diff --git a/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java
index e3280ca3c9f0..25e73e3740c5 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WallpaperControllerTests.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
@@ -13,33 +29,30 @@ import android.os.IBinder;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Tests for the {@link WallpaperController} class.
*
* Build/Install/Run:
- * atest com.android.server.wm.WallpaperControllerTests
+ * atest FrameworksServicesTests:WallpaperControllerTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class WallpaperControllerTests extends WindowTestsBase {
@Test
public void testWallpaperScreenshot() {
WindowSurfaceController windowSurfaceController = mock(WindowSurfaceController.class);
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
// No wallpaper
final DisplayContent dc = createNewDisplay();
- Bitmap wallpaperBitmap = sWm.mRoot.mWallpaperController.screenshotWallpaperLocked();
+ Bitmap wallpaperBitmap = mWm.mRoot.mWallpaperController.screenshotWallpaperLocked();
assertNull(wallpaperBitmap);
// No wallpaper WSA Surface
- WindowToken wallpaperWindowToken = new WallpaperWindowToken(sWm, mock(IBinder.class),
+ WindowToken wallpaperWindowToken = new WallpaperWindowToken(mWm, mock(IBinder.class),
true, dc, true /* ownerCanManageAppTokens */);
WindowState wallpaperWindow = createWindow(null /* parent */, TYPE_WALLPAPER,
wallpaperWindowToken, "wallpaperWindow");
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
index e7cc2859ff62..4369c96dd488 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowConfigurationTests.java
@@ -36,26 +36,24 @@ import android.view.DisplayInfo;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
+import org.junit.Before;
import org.junit.Test;
/**
* Test class to for {@link android.app.WindowConfiguration}.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.wm.WindowConfigurationTests
+ * atest FrameworksServicesTests:WindowConfigurationTests
*/
-@SmallTest
@FlakyTest(bugId = 74078662)
+@SmallTest
@Presubmit
-@org.junit.runner.RunWith(AndroidJUnit4.class)
public class WindowConfigurationTests extends WindowTestsBase {
private Rect mParentBounds;
- @Override
+ @Before
public void setUp() throws Exception {
- super.setUp();
mParentBounds = new Rect(10 /*left*/, 30 /*top*/, 80 /*right*/, 60 /*bottom*/);
}
@@ -95,7 +93,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
/** Tests {@link android.app.WindowConfiguration#compareTo(WindowConfiguration)}. */
@Test
- public void testConfigurationCompareTo() throws Exception {
+ public void testConfigurationCompareTo() {
final Configuration blankConfig = new Configuration();
final WindowConfiguration blankWinConfig = new WindowConfiguration();
@@ -135,7 +133,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
}
@Test
- public void testSetActivityType() throws Exception {
+ public void testSetActivityType() {
final WindowConfiguration config = new WindowConfiguration();
config.setActivityType(ACTIVITY_TYPE_HOME);
assertEquals(ACTIVITY_TYPE_HOME, config.getActivityType());
@@ -147,12 +145,12 @@ public class WindowConfigurationTests extends WindowTestsBase {
/** Ensures the configuration app bounds at the root level match the app dimensions. */
@Test
- public void testAppBounds_RootConfigurationBounds() throws Exception {
+ public void testAppBounds_RootConfigurationBounds() {
final DisplayInfo info = mDisplayContent.getDisplayInfo();
info.appWidth = 1024;
info.appHeight = 768;
- final Rect appBounds = sWm.computeNewConfiguration(
+ final Rect appBounds = mWm.computeNewConfiguration(
mDisplayContent.getDisplayId()).windowConfiguration.getAppBounds();
// The bounds should always be positioned in the top left.
assertEquals(appBounds.left, 0);
@@ -165,7 +163,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
/** Ensures that bounds are clipped to their parent. */
@Test
- public void testAppBounds_BoundsClipping() throws Exception {
+ public void testAppBounds_BoundsClipping() {
final Rect shiftedBounds = new Rect(mParentBounds);
shiftedBounds.offset(10, 10);
final Rect expectedBounds = new Rect(mParentBounds);
@@ -176,7 +174,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
/** Ensures that empty bounds are not propagated to the configuration. */
@Test
- public void testAppBounds_EmptyBounds() throws Exception {
+ public void testAppBounds_EmptyBounds() {
final Rect emptyBounds = new Rect();
testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, emptyBounds,
null /*ExpectedBounds*/);
@@ -184,7 +182,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
/** Ensures that bounds on freeform stacks are not clipped. */
@Test
- public void testAppBounds_FreeFormBounds() throws Exception {
+ public void testAppBounds_FreeFormBounds() {
final Rect freeFormBounds = new Rect(mParentBounds);
freeFormBounds.offset(10, 10);
testStackBoundsConfiguration(WINDOWING_MODE_FREEFORM, mParentBounds, freeFormBounds,
@@ -193,7 +191,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
/** Ensures that fully contained bounds are not clipped. */
@Test
- public void testAppBounds_ContainedBounds() throws Exception {
+ public void testAppBounds_ContainedBounds() {
final Rect insetBounds = new Rect(mParentBounds);
insetBounds.inset(5, 5, 5, 5);
testStackBoundsConfiguration(
@@ -202,7 +200,7 @@ public class WindowConfigurationTests extends WindowTestsBase {
/** Ensures that full screen free form bounds are clipped */
@Test
- public void testAppBounds_FullScreenFreeFormBounds() throws Exception {
+ public void testAppBounds_FullScreenFreeFormBounds() {
final Rect fullScreenBounds = new Rect(0, 0, mDisplayInfo.logicalWidth,
mDisplayInfo.logicalHeight);
testStackBoundsConfiguration(WINDOWING_MODE_FULLSCREEN, mParentBounds, fullScreenBounds,
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
index 6b1feb87aa42..7592f1c1fca0 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerControllerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -28,7 +28,6 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
@@ -36,18 +35,17 @@ import org.junit.Test;
* Test class for {@link WindowContainerController}.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.wm.WindowContainerControllerTests
+ * atest FrameworksServicesTests:WindowContainerControllerTests
*/
+@FlakyTest(bugId = 74078662)
@SmallTest
@Presubmit
-@FlakyTest(bugId = 74078662)
-@org.junit.runner.RunWith(AndroidJUnit4.class)
public class WindowContainerControllerTests extends WindowTestsBase {
@Test
- public void testCreation() throws Exception {
- final WindowContainerController controller = new WindowContainerController(null, sWm);
- final WindowContainer container = new WindowContainer(sWm);
+ public void testCreation() {
+ final WindowContainerController controller = new WindowContainerController<>(null, mWm);
+ final WindowContainer container = new WindowContainer(mWm);
container.setController(controller);
assertEquals(controller, container.getController());
@@ -55,9 +53,9 @@ public class WindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testSetContainer() throws Exception {
- final WindowContainerController controller = new WindowContainerController(null, sWm);
- final WindowContainer container = new WindowContainer(sWm);
+ public void testSetContainer() {
+ final WindowContainerController controller = new WindowContainerController<>(null, mWm);
+ final WindowContainer container = new WindowContainer(mWm);
controller.setContainer(container);
assertEquals(controller.mContainer, container);
@@ -65,7 +63,7 @@ public class WindowContainerControllerTests extends WindowTestsBase {
// Assert we can't change the container to another one once set
boolean gotException = false;
try {
- controller.setContainer(new WindowContainer(sWm));
+ controller.setContainer(new WindowContainer(mWm));
} catch (IllegalArgumentException e) {
gotException = true;
}
@@ -77,9 +75,9 @@ public class WindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testRemoveContainer() throws Exception {
- final WindowContainerController controller = new WindowContainerController(null, sWm);
- final WindowContainer container = new WindowContainer(sWm);
+ public void testRemoveContainer() {
+ final WindowContainerController controller = new WindowContainerController<>(null, mWm);
+ final WindowContainer container = new WindowContainer(mWm);
controller.setContainer(container);
assertEquals(controller.mContainer, container);
@@ -89,9 +87,9 @@ public class WindowContainerControllerTests extends WindowTestsBase {
}
@Test
- public void testOnOverrideConfigurationChanged() throws Exception {
- final WindowContainerController controller = new WindowContainerController(null, sWm);
- final WindowContainer container = new WindowContainer(sWm);
+ public void testOnOverrideConfigurationChanged() {
+ final WindowContainerController controller = new WindowContainerController<>(null, mWm);
+ final WindowContainer container = new WindowContainer(mWm);
controller.setContainer(container);
assertEquals(controller.mContainer, container);
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
index dc763b9bb079..e59afd656420 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -46,10 +46,8 @@ import android.view.SurfaceSession;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.util.Comparator;
@@ -57,24 +55,23 @@ import java.util.Comparator;
* Test class for {@link WindowContainer}.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.WindowContainerTests
+ * atest FrameworksServicesTests:WindowContainerTests
*/
@SmallTest
@Presubmit
@FlakyTest(bugId = 74078662)
-@RunWith(AndroidJUnit4.class)
public class WindowContainerTests extends WindowTestsBase {
@Test
- public void testCreation() throws Exception {
- final TestWindowContainer w = new TestWindowContainerBuilder().setLayer(0).build();
+ public void testCreation() {
+ final TestWindowContainer w = new TestWindowContainerBuilder(mWm).setLayer(0).build();
assertNull("window must have no parent", w.getParentWindow());
assertEquals("window must have no children", 0, w.getChildrenCount());
}
@Test
- public void testAdd() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testAdd() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer layer1 = root.addChildWindow(builder.setLayer(1));
@@ -113,23 +110,24 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testAddChildSetsSurfacePosition() throws Exception {
- MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer();
+ public void testAddChildSetsSurfacePosition() {
+ try (MockSurfaceBuildingContainer top = new MockSurfaceBuildingContainer(mWm)) {
- final SurfaceControl.Transaction transaction = mock(SurfaceControl.Transaction.class);
- sWm.mTransactionFactory = () -> transaction;
+ final SurfaceControl.Transaction transaction = mock(SurfaceControl.Transaction.class);
+ mWm.mTransactionFactory = () -> transaction;
- WindowContainer child = new WindowContainer(sWm);
- child.setBounds(1, 1, 10, 10);
+ WindowContainer child = new WindowContainer(mWm);
+ child.setBounds(1, 1, 10, 10);
- verify(transaction, never()).setPosition(any(), anyFloat(), anyFloat());
- top.addChild(child, 0);
- verify(transaction, times(1)).setPosition(any(), eq(1.f), eq(1.f));
+ verify(transaction, never()).setPosition(any(), anyFloat(), anyFloat());
+ top.addChild(child, 0);
+ verify(transaction, times(1)).setPosition(any(), eq(1.f), eq(1.f));
+ }
}
@Test
- public void testAdd_AlreadyHasParent() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testAdd_AlreadyHasParent() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -153,8 +151,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testHasChild() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testHasChild() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -183,8 +181,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testRemoveImmediately() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testRemoveImmediately() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -218,9 +216,9 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testRemoveImmediately_WithController() throws Exception {
- final WindowContainer container = new WindowContainer(sWm);
- final WindowContainerController controller = new WindowContainerController(null, sWm);
+ public void testRemoveImmediately_WithController() {
+ final WindowContainer container = new WindowContainer(mWm);
+ final WindowContainerController controller = new WindowContainerController<>(null, mWm);
container.setController(controller);
assertEquals(controller, container.getController());
@@ -232,9 +230,9 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testSetController() throws Exception {
- final WindowContainerController controller = new WindowContainerController(null, sWm);
- final WindowContainer container = new WindowContainer(sWm);
+ public void testSetController() {
+ final WindowContainerController controller = new WindowContainerController<>(null, mWm);
+ final WindowContainer container = new WindowContainer(mWm);
container.setController(controller);
assertEquals(controller, container.getController());
@@ -243,7 +241,7 @@ public class WindowContainerTests extends WindowTestsBase {
// Assert we can't change the controller to another one once set
boolean gotException = false;
try {
- container.setController(new WindowContainerController(null, sWm));
+ container.setController(new WindowContainerController<>(null, mWm));
} catch (IllegalArgumentException e) {
gotException = true;
}
@@ -256,8 +254,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testAddChildByIndex() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testAddChildByIndex() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child = root.addChildWindow();
@@ -283,8 +281,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testPositionChildAt() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testPositionChildAt() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -307,8 +305,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testPositionChildAtIncludeParents() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testPositionChildAtIncludeParents() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -349,12 +347,11 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testPositionChildAtInvalid() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testPositionChildAtInvalid() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
- final TestWindowContainer child2 = root.addChildWindow();
boolean gotException = false;
try {
@@ -376,8 +373,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testIsAnimating() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testIsAnimating() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow(builder.setIsAnimating(true));
@@ -402,8 +399,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testIsVisible() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testIsVisible() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow(builder.setIsVisible(true));
@@ -422,7 +419,7 @@ public class WindowContainerTests extends WindowTestsBase {
@Test
public void testOverrideConfigurationAncestorNotification() {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer grandparent = builder.setLayer(0).build();
final TestWindowContainer parent = grandparent.addChildWindow();
@@ -433,8 +430,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testRemoveChild() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testRemoveChild() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
final TestWindowContainer child2 = root.addChildWindow();
@@ -460,7 +457,7 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testGetOrientation_childSpecified() throws Exception {
+ public void testGetOrientation_childSpecified() {
testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_LANDSCAPE,
SCREEN_ORIENTATION_LANDSCAPE);
testGetOrientation_childSpecifiedConfig(false, SCREEN_ORIENTATION_UNSET,
@@ -469,7 +466,7 @@ public class WindowContainerTests extends WindowTestsBase {
private void testGetOrientation_childSpecifiedConfig(boolean childVisible, int childOrientation,
int expectedOrientation) {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
root.setFillsParent(true);
@@ -486,16 +483,16 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testGetOrientation_Unset() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testGetOrientation_Unset() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
// Unspecified well because we didn't specify anything...
assertEquals(SCREEN_ORIENTATION_UNSPECIFIED, root.getOrientation());
}
@Test
- public void testGetOrientation_InvisibleParentUnsetVisibleChildren() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testGetOrientation_InvisibleParentUnsetVisibleChildren() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
builder.setIsVisible(false).setLayer(-1);
@@ -516,12 +513,11 @@ public class WindowContainerTests extends WindowTestsBase {
visibleUnset.setOrientation(SCREEN_ORIENTATION_UNSET);
assertEquals(SCREEN_ORIENTATION_UNSET, visibleUnset.getOrientation());
assertEquals(SCREEN_ORIENTATION_LANDSCAPE, root.getOrientation());
-
}
@Test
- public void testGetOrientation_setBehind() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testGetOrientation_setBehind() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
builder.setIsVisible(true).setLayer(-1);
@@ -541,8 +537,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testGetOrientation_fillsParent() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testGetOrientation_fillsParent() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).setIsVisible(true).build();
builder.setIsVisible(true).setLayer(-1);
@@ -577,8 +573,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testCompareTo() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testCompareTo() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.setLayer(0).build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -588,8 +584,6 @@ public class WindowContainerTests extends WindowTestsBase {
final TestWindowContainer child2 = root.addChildWindow();
final TestWindowContainer child21 = child2.addChildWindow();
final TestWindowContainer child22 = child2.addChildWindow();
- final TestWindowContainer child23 = child2.addChildWindow();
- final TestWindowContainer child221 = child22.addChildWindow();
final TestWindowContainer child222 = child22.addChildWindow();
final TestWindowContainer child223 = child22.addChildWindow();
final TestWindowContainer child2221 = child222.addChildWindow();
@@ -620,8 +614,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testPrefixOrderIndex() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testPrefixOrderIndex() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -654,8 +648,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testPrefixOrder_addEntireSubtree() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testPrefixOrder_addEntireSubtree() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.build();
final TestWindowContainer subtree = builder.build();
final TestWindowContainer subtree2 = builder.build();
@@ -677,8 +671,8 @@ public class WindowContainerTests extends WindowTestsBase {
}
@Test
- public void testPrefixOrder_remove() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testPrefixOrder_remove() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.build();
final TestWindowContainer child1 = root.addChildWindow();
@@ -705,8 +699,8 @@ public class WindowContainerTests extends WindowTestsBase {
* is invoked with overridden bounds.
*/
@Test
- public void testOnParentResizePropagation() throws Exception {
- final TestWindowContainerBuilder builder = new TestWindowContainerBuilder();
+ public void testOnParentResizePropagation() {
+ final TestWindowContainerBuilder builder = new TestWindowContainerBuilder(mWm);
final TestWindowContainer root = builder.build();
final TestWindowContainer child = root.addChildWindow();
@@ -731,7 +725,7 @@ public class WindowContainerTests extends WindowTestsBase {
}
/* Used so we can gain access to some protected members of the {@link WindowContainer} class */
- private class TestWindowContainer extends WindowContainer<TestWindowContainer> {
+ private static class TestWindowContainer extends WindowContainer<TestWindowContainer> {
private final int mLayer;
private boolean mIsAnimating;
private boolean mIsVisible;
@@ -745,7 +739,7 @@ public class WindowContainerTests extends WindowTestsBase {
* Compares 2 window layers and returns -1 if the first is lesser than the second in terms
* of z-order and 1 otherwise.
*/
- private final Comparator<TestWindowContainer> mWindowSubLayerComparator = (w1, w2) -> {
+ private static final Comparator<TestWindowContainer> SUBLAYER_COMPARATOR = (w1, w2) -> {
final int layer1 = w1.mLayer;
final int layer2 = w2.mLayer;
if (layer1 < layer2 || (layer1 == layer2 && layer2 < 0 )) {
@@ -753,12 +747,14 @@ public class WindowContainerTests extends WindowTestsBase {
// the negative one should go below others; the positive one should go above others.
return -1;
}
+ if (layer1 == layer2) return 0;
return 1;
};
- TestWindowContainer(int layer, boolean isAnimating, boolean isVisible,
- Integer orientation) {
- super(sWm);
+ TestWindowContainer(WindowManagerService wm, int layer, boolean isAnimating,
+ boolean isVisible, Integer orientation) {
+ super(wm);
+
mLayer = layer;
mIsAnimating = isAnimating;
mIsVisible = isVisible;
@@ -775,18 +771,18 @@ public class WindowContainerTests extends WindowTestsBase {
}
TestWindowContainer addChildWindow(TestWindowContainer child) {
- addChild(child, mWindowSubLayerComparator);
+ addChild(child, SUBLAYER_COMPARATOR);
return child;
}
TestWindowContainer addChildWindow(TestWindowContainerBuilder childBuilder) {
TestWindowContainer child = childBuilder.build();
- addChild(child, mWindowSubLayerComparator);
+ addChild(child, SUBLAYER_COMPARATOR);
return child;
}
TestWindowContainer addChildWindow() {
- return addChildWindow(new TestWindowContainerBuilder().setLayer(1));
+ return addChildWindow(new TestWindowContainerBuilder(mService).setLayer(1));
}
@Override
@@ -830,14 +826,19 @@ public class WindowContainerTests extends WindowTestsBase {
}
}
- private class TestWindowContainerBuilder {
+ private static class TestWindowContainerBuilder {
+ private final WindowManagerService mWm;
private int mLayer;
private boolean mIsAnimating;
private boolean mIsVisible;
private Integer mOrientation;
- public TestWindowContainerBuilder() {
- reset();
+ TestWindowContainerBuilder(WindowManagerService wm) {
+ mWm = wm;
+ mLayer = 0;
+ mIsAnimating = false;
+ mIsVisible = false;
+ mOrientation = null;
}
TestWindowContainerBuilder setLayer(int layer) {
@@ -860,27 +861,20 @@ public class WindowContainerTests extends WindowTestsBase {
return this;
}
- TestWindowContainerBuilder reset() {
- mLayer = 0;
- mIsAnimating = false;
- mIsVisible = false;
- mOrientation = null;
- return this;
- }
-
TestWindowContainer build() {
- return new TestWindowContainer(mLayer, mIsAnimating, mIsVisible, mOrientation);
+ return new TestWindowContainer(mWm, mLayer, mIsAnimating, mIsVisible, mOrientation);
}
}
- private class MockSurfaceBuildingContainer extends WindowContainer<WindowContainer> {
- final SurfaceSession mSession = new SurfaceSession();
+ private static class MockSurfaceBuildingContainer extends WindowContainer<WindowContainer>
+ implements AutoCloseable {
+ private final SurfaceSession mSession = new SurfaceSession();
- MockSurfaceBuildingContainer() {
- super(sWm);
+ MockSurfaceBuildingContainer(WindowManagerService wm) {
+ super(wm);
}
- class MockSurfaceBuilder extends SurfaceControl.Builder {
+ static class MockSurfaceBuilder extends SurfaceControl.Builder {
MockSurfaceBuilder(SurfaceSession ss) {
super(ss);
}
@@ -895,5 +889,10 @@ public class WindowContainerTests extends WindowTestsBase {
SurfaceControl.Builder makeChildSurface(WindowContainer child) {
return new MockSurfaceBuilder(mSession);
}
+
+ @Override
+ public void close() {
+ mSession.kill();
+ }
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
index ffc86226cd39..2b8b93428701 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowContainerTraversalTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -28,23 +28,23 @@ import static org.mockito.Mockito.verify;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
import java.util.function.Consumer;
/**
* Tests for {@link WindowContainer#forAllWindows} and various implementations.
+ *
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:WindowContainerTraversalTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class WindowContainerTraversalTests extends WindowTestsBase {
@Test
- public void testDockedDividerPosition() throws Exception {
+ public void testDockedDividerPosition() {
final WindowState splitScreenWindow = createWindowOnStack(null,
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
mDisplayContent, "splitScreenWindow");
@@ -52,7 +52,7 @@ public class WindowContainerTraversalTests extends WindowTestsBase {
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
- sWm.mInputMethodTarget = splitScreenWindow;
+ mWm.mInputMethodTarget = splitScreenWindow;
Consumer<WindowState> c = mock(Consumer.class);
mDisplayContent.forAllWindows(c, false);
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
index 7cd131420049..b0c8d8bfee1b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowFrameTests.java
@@ -11,14 +11,14 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.DisplayCutout.fromBoundingRect;
-import static android.view.WindowManager.LayoutParams.FILL_PARENT;
+import static android.view.WindowManager.LayoutParams.MATCH_PARENT;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static org.junit.Assert.assertEquals;
@@ -33,33 +33,32 @@ import android.view.IWindow;
import android.view.WindowManager;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Before;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Tests for the {@link WindowState#computeFrameLw} method and other window frame machinery.
*
- * Build/Install/Run: bit FrameworksServicesTests:com.android.server.wm.WindowFrameTests
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:WindowFrameTests
*/
@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class WindowFrameTests extends WindowTestsBase {
private WindowToken mWindowToken;
private final IWindow mIWindow = new TestIWindow();
private final Rect mEmptyRect = new Rect();
- class WindowStateWithTask extends WindowState {
+ static class WindowStateWithTask extends WindowState {
final Task mTask;
boolean mDockedResizingForTest = false;
- WindowStateWithTask(WindowManager.LayoutParams attrs, Task t) {
- super(sWm, null, mIWindow, mWindowToken, null, 0, 0, attrs, 0, 0,
+ WindowStateWithTask(WindowManagerService wm, IWindow iWindow, WindowToken windowToken,
+ WindowManager.LayoutParams attrs, Task t) {
+ super(wm, null, iWindow, windowToken, null, 0, 0, attrs, 0, 0,
false /* ownerCanAddInternalSystemWindow */);
mTask = t;
}
@@ -73,14 +72,15 @@ public class WindowFrameTests extends WindowTestsBase {
boolean isDockedResizing() {
return mDockedResizingForTest;
}
- };
+ }
- class TaskWithBounds extends Task {
+ private static class TaskWithBounds extends Task {
final Rect mBounds;
final Rect mInsetBounds = new Rect();
boolean mFullscreenForTest = true;
- TaskWithBounds(Rect bounds) {
- super(0, mStubStack, 0, sWm, 0, false, new TaskDescription(), null);
+
+ TaskWithBounds(TaskStack stack, WindowManagerService wm, Rect bounds) {
+ super(0, stack, 0, wm, 0, false, new TaskDescription(), null);
mBounds = bounds;
setBounds(bounds);
}
@@ -113,14 +113,12 @@ public class WindowFrameTests extends WindowTestsBase {
@Before
public void setUp() throws Exception {
- super.setUp();
-
// Just any non zero value.
- sWm.mSystemDecorLayer = 10000;
+ mWm.mSystemDecorLayer = 10000;
mWindowToken = WindowTestUtils.createTestAppWindowToken(
- sWm.getDefaultDisplayContentLocked());
- mStubStack = new TaskStack(sWm, 0, null);
+ mWm.getDefaultDisplayContentLocked());
+ mStubStack = new TaskStack(mWm, 0, null);
}
// Do not use this function directly in the tests below. Instead, use more explicit function
@@ -170,9 +168,10 @@ public class WindowFrameTests extends WindowTestsBase {
}
@Test
- public void testLayoutInFullscreenTaskInsets() throws Exception {
- Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
- WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+ public void testLayoutInFullscreenTaskInsets() {
+ // fullscreen task doesn't use bounds for computeFrame
+ final Task task = new TaskWithBounds(mStubStack, mWm, null);
+ WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
final int bottomContentInset = 100;
@@ -227,9 +226,10 @@ public class WindowFrameTests extends WindowTestsBase {
}
@Test
- public void testLayoutInFullscreenTaskNoInsets() throws Exception {
- Task task = new TaskWithBounds(null); // fullscreen task doesn't use bounds for computeFrame
- WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+ public void testLayoutInFullscreenTaskNoInsets() {
+ // fullscreen task doesn't use bounds for computeFrame
+ final Task task = new TaskWithBounds(mStubStack, mWm, null);
+ WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
// With no insets or system decor all the frames incoming from PhoneWindowManager
@@ -307,7 +307,7 @@ public class WindowFrameTests extends WindowTestsBase {
@Test
public void testLayoutNonfullscreenTask() {
- final DisplayInfo displayInfo = sWm.getDefaultDisplayContentLocked().getDisplayInfo();
+ final DisplayInfo displayInfo = mWm.getDefaultDisplayContentLocked().getDisplayInfo();
final int logicalWidth = displayInfo.logicalWidth;
final int logicalHeight = displayInfo.logicalHeight;
@@ -316,9 +316,9 @@ public class WindowFrameTests extends WindowTestsBase {
final int taskRight = logicalWidth / 4 * 3;
final int taskBottom = logicalHeight / 4 * 3;
final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
- TaskWithBounds task = new TaskWithBounds(taskBounds);
+ final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
task.mFullscreenForTest = false;
- WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+ WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
@@ -367,7 +367,7 @@ public class WindowFrameTests extends WindowTestsBase {
@Test
public void testCalculatePolicyCrop() {
final WindowStateWithTask w = createWindow(
- new TaskWithBounds(null), FILL_PARENT, FILL_PARENT);
+ new TaskWithBounds(mStubStack, mWm, null), MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
final DisplayInfo displayInfo = w.getDisplayContent().getDisplayInfo();
@@ -423,7 +423,7 @@ public class WindowFrameTests extends WindowTestsBase {
@Test
public void testLayoutLetterboxedWindow() {
// First verify task behavior in multi-window mode.
- final DisplayInfo displayInfo = sWm.getDefaultDisplayContentLocked().getDisplayInfo();
+ final DisplayInfo displayInfo = mWm.getDefaultDisplayContentLocked().getDisplayInfo();
final int logicalWidth = displayInfo.logicalWidth;
final int logicalHeight = displayInfo.logicalHeight;
@@ -432,10 +432,10 @@ public class WindowFrameTests extends WindowTestsBase {
final int taskRight = logicalWidth / 4 * 3;
final int taskBottom = logicalHeight / 4 * 3;
final Rect taskBounds = new Rect(taskLeft, taskTop, taskRight, taskBottom);
- TaskWithBounds task = new TaskWithBounds(taskBounds);
+ final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm, taskBounds);
task.mInsetBounds.set(taskLeft, taskTop, taskRight, taskBottom);
task.mFullscreenForTest = false;
- WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+ WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
final Rect pf = new Rect(0, 0, logicalWidth, logicalHeight);
@@ -467,8 +467,8 @@ public class WindowFrameTests extends WindowTestsBase {
@Test
public void testDisplayCutout() {
// Regular fullscreen task and window
- Task task = new TaskWithBounds(null);
- WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+ final Task task = new TaskWithBounds(mStubStack, mWm, null);
+ WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
final Rect pf = new Rect(0, 0, 1000, 2000);
@@ -491,10 +491,11 @@ public class WindowFrameTests extends WindowTestsBase {
@Test
public void testDisplayCutout_tempInsetBounds() {
// Regular fullscreen task and window
- TaskWithBounds task = new TaskWithBounds(new Rect(0, -500, 1000, 1500));
+ final TaskWithBounds task = new TaskWithBounds(mStubStack, mWm,
+ new Rect(0, -500, 1000, 1500));
task.mFullscreenForTest = false;
task.mInsetBounds.set(0, 0, 1000, 2000);
- WindowState w = createWindow(task, FILL_PARENT, FILL_PARENT);
+ WindowState w = createWindow(task, MATCH_PARENT, MATCH_PARENT);
w.mAttrs.gravity = Gravity.LEFT | Gravity.TOP;
final Rect pf = new Rect(0, -500, 1000, 1500);
@@ -519,7 +520,6 @@ public class WindowFrameTests extends WindowTestsBase {
attrs.width = width;
attrs.height = height;
- return new WindowStateWithTask(attrs, task);
+ return new WindowStateWithTask(mWm, mIWindow, mWindowToken, attrs, task);
}
-
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
index 012c4be75fe5..4e75ec9e8348 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRule.java
@@ -19,6 +19,8 @@ package com.android.server.wm;
import static android.testing.DexmakerShareClassLoaderRule.runWithDexmakerShareClassLoader;
import static android.view.Display.DEFAULT_DISPLAY;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static org.mockito.ArgumentMatchers.any;
@@ -51,8 +53,6 @@ import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
-import androidx.test.InstrumentationRegistry;
-
/**
* A test rule that sets up a fresh WindowManagerService instance before each test and makes sure
* to properly tear it down after.
@@ -89,7 +89,7 @@ public class WindowManagerServiceRule implements TestRule {
}
private void setUp() {
- final Context context = InstrumentationRegistry.getTargetContext();
+ final Context context = getInstrumentation().getTargetContext();
removeServices();
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
index 570a853a62ca..343d35959df4 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowManagerServiceRuleTest.java
@@ -22,13 +22,14 @@ import static org.junit.Assert.assertThat;
import android.platform.test.annotations.Presubmit;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
-import org.junit.runner.RunWith;
-@RunWith(AndroidJUnit4.class)
+/**
+ * Build/InstallRun:
+ * atest FrameworksServicesTests:WindowManagerServiceRuleTest
+ */
@Presubmit
@SmallTest
public class WindowManagerServiceRuleTest {
@@ -40,4 +41,4 @@ public class WindowManagerServiceRuleTest {
public void testWindowManagerSetUp() {
assertThat(mRule.getWindowManagerService(), notNullValue());
}
-} \ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
index 3637baf13c72..118ce8962259 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowStateTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -58,32 +58,28 @@ import android.view.DisplayCutout;
import android.view.SurfaceControl;
import android.view.WindowManager;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.SmallTest;
+
import com.android.server.wm.utils.WmDisplayCutout;
import org.junit.Test;
-import org.junit.runner.RunWith;
-import java.util.Arrays;
import java.util.LinkedList;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
/**
* Tests for the {@link WindowState} class.
*
- * atest FrameworksServicesTests:com.android.server.wm.WindowStateTests
+ * Build/Install/Run:
+ * atest FrameworksServicesTests:WindowStateTests
*/
-@SmallTest
@FlakyTest(bugId = 74078662)
-// TODO(b/116597907): Re-enable this test in postsubmit after the bug is fixed.
-// @Presubmit
-@RunWith(AndroidJUnit4.class)
+@SmallTest
+@Presubmit
public class WindowStateTests extends WindowTestsBase {
@Test
- public void testIsParentWindowHidden() throws Exception {
+ public void testIsParentWindowHidden() {
final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
@@ -98,11 +94,10 @@ public class WindowStateTests extends WindowTestsBase {
assertFalse(parentWindow.isParentWindowHidden());
assertFalse(child1.isParentWindowHidden());
assertFalse(child2.isParentWindowHidden());
-
}
@Test
- public void testIsChildWindow() throws Exception {
+ public void testIsChildWindow() {
final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
@@ -115,7 +110,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testHasChild() throws Exception {
+ public void testHasChild() {
final WindowState win1 = createWindow(null, TYPE_APPLICATION, "win1");
final WindowState win11 = createWindow(win1, FIRST_SUB_WINDOW, "win11");
final WindowState win12 = createWindow(win1, FIRST_SUB_WINDOW, "win12");
@@ -136,7 +131,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testGetParentWindow() throws Exception {
+ public void testGetParentWindow() {
final WindowState parentWindow = createWindow(null, TYPE_APPLICATION, "parentWindow");
final WindowState child1 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child1");
final WindowState child2 = createWindow(parentWindow, FIRST_SUB_WINDOW, "child2");
@@ -157,7 +152,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testGetTopParentWindow() throws Exception {
+ public void testGetTopParentWindow() {
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
@@ -183,7 +178,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testCanBeImeTarget() throws Exception {
+ public void testCanBeImeTarget() {
final WindowState appWindow = createWindow(null, TYPE_APPLICATION, "appWindow");
final WindowState imeWindow = createWindow(null, TYPE_INPUT_METHOD, "imeWindow");
@@ -219,7 +214,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testGetWindow() throws Exception {
+ public void testGetWindow() {
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
final WindowState mediaChild = createWindow(root, TYPE_APPLICATION_MEDIA, "mediaChild");
final WindowState mediaOverlayChild = createWindow(root,
@@ -231,7 +226,7 @@ public class WindowStateTests extends WindowTestsBase {
final WindowState aboveSubPanelChild = createWindow(root,
TYPE_APPLICATION_ABOVE_SUB_PANEL, "aboveSubPanelChild");
- final LinkedList<WindowState> windows = new LinkedList();
+ final LinkedList<WindowState> windows = new LinkedList<>();
root.getWindow(w -> {
windows.addLast(w);
@@ -249,7 +244,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testPrepareWindowToDisplayDuringRelayout() throws Exception {
+ public void testPrepareWindowToDisplayDuringRelayout() {
testPrepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
testPrepareWindowToDisplayDuringRelayout(true /*wasVisible*/);
@@ -262,14 +257,14 @@ public class WindowStateTests extends WindowTestsBase {
final WindowState second = createWindow(null, TYPE_APPLICATION, appWindowToken, "second");
second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
- reset(mPowerManagerWrapper);
+ reset(sPowerManagerWrapper);
first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(mPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
assertTrue(appWindowToken.canTurnScreenOn());
- reset(mPowerManagerWrapper);
+ reset(sPowerManagerWrapper);
second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
// Call prepareWindowToDisplayDuringRelayout for two window that have FLAG_TURN_SCREEN_ON
@@ -278,14 +273,14 @@ public class WindowStateTests extends WindowTestsBase {
first.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
second.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
- reset(mPowerManagerWrapper);
+ reset(sPowerManagerWrapper);
first.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
- reset(mPowerManagerWrapper);
+ reset(sPowerManagerWrapper);
second.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(mPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper, never()).wakeUp(anyLong(), anyString());
assertFalse(appWindowToken.canTurnScreenOn());
// Call prepareWindowToDisplayDuringRelayout for a windows that are not children of an
@@ -299,17 +294,17 @@ public class WindowStateTests extends WindowTestsBase {
firstWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
secondWindow.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
- reset(mPowerManagerWrapper);
+ reset(sPowerManagerWrapper);
firstWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
- reset(mPowerManagerWrapper);
+ reset(sPowerManagerWrapper);
secondWindow.prepareWindowToDisplayDuringRelayout(false /*wasVisible*/);
- verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
}
@Test
- public void testCanAffectSystemUiFlags() throws Exception {
+ public void testCanAffectSystemUiFlags() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
app.mToken.setHidden(false);
assertTrue(app.canAffectSystemUiFlags());
@@ -318,11 +313,10 @@ public class WindowStateTests extends WindowTestsBase {
app.mToken.setHidden(false);
app.mAttrs.alpha = 0.0f;
assertFalse(app.canAffectSystemUiFlags());
-
}
@Test
- public void testCanAffectSystemUiFlags_disallow() throws Exception {
+ public void testCanAffectSystemUiFlags_disallow() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
app.mToken.setHidden(false);
assertTrue(app.canAffectSystemUiFlags());
@@ -331,7 +325,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testIsSelfOrAncestorWindowAnimating() throws Exception {
+ public void testIsSelfOrAncestorWindowAnimating() {
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
final WindowState child1 = createWindow(root, FIRST_SUB_WINDOW, "child1");
final WindowState child2 = createWindow(child1, FIRST_SUB_WINDOW, "child2");
@@ -344,7 +338,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testLayoutSeqResetOnReparent() throws Exception {
+ public void testLayoutSeqResetOnReparent() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
app.mLayoutSeq = 1;
mDisplayContent.mLayoutSeq = 1;
@@ -355,7 +349,7 @@ public class WindowStateTests extends WindowTestsBase {
}
@Test
- public void testDisplayIdUpdatedOnReparent() throws Exception {
+ public void testDisplayIdUpdatedOnReparent() {
final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
// fake a different display
app.mInputWindowHandle.displayId = mDisplayContent.getDisplayId() + 1;
@@ -418,11 +412,11 @@ public class WindowStateTests extends WindowTestsBase {
}
private void testPrepareWindowToDisplayDuringRelayout(boolean wasVisible) {
- reset(mPowerManagerWrapper);
+ reset(sPowerManagerWrapper);
final WindowState root = createWindow(null, TYPE_APPLICATION, "root");
root.mAttrs.flags |= WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON;
root.prepareWindowToDisplayDuringRelayout(wasVisible /*wasVisible*/);
- verify(mPowerManagerWrapper).wakeUp(anyLong(), anyString());
+ verify(sPowerManagerWrapper).wakeUp(anyLong(), anyString());
}
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
index e155be486a44..9e12f020d06e 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestUtils.java
@@ -11,30 +11,17 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
-import android.app.ActivityManager;
-import android.content.Context;
-import android.content.res.Configuration;
-import android.graphics.Rect;
-import android.os.Binder;
-import android.os.IBinder;
-import android.view.Display;
-import android.view.IApplicationToken;
-import android.view.IWindow;
-import android.view.Surface;
-import android.view.SurfaceControl;
-import android.view.SurfaceControl.Transaction;
-import android.view.WindowManager;
-
import static android.app.AppOpsManager.OP_NONE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
+
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyFloat;
@@ -44,6 +31,19 @@ import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.graphics.Rect;
+import android.os.Binder;
+import android.os.IBinder;
+import android.view.Display;
+import android.view.IApplicationToken;
+import android.view.IWindow;
+import android.view.Surface;
+import android.view.SurfaceControl.Transaction;
+import android.view.WindowManager;
+
import org.mockito.invocation.InvocationOnMock;
/**
@@ -277,35 +277,33 @@ public class WindowTestUtils {
*/
public static class TestTaskWindowContainerController extends TaskWindowContainerController {
- TestTaskWindowContainerController(WindowTestsBase testsBase) {
- this(testsBase.createStackControllerOnDisplay(testsBase.mDisplayContent));
- }
-
- TestTaskWindowContainerController(StackWindowController stackController) {
- super(sNextTaskId++, new TaskWindowContainerListener() {
- @Override
- public void registerConfigurationChangeListener(
- ConfigurationContainerListener listener) {
-
- }
-
- @Override
- public void unregisterConfigurationChangeListener(
- ConfigurationContainerListener listener) {
+ static final TaskWindowContainerListener NOP_LISTENER = new TaskWindowContainerListener() {
+ @Override
+ public void registerConfigurationChangeListener(
+ ConfigurationContainerListener listener) {
+ }
- }
+ @Override
+ public void unregisterConfigurationChangeListener(
+ ConfigurationContainerListener listener) {
+ }
- @Override
- public void onSnapshotChanged(ActivityManager.TaskSnapshot snapshot) {
+ @Override
+ public void onSnapshotChanged(ActivityManager.TaskSnapshot snapshot) {
+ }
- }
+ @Override
+ public void requestResize(Rect bounds, int resizeMode) {
+ }
+ };
- @Override
- public void requestResize(Rect bounds, int resizeMode) {
+ TestTaskWindowContainerController(WindowTestsBase testsBase) {
+ this(testsBase.createStackControllerOnDisplay(testsBase.mDisplayContent));
+ }
- }
- }, stackController, 0 /* userId */, null /* bounds */, RESIZE_MODE_UNRESIZEABLE,
- false /* supportsPictureInPicture */, true /* toTop*/,
+ TestTaskWindowContainerController(StackWindowController stackController) {
+ super(sNextTaskId++, NOP_LISTENER, stackController, 0 /* userId */, null /* bounds */,
+ RESIZE_MODE_UNRESIZEABLE, false /* supportsPictureInPicture */, true /* toTop*/,
true /* showForAllUsers */, new ActivityManager.TaskDescription(),
stackController.mService);
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
index 73bb1c9aa74b..945cbb91b029 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTestsBase.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -35,6 +35,8 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static org.mockito.Mockito.mock;
import android.content.Context;
@@ -52,13 +54,12 @@ import com.android.server.AttributeCache;
import org.junit.After;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Rule;
import java.util.HashSet;
import java.util.LinkedList;
-import androidx.test.InstrumentationRegistry;
-
/**
* Common base class for window manager unit test classes.
*
@@ -66,7 +67,8 @@ import androidx.test.InstrumentationRegistry;
*/
class WindowTestsBase {
private static final String TAG = WindowTestsBase.class.getSimpleName();
- WindowManagerService sWm = null; // TODO(roosa): rename to mWm in follow-up CL
+
+ WindowManagerService mWm;
private final IWindow mIWindow = new TestIWindow();
private Session mMockSession;
// The default display is removed in {@link #setUp} and then we iterate over all displays to
@@ -97,32 +99,36 @@ class WindowTestsBase {
@Rule
public final WindowManagerServiceRule mWmRule = new WindowManagerServiceRule();
- static WindowState.PowerManagerWrapper mPowerManagerWrapper; // TODO(roosa): make non-static.
+ static WindowState.PowerManagerWrapper sPowerManagerWrapper; // TODO(roosa): make non-static.
+
+ @BeforeClass
+ public static void setUpOnceBase() {
+ AttributeCache.init(getInstrumentation().getTargetContext());
+ sPowerManagerWrapper = mock(WindowState.PowerManagerWrapper.class);
+ }
@Before
- public void setUp() throws Exception {
+ public void setUpBase() {
// If @Before throws an exception, the error isn't logged. This will make sure any failures
// in the set up are clear. This can be removed when b/37850063 is fixed.
try {
mMockSession = mock(Session.class);
- mPowerManagerWrapper = mock(WindowState.PowerManagerWrapper.class);
- final Context context = InstrumentationRegistry.getTargetContext();
- AttributeCache.init(context);
+ final Context context = getInstrumentation().getTargetContext();
- sWm = mWmRule.getWindowManagerService();
+ mWm = mWmRule.getWindowManagerService();
beforeCreateDisplay();
- mWallpaperController = new WallpaperController(sWm);
+ mWallpaperController = new WallpaperController(mWm);
context.getDisplay().getDisplayInfo(mDisplayInfo);
mDisplayContent = createNewDisplay();
- sWm.mDisplayEnabled = true;
- sWm.mDisplayReady = true;
+ mWm.mDisplayEnabled = true;
+ mWm.mDisplayReady = true;
// Set-up some common windows.
- mCommonWindows = new HashSet();
- synchronized (sWm.mGlobalLock) {
+ mCommonWindows = new HashSet<>();
+ synchronized (mWm.mGlobalLock) {
mWallpaperWindow = createCommonWindow(null, TYPE_WALLPAPER, "wallpaperWindow");
mImeWindow = createCommonWindow(null, TYPE_INPUT_METHOD, "mImeWindow");
mDisplayContent.mInputMethodWindow = mImeWindow;
@@ -154,7 +160,7 @@ class WindowTestsBase {
}
@After
- public void tearDown() throws Exception {
+ public void tearDownBase() {
// If @After throws an exception, the error isn't logged. This will make sure any failures
// in the tear down are clear. This can be removed when b/37850063 is fixed.
try {
@@ -164,8 +170,8 @@ class WindowTestsBase {
final LinkedList<WindowState> nonCommonWindows = new LinkedList<>();
- synchronized (sWm.mGlobalLock) {
- sWm.mRoot.forAllWindows(w -> {
+ synchronized (mWm.mGlobalLock) {
+ mWm.mRoot.forAllWindows(w -> {
if (!mCommonWindows.contains(w)) {
nonCommonWindows.addLast(w);
}
@@ -175,18 +181,18 @@ class WindowTestsBase {
nonCommonWindows.pollLast().removeImmediately();
}
- for (int i = sWm.mRoot.mChildren.size() - 1; i >= 0; --i) {
- final DisplayContent displayContent = sWm.mRoot.mChildren.get(i);
+ for (int i = mWm.mRoot.mChildren.size() - 1; i >= 0; --i) {
+ final DisplayContent displayContent = mWm.mRoot.mChildren.get(i);
if (!displayContent.isDefaultDisplay) {
displayContent.removeImmediately();
}
}
// Remove app transition & window freeze timeout callbacks to prevent unnecessary
// actions after test.
- sWm.getDefaultDisplayContentLocked().mAppTransition
+ mWm.getDefaultDisplayContentLocked().mAppTransition
.removeAppTransitionTimeoutCallbacks();
- sWm.mH.removeMessages(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT);
- sWm.mInputMethodTarget = null;
+ mWm.mH.removeMessages(WindowManagerService.H.WINDOW_FREEZE_TIMEOUT);
+ mWm.mInputMethodTarget = null;
}
// Wait until everything is really cleaned up.
@@ -198,7 +204,7 @@ class WindowTestsBase {
}
private WindowState createCommonWindow(WindowState parent, int type, String name) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
final WindowState win = createWindow(parent, type, name);
mCommonWindows.add(win);
// Prevent common windows from been IMe targets
@@ -216,7 +222,7 @@ class WindowTestsBase {
private WindowToken createWindowToken(
DisplayContent dc, int windowingMode, int activityType, int type) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
if (type < FIRST_APPLICATION_WINDOW || type > LAST_APPLICATION_WINDOW) {
return WindowTestUtils.createTestWindowToken(type, dc);
}
@@ -241,7 +247,7 @@ class WindowTestsBase {
}
WindowState createWindow(WindowState parent, int type, String name) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
return (parent == null)
? createWindow(parent, type, mDisplayContent, name)
: createWindow(parent, type, parent.mToken, name);
@@ -250,14 +256,14 @@ class WindowTestsBase {
WindowState createWindowOnStack(WindowState parent, int windowingMode, int activityType,
int type, DisplayContent dc, String name) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
final WindowToken token = createWindowToken(dc, windowingMode, activityType, type);
return createWindow(parent, type, token, name);
}
}
WindowState createAppWindow(Task task, int type, String name) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
final AppWindowToken token = WindowTestUtils.createTestAppWindowToken(mDisplayContent);
task.addChild(token, 0);
return createWindow(null, type, token, name);
@@ -265,7 +271,7 @@ class WindowTestsBase {
}
WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
final WindowToken token = createWindowToken(
dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
return createWindow(parent, type, token, name);
@@ -274,7 +280,7 @@ class WindowTestsBase {
WindowState createWindow(WindowState parent, int type, DisplayContent dc, String name,
boolean ownerCanAddInternalSystemWindow) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
final WindowToken token = createWindowToken(
dc, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, type);
return createWindow(parent, type, token, name, 0 /* ownerId */,
@@ -283,7 +289,7 @@ class WindowTestsBase {
}
WindowState createWindow(WindowState parent, int type, WindowToken token, String name) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
return createWindow(parent, type, token, name, 0 /* ownerId */,
false /* ownerCanAddInternalSystemWindow */);
}
@@ -292,7 +298,7 @@ class WindowTestsBase {
WindowState createWindow(WindowState parent, int type, WindowToken token, String name,
int ownerId, boolean ownerCanAddInternalSystemWindow) {
return createWindow(parent, type, token, name, ownerId, ownerCanAddInternalSystemWindow,
- sWm, mMockSession, mIWindow);
+ mWm, mMockSession, mIWindow);
}
static WindowState createWindow(WindowState parent, int type, WindowToken token,
@@ -305,7 +311,7 @@ class WindowTestsBase {
final WindowState w = new WindowState(service, session, iWindow, token, parent,
OP_NONE,
0, attrs, VISIBLE, ownerId, ownerCanAddInternalSystemWindow,
- mPowerManagerWrapper);
+ sPowerManagerWrapper);
// TODO: Probably better to make this call in the WindowState ctor to avoid errors with
// adding it to the token...
token.addWindow(w);
@@ -315,13 +321,13 @@ class WindowTestsBase {
/** Creates a {@link TaskStack} and adds it to the specified {@link DisplayContent}. */
TaskStack createTaskStackOnDisplay(DisplayContent dc) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
return createStackControllerOnDisplay(dc).mContainer;
}
}
StackWindowController createStackControllerOnDisplay(DisplayContent dc) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
return createStackControllerOnStackOnDisplay(
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, dc);
}
@@ -329,13 +335,13 @@ class WindowTestsBase {
StackWindowController createStackControllerOnStackOnDisplay(
int windowingMode, int activityType, DisplayContent dc) {
- synchronized (sWm.mGlobalLock) {
+ synchronized (mWm.mGlobalLock) {
final Configuration overrideConfig = new Configuration();
overrideConfig.windowConfiguration.setWindowingMode(windowingMode);
overrideConfig.windowConfiguration.setActivityType(activityType);
final int stackId = ++sNextStackId;
final StackWindowController controller = new StackWindowController(stackId, null,
- dc.getDisplayId(), true /* onTop */, new Rect(), sWm);
+ dc.getDisplayId(), true /* onTop */, new Rect(), mWm);
controller.onOverrideConfigurationChanged(overrideConfig);
return controller;
}
@@ -343,7 +349,7 @@ class WindowTestsBase {
/** Creates a {@link Task} and adds it to the specified {@link TaskStack}. */
Task createTaskInStack(TaskStack stack, int userId) {
- return WindowTestUtils.createTaskInStack(sWm, stack, userId);
+ return WindowTestUtils.createTaskInStack(mWm, stack, userId);
}
/** Creates a {@link DisplayContent} and adds it to the system. */
@@ -351,8 +357,8 @@ class WindowTestsBase {
final int displayId = sNextDisplayId++;
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
mDisplayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
- synchronized (sWm.mGlobalLock) {
- return new DisplayContent(display, sWm, mWallpaperController,
+ synchronized (mWm.mGlobalLock) {
+ return new DisplayContent(display, mWm, mWallpaperController,
mock(DisplayWindowController.class));
}
}
@@ -375,20 +381,19 @@ class WindowTestsBase {
final int displayId = sNextDisplayId++;
final Display display = new Display(DisplayManagerGlobal.getInstance(), displayId,
displayInfo, DEFAULT_DISPLAY_ADJUSTMENTS);
- final DisplayWindowController dcw = new DisplayWindowController(display, sWm);
- synchronized (sWm.mGlobalLock) {
+ final DisplayWindowController dcw = new DisplayWindowController(display, mWm);
+ synchronized (mWm.mGlobalLock) {
// Display creation is driven by DisplayWindowController via ActivityStackSupervisor.
// We skip those steps here.
- return sWm.mRoot.createDisplayContent(display, dcw);
+ return mWm.mRoot.createDisplayContent(display, dcw);
}
}
/** Creates a {@link com.android.server.wm.WindowTestUtils.TestWindowState} */
WindowTestUtils.TestWindowState createWindowState(WindowManager.LayoutParams attrs,
WindowToken token) {
- synchronized (sWm.mGlobalLock) {
- return new WindowTestUtils.TestWindowState(sWm, mMockSession, mIWindow, attrs, token);
+ synchronized (mWm.mGlobalLock) {
+ return new WindowTestUtils.TestWindowState(mWm, mMockSession, mIWindow, attrs, token);
}
}
-
}
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
index 3732486f4a07..3048f1a3487b 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/WindowTokenTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -30,25 +30,22 @@ import android.platform.test.annotations.Presubmit;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
-import org.junit.runner.RunWith;
/**
* Tests for the {@link WindowToken} class.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.wm.WindowTokenTests
+ * atest FrameworksServicesTests:WindowTokenTests
*/
-@SmallTest
@FlakyTest(bugId = 74078662)
+@SmallTest
@Presubmit
-@RunWith(AndroidJUnit4.class)
public class WindowTokenTests extends WindowTestsBase {
@Test
- public void testAddWindow() throws Exception {
+ public void testAddWindow() {
final WindowTestUtils.TestWindowToken token =
WindowTestUtils.createTestWindowToken(0, mDisplayContent);
@@ -78,7 +75,7 @@ public class WindowTokenTests extends WindowTestsBase {
}
@Test
- public void testChildRemoval() throws Exception {
+ public void testChildRemoval() {
final DisplayContent dc = mDisplayContent;
final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken(0, dc);
@@ -102,7 +99,7 @@ public class WindowTokenTests extends WindowTestsBase {
* Tokens should only be removed from the system when all their windows are gone.
*/
@Test
- public void testTokenRemovalProcess() throws Exception {
+ public void testTokenRemovalProcess() {
final WindowTestUtils.TestWindowToken token = WindowTestUtils.createTestWindowToken(
TYPE_TOAST, mDisplayContent, true /* persistOnEmpty */);
diff --git a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
index 3a8c4ae73493..32e4e0265193 100644
--- a/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
+++ b/services/tests/servicestests/src/com/android/server/wm/ZOrderingTests.java
@@ -11,7 +11,7 @@
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
- * limitations under the License
+ * limitations under the License.
*/
package com.android.server.wm;
@@ -38,27 +38,30 @@ import android.platform.test.annotations.Presubmit;
import android.view.SurfaceControl;
import android.view.SurfaceSession;
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.SmallTest;
+
import org.junit.After;
import org.junit.Test;
import java.util.HashMap;
import java.util.LinkedList;
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-
/**
- * Tests for the {@link WindowLayersController} class.
+ * Tests for the {@link DisplayContent#assignChildLayers(SurfaceControl.Transaction)} method.
*
* Build/Install/Run:
- * atest FrameworksServicesTests:com.android.server.wm.ZOrderingTests
+ * atest FrameworksServicesTests:ZOrderingTests
*/
-@SmallTest
@FlakyTest(bugId = 74078662)
+@SmallTest
@Presubmit
public class ZOrderingTests extends WindowTestsBase {
- private class LayerRecordingTransaction extends SurfaceControl.Transaction {
+ private static class LayerRecordingTransaction extends SurfaceControl.Transaction {
+ // We have WM use our Hierarchy recording subclass of SurfaceControl.Builder
+ // such that we can keep track of the parents of Surfaces as they are constructed.
+ private final HashMap<SurfaceControl, SurfaceControl> mParentFor = new HashMap<>();
HashMap<SurfaceControl, Integer> mLayersForControl = new HashMap<>();
HashMap<SurfaceControl, SurfaceControl> mRelativeLayersForControl = new HashMap<>();
@@ -85,17 +88,28 @@ public class ZOrderingTests extends WindowTestsBase {
private SurfaceControl getRelativeLayer(SurfaceControl sc) {
return mRelativeLayersForControl.get(sc);
}
- }
- // We have WM use our Hierarchy recording subclass of SurfaceControl.Builder
- // such that we can keep track of the parents of Surfaces as they are constructed.
- private HashMap<SurfaceControl, SurfaceControl> mParentFor = new HashMap<>();
+ void addParentFor(SurfaceControl child, SurfaceControl parent) {
+ mParentFor.put(child, parent);
+ }
- private class HierarchyRecorder extends SurfaceControl.Builder {
- SurfaceControl mPendingParent;
+ SurfaceControl getParentFor(SurfaceControl child) {
+ return mParentFor.get(child);
+ }
- HierarchyRecorder(SurfaceSession s) {
+ @Override
+ public void close() {
+
+ }
+ }
+
+ private static class HierarchyRecorder extends SurfaceControl.Builder {
+ private LayerRecordingTransaction mTransaction;
+ private SurfaceControl mPendingParent;
+
+ HierarchyRecorder(SurfaceSession s, LayerRecordingTransaction transaction) {
super(s);
+ mTransaction = transaction;
}
@Override
@@ -106,16 +120,26 @@ public class ZOrderingTests extends WindowTestsBase {
@Override
public SurfaceControl build() {
- SurfaceControl sc = super.build();
- mParentFor.put(sc, mPendingParent);
+ final SurfaceControl sc = super.build();
+ mTransaction.addParentFor(sc, mPendingParent);
+ mTransaction = null;
mPendingParent = null;
return sc;
}
}
- private class HierarchyRecordingBuilderFactory implements SurfaceBuilderFactory {
+ private static class HierarchyRecordingBuilderFactory implements SurfaceBuilderFactory {
+ private LayerRecordingTransaction mTransaction;
+
+ HierarchyRecordingBuilderFactory(LayerRecordingTransaction transaction) {
+ mTransaction = transaction;
+ }
+
+ @Override
public SurfaceControl.Builder make(SurfaceSession s) {
- return new HierarchyRecorder(s);
+ final LayerRecordingTransaction transaction = mTransaction;
+ mTransaction = null;
+ return new HierarchyRecorder(s, transaction);
}
}
@@ -127,18 +151,17 @@ public class ZOrderingTests extends WindowTestsBase {
// which is after construction of the DisplayContent, meaning the HierarchyRecorder
// would miss construction of the top-level layers.
mTransaction = new LayerRecordingTransaction();
- sWm.mSurfaceBuilderFactory = new HierarchyRecordingBuilderFactory();
- sWm.mTransactionFactory = () -> mTransaction;
+ mWm.mSurfaceBuilderFactory = new HierarchyRecordingBuilderFactory(mTransaction);
+ mWm.mTransactionFactory = () -> mTransaction;
}
@After
- public void after() {
+ public void tearDown() {
mTransaction.close();
- mParentFor.keySet().forEach(SurfaceControl::destroy);
- mParentFor.clear();
}
- LinkedList<SurfaceControl> getAncestors(LayerRecordingTransaction t, SurfaceControl sc) {
+ private static LinkedList<SurfaceControl> getAncestors(LayerRecordingTransaction t,
+ SurfaceControl sc) {
LinkedList<SurfaceControl> p = new LinkedList<>();
SurfaceControl current = sc;
do {
@@ -148,23 +171,22 @@ public class ZOrderingTests extends WindowTestsBase {
if (rs != null) {
current = rs;
} else {
- current = mParentFor.get(current);
+ current = t.getParentFor(current);
}
} while (current != null);
return p;
}
- void assertZOrderGreaterThan(LayerRecordingTransaction t, SurfaceControl left,
+ private static void assertZOrderGreaterThan(LayerRecordingTransaction t, SurfaceControl left,
SurfaceControl right) {
final LinkedList<SurfaceControl> leftParentChain = getAncestors(t, left);
final LinkedList<SurfaceControl> rightParentChain = getAncestors(t, right);
- SurfaceControl commonAncestor = null;
SurfaceControl leftTop = leftParentChain.peekLast();
SurfaceControl rightTop = rightParentChain.peekLast();
while (leftTop != null && rightTop != null && leftTop == rightTop) {
- commonAncestor = leftParentChain.removeLast();
+ leftParentChain.removeLast();
rightParentChain.removeLast();
leftTop = leftParentChain.peekLast();
rightTop = rightParentChain.peekLast();
@@ -189,7 +211,7 @@ public class ZOrderingTests extends WindowTestsBase {
@Test
public void testAssignWindowLayers_ForImeWithNoTarget() {
- sWm.mInputMethodTarget = null;
+ mWm.mInputMethodTarget = null;
mDisplayContent.assignChildLayers(mTransaction);
// The Ime has an higher base layer than app windows and lower base layer than system
@@ -207,7 +229,7 @@ public class ZOrderingTests extends WindowTestsBase {
@Test
public void testAssignWindowLayers_ForImeWithAppTarget() {
final WindowState imeAppTarget = createWindow("imeAppTarget");
- sWm.mInputMethodTarget = imeAppTarget;
+ mWm.mInputMethodTarget = imeAppTarget;
mDisplayContent.assignChildLayers(mTransaction);
@@ -233,7 +255,7 @@ public class ZOrderingTests extends WindowTestsBase {
TYPE_APPLICATION_MEDIA_OVERLAY, imeAppTarget.mToken,
"imeAppTargetChildBelowWindow");
- sWm.mInputMethodTarget = imeAppTarget;
+ mWm.mInputMethodTarget = imeAppTarget;
mDisplayContent.assignChildLayers(mTransaction);
// Ime should be above all app windows except for child windows that are z-ordered above it
@@ -255,7 +277,7 @@ public class ZOrderingTests extends WindowTestsBase {
final WindowState imeAppTarget = createWindow("imeAppTarget");
final WindowState appAboveImeTarget = createWindow("appAboveImeTarget");
- sWm.mInputMethodTarget = imeAppTarget;
+ mWm.mInputMethodTarget = imeAppTarget;
mDisplayContent.assignChildLayers(mTransaction);
// Ime should be above all app windows except for non-fullscreen app window above it and
@@ -278,7 +300,7 @@ public class ZOrderingTests extends WindowTestsBase {
mDisplayContent, "imeSystemOverlayTarget",
true /* ownerCanAddInternalSystemWindow */);
- sWm.mInputMethodTarget = imeSystemOverlayTarget;
+ mWm.mInputMethodTarget = imeSystemOverlayTarget;
mDisplayContent.assignChildLayers(mTransaction);
// The IME target base layer is higher than all window except for the nav bar window, so the
@@ -301,7 +323,7 @@ public class ZOrderingTests extends WindowTestsBase {
@Test
public void testAssignWindowLayers_ForStatusBarImeTarget() {
- sWm.mInputMethodTarget = mStatusBarWindow;
+ mWm.mInputMethodTarget = mStatusBarWindow;
mDisplayContent.assignChildLayers(mTransaction);
assertWindowHigher(mImeWindow, mChildAppWindowAbove);
@@ -322,8 +344,8 @@ public class ZOrderingTests extends WindowTestsBase {
final WindowState dockedStackWindow = createWindowOnStack(null,
WINDOWING_MODE_SPLIT_SCREEN_PRIMARY, ACTIVITY_TYPE_STANDARD, TYPE_BASE_APPLICATION,
mDisplayContent, "dockedStackWindow");
- final WindowState assistantStackWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
- ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
+ final WindowState assistantStackWindow = createWindowOnStack(null,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
mDisplayContent, "assistantStackWindow");
final WindowState homeActivityWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
ACTIVITY_TYPE_HOME, TYPE_BASE_APPLICATION,
@@ -368,7 +390,8 @@ public class ZOrderingTests extends WindowTestsBase {
final WindowState anyWindow = createWindow("anyWindow");
final WindowState child = createWindow(anyWindow, TYPE_APPLICATION_MEDIA, mDisplayContent,
"TypeApplicationMediaChild");
- final WindowState mediaOverlayChild = createWindow(anyWindow, TYPE_APPLICATION_MEDIA_OVERLAY,
+ final WindowState mediaOverlayChild = createWindow(anyWindow,
+ TYPE_APPLICATION_MEDIA_OVERLAY,
mDisplayContent, "TypeApplicationMediaOverlayChild");
mDisplayContent.assignChildLayers(mTransaction);
@@ -388,8 +411,8 @@ public class ZOrderingTests extends WindowTestsBase {
final WindowState splitScreenSecondaryWindow = createWindowOnStack(null,
WINDOWING_MODE_SPLIT_SCREEN_SECONDARY, ACTIVITY_TYPE_STANDARD,
TYPE_BASE_APPLICATION, mDisplayContent, "splitScreenSecondaryWindow");
- final WindowState assistantStackWindow = createWindowOnStack(null, WINDOWING_MODE_FULLSCREEN,
- ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
+ final WindowState assistantStackWindow = createWindowOnStack(null,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_ASSISTANT, TYPE_BASE_APPLICATION,
mDisplayContent, "assistantStackWindow");
mDisplayContent.assignChildLayers(mTransaction);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
index 6c125d1648f3..32f389a4fa2d 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeFilteringTest.java
@@ -71,7 +71,8 @@ public class ZenModeFilteringTest extends UiServiceTestCase {
private NotificationRecord getNotificationRecord(NotificationChannel c) {
StatusBarNotification sbn = mock(StatusBarNotification.class);
- when(sbn.getNotification()).thenReturn(mock(Notification.class));
+ Notification notification = mock(Notification.class);
+ when(sbn.getNotification()).thenReturn(notification);
return new NotificationRecord(mContext, sbn, c);
}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
index b19cc86a3404..38d8e3990e00 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -21,13 +21,14 @@ import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_FULL_SCRE
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_LIGHTS;
import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_PEEK;
-import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
import static junit.framework.TestCase.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doNothing;
@@ -45,13 +46,14 @@ import android.app.NotificationManager.Policy;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioManagerInternal;
-import android.media.VolumePolicy;
import android.media.AudioSystem;
+import android.media.VolumePolicy;
import android.net.Uri;
import android.provider.Settings;
import android.provider.Settings.Global;
@@ -67,9 +69,9 @@ import android.util.Xml;
import com.android.internal.R;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
-import com.android.server.notification.ManagedServices.UserProfiles;
import com.android.internal.util.FastXmlSerializer;
import com.android.server.UiServiceTestCase;
+import com.android.server.notification.ManagedServices.UserProfiles;
import org.junit.Before;
import org.junit.Test;
@@ -87,12 +89,16 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
+import java.util.Objects;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class ZenModeHelperTest extends UiServiceTestCase {
+ private static final String EVENTS_DEFAULT_RULE_ID = "EVENTS_DEFAULT_RULE";
+ private static final String SCHEDULE_DEFAULT_RULE_ID = "EVERY_NIGHT_DEFAULT_RULE";
+
ConditionProviders mConditionProviders;
@Mock NotificationManager mNotificationManager;
private Resources mResources;
@@ -108,7 +114,6 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mTestableLooper = TestableLooper.get(this);
mContext = spy(getContext());
mContentResolver = mContext.getContentResolver();
-
mResources = spy(mContext.getResources());
try {
when(mResources.getXml(R.xml.default_zen_mode_config)).thenReturn(
@@ -132,12 +137,13 @@ public class ZenModeHelperTest extends UiServiceTestCase {
+ "reminders=\"false\" events=\"false\" callsFrom=\"1\" messagesFrom=\"2\" "
+ "visualScreenOff=\"true\" alarms=\"true\" "
+ "media=\"true\" system=\"false\" />\n"
- + "<automatic ruleId=\"EVENTS_DEFAULT_RULE\" enabled=\"false\" snoozing=\"false\""
+ + "<automatic ruleId=\"" + EVENTS_DEFAULT_RULE_ID
+ + "\" enabled=\"false\" snoozing=\"false\""
+ " name=\"Event\" zen=\"1\""
+ " component=\"android/com.android.server.notification.EventConditionProvider\""
+ " conditionId=\"condition://android/event?userId=-10000&amp;calendar=&amp;"
+ "reply=1\"/>\n"
- + "<automatic ruleId=\"EVERY_NIGHT_DEFAULT_RULE\" enabled=\"false\""
+ + "<automatic ruleId=\"" + SCHEDULE_DEFAULT_RULE_ID + "\" enabled=\"false\""
+ " snoozing=\"false\" name=\"Sleeping\" zen=\"1\""
+ " component=\"android/com.android.server.notification.ScheduleConditionProvider\""
+ " conditionId=\"condition://android/schedule?days=1.2.3.4.5.6.7 &amp;start=22.0"
@@ -770,8 +776,8 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeHelperSpy.readXml(parser, false);
assertEquals(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT
- | SUPPRESSED_EFFECT_LIGHTS
- | SUPPRESSED_EFFECT_PEEK,
+ | SUPPRESSED_EFFECT_LIGHTS
+ | SUPPRESSED_EFFECT_PEEK,
mZenModeHelperSpy.mConfig.suppressedVisualEffects);
xml = "<zen version=\"6\" user=\"0\">\n"
@@ -1007,6 +1013,90 @@ public class ZenModeHelperTest extends UiServiceTestCase {
mZenModeHelperSpy.updateDefaultZenRules(); // shouldn't throw null pointer
}
+ @Test
+ public void testDoNotUpdateModifiedDefaultAutoRule() {
+ // mDefaultConfig is set to default config in setup by getDefaultConfigParser
+ when(mContext.checkCallingPermission(anyString()))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ // shouldn't update rule that's been modified
+ ZenModeConfig.ZenRule updatedDefaultRule = new ZenModeConfig.ZenRule();
+ updatedDefaultRule.modified = true;
+ updatedDefaultRule.enabled = false;
+ updatedDefaultRule.creationTime = 0;
+ updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
+ updatedDefaultRule.name = "Schedule Default Rule";
+ updatedDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo());
+ updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
+
+ ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
+ autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
+ mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+
+ mZenModeHelperSpy.updateDefaultZenRules();
+ assertEquals(updatedDefaultRule,
+ mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
+ }
+
+ @Test
+ public void testDoNotUpdateEnabledDefaultAutoRule() {
+ // mDefaultConfig is set to default config in setup by getDefaultConfigParser
+ when(mContext.checkCallingPermission(anyString()))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ // shouldn't update the rule that's enabled
+ ZenModeConfig.ZenRule updatedDefaultRule = new ZenModeConfig.ZenRule();
+ updatedDefaultRule.enabled = true;
+ updatedDefaultRule.modified = false;
+ updatedDefaultRule.creationTime = 0;
+ updatedDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
+ updatedDefaultRule.name = "Schedule Default Rule";
+ updatedDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ updatedDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo());
+ updatedDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
+
+ ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
+ autoRules.put(SCHEDULE_DEFAULT_RULE_ID, updatedDefaultRule);
+ mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+
+ mZenModeHelperSpy.updateDefaultZenRules();
+ assertEquals(updatedDefaultRule,
+ mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID));
+ }
+
+ @Test
+ public void testUpdateDefaultAutoRule() {
+ // mDefaultConfig is set to default config in setup by getDefaultConfigParser
+ final String defaultRuleName = "rule name test";
+ when(mContext.checkCallingPermission(anyString()))
+ .thenReturn(PackageManager.PERMISSION_GRANTED);
+
+ // will update rule that is not enabled and modified
+ ZenModeConfig.ZenRule customDefaultRule = new ZenModeConfig.ZenRule();
+ customDefaultRule.enabled = false;
+ customDefaultRule.modified = false;
+ customDefaultRule.creationTime = 0;
+ customDefaultRule.id = SCHEDULE_DEFAULT_RULE_ID;
+ customDefaultRule.name = "Schedule Default Rule";
+ customDefaultRule.zenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
+ customDefaultRule.conditionId = ZenModeConfig.toScheduleConditionId(new ScheduleInfo());
+ customDefaultRule.component = new ComponentName("android", "ScheduleConditionProvider");
+
+ ArrayMap<String, ZenModeConfig.ZenRule> autoRules = new ArrayMap<>();
+ autoRules.put(SCHEDULE_DEFAULT_RULE_ID, customDefaultRule);
+ mZenModeHelperSpy.mConfig.automaticRules = autoRules;
+
+ mZenModeHelperSpy.updateDefaultZenRules();
+ ZenModeConfig.ZenRule ruleAfterUpdating =
+ mZenModeHelperSpy.mConfig.automaticRules.get(SCHEDULE_DEFAULT_RULE_ID);
+ assertEquals(customDefaultRule.enabled, ruleAfterUpdating.enabled);
+ assertEquals(customDefaultRule.modified, ruleAfterUpdating.modified);
+ assertEquals(customDefaultRule.id, ruleAfterUpdating.id);
+ assertEquals(customDefaultRule.conditionId, ruleAfterUpdating.conditionId);
+ assertFalse(Objects.equals(defaultRuleName, ruleAfterUpdating.name)); // update name
+ }
+
private void setupZenConfig() {
mZenModeHelperSpy.mZenMode = Settings.Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS;
mZenModeHelperSpy.mConfig.allowAlarms = false;
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index 73a34b621a29..ff8480373f4e 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -41,7 +41,8 @@
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityRequestedOrientationChange" />
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityTaskChangeCallbacks" />
<activity android:name="com.android.server.wm.TaskStackChangedListenerTest$ActivityTaskDescriptionChange" />
- <activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity" />
+ <activity android:name="com.android.server.wm.ScreenDecorWindowTests$TestActivity"
+ android:showWhenLocked="true" />
</application>
<instrumentation
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
new file mode 100644
index 000000000000..215c51d79abc
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityMetricsLaunchObserverTests.java
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.wm;
+
+import static android.app.ActivityManager.START_SUCCESS;
+import static android.app.ActivityManager.START_TASK_TO_FRONT;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
+
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+
+import android.content.Intent;
+import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
+import android.util.SparseIntArray;
+
+import androidx.test.filters.FlakyTest;
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Tests for the {@link ActivityMetricsLaunchObserver} class.
+ *
+ * Build/Install/Run:
+ * atest WmTests:ActivityMetricsLaunchObserverTests
+ */
+@SmallTest
+@Presubmit
+@FlakyTest(detail="promote once confirmed non-flaky")
+public class ActivityMetricsLaunchObserverTests extends ActivityTestsBase {
+ private ActivityMetricsLogger mActivityMetricsLogger;
+ private ActivityMetricsLaunchObserver mLaunchObserver;
+
+ private TestActivityStack mStack;
+ private TaskRecord mTask;
+ private ActivityRecord mActivityRecord;
+ private ActivityRecord mActivityRecordTrampoline;
+
+ @Before
+ public void setUpAMLO() throws Exception {
+ setupActivityTaskManagerService();
+
+ mActivityMetricsLogger =
+ new ActivityMetricsLogger(mSupervisor, mService.mContext, mService.mH.getLooper());
+
+ mLaunchObserver = mock(ActivityMetricsLaunchObserver.class);
+
+ // TODO: Use ActivityMetricsLaunchObserverRegistry .
+ java.lang.reflect.Field f =
+ mActivityMetricsLogger.getClass().getDeclaredField("mLaunchObserver");
+ f.setAccessible(true);
+ f.set(mActivityMetricsLogger, mLaunchObserver);
+
+ // Sometimes we need an ActivityRecord for ActivityMetricsLogger to do anything useful.
+ // This seems to be the easiest way to create an ActivityRecord.
+ mStack = mSupervisor.getDefaultDisplay().createStack(
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
+ mTask = new TaskBuilder(mSupervisor).setStack(mStack).build();
+ mActivityRecord = new ActivityBuilder(mService).setTask(mTask).build();
+ mActivityRecordTrampoline = new ActivityBuilder(mService).setTask(mTask).build();
+ }
+
+ @Test
+ public void testOnIntentStarted() throws Exception {
+ Intent intent = new Intent("action 1");
+
+ mActivityMetricsLogger.notifyActivityLaunching(intent);
+
+ verify(mLaunchObserver).onIntentStarted(eq(intent));
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+
+ @Test
+ public void testOnIntentFailed() throws Exception {
+ testOnIntentStarted();
+
+ ActivityRecord activityRecord = null;
+
+ // Bringing an intent that's already running 'to front' is not considered
+ // as an ACTIVITY_LAUNCHED state transition.
+ mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT,
+ activityRecord);
+
+ verify(mLaunchObserver).onIntentFailed();
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+
+ @Test
+ public void testOnActivityLaunched() throws Exception {
+ testOnIntentStarted();
+
+ mActivityMetricsLogger.notifyActivityLaunched(START_SUCCESS,
+ mActivityRecord);
+
+ verify(mLaunchObserver).onActivityLaunched(eq(mActivityRecord), anyInt());
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+
+ @Test
+ public void testOnActivityLaunchFinished() throws Exception {
+ testOnActivityLaunched();
+
+ mActivityMetricsLogger.notifyTransitionStarting(new SparseIntArray(),
+ SystemClock.uptimeMillis());
+
+ mActivityMetricsLogger.notifyWindowsDrawn(mActivityRecord.getWindowingMode(),
+ SystemClock.uptimeMillis());
+
+ verify(mLaunchObserver).onActivityLaunchFinished(eq(mActivityRecord));
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+
+ @Test
+ public void testOnActivityLaunchCancelled() throws Exception {
+ testOnActivityLaunched();
+
+ mActivityRecord.nowVisible = true;
+
+ // Cannot time already-visible activities.
+ mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT, mActivityRecord);
+
+ verify(mLaunchObserver).onActivityLaunchCancelled(eq(mActivityRecord));
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+
+ @Test
+ public void testOnActivityLaunchedTrampoline() throws Exception {
+ testOnIntentStarted();
+
+ mActivityMetricsLogger.notifyActivityLaunched(START_SUCCESS,
+ mActivityRecord);
+
+ verify(mLaunchObserver).onActivityLaunched(eq(mActivityRecord), anyInt());
+
+ // A second, distinct, activity launch is coalesced into the the current app launch sequence
+ mActivityMetricsLogger.notifyActivityLaunched(START_SUCCESS,
+ mActivityRecordTrampoline);
+
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+
+ @Test
+ public void testOnActivityLaunchFinishedTrampoline() throws Exception {
+ testOnActivityLaunchedTrampoline();
+
+ mActivityMetricsLogger.notifyTransitionStarting(new SparseIntArray(),
+ SystemClock.uptimeMillis());
+
+ mActivityMetricsLogger.notifyWindowsDrawn(mActivityRecordTrampoline.getWindowingMode(),
+ SystemClock.uptimeMillis());
+
+ verify(mLaunchObserver).onActivityLaunchFinished(eq(mActivityRecordTrampoline));
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+
+ @Test
+ public void testOnActivityLaunchCancelledTrampoline() throws Exception {
+ testOnActivityLaunchedTrampoline();
+
+ mActivityRecordTrampoline.nowVisible = true;
+
+ // Cannot time already-visible activities.
+ mActivityMetricsLogger.notifyActivityLaunched(START_TASK_TO_FRONT,
+ mActivityRecordTrampoline);
+
+ verify(mLaunchObserver).onActivityLaunchCancelled(eq(mActivityRecordTrampoline));
+ verifyNoMoreInteractions(mLaunchObserver);
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
index a794d6d5cf43..c2ef478406e7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackSupervisorTests.java
@@ -458,4 +458,23 @@ public class ActivityStackSupervisorTests extends ActivityTestsBase {
assertNotNull(secondDisplay.getTopStack());
assertTrue(secondDisplay.getTopStack().isActivityTypeHome());
}
+
+ /**
+ * Tests that home activities won't be started before booting when display added.
+ */
+ @Test
+ public void testNotStartHomeBeforeBoot() throws Exception {
+ final int displayId = 1;
+ final boolean isBooting = mService.mAmInternal.isBooting();
+ final boolean isBooted = mService.mAmInternal.isBooted();
+ try {
+ mService.mAmInternal.setBooting(false);
+ mService.mAmInternal.setBooted(false);
+ mSupervisor.onDisplayAdded(displayId);
+ verify(mSupervisor, never()).startHomeOnDisplay(anyInt(), any(), anyInt());
+ } finally {
+ mService.mAmInternal.setBooting(isBooting);
+ mService.mAmInternal.setBooted(isBooted);
+ }
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 974e285133f8..62767e33b3bf 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -457,7 +457,7 @@ public class ActivityStackTests extends ActivityTestsBase {
final TestActivityStack fullscreenStack2 = createStackForShouldBeVisibleTest(
mDefaultDisplay, WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
true /* onTop */);
- final TestActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
+ final ActivityStack pinnedStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_PINNED, ACTIVITY_TYPE_STANDARD, true /* onTop */);
homeStack.setIsTranslucent(false);
diff --git a/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
index 01b7c4f650e7..0445ea03da73 100644
--- a/services/tests/servicestests/src/com/android/server/wm/WindowTracingTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTracingTest.java
@@ -16,6 +16,8 @@
package com.android.server.wm;
+import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentation;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -29,21 +31,21 @@ import static org.mockito.Mockito.verifyZeroInteractions;
import android.content.Context;
import android.platform.test.annotations.Presubmit;
+import android.testing.DexmakerShareClassLoaderRule;
import android.util.proto.ProtoOutputStream;
-import androidx.test.InstrumentationRegistry;
import androidx.test.filters.FlakyTest;
import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
import com.android.internal.util.Preconditions;
-import com.android.server.wm.WindowManagerTraceProto;
import org.junit.After;
import org.junit.Before;
import org.junit.Ignore;
+import org.junit.Rule;
import org.junit.Test;
-import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
import java.io.File;
import java.io.FileInputStream;
@@ -55,41 +57,44 @@ import java.nio.charset.StandardCharsets;
* Test class for {@link WindowTracing}.
*
* Build/Install/Run:
- * bit FrameworksServicesTests:com.android.server.wm.WindowTracingTest
+ * atest FrameworksServicesTests:WindowTracingTest
*/
-@SmallTest
@FlakyTest(bugId = 74078662)
-// TODO(b/116597907): Re-enable this test in postsubmit after the bug is fixed.
-// @Presubmit
-@RunWith(AndroidJUnit4.class)
-public class WindowTracingTest extends WindowTestsBase {
+@SmallTest
+@Presubmit
+public class WindowTracingTest {
- private static final byte[] MAGIC_HEADER = new byte[] {
- 0x9, 0x57, 0x49, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45,
+ private static final byte[] MAGIC_HEADER = new byte[]{
+ 0x9, 0x57, 0x49, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x45,
};
- private Context mTestContext;
- private WindowTracing mWindowTracing;
+ @Rule
+ public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
+ new DexmakerShareClassLoaderRule();
+
+ @Mock
private WindowManagerService mWmMock;
+ private WindowTracing mWindowTracing;
private File mFile;
- @Override
@Before
public void setUp() throws Exception {
- super.setUp();
+ MockitoAnnotations.initMocks(this);
- mWmMock = mock(WindowManagerService.class);
-
- mTestContext = InstrumentationRegistry.getContext();
-
- mFile = mTestContext.getFileStreamPath("tracing_test.dat");
+ final Context testContext = getInstrumentation().getContext();
+ mFile = testContext.getFileStreamPath("tracing_test.dat");
mFile.delete();
mWindowTracing = new WindowTracing(mFile);
}
+ @After
+ public void tearDown() throws Exception {
+ mFile.delete();
+ }
+
@Test
- public void isEnabled_returnsFalseByDefault() throws Exception {
+ public void isEnabled_returnsFalseByDefault() {
assertFalse(mWindowTracing.isEnabled());
}
@@ -107,7 +112,7 @@ public class WindowTracingTest extends WindowTestsBase {
}
@Test
- public void trace_discared_whenNotTracing() throws Exception {
+ public void trace_discared_whenNotTracing() {
mWindowTracing.traceStateLocked("where", mWmMock);
verifyZeroInteractions(mWmMock);
}
@@ -132,12 +137,12 @@ public class WindowTracingTest extends WindowTestsBase {
}
}
- @Test
@Ignore("Figure out why this test is crashing when setting up mWmMock.")
+ @Test
public void tracing_endsUpInFile() throws Exception {
mWindowTracing.startTrace(mock(PrintWriter.class));
- doAnswer((inv) -> {
+ doAnswer(inv -> {
inv.<ProtoOutputStream>getArgument(0).write(
WindowManagerTraceProto.WHERE, "TEST_WM_PROTO");
return null;
@@ -157,22 +162,14 @@ public class WindowTracingTest extends WindowTestsBase {
}
}
- @Override
- @After
- public void tearDown() throws Exception {
- super.tearDown();
-
- mFile.delete();
- }
-
/** Return true if {@code needle} appears anywhere in {@code haystack[0..length]} */
- boolean containsBytes(byte[] haystack, int haystackLenght, byte[] needle) {
- Preconditions.checkArgument(haystackLenght > 0);
+ private static boolean containsBytes(byte[] haystack, int haystackLength, byte[] needle) {
+ Preconditions.checkArgument(haystackLength > 0);
Preconditions.checkArgument(needle.length > 0);
- outer: for (int i = 0; i <= haystackLenght - needle.length; i++) {
+ outer: for (int i = 0; i <= haystackLength - needle.length; i++) {
for (int j = 0; j < needle.length; j++) {
- if (haystack[i+j] != needle[j]) {
+ if (haystack[i + j] != needle[j]) {
continue outer;
}
}
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 52ac32daf565..d7024cfb7e2f 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -16,6 +16,7 @@
package android.provider;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
@@ -1271,6 +1272,31 @@ public final class Telephony {
*/
public static final String EXTRA_IS_INITIAL_CREATE =
"android.provider.extra.IS_INITIAL_CREATE";
+
+ /**
+ * Broadcast intent action indicating that the telephony provider SMS MMS database is
+ * corrupted. A boolean is specified in {@link #EXTRA_IS_CORRUPTED} to indicate if the
+ * database is corrupted. Requires the
+ * {@link android.Manifest.permission#READ_PRIVILEGED_PHONE_STATE permission.
+ *
+ * @hide
+ */
+ @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+ @RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
+ public static final String ACTION_SMS_MMS_DB_LOST =
+ "android.provider.action.SMS_MMS_DB_LOST";
+
+ /**
+ * Boolean flag passed as an extra with {@link #ACTION_SMS_MMS_DB_LOST} to indicate
+ * whether the DB got corrupted or not.
+ *
+ * @see #ACTION_SMS_MMS_DB_LOST
+ *
+ * @hide
+ */
+ public static final String EXTRA_IS_CORRUPTED =
+ "android.provider.extra.IS_CORRUPTED";
+
/**
* Read the PDUs out of an {@link #SMS_RECEIVED_ACTION} or a
* {@link #DATA_SMS_RECEIVED_ACTION} intent.
diff --git a/telephony/java/android/telephony/AccessNetworkConstants.java b/telephony/java/android/telephony/AccessNetworkConstants.java
index cac9f2b51b73..9c64cf6ddd8f 100644
--- a/telephony/java/android/telephony/AccessNetworkConstants.java
+++ b/telephony/java/android/telephony/AccessNetworkConstants.java
@@ -32,7 +32,20 @@ public final class AccessNetworkConstants {
public static final int IWLAN = 5;
/** @hide */
- private AccessNetworkType() {};
+ private AccessNetworkType() {}
+
+ /** @hide */
+ public static String toString(int type) {
+ switch (type) {
+ case UNKNOWN: return "UNKNOWN";
+ case GERAN: return "GERAN";
+ case UTRAN: return "UTRAN";
+ case EUTRAN: return "EUTRAN";
+ case CDMA2000: return "CDMA2000";
+ case IWLAN: return "IWLAN";
+ default: return Integer.toString(type);
+ }
+ }
}
/**
@@ -47,7 +60,16 @@ public final class AccessNetworkConstants {
public static final int WLAN = 2;
/** @hide */
- private TransportType() {};
+ private TransportType() {}
+
+ /** @hide */
+ public static String toString(int type) {
+ switch (type) {
+ case WWAN: return "WWAN";
+ case WLAN: return "WLAN";
+ default: return Integer.toString(type);
+ }
+ }
}
/**
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 983e766a6a98..99de4cad605a 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1231,6 +1231,47 @@ public class CarrierConfigManager {
public static final String KEY_SHOW_PRECISE_FAILED_CAUSE_BOOL =
"show_precise_failed_cause_bool";
+ /**
+ * Boolean to decide whether lte is enabled.
+ * @hide
+ */
+ public static final String KEY_LTE_ENABLED_BOOL = "lte_enabled_bool";
+
+ /**
+ * Boolean to decide whether TD-SCDMA is supported.
+ * @hide
+ */
+ public static final String KEY_SUPPORT_TDSCDMA_BOOL = "support_tdscdma_bool";
+
+ /**
+ * A list of mcc/mnc that support TD-SCDMA for device when connect to the roaming network.
+ * @hide
+ */
+ public static final String KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY =
+ "support_tdscdma_roaming_networks_string_array";
+
+ /**
+ * Boolean to decide whether world mode is enabled.
+ * @hide
+ */
+ public static final String KEY_WORLD_MODE_ENABLED_BOOL = "world_mode_enabled_bool";
+
+ /**
+ * Package name of the carrier settings activity.
+ * @see {@link #KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING}.
+ * @hide
+ */
+ public static final String KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING =
+ "carrier_settings_activity_package_name_string";
+
+ /**
+ * Class name of the carrier settings activity.
+ * @see {@link #KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING}.
+ * @hide
+ */
+ public static final String KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING =
+ "carrier_settings_activity_class_name_string";
+
// These variables are used by the MMS service and exposed through another API,
// SmsManager. The variable names and string values are copied from there.
public static final String KEY_MMS_ALIAS_ENABLED_BOOL = "aliasEnabled";
@@ -2570,6 +2611,12 @@ public class CarrierConfigManager {
sDefaults.putBoolean(KEY_ALWAYS_SHOW_DATA_RAT_ICON_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_4G_FOR_LTE_DATA_ICON_BOOL, false);
sDefaults.putBoolean(KEY_HIDE_LTE_PLUS_DATA_ICON_BOOL, true);
+ sDefaults.putBoolean(KEY_LTE_ENABLED_BOOL, true);
+ sDefaults.putBoolean(KEY_SUPPORT_TDSCDMA_BOOL, false);
+ sDefaults.putStringArray(KEY_SUPPORT_TDSCDMA_ROAMING_NETWORKS_STRING_ARRAY, null);
+ sDefaults.putBoolean(KEY_WORLD_MODE_ENABLED_BOOL, false);
+ sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_PACKAGE_NAME_STRING, "");
+ sDefaults.putString(KEY_CARRIER_SETTINGS_ACTIVITY_CLASS_NAME_STRING, "");
sDefaults.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, false);
sDefaults.putBoolean(KEY_CHECK_PRICING_WITH_CARRIER_FOR_DATA_ROAMING_BOOL, false);
sDefaults.putIntArray(KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY,
diff --git a/telephony/java/android/telephony/CellSignalStrengthLte.java b/telephony/java/android/telephony/CellSignalStrengthLte.java
index 05c1fd53e901..d6856b397a00 100644
--- a/telephony/java/android/telephony/CellSignalStrengthLte.java
+++ b/telephony/java/android/telephony/CellSignalStrengthLte.java
@@ -31,27 +31,8 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
private static final String LOG_TAG = "CellSignalStrengthLte";
private static final boolean DBG = false;
- /**
- * Indicates the unknown or undetectable RSSI value in ASU.
- *
- * Reference: TS 27.007 8.5 - Signal quality +CSQ
- */
- private static final int SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN = 99;
- /**
- * Indicates the maximum valid RSSI value in ASU.
- *
- * Reference: TS 27.007 8.5 - Signal quality +CSQ
- */
- private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE = 31;
- /**
- * Indicates the minimum valid RSSI value in ASU.
- *
- * Reference: TS 27.007 8.5 - Signal quality +CSQ
- */
- private static final int SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE = 0;
-
@UnsupportedAppUsage
- private int mRssi;
+ private int mSignalStrength;
@UnsupportedAppUsage
private int mRsrp;
@UnsupportedAppUsage
@@ -70,9 +51,9 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
}
/** @hide */
- public CellSignalStrengthLte(int rssi, int rsrp, int rsrq, int rssnr, int cqi,
+ public CellSignalStrengthLte(int signalStrength, int rsrp, int rsrq, int rssnr, int cqi,
int timingAdvance) {
- mRssi = convertRssiAsuToDBm(rssi);
+ mSignalStrength = signalStrength;
mRsrp = rsrp;
mRsrq = rsrq;
mRssnr = rssnr;
@@ -87,7 +68,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
/** @hide */
protected void copyFrom(CellSignalStrengthLte s) {
- mRssi = s.mRssi;
+ mSignalStrength = s.mSignalStrength;
mRsrp = s.mRsrp;
mRsrq = s.mRsrq;
mRssnr = s.mRssnr;
@@ -104,7 +85,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
/** @hide */
@Override
public void setDefaultValues() {
- mRssi = CellInfo.UNAVAILABLE;
+ mSignalStrength = CellInfo.UNAVAILABLE;
mRsrp = CellInfo.UNAVAILABLE;
mRsrq = CellInfo.UNAVAILABLE;
mRssnr = CellInfo.UNAVAILABLE;
@@ -161,19 +142,6 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
}
/**
- * Get Received Signal Strength Indication (RSSI) in dBm
- *
- * The value range is [-113, -51] inclusively or {@link CellInfo#UNAVAILABLE} if unavailable.
- *
- * Reference: TS 27.007 8.5 Signal quality +CSQ
- *
- * @return the RSSI if available or {@link CellInfo#UNAVAILABLE} if unavailable.
- */
- public int getRssi() {
- return mRssi;
- }
-
- /**
* Get reference signal signal-to-noise ratio
*
* @return the RSSNR if available or
@@ -242,7 +210,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
@Override
public int hashCode() {
- return Objects.hash(mRssi, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance);
+ return Objects.hash(mSignalStrength, mRsrp, mRsrq, mRssnr, mCqi, mTimingAdvance);
}
@Override
@@ -259,7 +227,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
return false;
}
- return mRssi == s.mRssi
+ return mSignalStrength == s.mSignalStrength
&& mRsrp == s.mRsrp
&& mRsrq == s.mRsrq
&& mRssnr == s.mRssnr
@@ -273,7 +241,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
@Override
public String toString() {
return "CellSignalStrengthLte:"
- + " rssi(dBm)=" + mRssi
+ + " ss=" + mSignalStrength
+ " rsrp=" + mRsrp
+ " rsrq=" + mRsrq
+ " rssnr=" + mRssnr
@@ -285,7 +253,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
@Override
public void writeToParcel(Parcel dest, int flags) {
if (DBG) log("writeToParcel(Parcel, int): " + toString());
- dest.writeInt(mRssi);
+ dest.writeInt(mSignalStrength);
// Need to multiply rsrp and rsrq by -1
// to ensure consistency when reading values written here
// unless the values are invalid
@@ -301,7 +269,7 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
* where the token is already been processed.
*/
private CellSignalStrengthLte(Parcel in) {
- mRssi = convertRssiAsuToDBm(in.readInt());
+ mSignalStrength = in.readInt();
// rsrp and rsrq are written into the parcel as positive values.
// Need to convert into negative values unless the values are invalid
mRsrp = in.readInt();
@@ -341,17 +309,4 @@ public final class CellSignalStrengthLte extends CellSignalStrength implements P
private static void log(String s) {
Rlog.w(LOG_TAG, s);
}
-
- private static int convertRssiAsuToDBm(int rssiAsu) {
- if (rssiAsu != SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN
- && (rssiAsu < SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MIN_VALUE
- || rssiAsu > SIGNAL_STRENGTH_LTE_RSSI_VALID_ASU_MAX_VALUE)) {
- Rlog.e(LOG_TAG, "convertRssiAsuToDBm: invalid RSSI in ASU=" + rssiAsu);
- return CellInfo.UNAVAILABLE;
- }
- if (rssiAsu == SIGNAL_STRENGTH_LTE_RSSI_ASU_UNKNOWN) {
- return CellInfo.UNAVAILABLE;
- }
- return -113 + (2 * rssiAsu);
- }
}
diff --git a/telephony/java/android/telephony/DisconnectCause.java b/telephony/java/android/telephony/DisconnectCause.java
index d7169b23d94b..c6887ab93109 100644
--- a/telephony/java/android/telephony/DisconnectCause.java
+++ b/telephony/java/android/telephony/DisconnectCause.java
@@ -342,6 +342,12 @@ public class DisconnectCause {
*/
public static final int TOO_MANY_ONGOING_CALLS = 75;
+ /**
+ * Indicates that a new outgoing call cannot be placed because OTASP provisioning is currently
+ * in process.
+ */
+ public static final int OTASP_PROVISIONING_IN_PROCESS = 76;
+
//*********************************************************************************************
// When adding a disconnect type:
// 1) Update toString() with the newly added disconnect type.
@@ -505,6 +511,8 @@ public class DisconnectCause {
return "CALLING_DISABLED";
case TOO_MANY_ONGOING_CALLS:
return "TOO_MANY_ONGOING_CALLS";
+ case OTASP_PROVISIONING_IN_PROCESS:
+ return "OTASP_PROVISIONING_IN_PROCESS";
default:
return "INVALID: " + cause;
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index e5c4ccda422a..1091b5839fe4 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1238,38 +1238,6 @@ public class TelephonyManager {
*/
public static final String EXTRA_RECOVERY_ACTION = "recoveryAction";
- /**
- * Broadcast intent action indicating that the telephony provider DB got lost.
- *
- * <p>
- * The {@link #EXTRA_IS_CORRUPTED} extra indicates whether the database is lost
- * due to corruption or not
- *
- * <p class="note">
- * Requires the MODIFY_PHONE_STATE permission.
- *
- * <p class="note">
- * This is a protected intent that can only be sent by the system.
- *
- * @see #EXTRA_IS_CORRUPTED
- *
- * @hide
- */
- @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
- public static final String ACTION_MMSSMS_DATABASE_LOST =
- "android.intent.action.MMSSMS_DATABASE_LOST";
-
- /**
- * A boolean extra used with {@link #ACTION_MMSSMS_DATABASE_LOST} to indicate
- * whether the database is lost due to corruption or not.
- *
- * @see #ACTION_MMSSMS_DATABASE_LOST
- *
- * @hide
- */
- public static final String EXTRA_IS_CORRUPTED = "isCorrupted";
-
//
//
// Device Info
@@ -1317,9 +1285,10 @@ public class TelephonyManager {
* Returns the unique device ID, for example, the IMEI for GSM and the MEID
* or ESN for CDMA phones. Return null if device ID is not available.
*
- * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
- * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
- * that owns a managed profile on the device; for more details see <a
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
@@ -1327,7 +1296,7 @@ public class TelephonyManager {
* MEID for CDMA.
*/
@Deprecated
- @SuppressAutoDoc // No support for device / profile owner.
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getDeviceId() {
try {
@@ -1346,9 +1315,10 @@ public class TelephonyManager {
* Returns the unique device ID of a subscription, for example, the IMEI for
* GSM and the MEID for CDMA phones. Return null if device ID is not available.
*
- * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
- * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
- * that owns a managed profile on the device; for more details see <a
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
@@ -1358,7 +1328,7 @@ public class TelephonyManager {
* MEID for CDMA.
*/
@Deprecated
- @SuppressAutoDoc // No support for device / profile owner.
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getDeviceId(int slotIndex) {
// FIXME this assumes phoneId == slotIndex
@@ -1378,13 +1348,14 @@ public class TelephonyManager {
* Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
* available.
*
- * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
- * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
- * that owns a managed profile on the device; for more details see <a
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*/
- @SuppressAutoDoc // No support for device / profile owner.
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getImei() {
return getImei(getSlotIndex());
@@ -1394,15 +1365,16 @@ public class TelephonyManager {
* Returns the IMEI (International Mobile Equipment Identity). Return null if IMEI is not
* available.
*
- * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
- * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
- * that owns a managed profile on the device; for more details see <a
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
* @param slotIndex of which IMEI is returned
*/
- @SuppressAutoDoc // No support for device / profile owner.
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getImei(int slotIndex) {
ITelephony telephony = getITelephony();
@@ -1447,13 +1419,14 @@ public class TelephonyManager {
/**
* Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
*
- * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
- * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
- * that owns a managed profile on the device; for more details see <a
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*/
- @SuppressAutoDoc // No support for device / profile owner.
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getMeid() {
return getMeid(getSlotIndex());
@@ -1462,15 +1435,16 @@ public class TelephonyManager {
/**
* Returns the MEID (Mobile Equipment Identifier). Return null if MEID is not available.
*
- * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, or for the calling package to be the
- * device or profile owner and have the READ_PHONE_STATE permission. The profile owner is an app
- * that owns a managed profile on the device; for more details see <a
+ * <p>Requires Permission: READ_PRIVILEGED_PHONE_STATE, for the calling app to be the device or
+ * profile owner and have the READ_PHONE_STATE permission, or that the calling app has carrier
+ * privileges (see {@link #hasCarrierPrivileges}). The profile owner is an app that owns a
+ * managed profile on the device; for more details see <a
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*
* @param slotIndex of which MEID is returned
*/
- @SuppressAutoDoc // No support for device / profile owner.
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getMeid(int slotIndex) {
ITelephony telephony = getITelephony();
@@ -2968,7 +2942,7 @@ public class TelephonyManager {
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*/
- @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getSimSerialNumber() {
return getSimSerialNumber(getSubId());
@@ -3130,7 +3104,7 @@ public class TelephonyManager {
* href="https://developer.android.com/work/managed-profiles">Work profiles</a>. Profile owner
* access is deprecated and will be removed in a future release.
*/
- @SuppressAutoDoc // Blocked by b/72967236 - no support for carrier privileges
+ @SuppressAutoDoc // No support for device / profile owner or carrier privileges (b/72967236).
@RequiresPermission(android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public String getSubscriberId() {
return getSubscriberId(getSubId());
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index aabefe324d82..2e9bffe9e0d9 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -1184,6 +1184,16 @@ public class ApnSetting implements Parcelable {
}
/**
+ * @param apnType APN type
+ * @return APN type in string format
+ * @hide
+ */
+ public static String getApnTypeString(int apnType) {
+ String apnTypeString = APN_TYPE_INT_MAP.get(apnType);
+ return apnTypeString == null ? "Unknown" : apnTypeString;
+ }
+
+ /**
* @param types comma delimited list of APN types.
* @return bitmask of APN types.
* @hide
diff --git a/telephony/java/android/telephony/euicc/EuiccCardManager.java b/telephony/java/android/telephony/euicc/EuiccCardManager.java
index 11411778a9ab..3b1ef3f45993 100644
--- a/telephony/java/android/telephony/euicc/EuiccCardManager.java
+++ b/telephony/java/android/telephony/euicc/EuiccCardManager.java
@@ -15,6 +15,7 @@
*/
package android.telephony.euicc;
+import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -50,7 +51,6 @@ import com.android.internal.telephony.euicc.ISwitchToProfileCallback;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
-import android.annotation.CallbackExecutor;
import java.util.concurrent.Executor;
/**
@@ -119,6 +119,9 @@ public class EuiccCardManager {
/** Result code when the eUICC card with the given card Id is not found. */
public static final int RESULT_EUICC_NOT_FOUND = -2;
+ /** Result code indicating the caller is not the active LPA. */
+ public static final int RESULT_CALLER_NOT_ALLOWED = -3;
+
/**
* Callback to receive the result of an eUICC card API.
*
@@ -152,7 +155,7 @@ public class EuiccCardManager {
* Requests all the profiles on eUicc.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code and all the profiles.
*/
public void requestAllProfiles(String cardId, @CallbackExecutor Executor executor,
@@ -176,7 +179,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code and profile.
*/
public void requestProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
@@ -201,7 +204,7 @@ public class EuiccCardManager {
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
* @param refresh Whether sending the REFRESH command to modem.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code.
*/
public void disableProfile(String cardId, String iccid, boolean refresh,
@@ -227,7 +230,7 @@ public class EuiccCardManager {
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile to switch to.
* @param refresh Whether sending the REFRESH command to modem.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code and the EuiccProfileInfo enabled.
*/
public void switchToProfile(String cardId, String iccid, boolean refresh,
@@ -252,7 +255,7 @@ public class EuiccCardManager {
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
* @param nickname The nickname of the profile.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code.
*/
public void setNickname(String cardId, String iccid, String nickname,
@@ -276,7 +279,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param iccid The iccid of the profile.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code.
*/
public void deleteProfile(String cardId, String iccid, @CallbackExecutor Executor executor,
@@ -301,7 +304,7 @@ public class EuiccCardManager {
* @param cardId The Id of the eUICC.
* @param options Bits of the options of resetting which parts of the eUICC memory. See
* EuiccCard for details.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code.
*/
public void resetMemory(String cardId, @ResetOption int options,
@@ -324,7 +327,7 @@ public class EuiccCardManager {
* Requests the default SM-DP+ address from eUICC.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code and the default SM-DP+ address.
*/
public void requestDefaultSmdpAddress(String cardId, @CallbackExecutor Executor executor,
@@ -347,7 +350,7 @@ public class EuiccCardManager {
* Requests the SM-DS address from eUICC.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code and the SM-DS address.
*/
public void requestSmdsAddress(String cardId, @CallbackExecutor Executor executor,
@@ -371,7 +374,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param defaultSmdpAddress The default SM-DP+ address to set.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback The callback to get the result code.
*/
public void setDefaultSmdpAddress(String cardId, String defaultSmdpAddress,
@@ -395,7 +398,7 @@ public class EuiccCardManager {
* Requests Rules Authorisation Table.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and the rule authorisation table.
*/
public void requestRulesAuthTable(String cardId, @CallbackExecutor Executor executor,
@@ -418,7 +421,7 @@ public class EuiccCardManager {
* Requests the eUICC challenge for new profile downloading.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and the challenge.
*/
public void requestEuiccChallenge(String cardId, @CallbackExecutor Executor executor,
@@ -441,7 +444,7 @@ public class EuiccCardManager {
* Requests the eUICC info1 defined in GSMA RSP v2.0+ for new profile downloading.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and the info1.
*/
public void requestEuiccInfo1(String cardId, @CallbackExecutor Executor executor,
@@ -464,7 +467,7 @@ public class EuiccCardManager {
* Gets the eUICC info2 defined in GSMA RSP v2.0+ for new profile downloading.
*
* @param cardId The Id of the eUICC.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and the info2.
*/
public void requestEuiccInfo2(String cardId, @CallbackExecutor Executor executor,
@@ -497,7 +500,7 @@ public class EuiccCardManager {
* GSMA RSP v2.0+.
* @param serverCertificate ASN.1 data in byte array indicating SM-DP+ Certificate returned by
* SM-DP+ server.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and a byte array which represents a
* {@code AuthenticateServerResponse} defined in GSMA RSP v2.0+.
*/
@@ -537,7 +540,7 @@ public class EuiccCardManager {
* SM-DP+ server.
* @param smdpCertificate ASN.1 data in byte array indicating the SM-DP+ Certificate returned
* by SM-DP+ server.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and a byte array which represents a
* {@code PrepareDownloadResponse} defined in GSMA RSP v2.0+
*/
@@ -569,7 +572,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param boundProfilePackage the Bound Profile Package data returned by SM-DP+ server.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and a byte array which represents a
* {@code LoadBoundProfilePackageResponse} defined in GSMA RSP v2.0+.
*/
@@ -598,7 +601,7 @@ public class EuiccCardManager {
* @param cardId The Id of the eUICC.
* @param transactionId the transaction ID returned by SM-DP+ server.
* @param reason the cancel reason.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and an byte[] which represents a
* {@code CancelSessionResponse} defined in GSMA RSP v2.0+.
*/
@@ -627,7 +630,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param events bits of the event types ({@link EuiccNotification.Event}) to list.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and the list of notifications.
*/
public void listNotifications(String cardId, @EuiccNotification.Event int events,
@@ -651,7 +654,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param events bits of the event types ({@link EuiccNotification.Event}) to list.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and the list of notifications.
*/
public void retrieveNotificationList(String cardId, @EuiccNotification.Event int events,
@@ -675,7 +678,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param seqNumber the sequence number of the notification.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code and the notification.
*/
public void retrieveNotification(String cardId, int seqNumber,
@@ -699,7 +702,7 @@ public class EuiccCardManager {
*
* @param cardId The Id of the eUICC.
* @param seqNumber the sequence number of the notification.
- * @param executor The executor through which the callback should be invode.
+ * @param executor The executor through which the callback should be invoke.
* @param callback the callback to get the result code.
*/
public void removeNotificationFromList(String cardId, int seqNumber,
diff --git a/telephony/java/android/telephony/ims/ImsCallProfile.java b/telephony/java/android/telephony/ims/ImsCallProfile.java
index 89ef33914c12..f73036e88a95 100644
--- a/telephony/java/android/telephony/ims/ImsCallProfile.java
+++ b/telephony/java/android/telephony/ims/ImsCallProfile.java
@@ -16,17 +16,20 @@
package android.telephony.ims;
+import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.PersistableBundle;
import android.telecom.VideoProfile;
import android.util.Log;
import com.android.internal.telephony.PhoneConstants;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
/**
* Parcelable object to handle IMS call profile.
* It is created from GSMA IR.92/IR.94, 3GPP TS 24.229/TS 26.114/TS26.111.
@@ -206,17 +209,36 @@ public final class ImsCallProfile implements Parcelable {
public static final int DIALSTRING_USSD = 2;
/**
- * Values for causes that restrict call types
+ * Call is not restricted on peer side and High Definition media is supported
*/
- // Default cause not restricted at peer and HD is supported
public static final int CALL_RESTRICT_CAUSE_NONE = 0;
- // Service not supported by RAT at peer
+
+ /**
+ * High Definition media is not supported on the peer side due to the Radio Access Technology
+ * (RAT) it is are connected to.
+ */
public static final int CALL_RESTRICT_CAUSE_RAT = 1;
- // Service Disabled at peer
+
+ /**
+ * The service has been disabled on the peer side.
+ */
public static final int CALL_RESTRICT_CAUSE_DISABLED = 2;
- // HD is not supported
+
+ /**
+ * High definition media is not currently supported.
+ */
public static final int CALL_RESTRICT_CAUSE_HD = 3;
+ /**@hide*/
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = "CALL_RESTRICT_CAUSE_", value = {
+ CALL_RESTRICT_CAUSE_NONE,
+ CALL_RESTRICT_CAUSE_RAT,
+ CALL_RESTRICT_CAUSE_DISABLED,
+ CALL_RESTRICT_CAUSE_HD
+ })
+ public @interface CallRestrictCause {}
+
/**
* String extra properties
* oi : Originating identity (number), MT only
@@ -270,7 +292,7 @@ public final class ImsCallProfile implements Parcelable {
public int mCallType;
/** @hide */
@UnsupportedAppUsage
- public int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
+ public @CallRestrictCause int mRestrictCause = CALL_RESTRICT_CAUSE_NONE;
/**
* Extras associated with this {@link ImsCallProfile}.
@@ -285,7 +307,7 @@ public final class ImsCallProfile implements Parcelable {
* <li>{@code long[]}</li>
* <li>{@code double[]}</li>
* <li>{@code String[]}</li>
- * <li>{@link PersistableBundle}</li>
+ * <li>{@link android.os.PersistableBundle}</li>
* <li>{@link Boolean} (and boolean)</li>
* <li>{@code boolean[]}</li>
* <li>Other {@link Parcelable} classes in the {@code android.*} namespace.</li>
@@ -426,6 +448,14 @@ public final class ImsCallProfile implements Parcelable {
}
}
+ /**
+ * Set the call restrict cause, which provides the reason why a call has been restricted from
+ * using High Definition media.
+ */
+ public void setCallRestrictCause(@CallRestrictCause int cause) {
+ mRestrictCause = cause;
+ }
+
public void updateCallType(ImsCallProfile profile) {
mCallType = profile.mCallType;
}
@@ -494,7 +524,11 @@ public final class ImsCallProfile implements Parcelable {
return mCallType;
}
- public int getRestrictCause() {
+ /**
+ * @return The call restrict cause, which provides the reason why a call has been restricted
+ * from using High Definition media.
+ */
+ public @CallRestrictCause int getRestrictCause() {
return mRestrictCause;
}
diff --git a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
index eb6be65104d1..553e3fb9d219 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyPermissions.java
@@ -188,6 +188,13 @@ public final class TelephonyPermissions {
if (checkReadDeviceIdentifiers(context, pid, uid, callingPackage)) {
return true;
}
+ // Calling packages with carrier privileges will also have access to device identifiers, but
+ // this may be removed in a future release.
+ if (SubscriptionManager.isValidSubscriptionId(subId) && getCarrierPrivilegeStatus(
+ TELEPHONY_SUPPLIER, subId, uid)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return true;
+ }
// else the calling package is not authorized to access the device identifiers; call
// a central method to report the failure based on the target SDK and if the calling package
// has the READ_PHONE_STATE permission or carrier privileges that were previously required
@@ -279,44 +286,51 @@ public final class TelephonyPermissions {
int uid, String callingPackage, String message) {
Log.wtf(LOG_TAG,
"reportAccessDeniedToReadIdentifiers:" + callingPackage + ":" + message);
- // if the device identifier check is relaxed then revert to the READ_PHONE_STATE permission
- // check that was previously required to access device identifiers.
- boolean relaxDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
- Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED, 0) == 0;
- if (relaxDeviceIdentifierCheck) {
- return checkReadPhoneState(context, subId, pid, uid, callingPackage, message);
- } else {
+ // If the device identifier check is enabled then enforce the new access requirements for
+ // both 1P and 3P apps.
+ boolean enableDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_CHECK_ENABLED, 0) == 1;
+ // Check if the application is a 3P app; if so then a separate setting is required to relax
+ // the check to begin flagging problems with 3P apps early.
+ boolean relax3PDeviceIdentifierCheck = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_3P_CHECK_RELAXED, 0) == 1;
+ boolean is3PApp = true;
+ ApplicationInfo callingPackageInfo = null;
+ try {
+ callingPackageInfo = context.getPackageManager().getApplicationInfo(callingPackage, 0);
+ if (callingPackageInfo.isSystemApp()) {
+ is3PApp = false;
+ }
+ } catch (PackageManager.NameNotFoundException e) {
+ // If the application info for the calling package could not be found then assume the
+ // calling app is a 3P app to detect any issues with the check
+ }
+ if (enableDeviceIdentifierCheck || (is3PApp && !relax3PDeviceIdentifierCheck)) {
boolean targetQBehaviorDisabled = Settings.Global.getInt(context.getContentResolver(),
Settings.Global.PRIVILEGED_DEVICE_IDENTIFIER_TARGET_Q_BEHAVIOR_ENABLED, 0) == 0;
if (callingPackage != null) {
- try {
- // if the target SDK is pre-Q or the target Q behavior is disabled then check if
- // the calling package would have previously had access to device identifiers.
- ApplicationInfo callingPackageInfo =
- context.getPackageManager().getApplicationInfo(
- callingPackage, 0);
- if (callingPackageInfo != null && (
- callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q
- || targetQBehaviorDisabled)) {
- if (context.checkPermission(
- android.Manifest.permission.READ_PHONE_STATE,
- pid,
- uid) == PackageManager.PERMISSION_GRANTED) {
- return false;
- }
- if (SubscriptionManager.isValidSubscriptionId(subId)
- && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, uid)
- == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
- return false;
- }
+ // if the target SDK is pre-Q or the target Q behavior is disabled then check if
+ // the calling package would have previously had access to device identifiers.
+ if (callingPackageInfo != null && (
+ callingPackageInfo.targetSdkVersion < Build.VERSION_CODES.Q
+ || targetQBehaviorDisabled)) {
+ if (context.checkPermission(
+ android.Manifest.permission.READ_PHONE_STATE,
+ pid,
+ uid) == PackageManager.PERMISSION_GRANTED) {
+ return false;
+ }
+ if (SubscriptionManager.isValidSubscriptionId(subId)
+ && getCarrierPrivilegeStatus(TELEPHONY_SUPPLIER, subId, uid)
+ == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
+ return false;
}
- } catch (PackageManager.NameNotFoundException e) {
- // If the application info for the calling package could not be found then
- // default to throwing the SecurityException.
}
}
throw new SecurityException(message + ": The user " + uid
+ " does not meet the requirements to access device identifiers.");
+ } else {
+ return checkReadPhoneState(context, subId, pid, uid, callingPackage, message);
}
}
diff --git a/tests/net/java/android/net/MacAddressTest.java b/tests/net/java/android/net/MacAddressTest.java
index 04266c5b3a0f..b9222a86a092 100644
--- a/tests/net/java/android/net/MacAddressTest.java
+++ b/tests/net/java/android/net/MacAddressTest.java
@@ -17,8 +17,8 @@
package android.net;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import android.support.test.filters.SmallTest;
@@ -252,6 +252,39 @@ public class MacAddressTest {
}
}
+ @Test
+ public void testMatches() {
+ // match 4 bytes prefix
+ assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+ MacAddress.fromString("aa:bb:cc:dd:00:00"),
+ MacAddress.fromString("ff:ff:ff:ff:00:00")));
+
+ // match bytes 0,1,2 and 5
+ assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+ MacAddress.fromString("aa:bb:cc:00:00:11"),
+ MacAddress.fromString("ff:ff:ff:00:00:ff")));
+
+ // match 34 bit prefix
+ assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+ MacAddress.fromString("aa:bb:cc:dd:c0:00"),
+ MacAddress.fromString("ff:ff:ff:ff:c0:00")));
+
+ // fail to match 36 bit prefix
+ assertFalse(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+ MacAddress.fromString("aa:bb:cc:dd:40:00"),
+ MacAddress.fromString("ff:ff:ff:ff:f0:00")));
+
+ // match all 6 bytes
+ assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+ MacAddress.fromString("aa:bb:cc:dd:ee:11"),
+ MacAddress.fromString("ff:ff:ff:ff:ff:ff")));
+
+ // match none of 6 bytes
+ assertTrue(MacAddress.fromString("aa:bb:cc:dd:ee:11").matches(
+ MacAddress.fromString("00:00:00:00:00:00"),
+ MacAddress.fromString("00:00:00:00:00:00")));
+ }
+
static byte[] toByteArray(int... in) {
byte[] out = new byte[in.length];
for (int i = 0; i < in.length; i++) {
diff --git a/tools/aapt2/Debug.cpp b/tools/aapt2/Debug.cpp
index 0a517ab8a2de..0bc5221245ca 100644
--- a/tools/aapt2/Debug.cpp
+++ b/tools/aapt2/Debug.cpp
@@ -306,8 +306,29 @@ void Debug::PrintTable(const ResourceTable& table, const DebugPrintTableOptions&
break;
}
- if (entry->overlayable) {
- printer->Print(" OVERLAYABLE");
+ for (size_t i = 0; i < entry->overlayable_declarations.size(); i++) {
+ printer->Print((i == 0) ? " " : "|");
+ printer->Print("OVERLAYABLE");
+
+ if (entry->overlayable_declarations[i].policy) {
+ switch (entry->overlayable_declarations[i].policy.value()) {
+ case Overlayable::Policy::kProduct:
+ printer->Print("_PRODUCT");
+ break;
+ case Overlayable::Policy::kProductServices:
+ printer->Print("_PRODUCT_SERVICES");
+ break;
+ case Overlayable::Policy::kSystem:
+ printer->Print("_SYSTEM");
+ break;
+ case Overlayable::Policy::kVendor:
+ printer->Print("_VENDOR");
+ break;
+ case Overlayable::Policy::kPublic:
+ printer->Print("_PUBLIC");
+ break;
+ }
+ }
}
printer->Println();
diff --git a/tools/aapt2/ResourceParser.cpp b/tools/aapt2/ResourceParser.cpp
index 9a3f14c8e08e..4f25e0968c0e 100644
--- a/tools/aapt2/ResourceParser.cpp
+++ b/tools/aapt2/ResourceParser.cpp
@@ -99,7 +99,7 @@ struct ParsedResource {
ResourceId id;
Visibility::Level visibility_level = Visibility::Level::kUndefined;
bool allow_new = false;
- bool overlayable = false;
+ std::vector<Overlayable> overlayable_declarations;
std::string comment;
std::unique_ptr<Value> value;
@@ -133,11 +133,8 @@ static bool AddResourcesToTable(ResourceTable* table, IDiagnostics* diag, Parsed
}
}
- if (res->overlayable) {
- Overlayable overlayable;
- overlayable.source = res->source;
- overlayable.comment = res->comment;
- if (!table->SetOverlayable(res->name, overlayable, diag)) {
+ for (auto& overlayable : res->overlayable_declarations) {
+ if (!table->AddOverlayable(res->name, overlayable, diag)) {
return false;
}
}
@@ -673,7 +670,7 @@ bool ResourceParser::ParseResource(xml::XmlPullParser* parser,
if (can_be_bag) {
const auto bag_iter = elToBagMap.find(resource_type);
if (bag_iter != elToBagMap.end()) {
- // Ensure we have a name (unless this is a <public-group>).
+ // Ensure we have a name (unless this is a <public-group> or <overlayable>).
if (resource_type != "public-group" && resource_type != "overlayable") {
if (!maybe_name) {
diag_->Error(DiagMessage(out_resource->source)
@@ -1062,72 +1059,135 @@ bool ResourceParser::ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out
bool ResourceParser::ParseOverlayable(xml::XmlPullParser* parser, ParsedResource* out_resource) {
if (out_resource->config != ConfigDescription::DefaultConfig()) {
diag_->Warn(DiagMessage(out_resource->source)
- << "ignoring configuration '" << out_resource->config << "' for <overlayable> tag");
+ << "ignoring configuration '" << out_resource->config
+ << "' for <overlayable> tag");
}
- if (Maybe<StringPiece> maybe_policy = xml::FindNonEmptyAttribute(parser, "policy")) {
- const StringPiece& policy = maybe_policy.value();
- if (policy != "system") {
- diag_->Error(DiagMessage(out_resource->source)
- << "<overlayable> has invalid policy '" << policy << "'");
- return false;
- }
- }
+ std::string comment;
+ std::vector<Overlayable::Policy> policies;
bool error = false;
- const size_t depth = parser->depth();
- while (xml::XmlPullParser::NextChildNode(parser, depth)) {
- if (parser->event() != xml::XmlPullParser::Event::kStartElement) {
- // Skip text/comments.
+ const size_t start_depth = parser->depth();
+ while (xml::XmlPullParser::IsGoodEvent(parser->Next())) {
+ xml::XmlPullParser::Event event = parser->event();
+ if (event == xml::XmlPullParser::Event::kEndElement && parser->depth() == start_depth) {
+ // Break the loop when exiting the overyabale element
+ break;
+ } else if (event == xml::XmlPullParser::Event::kEndElement
+ && parser->depth() == start_depth + 1) {
+ // Clear the current policies when exiting the policy element
+ policies.clear();
+ continue;
+ } else if (event == xml::XmlPullParser::Event::kComment) {
+ // Get the comment of individual item elements
+ comment = parser->comment();
+ continue;
+ } else if (event != xml::XmlPullParser::Event::kStartElement) {
+ // Skip to the next element
continue;
}
const Source item_source = source_.WithLine(parser->line_number());
- const std::string& element_namespace = parser->element_namespace();
const std::string& element_name = parser->element_name();
+ const std::string& element_namespace = parser->element_namespace();
+
if (element_namespace.empty() && element_name == "item") {
- Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
- if (!maybe_name) {
- diag_->Error(DiagMessage(item_source)
- << "<item> within an <overlayable> tag must have a 'name' attribute");
+ if (!ParseOverlayableItem(parser, policies, comment, out_resource)) {
error = true;
- continue;
}
-
- Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
- if (!maybe_type) {
- diag_->Error(DiagMessage(item_source)
- << "<item> within an <overlayable> tag must have a 'type' attribute");
+ } else if (element_namespace.empty() && element_name == "policy") {
+ if (!policies.empty()) {
+ // If the policy list is not empty, then we are currently inside a policy element
+ diag_->Error(DiagMessage(item_source) << "<policy> blocks cannot be recursively nested");
error = true;
- continue;
+ break;
+ } else if (Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type")) {
+ // Parse the polices separated by vertical bar characters to allow for specifying multiple
+ // policies at once
+ for (StringPiece part : util::Tokenize(maybe_type.value(), '|')) {
+ StringPiece trimmed_part = util::TrimWhitespace(part);
+ if (trimmed_part == "public") {
+ policies.push_back(Overlayable::Policy::kPublic);
+ } else if (trimmed_part == "product") {
+ policies.push_back(Overlayable::Policy::kProduct);
+ } else if (trimmed_part == "product_services") {
+ policies.push_back(Overlayable::Policy::kProductServices);
+ } else if (trimmed_part == "system") {
+ policies.push_back(Overlayable::Policy::kSystem);
+ } else if (trimmed_part == "vendor") {
+ policies.push_back(Overlayable::Policy::kVendor);
+ } else {
+ diag_->Error(DiagMessage(out_resource->source)
+ << "<policy> has unsupported type '" << trimmed_part << "'");
+ error = true;
+ continue;
+ }
+ }
}
+ } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
+ diag_->Error(DiagMessage(item_source) << "invalid element <" << element_name << "> in "
+ << " <overlayable>");
+ error = true;
+ break;
+ }
+ }
- const ResourceType* type = ParseResourceType(maybe_type.value());
- if (type == nullptr) {
- diag_->Error(DiagMessage(out_resource->source)
+ return !error;
+}
+
+bool ResourceParser::ParseOverlayableItem(xml::XmlPullParser* parser,
+ const std::vector<Overlayable::Policy>& policies,
+ const std::string& comment,
+ ParsedResource* out_resource) {
+ const Source item_source = source_.WithLine(parser->line_number());
+
+ Maybe<StringPiece> maybe_name = xml::FindNonEmptyAttribute(parser, "name");
+ if (!maybe_name) {
+ diag_->Error(DiagMessage(item_source)
+ << "<item> within an <overlayable> tag must have a 'name' attribute");
+ return false;
+ }
+
+ Maybe<StringPiece> maybe_type = xml::FindNonEmptyAttribute(parser, "type");
+ if (!maybe_type) {
+ diag_->Error(DiagMessage(item_source)
+ << "<item> within an <overlayable> tag must have a 'type' attribute");
+ return false;
+ }
+
+ const ResourceType* type = ParseResourceType(maybe_type.value());
+ if (type == nullptr) {
+ diag_->Error(DiagMessage(out_resource->source)
<< "invalid resource type '" << maybe_type.value()
<< "' in <item> within an <overlayable>");
- error = true;
- continue;
- }
+ return false;
+ }
- ParsedResource child_resource;
- child_resource.name.type = *type;
- child_resource.name.entry = maybe_name.value().to_string();
- child_resource.source = item_source;
- child_resource.overlayable = true;
- if (options_.visibility) {
- child_resource.visibility_level = options_.visibility.value();
- }
- out_resource->child_resources.push_back(std::move(child_resource));
+ ParsedResource child_resource;
+ child_resource.name.type = *type;
+ child_resource.name.entry = maybe_name.value().to_string();
+ child_resource.source = item_source;
- xml::XmlPullParser::SkipCurrentElement(parser);
- } else if (!ShouldIgnoreElement(element_namespace, element_name)) {
- diag_->Error(DiagMessage(item_source) << ":" << element_name << ">");
- error = true;
+ if (policies.empty()) {
+ Overlayable overlayable;
+ overlayable.source = item_source;
+ overlayable.comment = comment;
+ child_resource.overlayable_declarations.push_back(overlayable);
+ } else {
+ for (Overlayable::Policy policy : policies) {
+ Overlayable overlayable;
+ overlayable.policy = policy;
+ overlayable.source = item_source;
+ overlayable.comment = comment;
+ child_resource.overlayable_declarations.push_back(overlayable);
}
}
- return !error;
+
+ if (options_.visibility) {
+ child_resource.visibility_level = options_.visibility.value();
+ }
+ out_resource->child_resources.push_back(std::move(child_resource));
+ return true;
}
bool ResourceParser::ParseAddResource(xml::XmlPullParser* parser, ParsedResource* out_resource) {
diff --git a/tools/aapt2/ResourceParser.h b/tools/aapt2/ResourceParser.h
index 06bb0c9cf264..ebacd6f1280e 100644
--- a/tools/aapt2/ResourceParser.h
+++ b/tools/aapt2/ResourceParser.h
@@ -96,6 +96,10 @@ class ResourceParser {
bool ParseSymbolImpl(xml::XmlPullParser* parser, ParsedResource* out_resource);
bool ParseSymbol(xml::XmlPullParser* parser, ParsedResource* out_resource);
bool ParseOverlayable(xml::XmlPullParser* parser, ParsedResource* out_resource);
+ bool ParseOverlayableItem(xml::XmlPullParser* parser,
+ const std::vector<Overlayable::Policy>& policies,
+ const std::string& comment,
+ ParsedResource* out_resource);
bool ParseAddResource(xml::XmlPullParser* parser, ParsedResource* out_resource);
bool ParseAttr(xml::XmlPullParser* parser, ParsedResource* out_resource);
bool ParseAttrImpl(xml::XmlPullParser* parser, ParsedResource* out_resource, bool weak);
diff --git a/tools/aapt2/ResourceParser_test.cpp b/tools/aapt2/ResourceParser_test.cpp
index 0dff66430532..c6f29ac53ca6 100644
--- a/tools/aapt2/ResourceParser_test.cpp
+++ b/tools/aapt2/ResourceParser_test.cpp
@@ -891,56 +891,162 @@ TEST_F(ResourceParserTest, ParsePlatformIndependentNewline) {
ASSERT_TRUE(TestParse(R"(<string name="foo">%1$s %n %2$s</string>)"));
}
-TEST_F(ResourceParserTest, ParseOverlayableTagWithSystemPolicy) {
- std::string input = R"(
- <overlayable policy="illegal_policy">
+TEST_F(ResourceParserTest, ParseOverlayable) {
+ std::string input = R"(<overlayable />)";
+ EXPECT_TRUE(TestParse(input));
+
+ input = R"(
+ <overlayable>
<item type="string" name="foo" />
+ <item type="drawable" name="bar" />
</overlayable>)";
- EXPECT_FALSE(TestParse(input));
+ ASSERT_TRUE(TestParse(input));
+
+ auto search_result = table_.FindResource(test::ParseNameOrDie("string/foo"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_FALSE(search_result.value().entry->overlayable_declarations[0].policy);
+
+ search_result = table_.FindResource(test::ParseNameOrDie("drawable/bar"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_FALSE(search_result.value().entry->overlayable_declarations[0].policy);
+}
+
+TEST_F(ResourceParserTest, ParseOverlayablePolicy) {
+ std::string input = R"(<overlayable />)";
+ EXPECT_TRUE(TestParse(input));
input = R"(
- <overlayable policy="system">
- <item name="foo" />
+ <overlayable>
+ <item type="string" name="foo" />
+ <policy type="product">
+ <item type="string" name="bar" />
+ </policy>
+ <policy type="product_services">
+ <item type="string" name="baz" />
+ </policy>
+ <policy type="system">
+ <item type="string" name="fiz" />
+ </policy>
+ <policy type="vendor">
+ <item type="string" name="fuz" />
+ </policy>
+ <policy type="public">
+ <item type="string" name="faz" />
+ </policy>
</overlayable>)";
- EXPECT_FALSE(TestParse(input));
+ ASSERT_TRUE(TestParse(input));
- input = R"(
- <overlayable policy="system">
- <item type="attr" />
+ auto search_result = table_.FindResource(test::ParseNameOrDie("string/foo"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_FALSE(search_result.value().entry->overlayable_declarations[0].policy);
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/bar"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kProduct));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/baz"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kProductServices));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/fiz"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kSystem));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/fuz"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kVendor));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/faz"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kPublic));
+}
+
+TEST_F(ResourceParserTest, ParseOverlayableBadPolicyError) {
+ std::string input = R"(
+ <overlayable>
+ <policy type="illegal_policy">
+ <item type="string" name="foo" />
+ </policy>
</overlayable>)";
EXPECT_FALSE(TestParse(input));
input = R"(
- <overlayable policy="system">
- <item type="bad_type" name="foo" />
+ <overlayable>
+ <policy type="product">
+ <item name="foo" />
+ </policy>
</overlayable>)";
EXPECT_FALSE(TestParse(input));
- input = R"(<overlayable policy="system" />)";
- EXPECT_TRUE(TestParse(input));
-
- input = R"(<overlayable />)";
- EXPECT_TRUE(TestParse(input));
-
input = R"(
- <overlayable policy="system">
- <item type="string" name="foo" />
- <item type="dimen" name="foo" />
+ <overlayable>
+ <policy type="vendor">
+ <item type="string" />
+ </policy>
</overlayable>)";
- ASSERT_TRUE(TestParse(input));
+ EXPECT_FALSE(TestParse(input));
+}
- input = R"(
+TEST_F(ResourceParserTest, ParseOverlayableMultiplePolicy) {
+ std::string input = R"(
<overlayable>
- <item type="string" name="bar" />
+ <policy type="vendor|product_services">
+ <item type="string" name="foo" />
+ </policy>
+ <policy type="product|system">
+ <item type="string" name="bar" />
+ </policy>
</overlayable>)";
ASSERT_TRUE(TestParse(input));
- Maybe<ResourceTable::SearchResult> search_result =
- table_.FindResource(test::ParseNameOrDie("string/bar"));
+ auto search_result = table_.FindResource(test::ParseNameOrDie("string/foo"));
+ ASSERT_TRUE(search_result);
+ ASSERT_THAT(search_result.value().entry, NotNull());
+ EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(2));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kVendor));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[1].policy,
+ Eq(Overlayable::Policy::kProductServices));
+
+ search_result = table_.FindResource(test::ParseNameOrDie("string/bar"));
ASSERT_TRUE(search_result);
ASSERT_THAT(search_result.value().entry, NotNull());
EXPECT_THAT(search_result.value().entry->visibility.level, Eq(Visibility::Level::kUndefined));
- EXPECT_TRUE(search_result.value().entry->overlayable);
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(2));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kProduct));
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations[1].policy,
+ Eq(Overlayable::Policy::kSystem));
}
TEST_F(ResourceParserTest, DuplicateOverlayableIsError) {
@@ -950,6 +1056,85 @@ TEST_F(ResourceParserTest, DuplicateOverlayableIsError) {
<item type="string" name="foo" />
</overlayable>)";
EXPECT_FALSE(TestParse(input));
+
+ input = R"(
+ <overlayable>
+ <item type="string" name="foo" />
+ </overlayable>
+ <overlayable>
+ <item type="string" name="foo" />
+ </overlayable>)";
+ EXPECT_FALSE(TestParse(input));
+
+ input = R"(
+ <overlayable">
+ <policy type="product">
+ <item type="string" name="foo" />
+ <item type="string" name="foo" />
+ </policy>
+ </overlayable>)";
+ EXPECT_FALSE(TestParse(input));
+
+ input = R"(
+ <overlayable>
+ <policy type="product">
+ <item type="string" name="foo" />
+ </policy>
+ </overlayable>
+
+ <overlayable>
+ <policy type="product">
+ <item type="string" name="foo" />
+ </policy>
+ </overlayable>)";
+ EXPECT_FALSE(TestParse(input));
+}
+
+TEST_F(ResourceParserTest, PolicyAndNonPolicyOverlayableError) {
+ std::string input = R"(
+ <overlayable policy="product">
+ <item type="string" name="foo" />
+ </overlayable>
+ <overlayable policy="">
+ <item type="string" name="foo" />
+ </overlayable>)";
+ EXPECT_FALSE(TestParse(input));
+
+ input = R"(
+ <overlayable policy="">
+ <item type="string" name="foo" />
+ </overlayable>
+ <overlayable policy="product">
+ <item type="string" name="foo" />
+ </overlayable>)";
+ EXPECT_FALSE(TestParse(input));
+}
+
+TEST_F(ResourceParserTest, DuplicateOverlayableMultiplePolicyError) {
+ std::string input = R"(
+ <overlayable>
+ <policy type="vendor|product">
+ <item type="string" name="foo" />
+ </policy>
+ </overlayable>
+ <overlayable>
+ <policy type="product_services|vendor">
+ <item type="string" name="foo" />
+ </policy>
+ </overlayable>)";
+ EXPECT_FALSE(TestParse(input));
+}
+
+TEST_F(ResourceParserTest, NestPolicyInOverlayableError) {
+ std::string input = R"(
+ <overlayable>
+ <policy type="vendor|product">
+ <policy type="product_services">
+ <item type="string" name="foo" />
+ </policy>
+ </policy>
+ </overlayable>)";
+ EXPECT_FALSE(TestParse(input));
}
TEST_F(ResourceParserTest, ParseIdItem) {
diff --git a/tools/aapt2/ResourceTable.cpp b/tools/aapt2/ResourceTable.cpp
index 056a27bf011d..bc8a4d1f85b8 100644
--- a/tools/aapt2/ResourceTable.cpp
+++ b/tools/aapt2/ResourceTable.cpp
@@ -625,17 +625,17 @@ bool ResourceTable::SetAllowNewImpl(const ResourceNameRef& name, const AllowNew&
return true;
}
-bool ResourceTable::SetOverlayable(const ResourceNameRef& name, const Overlayable& overlayable,
+bool ResourceTable::AddOverlayable(const ResourceNameRef& name, const Overlayable& overlayable,
IDiagnostics* diag) {
- return SetOverlayableImpl(name, overlayable, ResourceNameValidator, diag);
+ return AddOverlayableImpl(name, overlayable, ResourceNameValidator, diag);
}
-bool ResourceTable::SetOverlayableMangled(const ResourceNameRef& name,
+bool ResourceTable::AddOverlayableMangled(const ResourceNameRef& name,
const Overlayable& overlayable, IDiagnostics* diag) {
- return SetOverlayableImpl(name, overlayable, SkipNameValidator, diag);
+ return AddOverlayableImpl(name, overlayable, SkipNameValidator, diag);
}
-bool ResourceTable::SetOverlayableImpl(const ResourceNameRef& name, const Overlayable& overlayable,
+bool ResourceTable::AddOverlayableImpl(const ResourceNameRef& name, const Overlayable& overlayable,
NameValidator name_validator, IDiagnostics* diag) {
CHECK(diag != nullptr);
@@ -646,13 +646,28 @@ bool ResourceTable::SetOverlayableImpl(const ResourceNameRef& name, const Overla
ResourceTablePackage* package = FindOrCreatePackage(name.package);
ResourceTableType* type = package->FindOrCreateType(name.type);
ResourceEntry* entry = type->FindOrCreateEntry(name.entry);
- if (entry->overlayable) {
- diag->Error(DiagMessage(overlayable.source)
- << "duplicate overlayable declaration for resource '" << name << "'");
- diag->Error(DiagMessage(entry->overlayable.value().source) << "previous declaration here");
- return false;
+
+ for (auto& overlayable_declaration : entry->overlayable_declarations) {
+ // An overlayable resource cannot be declared twice with the same policy
+ if (overlayable.policy == overlayable_declaration.policy) {
+ diag->Error(DiagMessage(overlayable.source)
+ << "duplicate overlayable declaration for resource '" << name << "'");
+ diag->Error(DiagMessage(overlayable_declaration.source) << "previous declaration here");
+ return false;
+ }
+
+ // An overlayable resource cannot be declared once with a policy and without a policy because
+ // the policy becomes unused
+ if (!overlayable.policy || !overlayable_declaration.policy) {
+ diag->Error(DiagMessage(overlayable.source)
+ << "overlayable resource '" << name << "'"
+ << " declared once with a policy and once with no policy");
+ diag->Error(DiagMessage(overlayable_declaration.source) << "previous declaration here");
+ return false;
+ }
}
- entry->overlayable = overlayable;
+
+ entry->overlayable_declarations.push_back(overlayable);
return true;
}
@@ -688,7 +703,7 @@ std::unique_ptr<ResourceTable> ResourceTable::Clone() const {
new_entry->id = entry->id;
new_entry->visibility = entry->visibility;
new_entry->allow_new = entry->allow_new;
- new_entry->overlayable = entry->overlayable;
+ new_entry->overlayable_declarations = entry->overlayable_declarations;
for (const auto& config_value : entry->values) {
ResourceConfigValue* new_value =
diff --git a/tools/aapt2/ResourceTable.h b/tools/aapt2/ResourceTable.h
index 1917d7e78c4f..3dd0a769d944 100644
--- a/tools/aapt2/ResourceTable.h
+++ b/tools/aapt2/ResourceTable.h
@@ -57,8 +57,27 @@ struct AllowNew {
std::string comment;
};
-// The policy dictating whether an entry is overlayable at runtime by RROs.
+// Represents a declaration that a resource is overayable at runtime.
struct Overlayable {
+ // Represents the types overlays that are allowed to overlay the resource.
+ enum class Policy {
+ // The resource can be overlaid by any overlay.
+ kPublic,
+
+ // The resource can be overlaid by any overlay on the system partition.
+ kSystem,
+
+ // The resource can be overlaid by any overlay on the vendor partition.
+ kVendor,
+
+ // The resource can be overlaid by any overlay on the product partition.
+ kProduct,
+
+ // The resource can be overlaid by any overlay on the product services partition.
+ kProductServices,
+ };
+
+ Maybe<Policy> policy;
Source source;
std::string comment;
};
@@ -96,7 +115,8 @@ class ResourceEntry {
Maybe<AllowNew> allow_new;
- Maybe<Overlayable> overlayable;
+ // The declarations of this resource as overlayable for RROs
+ std::vector<Overlayable> overlayable_declarations;
// The resource's values for each configuration.
std::vector<std::unique_ptr<ResourceConfigValue>> values;
@@ -226,9 +246,9 @@ class ResourceTable {
bool SetVisibilityWithIdMangled(const ResourceNameRef& name, const Visibility& visibility,
const ResourceId& res_id, IDiagnostics* diag);
- bool SetOverlayable(const ResourceNameRef& name, const Overlayable& overlayable,
+ bool AddOverlayable(const ResourceNameRef& name, const Overlayable& overlayable,
IDiagnostics* diag);
- bool SetOverlayableMangled(const ResourceNameRef& name, const Overlayable& overlayable,
+ bool AddOverlayableMangled(const ResourceNameRef& name, const Overlayable& overlayable,
IDiagnostics* diag);
bool SetAllowNew(const ResourceNameRef& name, const AllowNew& allow_new, IDiagnostics* diag);
@@ -303,7 +323,7 @@ class ResourceTable {
bool SetAllowNewImpl(const ResourceNameRef& name, const AllowNew& allow_new,
NameValidator name_validator, IDiagnostics* diag);
- bool SetOverlayableImpl(const ResourceNameRef& name, const Overlayable& overlayable,
+ bool AddOverlayableImpl(const ResourceNameRef& name, const Overlayable& overlayable,
NameValidator name_validator, IDiagnostics* diag);
bool SetSymbolStateImpl(const ResourceNameRef& name, const ResourceId& res_id,
diff --git a/tools/aapt2/ResourceTable_test.cpp b/tools/aapt2/ResourceTable_test.cpp
index 05c6f1531d34..7c28f07d0f66 100644
--- a/tools/aapt2/ResourceTable_test.cpp
+++ b/tools/aapt2/ResourceTable_test.cpp
@@ -242,21 +242,69 @@ TEST(ResourceTableTest, SetAllowNew) {
ASSERT_THAT(result.value().entry->allow_new.value().comment, StrEq("second"));
}
-TEST(ResourceTableTest, SetOverlayable) {
+TEST(ResourceTableTest, AddOverlayable) {
ResourceTable table;
const ResourceName name = test::ParseNameOrDie("android:string/foo");
Overlayable overlayable;
-
+ overlayable.policy = Overlayable::Policy::kProduct;
overlayable.comment = "first";
- ASSERT_TRUE(table.SetOverlayable(name, overlayable, test::GetDiagnostics()));
+ ASSERT_TRUE(table.AddOverlayable(name, overlayable, test::GetDiagnostics()));
Maybe<ResourceTable::SearchResult> result = table.FindResource(name);
ASSERT_TRUE(result);
- ASSERT_TRUE(result.value().entry->overlayable);
- ASSERT_THAT(result.value().entry->overlayable.value().comment, StrEq("first"));
+ ASSERT_THAT(result.value().entry->overlayable_declarations.size(), Eq(1));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[0].comment, StrEq("first"));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kProduct));
+
+ Overlayable overlayable2;
+ overlayable2.comment = "second";
+ overlayable2.policy = Overlayable::Policy::kProductServices;
+ ASSERT_TRUE(table.AddOverlayable(name, overlayable2, test::GetDiagnostics()));
+ result = table.FindResource(name);
+ ASSERT_TRUE(result);
+ ASSERT_THAT(result.value().entry->overlayable_declarations.size(), Eq(2));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[0].comment, StrEq("first"));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kProduct));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[1].comment, StrEq("second"));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[1].policy,
+ Eq(Overlayable::Policy::kProductServices));
+}
+
+TEST(ResourceTableTest, AddDuplicateOverlayableFail) {
+ ResourceTable table;
+ const ResourceName name = test::ParseNameOrDie("android:string/foo");
+
+ Overlayable overlayable;
+ overlayable.policy = Overlayable::Policy::kProduct;
+ ASSERT_TRUE(table.AddOverlayable(name, overlayable, test::GetDiagnostics()));
+
+ Overlayable overlayable2;
+ overlayable2.policy = Overlayable::Policy::kProduct;
+ ASSERT_FALSE(table.AddOverlayable(name, overlayable2, test::GetDiagnostics()));
+}
+
+TEST(ResourceTableTest, AddOverlayablePolicyAndNoneFirstFail) {
+ ResourceTable table;
+ const ResourceName name = test::ParseNameOrDie("android:string/foo");
+
+ ASSERT_TRUE(table.AddOverlayable(name, {}, test::GetDiagnostics()));
+
+ Overlayable overlayable2;
+ overlayable2.policy = Overlayable::Policy::kProduct;
+ ASSERT_FALSE(table.AddOverlayable(name, overlayable2, test::GetDiagnostics()));
+}
+
+TEST(ResourceTableTest, AddOverlayablePolicyAndNoneLastFail) {
+ ResourceTable table;
+ const ResourceName name = test::ParseNameOrDie("android:string/foo");
+
+ Overlayable overlayable;
+ overlayable.policy = Overlayable::Policy::kProduct;
+ ASSERT_TRUE(table.AddOverlayable(name, overlayable, test::GetDiagnostics()));
- overlayable.comment = "second";
- ASSERT_FALSE(table.SetOverlayable(name, overlayable, test::GetDiagnostics()));
+ ASSERT_FALSE(table.AddOverlayable(name, {}, test::GetDiagnostics()));
}
TEST(ResourceTableTest, AllowDuplictaeResourcesNames) {
diff --git a/tools/aapt2/Resources.proto b/tools/aapt2/Resources.proto
index d7a377176fc5..bf9fe49da2d6 100644
--- a/tools/aapt2/Resources.proto
+++ b/tools/aapt2/Resources.proto
@@ -133,13 +133,25 @@ message AllowNew {
string comment = 2;
}
-// Whether a resource is overlayable by runtime resource overlays (RRO).
+// Represents a declaration that a resource is overayable at runtime.
message Overlayable {
+ enum Policy {
+ NONE = 0;
+ PUBLIC = 1;
+ SYSTEM = 2;
+ VENDOR = 3;
+ PRODUCT = 4;
+ PRODUCT_SERVICES = 5;
+ }
+
// Where this declaration was defined in source.
Source source = 1;
// Any comment associated with the declaration.
string comment = 2;
+
+ // The policy of the overlayable declaration
+ Policy policy = 3;
}
// An entry ID in the range [0x0000, 0xffff].
@@ -169,7 +181,7 @@ message Entry {
AllowNew allow_new = 4;
// Whether this resource can be overlaid by a runtime resource overlay (RRO).
- Overlayable overlayable = 5;
+ repeated Overlayable overlayable = 5;
// The set of values defined for this entry, each corresponding to a different
// configuration/variant.
diff --git a/tools/aapt2/format/binary/BinaryResourceParser.cpp b/tools/aapt2/format/binary/BinaryResourceParser.cpp
index 3a39a6baeeeb..ed70fb3c57d6 100644
--- a/tools/aapt2/format/binary/BinaryResourceParser.cpp
+++ b/tools/aapt2/format/binary/BinaryResourceParser.cpp
@@ -398,7 +398,7 @@ bool BinaryResourceParser::ParseType(const ResourceTablePackage* package,
if (type_spec_flags & ResTable_typeSpec::SPEC_OVERLAYABLE) {
Overlayable overlayable;
overlayable.source = source_.WithLine(0);
- if (!table_->SetOverlayableMangled(name, overlayable, diag_)) {
+ if (!table_->AddOverlayableMangled(name, overlayable, diag_)) {
return false;
}
}
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index 8641a7c93d19..8a86f63a30c1 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -446,7 +446,7 @@ class PackageFlattener {
config_masks[entry->id.value()] |= util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
}
- if (entry->overlayable) {
+ if (!entry->overlayable_declarations.empty()) {
config_masks[entry->id.value()] |=
util::HostToDevice32(ResTable_typeSpec::SPEC_OVERLAYABLE);
}
diff --git a/tools/aapt2/format/binary/TableFlattener_test.cpp b/tools/aapt2/format/binary/TableFlattener_test.cpp
index af19b98e528b..cd1414c7e628 100644
--- a/tools/aapt2/format/binary/TableFlattener_test.cpp
+++ b/tools/aapt2/format/binary/TableFlattener_test.cpp
@@ -634,7 +634,7 @@ TEST_F(TableFlattenerTest, FlattenOverlayable) {
.AddSimple("com.app.test:integer/overlayable", ResourceId(0x7f020000))
.Build();
- ASSERT_TRUE(table->SetOverlayable(test::ParseNameOrDie("com.app.test:integer/overlayable"),
+ ASSERT_TRUE(table->AddOverlayable(test::ParseNameOrDie("com.app.test:integer/overlayable"),
Overlayable{}, test::GetDiagnostics()));
ResTable res_table;
diff --git a/tools/aapt2/format/proto/ProtoDeserialize.cpp b/tools/aapt2/format/proto/ProtoDeserialize.cpp
index d1b2fdb84afc..f612914269de 100644
--- a/tools/aapt2/format/proto/ProtoDeserialize.cpp
+++ b/tools/aapt2/format/proto/ProtoDeserialize.cpp
@@ -437,15 +437,37 @@ static bool DeserializePackageFromPb(const pb::Package& pb_package, const ResStr
entry->allow_new = std::move(allow_new);
}
- if (pb_entry.has_overlayable()) {
- const pb::Overlayable& pb_overlayable = pb_entry.overlayable();
-
+ for (const pb::Overlayable& pb_overlayable : pb_entry.overlayable()) {
Overlayable overlayable;
+ switch (pb_overlayable.policy()) {
+ case pb::Overlayable::NONE:
+ overlayable.policy = {};
+ break;
+ case pb::Overlayable::PUBLIC:
+ overlayable.policy = Overlayable::Policy::kPublic;
+ break;
+ case pb::Overlayable::PRODUCT:
+ overlayable.policy = Overlayable::Policy::kProduct;
+ break;
+ case pb::Overlayable::PRODUCT_SERVICES:
+ overlayable.policy = Overlayable::Policy::kProductServices;
+ break;
+ case pb::Overlayable::SYSTEM:
+ overlayable.policy = Overlayable::Policy::kSystem;
+ break;
+ case pb::Overlayable::VENDOR:
+ overlayable.policy = Overlayable::Policy::kVendor;
+ break;
+ default:
+ *out_error = "unknown overlayable policy";
+ return false;
+ }
+
if (pb_overlayable.has_source()) {
DeserializeSourceFromPb(pb_overlayable.source(), src_pool, &overlayable.source);
}
overlayable.comment = pb_overlayable.comment();
- entry->overlayable = std::move(overlayable);
+ entry->overlayable_declarations.push_back(overlayable);
}
ResourceId resid(pb_package.package_id().id(), pb_type.type_id().id(),
diff --git a/tools/aapt2/format/proto/ProtoSerialize.cpp b/tools/aapt2/format/proto/ProtoSerialize.cpp
index 7e35ea7bb7a3..f1e96d61191b 100644
--- a/tools/aapt2/format/proto/ProtoSerialize.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize.cpp
@@ -310,11 +310,31 @@ void SerializeTableToPb(const ResourceTable& table, pb::ResourceTable* out_table
pb_allow_new->set_comment(entry->allow_new.value().comment);
}
- if (entry->overlayable) {
- pb::Overlayable* pb_overlayable = pb_entry->mutable_overlayable();
- SerializeSourceToPb(entry->overlayable.value().source, &source_pool,
+ for (const Overlayable& overlayable : entry->overlayable_declarations) {
+ pb::Overlayable* pb_overlayable = pb_entry->add_overlayable();
+ if (overlayable.policy) {
+ switch (overlayable.policy.value()) {
+ case Overlayable::Policy::kPublic:
+ pb_overlayable->set_policy(pb::Overlayable::PUBLIC);
+ break;
+ case Overlayable::Policy::kProduct:
+ pb_overlayable->set_policy(pb::Overlayable::PRODUCT);
+ break;
+ case Overlayable::Policy::kProductServices:
+ pb_overlayable->set_policy(pb::Overlayable::PRODUCT_SERVICES);
+ break;
+ case Overlayable::Policy::kSystem:
+ pb_overlayable->set_policy(pb::Overlayable::SYSTEM);
+ break;
+ case Overlayable::Policy::kVendor:
+ pb_overlayable->set_policy(pb::Overlayable::VENDOR);
+ break;
+ }
+ }
+
+ SerializeSourceToPb(overlayable.source, &source_pool,
pb_overlayable->mutable_source());
- pb_overlayable->set_comment(entry->overlayable.value().comment);
+ pb_overlayable->set_comment(overlayable.comment);
}
for (const std::unique_ptr<ResourceConfigValue>& config_value : entry->values) {
diff --git a/tools/aapt2/format/proto/ProtoSerialize_test.cpp b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
index 3c4d41ae5d1a..95dbbeb58a5d 100644
--- a/tools/aapt2/format/proto/ProtoSerialize_test.cpp
+++ b/tools/aapt2/format/proto/ProtoSerialize_test.cpp
@@ -93,7 +93,7 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
util::make_unique<Reference>(expected_ref), context->GetDiagnostics()));
// Make an overlayable resource.
- ASSERT_TRUE(table->SetOverlayable(test::ParseNameOrDie("com.app.a:integer/overlayable"),
+ ASSERT_TRUE(table->AddOverlayable(test::ParseNameOrDie("com.app.a:integer/overlayable"),
Overlayable{}, test::GetDiagnostics()));
pb::ResourceTable pb_table;
@@ -106,7 +106,7 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
ResourceTable new_table;
std::string error;
- ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error));
+ ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error)) << error;
EXPECT_THAT(error, IsEmpty());
Id* new_id = test::GetValue<Id>(&new_table, "com.app.a:id/foo");
@@ -160,7 +160,8 @@ TEST(ProtoSerializeTest, SerializeSinglePackage) {
new_table.FindResource(test::ParseNameOrDie("com.app.a:integer/overlayable"));
ASSERT_TRUE(search_result);
ASSERT_THAT(search_result.value().entry, NotNull());
- EXPECT_TRUE(search_result.value().entry->overlayable);
+ EXPECT_THAT(search_result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_FALSE(search_result.value().entry->overlayable_declarations[0].policy);
}
TEST(ProtoSerializeTest, SerializeAndDeserializeXml) {
@@ -464,4 +465,59 @@ TEST(ProtoSerializeTest, SerializeDeserializeConfiguration) {
"night-xhdpi-stylus-keysexposed-qwerty-navhidden-dpad-300x200-v23");
}
+TEST(ProtoSerializeTest, SerializeAndDeserializeOverlayable) {
+ std::unique_ptr<IAaptContext> context = test::ContextBuilder().Build();
+ std::unique_ptr<ResourceTable> table =
+ test::ResourceTableBuilder()
+ .AddOverlayable("com.app.a:bool/foo", Overlayable::Policy::kSystem)
+ .AddOverlayable("com.app.a:bool/foo", Overlayable::Policy::kProduct)
+ .AddOverlayable("com.app.a:bool/bar", Overlayable::Policy::kProductServices)
+ .AddOverlayable("com.app.a:bool/bar", Overlayable::Policy::kVendor)
+ .AddOverlayable("com.app.a:bool/baz", Overlayable::Policy::kPublic)
+ .AddOverlayable("com.app.a:bool/biz", {})
+ .AddValue("com.app.a:bool/fiz", ResourceUtils::TryParseBool("true"))
+ .Build();
+
+ pb::ResourceTable pb_table;
+ SerializeTableToPb(*table, &pb_table, context->GetDiagnostics());
+
+ MockFileCollection files;
+ ResourceTable new_table;
+ std::string error;
+ ASSERT_TRUE(DeserializeTableFromPb(pb_table, &files, &new_table, &error));
+ EXPECT_THAT(error, IsEmpty());
+
+ Maybe<ResourceTable::SearchResult> result =
+ new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/foo"));
+ ASSERT_TRUE(result);
+ ASSERT_THAT(result.value().entry->overlayable_declarations.size(), Eq(2));
+ EXPECT_THAT(result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kSystem));
+ EXPECT_THAT(result.value().entry->overlayable_declarations[1].policy,
+ Eq(Overlayable::Policy::kProduct));
+
+ result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/bar"));
+ ASSERT_TRUE(result);
+ ASSERT_THAT(result.value().entry->overlayable_declarations.size(), Eq(2));
+ EXPECT_THAT(result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kProductServices));
+ EXPECT_THAT(result.value().entry->overlayable_declarations[1].policy,
+ Eq(Overlayable::Policy::kVendor));
+
+ result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/baz"));
+ ASSERT_TRUE(result);
+ ASSERT_THAT(result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_THAT(result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kPublic));
+
+ result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/biz"));
+ ASSERT_TRUE(result);
+ ASSERT_THAT(result.value().entry->overlayable_declarations.size(), Eq(1));
+ EXPECT_FALSE(result.value().entry->overlayable_declarations[0].policy);
+
+ result = new_table.FindResource(test::ParseNameOrDie("com.app.a:bool/fiz"));
+ ASSERT_TRUE(result);
+ EXPECT_THAT(result.value().entry->overlayable_declarations.size(), Eq(0));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/link/TableMerger.cpp b/tools/aapt2/link/TableMerger.cpp
index afb8ae097449..d777e22fa4b7 100644
--- a/tools/aapt2/link/TableMerger.cpp
+++ b/tools/aapt2/link/TableMerger.cpp
@@ -101,7 +101,7 @@ static bool MergeType(IAaptContext* context, const Source& src, ResourceTableTyp
return true;
}
-static bool MergeEntry(IAaptContext* context, const Source& src, bool overlay,
+static bool MergeEntry(IAaptContext* context, const Source& src,
ResourceEntry* dst_entry, ResourceEntry* src_entry,
bool strict_visibility) {
if (strict_visibility
@@ -134,17 +134,35 @@ static bool MergeEntry(IAaptContext* context, const Source& src, bool overlay,
dst_entry->allow_new = std::move(src_entry->allow_new);
}
- if (src_entry->overlayable) {
- if (dst_entry->overlayable && !overlay) {
- context->GetDiagnostics()->Error(DiagMessage(src_entry->overlayable.value().source)
- << "duplicate overlayable declaration for resource '"
- << src_entry->name << "'");
- context->GetDiagnostics()->Error(DiagMessage(dst_entry->overlayable.value().source)
- << "previous declaration here");
- return false;
+ for (auto& src_overlayable : src_entry->overlayable_declarations) {
+ for (auto& dst_overlayable : dst_entry->overlayable_declarations) {
+ // An overlayable resource cannot be declared twice with the same policy
+ if (src_overlayable.policy == dst_overlayable.policy) {
+ context->GetDiagnostics()->Error(DiagMessage(src_overlayable.source)
+ << "duplicate overlayable declaration for resource '"
+ << src_entry->name << "'");
+ context->GetDiagnostics()->Error(DiagMessage(dst_overlayable.source)
+ << "previous declaration here");
+ return false;
+ }
+
+ // An overlayable resource cannot be declared once with a policy and without a policy because
+ // the policy becomes unused
+ if (!src_overlayable.policy || !dst_overlayable.policy) {
+ context->GetDiagnostics()->Error(DiagMessage(src_overlayable.source)
+ << "overlayable resource '" << src_entry->name
+ << "' declared once with a policy and once with no "
+ << "policy");
+ context->GetDiagnostics()->Error(DiagMessage(dst_overlayable.source)
+ << "previous declaration here");
+ return false;
+ }
}
- dst_entry->overlayable = std::move(src_entry->overlayable);
}
+
+ dst_entry->overlayable_declarations.insert(dst_entry->overlayable_declarations.end(),
+ src_entry->overlayable_declarations.begin(),
+ src_entry->overlayable_declarations.end());
return true;
}
@@ -244,7 +262,7 @@ bool TableMerger::DoMerge(const Source& src, ResourceTable* src_table,
continue;
}
- if (!MergeEntry(context_, src, overlay, dst_entry, src_entry.get(), options_.strict_visibility)) {
+ if (!MergeEntry(context_, src, dst_entry, src_entry.get(), options_.strict_visibility)) {
error = true;
continue;
}
diff --git a/tools/aapt2/link/TableMerger_test.cpp b/tools/aapt2/link/TableMerger_test.cpp
index 79a734bffabd..d6579d37b452 100644
--- a/tools/aapt2/link/TableMerger_test.cpp
+++ b/tools/aapt2/link/TableMerger_test.cpp
@@ -436,4 +436,97 @@ TEST_F(TableMergerTest, OverlaidStyleablesAndStylesShouldBeMerged) {
Eq(make_value(Reference(test::ParseNameOrDie("com.app.a:style/OverlayParent")))));
}
+TEST_F(TableMergerTest, AddOverlayable) {
+ std::unique_ptr<ResourceTable> table_a =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", Overlayable::Policy::kProduct)
+ .Build();
+
+ std::unique_ptr<ResourceTable> table_b =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", Overlayable::Policy::kProductServices)
+ .Build();
+
+ ResourceTable final_table;
+ TableMergerOptions options;
+ options.auto_add_overlay = true;
+ TableMerger merger(context_.get(), &final_table, options);
+ ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
+ ASSERT_TRUE(merger.Merge({}, table_b.get(), false /*overlay*/));
+
+ const ResourceName name = test::ParseNameOrDie("com.app.a:bool/foo");
+ Maybe<ResourceTable::SearchResult> result = final_table.FindResource(name);
+ ASSERT_TRUE(result);
+ ASSERT_THAT(result.value().entry->overlayable_declarations.size(), Eq(2));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[0].policy,
+ Eq(Overlayable::Policy::kProduct));
+ ASSERT_THAT(result.value().entry->overlayable_declarations[1].policy,
+ Eq(Overlayable::Policy::kProductServices));
+}
+
+TEST_F(TableMergerTest, AddDuplicateOverlayableFail) {
+ std::unique_ptr<ResourceTable> table_a =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", Overlayable::Policy::kProduct)
+ .Build();
+
+ std::unique_ptr<ResourceTable> table_b =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", Overlayable::Policy::kProduct)
+ .Build();
+
+ ResourceTable final_table;
+ TableMergerOptions options;
+ options.auto_add_overlay = true;
+ TableMerger merger(context_.get(), &final_table, options);
+ ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
+ ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
+}
+
+TEST_F(TableMergerTest, AddOverlayablePolicyAndNoneFirstFail) {
+ std::unique_ptr<ResourceTable> table_a =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", {})
+ .Build();
+
+ std::unique_ptr<ResourceTable> table_b =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", Overlayable::Policy::kProduct)
+ .Build();
+
+ ResourceTable final_table;
+ TableMergerOptions options;
+ options.auto_add_overlay = true;
+ TableMerger merger(context_.get(), &final_table, options);
+ ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
+ ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
+}
+
+TEST_F(TableMergerTest, AddOverlayablePolicyAndNoneLastFail) {
+ std::unique_ptr<ResourceTable> table_a =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", Overlayable::Policy::kProduct)
+ .Build();
+
+ std::unique_ptr<ResourceTable> table_b =
+ test::ResourceTableBuilder()
+ .SetPackageId("com.app.a", 0x7f)
+ .AddOverlayable("bool/foo", {})
+ .Build();
+
+ ResourceTable final_table;
+ TableMergerOptions options;
+ options.auto_add_overlay = true;
+ TableMerger merger(context_.get(), &final_table, options);
+ ASSERT_TRUE(merger.Merge({}, table_a.get(), false /*overlay*/));
+ ASSERT_FALSE(merger.Merge({}, table_b.get(), false /*overlay*/));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/test/Builders.cpp b/tools/aapt2/test/Builders.cpp
index f33ae3155192..03b59e033402 100644
--- a/tools/aapt2/test/Builders.cpp
+++ b/tools/aapt2/test/Builders.cpp
@@ -135,6 +135,15 @@ ResourceTableBuilder& ResourceTableBuilder::SetSymbolState(const StringPiece& na
return *this;
}
+ResourceTableBuilder& ResourceTableBuilder::AddOverlayable(const StringPiece& name,
+ const Maybe<Overlayable::Policy> p) {
+ ResourceName res_name = ParseNameOrDie(name);
+ Overlayable overlayable;
+ overlayable.policy = p;
+ CHECK(table_->AddOverlayable(res_name, overlayable, GetDiagnostics()));
+ return *this;
+}
+
StringPool* ResourceTableBuilder::string_pool() {
return &table_->string_pool;
}
diff --git a/tools/aapt2/test/Builders.h b/tools/aapt2/test/Builders.h
index 915959972bed..d68c24ddc665 100644
--- a/tools/aapt2/test/Builders.h
+++ b/tools/aapt2/test/Builders.h
@@ -73,6 +73,8 @@ class ResourceTableBuilder {
const ResourceId& id, std::unique_ptr<Value> value);
ResourceTableBuilder& SetSymbolState(const android::StringPiece& name, const ResourceId& id,
Visibility::Level level, bool allow_new = false);
+ ResourceTableBuilder& AddOverlayable(const android::StringPiece& name,
+ Maybe<Overlayable::Policy> policy);
StringPool* string_pool();
std::unique_ptr<ResourceTable> Build();
diff --git a/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
new file mode 100644
index 000000000000..f472a021b031
--- /dev/null
+++ b/wifi/java/android/net/wifi/INetworkRequestMatchCallback.aidl
@@ -0,0 +1,36 @@
+/*
+ * 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.net.wifi;
+
+import android.net.wifi.INetworkRequestUserSelectionCallback;
+import android.net.wifi.WifiConfiguration;
+
+/**
+ * Interface for network request match callback.
+ *
+ * @hide
+ */
+oneway interface INetworkRequestMatchCallback
+{
+ void onUserSelectionCallbackRegistration(in INetworkRequestUserSelectionCallback userSelectionCallback);
+
+ void onMatch(in List<WifiConfiguration> wificonfigurations);
+
+ void onUserSelectionConnectSuccess(in WifiConfiguration wificonfiguration);
+
+ void onUserSelectionConnectFailure(in WifiConfiguration wificonfiguration);
+}
diff --git a/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl b/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
new file mode 100644
index 000000000000..524cefbb295f
--- /dev/null
+++ b/wifi/java/android/net/wifi/INetworkRequestUserSelectionCallback.aidl
@@ -0,0 +1,31 @@
+/*
+ * 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.net.wifi;
+
+import android.net.wifi.WifiConfiguration;
+
+/**
+ * Interface for providing user selection in response to
+ * network request match callback.
+ * @hide
+ */
+oneway interface INetworkRequestUserSelectionCallback
+{
+ void select(in WifiConfiguration wificonfiguration);
+
+ void reject();
+}
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 12f50c8af8a9..1fd68ec1df70 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -25,6 +25,7 @@ import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.DhcpInfo;
import android.net.Network;
+import android.net.wifi.INetworkRequestMatchCallback;
import android.net.wifi.ISoftApCallback;
import android.net.wifi.ITrafficStateCallback;
import android.net.wifi.PasspointManagementObjectDefinition;
@@ -185,5 +186,9 @@ interface IWifiManager
void registerTrafficStateCallback(in IBinder binder, in ITrafficStateCallback callback, int callbackIdentifier);
void unregisterTrafficStateCallback(int callbackIdentifier);
+
+ void registerNetworkRequestMatchCallback(in IBinder binder, in INetworkRequestMatchCallback callback, int callbackIdentifier);
+
+ void unregisterNetworkRequestMatchCallback(int callbackIdentifier);
}
diff --git a/wifi/java/android/net/wifi/ScanResult.java b/wifi/java/android/net/wifi/ScanResult.java
index 3a4e88b49daf..9b9247dba17c 100644
--- a/wifi/java/android/net/wifi/ScanResult.java
+++ b/wifi/java/android/net/wifi/ScanResult.java
@@ -86,9 +86,9 @@ public class ScanResult implements Parcelable {
public static final int PROTOCOL_WPA = 1;
/**
* @hide
- * Security protocol type: WPA version 2, also called RSN.
+ * Security protocol type: RSN, for WPA version 2, and version 3.
*/
- public static final int PROTOCOL_WPA2 = 2;
+ public static final int PROTOCOL_RSN = 2;
/**
* @hide
* Security protocol type:
@@ -138,7 +138,21 @@ public class ScanResult implements Parcelable {
* Used for Hotspot 2.0.
*/
public static final int KEY_MGMT_OSEN = 7;
-
+ /**
+ * @hide
+ * Security key management scheme: SAE.
+ */
+ public static final int KEY_MGMT_SAE = 8;
+ /**
+ * @hide
+ * Security key management scheme: OWE.
+ */
+ public static final int KEY_MGMT_OWE = 9;
+ /**
+ * @hide
+ * Security key management scheme: SUITE_B_192.
+ */
+ public static final int KEY_MGMT_EAP_SUITE_B_192 = 10;
/**
* @hide
* No cipher suite.
@@ -159,6 +173,11 @@ public class ScanResult implements Parcelable {
* Cipher suite: CCMP
*/
public static final int CIPHER_CCMP = 3;
+ /**
+ * @hide
+ * Cipher suite: GCMP
+ */
+ public static final int CIPHER_GCMP_256 = 4;
/**
* The detected signal level in dBm, also known as the RSSI.
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 03306143872b..8fc9b9759469 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -23,6 +23,7 @@ import android.content.pm.PackageManager;
import android.net.IpConfiguration;
import android.net.IpConfiguration.ProxySettings;
import android.net.MacAddress;
+import android.net.NetworkSpecifier;
import android.net.ProxyInfo;
import android.net.StaticIpConfiguration;
import android.net.Uri;
@@ -47,7 +48,11 @@ import java.util.HashMap;
/**
* A class representing a configured Wi-Fi network, including the
* security configuration.
+ *
+ * @deprecated Use {@link WifiNetworkConfigBuilder} to create {@link NetworkSpecifier} and
+ * {@link WifiNetworkSuggestion}. This will become a system use only object in the future.
*/
+@Deprecated
public class WifiConfiguration implements Parcelable {
private static final String TAG = "WifiConfiguration";
/**
@@ -125,10 +130,26 @@ public class WifiConfiguration implements Parcelable {
*/
public static final int FT_EAP = 7;
+ /**
+ * Simultaneous Authentication of Equals
+ */
+ public static final int SAE = 8;
+
+ /**
+ * Opportunististic Wireless Encryption
+ */
+ public static final int OWE = 9;
+
+ /**
+ * SUITE_B_192 192 bit level
+ */
+ public static final int SUITE_B_192 = 10;
+
public static final String varName = "key_mgmt";
public static final String[] strings = { "NONE", "WPA_PSK", "WPA_EAP",
- "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP" };
+ "IEEE8021X", "WPA2_PSK", "OSEN", "FT_PSK", "FT_EAP",
+ "SAE", "OWE", "SUITE_B_192"};
}
/**
@@ -142,7 +163,7 @@ public class WifiConfiguration implements Parcelable {
* is discouraged. WPA-2 (RSN) should be used instead. */
@Deprecated
public static final int WPA = 0;
- /** WPA2/IEEE 802.11i */
+ /** RSN WPA2/WPA3/IEEE 802.11i */
public static final int RSN = 1;
/** HS2.0 r2 OSEN
* @hide
@@ -190,10 +211,14 @@ public class WifiConfiguration implements Parcelable {
public static final int TKIP = 1;
/** AES in Counter mode with CBC-MAC [RFC 3610, IEEE 802.11i/D7.0] */
public static final int CCMP = 2;
+ /**
+ * AES in Galois/Counter Mode
+ */
+ public static final int GCMP_256 = 3;
public static final String varName = "pairwise";
- public static final String[] strings = { "NONE", "TKIP", "CCMP" };
+ public static final String[] strings = { "NONE", "TKIP", "CCMP", "GCMP_256" };
}
/**
@@ -203,6 +228,7 @@ public class WifiConfiguration implements Parcelable {
* TKIP = Temporal Key Integrity Protocol [IEEE 802.11i/D7.0]
* WEP104 = WEP (Wired Equivalent Privacy) with 104-bit key
* WEP40 = WEP (Wired Equivalent Privacy) with 40-bit key (original 802.11)
+ * GCMP_256 = AES in Galois/Counter Mode
* </pre>
*/
public static class GroupCipher {
@@ -226,12 +252,64 @@ public class WifiConfiguration implements Parcelable {
* @hide
*/
public static final int GTK_NOT_USED = 4;
+ /**
+ * AES in Galois/Counter Mode
+ */
+ public static final int GCMP_256 = 5;
public static final String varName = "group";
public static final String[] strings =
{ /* deprecated */ "WEP40", /* deprecated */ "WEP104",
- "TKIP", "CCMP", "GTK_NOT_USED" };
+ "TKIP", "CCMP", "GTK_NOT_USED", "GCMP_256" };
+ }
+
+ /**
+ * Recognized group management ciphers.
+ * <pre>
+ * BIP_CMAC_256 = Cipher-based Message Authentication Code 256 bits
+ * BIP_GMAC_128 = Galois Message Authentication Code 128 bits
+ * BIP_GMAC_256 = Galois Message Authentication Code 256 bits
+ * </pre>
+ */
+ public static class GroupMgmtCipher {
+ private GroupMgmtCipher() { }
+
+ /** CMAC-256 = Cipher-based Message Authentication Code */
+ public static final int BIP_CMAC_256 = 0;
+
+ /** GMAC-128 = Galois Message Authentication Code */
+ public static final int BIP_GMAC_128 = 1;
+
+ /** GMAC-256 = Galois Message Authentication Code */
+ public static final int BIP_GMAC_256 = 2;
+
+ private static final String varName = "groupMgmt";
+
+ private static final String[] strings = { "BIP_CMAC_256",
+ "BIP_GMAC_128", "BIP_GMAC_256"};
+ }
+
+ /**
+ * Recognized suiteB ciphers.
+ * <pre>
+ * ECDHE_ECDSA
+ * ECDHE_RSA
+ * </pre>
+ * @hide
+ */
+ public static class SuiteBCipher {
+ private SuiteBCipher() { }
+
+ /** Diffie-Hellman with Elliptic Curve_ECDSA signature */
+ public static final int ECDHE_ECDSA = 0;
+
+ /** Diffie-Hellman with_RSA signature */
+ public static final int ECDHE_RSA = 1;
+
+ private static final String varName = "SuiteB";
+
+ private static final String[] strings = { "ECDHE_ECDSA", "ECDHE_RSA" };
}
/** Possible status of a network configuration. */
@@ -409,6 +487,17 @@ public class WifiConfiguration implements Parcelable {
*/
public BitSet allowedGroupCiphers;
/**
+ * The set of group management ciphers supported by this configuration.
+ * See {@link GroupMgmtCipher} for descriptions of the values.
+ */
+ public BitSet allowedGroupMgmtCiphers;
+ /**
+ * The set of SuiteB ciphers supported by this configuration.
+ * To be used for WPA3-Enterprise mode.
+ * See {@link SuiteBCipher} for descriptions of the values.
+ */
+ public BitSet allowedSuiteBCiphers;
+ /**
* The enterprise configuration details specifying the EAP method,
* certificates and other settings associated with the EAP.
*/
@@ -733,7 +822,8 @@ public class WifiConfiguration implements Parcelable {
public boolean isOpenNetwork() {
final int cardinality = allowedKeyManagement.cardinality();
final boolean hasNoKeyMgmt = cardinality == 0
- || (cardinality == 1 && allowedKeyManagement.get(KeyMgmt.NONE));
+ || (cardinality == 1 && (allowedKeyManagement.get(KeyMgmt.NONE)
+ || allowedKeyManagement.get(KeyMgmt.OWE)));
boolean hasNoWepKeys = true;
if (wepKeys != null) {
@@ -1538,6 +1628,8 @@ public class WifiConfiguration implements Parcelable {
allowedAuthAlgorithms = new BitSet();
allowedPairwiseCiphers = new BitSet();
allowedGroupCiphers = new BitSet();
+ allowedGroupMgmtCiphers = new BitSet();
+ allowedSuiteBCiphers = new BitSet();
wepKeys = new String[4];
for (int i = 0; i < wepKeys.length; i++) {
wepKeys[i] = null;
@@ -1591,7 +1683,8 @@ public class WifiConfiguration implements Parcelable {
@UnsupportedAppUsage
public boolean isEnterprise() {
return (allowedKeyManagement.get(KeyMgmt.WPA_EAP)
- || allowedKeyManagement.get(KeyMgmt.IEEE8021X))
+ || allowedKeyManagement.get(KeyMgmt.IEEE8021X)
+ || allowedKeyManagement.get(KeyMgmt.SUITE_B_192))
&& enterpriseConfig != null
&& enterpriseConfig.getEapMethod() != WifiEnterpriseConfig.Eap.NONE;
}
@@ -1609,6 +1702,7 @@ public class WifiConfiguration implements Parcelable {
append(" BSSID: ").append(this.BSSID).append(" FQDN: ").append(this.FQDN)
.append(" PRIO: ").append(this.priority)
.append(" HIDDEN: ").append(this.hiddenSSID)
+ .append(" PMF: ").append(this.requirePMF)
.append('\n');
@@ -1721,10 +1815,35 @@ public class WifiConfiguration implements Parcelable {
}
}
}
- sbuf.append('\n').append(" PSK: ");
+ sbuf.append('\n');
+ sbuf.append(" GroupMgmtCiphers:");
+ for (int gmc = 0; gmc < this.allowedGroupMgmtCiphers.size(); gmc++) {
+ if (this.allowedGroupMgmtCiphers.get(gmc)) {
+ sbuf.append(" ");
+ if (gmc < GroupMgmtCipher.strings.length) {
+ sbuf.append(GroupMgmtCipher.strings[gmc]);
+ } else {
+ sbuf.append("??");
+ }
+ }
+ }
+ sbuf.append('\n');
+ sbuf.append(" SuiteBCiphers:");
+ for (int sbc = 0; sbc < this.allowedSuiteBCiphers.size(); sbc++) {
+ if (this.allowedSuiteBCiphers.get(sbc)) {
+ sbuf.append(" ");
+ if (sbc < SuiteBCipher.strings.length) {
+ sbuf.append(SuiteBCipher.strings[sbc]);
+ } else {
+ sbuf.append("??");
+ }
+ }
+ }
+ sbuf.append('\n').append(" PSK/SAE: ");
if (this.preSharedKey != null) {
sbuf.append('*');
}
+
sbuf.append("\nEnterprise config:\n");
sbuf.append(enterpriseConfig);
@@ -1887,6 +2006,12 @@ public class WifiConfiguration implements Parcelable {
return KeyMgmt.WPA_EAP;
} else if (allowedKeyManagement.get(KeyMgmt.IEEE8021X)) {
return KeyMgmt.IEEE8021X;
+ } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
+ return KeyMgmt.SAE;
+ } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
+ return KeyMgmt.OWE;
+ } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
+ return KeyMgmt.SUITE_B_192;
}
return KeyMgmt.NONE;
}
@@ -1918,6 +2043,12 @@ public class WifiConfiguration implements Parcelable {
key = SSID + KeyMgmt.strings[KeyMgmt.WPA_EAP];
} else if (wepKeys[0] != null) {
key = SSID + "WEP";
+ } else if (allowedKeyManagement.get(KeyMgmt.OWE)) {
+ key = SSID + KeyMgmt.strings[KeyMgmt.OWE];
+ } else if (allowedKeyManagement.get(KeyMgmt.SAE)) {
+ key = SSID + KeyMgmt.strings[KeyMgmt.SAE];
+ } else if (allowedKeyManagement.get(KeyMgmt.SUITE_B_192)) {
+ key = SSID + KeyMgmt.strings[KeyMgmt.SUITE_B_192];
} else {
key = SSID + KeyMgmt.strings[KeyMgmt.NONE];
}
@@ -2086,6 +2217,8 @@ public class WifiConfiguration implements Parcelable {
allowedAuthAlgorithms = (BitSet) source.allowedAuthAlgorithms.clone();
allowedPairwiseCiphers = (BitSet) source.allowedPairwiseCiphers.clone();
allowedGroupCiphers = (BitSet) source.allowedGroupCiphers.clone();
+ allowedGroupMgmtCiphers = (BitSet) source.allowedGroupMgmtCiphers.clone();
+ allowedSuiteBCiphers = (BitSet) source.allowedSuiteBCiphers.clone();
enterpriseConfig = new WifiEnterpriseConfig(source.enterpriseConfig);
defaultGwMacAddress = source.defaultGwMacAddress;
@@ -2128,6 +2261,7 @@ public class WifiConfiguration implements Parcelable {
recentFailure.setAssociationStatus(source.recentFailure.getAssociationStatus());
mRandomizedMacAddress = source.mRandomizedMacAddress;
macRandomizationSetting = source.macRandomizationSetting;
+ requirePMF = source.requirePMF;
}
}
@@ -2163,6 +2297,8 @@ public class WifiConfiguration implements Parcelable {
writeBitSet(dest, allowedAuthAlgorithms);
writeBitSet(dest, allowedPairwiseCiphers);
writeBitSet(dest, allowedGroupCiphers);
+ writeBitSet(dest, allowedGroupMgmtCiphers);
+ writeBitSet(dest, allowedSuiteBCiphers);
dest.writeParcelable(enterpriseConfig, flags);
@@ -2231,6 +2367,8 @@ public class WifiConfiguration implements Parcelable {
config.allowedAuthAlgorithms = readBitSet(in);
config.allowedPairwiseCiphers = readBitSet(in);
config.allowedGroupCiphers = readBitSet(in);
+ config.allowedGroupMgmtCiphers = readBitSet(in);
+ config.allowedSuiteBCiphers = readBitSet(in);
config.enterpriseConfig = in.readParcelable(null);
config.setIpConfiguration(in.readParcelable(null));
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 9adbe67c1553..954b51f02820 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -25,19 +25,17 @@ import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.UnsupportedAppUsage;
+import android.app.PendingIntent;
import android.content.Context;
import android.content.pm.ParceledListSlice;
import android.net.ConnectivityManager;
import android.net.DhcpInfo;
import android.net.Network;
-import android.net.NetworkCapabilities;
-import android.net.NetworkRequest;
import android.net.wifi.hotspot2.IProvisioningCallback;
import android.net.wifi.hotspot2.OsuProvider;
import android.net.wifi.hotspot2.PasspointConfiguration;
import android.net.wifi.hotspot2.ProvisioningCallback;
import android.os.Binder;
-import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
@@ -52,7 +50,6 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
-import com.android.server.net.NetworkPinner;
import dalvik.system.CloseGuard;
@@ -1035,7 +1032,17 @@ public class WifiManager {
* </ul>
* @return a list of network configurations in the form of a list
* of {@link WifiConfiguration} objects.
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return an empty list.
*/
+ @Deprecated
public List<WifiConfiguration> getConfiguredNetworks() {
try {
ParceledListSlice<WifiConfiguration> parceledList =
@@ -1135,7 +1142,17 @@ public class WifiManager {
* @return the ID of the newly created network description. This is used in
* other operations to specified the network to be acted upon.
* Returns {@code -1} on failure.
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}.
*/
+ @Deprecated
public int addNetwork(WifiConfiguration config) {
if (config == null) {
return -1;
@@ -1160,7 +1177,17 @@ public class WifiManager {
* Returns {@code -1} on failure, including when the {@code networkId}
* field of the {@code WifiConfiguration} does not refer to an
* existing network.
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code -1}.
*/
+ @Deprecated
public int updateNetwork(WifiConfiguration config) {
if (config == null || config.networkId < 0) {
return -1;
@@ -1185,6 +1212,301 @@ public class WifiManager {
}
/**
+ * Interface for indicating user selection from the list of networks presented in the
+ * {@link NetworkRequestMatchCallback#onMatch(List)}.
+ *
+ * The platform will implement this callback and pass it along with the
+ * {@link NetworkRequestMatchCallback#onUserSelectionCallbackRegistration(
+ * NetworkRequestUserSelectionCallback)}. The UI component handling
+ * {@link NetworkRequestMatchCallback} will invoke {@link #select(WifiConfiguration)} or
+ * {@link #reject()} to return the user's selection back to the platform via this callback.
+ * @hide
+ */
+ @SystemApi
+ public interface NetworkRequestUserSelectionCallback {
+ /**
+ * User selected this network to connect to.
+ * @param wifiConfiguration WifiConfiguration object corresponding to the network
+ * user selected.
+ */
+ void select(@NonNull WifiConfiguration wifiConfiguration);
+
+ /**
+ * User rejected the app's request.
+ */
+ void reject();
+ }
+
+ /**
+ * Interface for network request callback. Should be implemented by applications and passed when
+ * calling {@link #registerNetworkRequestMatchCallback(NetworkRequestMatchCallback, Handler)}.
+ *
+ * This is meant to be implemented by a UI component to present the user with a list of networks
+ * matching the app's request. The user is allowed to pick one of these networks to connect to
+ * or reject the request by the app.
+ * @hide
+ */
+ @SystemApi
+ public interface NetworkRequestMatchCallback {
+ /**
+ * Invoked to register a callback to be invoked to convey user selection. The callback
+ * object paased in this method is to be invoked by the UI component after the service sends
+ * a list of matching scan networks using {@link #onMatch(List)} and user picks a network
+ * from that list.
+ *
+ * @param userSelectionCallback Callback object to send back the user selection.
+ */
+ void onUserSelectionCallbackRegistration(
+ @NonNull NetworkRequestUserSelectionCallback userSelectionCallback);
+
+ /**
+ * Invoked when a network request initiated by an app matches some networks in scan results.
+ * This may be invoked multiple times for a single network request as the platform finds new
+ * networks in scan results.
+ *
+ * @param wifiConfigurations List of {@link WifiConfiguration} objects corresponding to the
+ * networks matching the request.
+ */
+ void onMatch(@NonNull List<WifiConfiguration> wifiConfigurations);
+
+ /**
+ * Invoked on a successful connection with the network that the user selected
+ * via {@link NetworkRequestUserSelectionCallback}.
+ *
+ * @param wifiConfiguration WifiConfiguration object corresponding to the network that the
+ * user selected.
+ */
+ void onUserSelectionConnectSuccess(@NonNull WifiConfiguration wifiConfiguration);
+
+ /**
+ * Invoked on failure to establish connection with the network that the user selected
+ * via {@link NetworkRequestUserSelectionCallback}.
+ *
+ * @param wifiConfiguration WifiConfiguration object corresponding to the network
+ * user selected.
+ */
+ void onUserSelectionConnectFailure(@NonNull WifiConfiguration wifiConfiguration);
+ }
+
+ /**
+ * Callback proxy for NetworkRequestUserSelectionCallback objects.
+ * @hide
+ */
+ private class NetworkRequestUserSelectionCallbackProxy implements
+ NetworkRequestUserSelectionCallback {
+ private final INetworkRequestUserSelectionCallback mCallback;
+
+ NetworkRequestUserSelectionCallbackProxy(
+ INetworkRequestUserSelectionCallback callback) {
+ mCallback = callback;
+ }
+
+ @Override
+ public void select(@NonNull WifiConfiguration wifiConfiguration) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: select "
+ + "wificonfiguration: " + wifiConfiguration);
+ }
+ try {
+ mCallback.select(wifiConfiguration);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to invoke onSelected", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ @Override
+ public void reject() {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "NetworkRequestUserSelectionCallbackProxy: reject");
+ }
+ try {
+ mCallback.reject();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to invoke onRejected", e);
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Callback proxy for NetworkRequestMatchCallback objects.
+ * @hide
+ */
+ private class NetworkRequestMatchCallbackProxy extends INetworkRequestMatchCallback.Stub {
+ private final Handler mHandler;
+ private final NetworkRequestMatchCallback mCallback;
+
+ NetworkRequestMatchCallbackProxy(Looper looper, NetworkRequestMatchCallback callback) {
+ mHandler = new Handler(looper);
+ mCallback = callback;
+ }
+
+ @Override
+ public void onUserSelectionCallbackRegistration(
+ INetworkRequestUserSelectionCallback userSelectionCallback) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "NetworkRequestMatchCallbackProxy: "
+ + "onUserSelectionCallbackRegistration callback: " + userSelectionCallback);
+ }
+ mHandler.post(() -> {
+ mCallback.onUserSelectionCallbackRegistration(
+ new NetworkRequestUserSelectionCallbackProxy(userSelectionCallback));
+ });
+ }
+
+ @Override
+ public void onMatch(List<WifiConfiguration> wifiConfigurations) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "NetworkRequestMatchCallbackProxy: onMatch wificonfigurations: "
+ + wifiConfigurations);
+ }
+ mHandler.post(() -> {
+ mCallback.onMatch(wifiConfigurations);
+ });
+ }
+
+ @Override
+ public void onUserSelectionConnectSuccess(WifiConfiguration wifiConfiguration) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectSuccess "
+ + " wificonfiguration: " + wifiConfiguration);
+ }
+ mHandler.post(() -> {
+ mCallback.onUserSelectionConnectSuccess(wifiConfiguration);
+ });
+ }
+
+ @Override
+ public void onUserSelectionConnectFailure(WifiConfiguration wifiConfiguration) {
+ if (mVerboseLoggingEnabled) {
+ Log.v(TAG, "NetworkRequestMatchCallbackProxy: onUserSelectionConnectFailure"
+ + " wificonfiguration: " + wifiConfiguration);
+ }
+ mHandler.post(() -> {
+ mCallback.onUserSelectionConnectFailure(wifiConfiguration);
+ });
+ }
+ }
+
+ /**
+ * Registers a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
+ * Caller can unregister a previously registered callback using
+ * {@link #unregisterNetworkRequestMatchCallback(NetworkRequestMatchCallback)}
+ * <p>
+ * Applications should have the
+ * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
+ * without the permission will trigger a {@link java.lang.SecurityException}.
+ * <p>
+ *
+ * @param callback Callback for network match events
+ * @param handler The Handler on whose thread to execute the callbacks of the {@code callback}
+ * object. If null, then the application's main thread will be used.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ public void registerNetworkRequestMatchCallback(@NonNull NetworkRequestMatchCallback callback,
+ @Nullable Handler handler) {
+ if (callback == null) throw new IllegalArgumentException("callback cannot be null");
+ Log.v(TAG, "registerNetworkRequestMatchCallback: callback=" + callback
+ + ", handler=" + handler);
+
+ Looper looper = (handler == null) ? mContext.getMainLooper() : handler.getLooper();
+ Binder binder = new Binder();
+ try {
+ mService.registerNetworkRequestMatchCallback(
+ binder, new NetworkRequestMatchCallbackProxy(looper, callback),
+ callback.hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Unregisters a callback for NetworkRequest matches. See {@link NetworkRequestMatchCallback}.
+ * <p>
+ * Applications should have the
+ * {@link android.Manifest.permission#NETWORK_SETTINGS} permission. Callers
+ * without the permission will trigger a {@link java.lang.SecurityException}.
+ * <p>
+ *
+ * @param callback Callback for network match events
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.NETWORK_SETTINGS)
+ public void unregisterNetworkRequestMatchCallback(
+ @NonNull NetworkRequestMatchCallback callback) {
+ if (callback == null) throw new IllegalArgumentException("callback cannot be null");
+ Log.v(TAG, "unregisterNetworkRequestMatchCallback: callback=" + callback);
+
+ try {
+ mService.unregisterNetworkRequestMatchCallback(callback.hashCode());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Provide a list of network suggestions to the device. See {@link WifiNetworkSuggestion}
+ * for a detailed explanation of the parameters.
+ *<p>
+ * When the device decides to connect to one of the provided network suggestions, platform fires
+ * the associated {@code pendingIntent} if
+ * the network was created with {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()}
+ * flag set and the provided {@code pendingIntent} is non-null.
+ *<p>
+ * Registration of a non-null pending intent {@code pendingIntent} requires
+ * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION ACCESS_COARSE_LOCATION} or
+ * {@link android.Manifest.permission#ACCESS_FINE_LOCATION ACCESS_FINE_LOCATION} permission.
+ *<p>
+ * NOTE:
+ * <li> These networks are just a suggestion to the platform. The platform will ultimately
+ * decide on which network the device connects to. </li>
+ * <li> When an app is uninstalled, all its suggested networks are discarded. If the device is
+ * currently connected to a suggested network which is being removed then the device will
+ * disconnect from that network.</li>
+ * <li> No in-place modification of existing suggestions are allowed. Apps are expected to
+ * remove suggestions using {@link #removeNetworkSuggestions(List)} and then add the modified
+ * suggestion back using this API.</li>
+ *
+ * @param networkSuggestions List of network suggestions provided by the app.
+ * @param pendingIntent Pending intent to be fired post connection for networks. These will be
+ * fired only when connecting to a network that was created with
+ * {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()} flag set.
+ * Pending intent must hold a foreground service, else will be rejected.
+ * @return true on success, false if any of the suggestions match (See
+ * {@link WifiNetworkSuggestion#equals(Object)} any previously provided suggestions by the app.
+ * @throws {@link SecurityException} if the caller is missing required permissions.
+ */
+ public boolean addNetworkSuggestions(
+ @NonNull List<WifiNetworkSuggestion> networkSuggestions,
+ @Nullable PendingIntent pendingIntent) {
+ // TODO(b/115504887): Implementation
+ return false;
+ }
+
+
+ /**
+ * Remove a subset of or all of networks from previously provided suggestions by the app to the
+ * device.
+ * See {@link WifiNetworkSuggestion} for a detailed explanation of the parameters.
+ * See {@link WifiNetworkSuggestion#equals(Object)} for the equivalence evaluation used.
+ *
+ * @param networkSuggestions List of network suggestions to be removed. Pass an empty list
+ * to remove all the previous suggestions provided by the app.
+ * @return true on success, false if any of the suggestions do not match any suggestions
+ * previously provided by the app. Any matching suggestions are removed from the device and
+ * will not be considered for any further connection attempts.
+ */
+ public boolean removeNetworkSuggestions(
+ @NonNull List<WifiNetworkSuggestion> networkSuggestions) {
+ // TODO(b/115504887): Implementation
+ return false;
+ }
+
+ /**
* Add or update a Passpoint configuration. The configuration provides a credential
* for connecting to Passpoint networks that are operated by the Passpoint
* service provider specified in the configuration.
@@ -1299,7 +1621,17 @@ public class WifiManager {
* @param netId the ID of the network as returned by {@link #addNetwork} or {@link
* #getConfiguredNetworks}.
* @return {@code true} if the operation succeeded
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
+ @Deprecated
public boolean removeNetwork(int netId) {
try {
return mService.removeNetwork(netId, mContext.getOpPackageName());
@@ -1314,10 +1646,8 @@ public class WifiManager {
* network is initiated. This may result in the asynchronous delivery
* of state change events.
* <p>
- * <b>Note:</b> If an application's target SDK version is
- * {@link android.os.Build.VERSION_CODES#LOLLIPOP} or newer, network
- * communication may not use Wi-Fi even if Wi-Fi is connected; traffic may
- * instead be sent through another network, such as cellular data,
+ * <b>Note:</b> Network communication may not use Wi-Fi even if Wi-Fi is connected;
+ * traffic may instead be sent through another network, such as cellular data,
* Bluetooth tethering, or Ethernet. For example, traffic will never use a
* Wi-Fi network that does not provide Internet access (e.g. a wireless
* printer), if another network that does offer Internet access (e.g.
@@ -1335,29 +1665,24 @@ public class WifiManager {
* @param attemptConnect The way to select a particular network to connect to is specify
* {@code true} for this parameter.
* @return {@code true} if the operation succeeded
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
+ @Deprecated
public boolean enableNetwork(int netId, boolean attemptConnect) {
- final boolean pin = attemptConnect && mTargetSdkVersion < Build.VERSION_CODES.LOLLIPOP;
- if (pin) {
- NetworkRequest request = new NetworkRequest.Builder()
- .clearCapabilities()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- .build();
- NetworkPinner.pin(mContext, request);
- }
-
boolean success;
try {
success = mService.enableNetwork(netId, attemptConnect, mContext.getOpPackageName());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
-
- if (pin && !success) {
- NetworkPinner.unpin();
- }
-
return success;
}
@@ -1372,7 +1697,17 @@ public class WifiManager {
* @param netId the ID of the network as returned by {@link #addNetwork} or {@link
* #getConfiguredNetworks}.
* @return {@code true} if the operation succeeded
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
+ @Deprecated
public boolean disableNetwork(int netId) {
try {
return mService.disableNetwork(netId, mContext.getOpPackageName());
@@ -1385,7 +1720,17 @@ public class WifiManager {
* Disassociate from the currently active access point. This may result
* in the asynchronous delivery of state change events.
* @return {@code true} if the operation succeeded
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
+ @Deprecated
public boolean disconnect() {
try {
mService.disconnect(mContext.getOpPackageName());
@@ -1400,7 +1745,17 @@ public class WifiManager {
* disconnected. This may result in the asynchronous delivery of state
* change events.
* @return {@code true} if the operation succeeded
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
+ @Deprecated
public boolean reconnect() {
try {
mService.reconnect(mContext.getOpPackageName());
@@ -1415,7 +1770,17 @@ public class WifiManager {
* connected. This may result in the asynchronous delivery of state
* change events.
* @return {@code true} if the operation succeeded
+ *
+ * @deprecated
+ * a) See {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for new
+ * mechanism to trigger connection to a Wi-Fi network.
+ * b) See {@link #addNetworkSuggestions(List, PendingIntent)},
+ * {@link #removeNetworkSuggestions(List)} for new API to add Wi-Fi networks for consideration
+ * when auto-connecting to wifi.
+ * <b>Compatibility Note:</b> For applications targeting
+ * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return false.
*/
+ @Deprecated
public boolean reassociate() {
try {
mService.reassociate(mContext.getOpPackageName());
@@ -1490,7 +1855,12 @@ public class WifiManager {
public static final int WIFI_FEATURE_SCAN_RAND = 0x2000000; // Random MAC & Probe seq
/** @hide */
public static final int WIFI_FEATURE_TX_POWER_LIMIT = 0x4000000; // Set Tx power limit
-
+ /** @hide */
+ public static final int WIFI_FEATURE_WPA3_SAE = 0x8000000; // WPA3-Personal SAE
+ /** @hide */
+ public static final int WIFI_FEATURE_WPA3_SUITE_B = 0x10000000; // WPA3-Enterprise Suite-B
+ /** @hide */
+ public static final int WIFI_FEATURE_OWE = 0x20000000; // Enhanced Open
private int getSupportedFeatures() {
try {
@@ -1715,7 +2085,10 @@ public class WifiManager {
* even when Wi-Fi is turned off.
*
* To change this setting, see {@link #ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE}.
+ * @deprecated The ability for apps to trigger scan requests will be removed in a future
+ * release.
*/
+ @Deprecated
public boolean isScanAlwaysAvailable() {
try {
return mService.isScanAlwaysAvailable();
@@ -1821,7 +2194,12 @@ public class WifiManager {
* @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is
* either already in the requested state, or in progress toward the requested state.
* @throws {@link java.lang.SecurityException} if the caller is missing required permissions.
+ *
+ * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to
+ * enable/disable Wi-Fi regardless of application's target SDK. This API will have no effect
+ * and will always return false.
*/
+ @Deprecated
public boolean setWifiEnabled(boolean enabled) {
try {
return mService.setWifiEnabled(mContext.getOpPackageName(), enabled);
@@ -3875,4 +4253,31 @@ public class WifiManager {
private void updateVerboseLoggingEnabledFromService() {
mVerboseLoggingEnabled = getVerboseLoggingLevel() > 0;
}
+
+ /**
+ * @return true if this device supports WPA3-Personal SAE
+ * @hide
+ */
+ @SystemApi
+ public boolean isWpa3SaeSupported() {
+ return isFeatureSupported(WIFI_FEATURE_WPA3_SAE);
+ }
+
+ /**
+ * @return true if this device supports WPA3-Enterprise Suite-B-192
+ * @hide
+ */
+ @SystemApi
+ public boolean isWpa3SuiteBSupported() {
+ return isFeatureSupported(WIFI_FEATURE_WPA3_SUITE_B);
+ }
+
+ /**
+ * @return true if this device supports Wi-Fi Enhanced Open (OWE)
+ * @hide
+ */
+ @SystemApi
+ public boolean isOweSupported() {
+ return isFeatureSupported(WIFI_FEATURE_OWE);
+ }
}
diff --git a/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
new file mode 100644
index 000000000000..55fde4ca335e
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkAgentSpecifier.java
@@ -0,0 +1,187 @@
+/*
+ * 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.net.wifi;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+import static com.android.internal.util.Preconditions.checkState;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkAgent;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * Network specifier object used by wifi's {@link android.net.NetworkAgent}.
+ * @hide
+ */
+public final class WifiNetworkAgentSpecifier extends NetworkSpecifier implements Parcelable {
+ /**
+ * Security credentials for the currently connected network.
+ */
+ private final WifiConfiguration mWifiConfiguration;
+
+ /**
+ * The UID of the app that requested a specific wifi network using {@link WifiNetworkSpecifier}.
+ *
+ * Will only be filled when the device connects to a wifi network as a result of a
+ * {@link NetworkRequest} with {@link WifiNetworkSpecifier}. Will be set to -1 if the device
+ * auto-connected to a wifi network.
+ */
+ private final int mOriginalRequestorUid;
+
+ public WifiNetworkAgentSpecifier(@NonNull WifiConfiguration wifiConfiguration,
+ int originalRequestorUid) {
+ checkNotNull(wifiConfiguration);
+
+ mWifiConfiguration = wifiConfiguration;
+ mOriginalRequestorUid = originalRequestorUid;
+ }
+
+ /**
+ * @hide
+ */
+ public static final Creator<WifiNetworkAgentSpecifier> CREATOR =
+ new Creator<WifiNetworkAgentSpecifier>() {
+ @Override
+ public WifiNetworkAgentSpecifier createFromParcel(@NonNull Parcel in) {
+ WifiConfiguration wifiConfiguration = in.readParcelable(null);
+ int originalRequestorUid = in.readInt();
+ return new WifiNetworkAgentSpecifier(wifiConfiguration, originalRequestorUid);
+ }
+
+ @Override
+ public WifiNetworkAgentSpecifier[] newArray(int size) {
+ return new WifiNetworkAgentSpecifier[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
+ dest.writeParcelable(mWifiConfiguration, flags);
+ dest.writeInt(mOriginalRequestorUid);
+ }
+
+ @Override
+ public boolean satisfiedBy(@Nullable NetworkSpecifier other) {
+ if (this == other) {
+ return true;
+ }
+ // Any generic requests should be satisifed by a specific wifi network.
+ if (other == null || other instanceof MatchAllNetworkSpecifier) {
+ return true;
+ }
+ if (other instanceof WifiNetworkSpecifier) {
+ return satisfiesNetworkSpecifier((WifiNetworkSpecifier) other);
+ }
+ if (other instanceof WifiNetworkAgentSpecifier) {
+ throw new IllegalStateException("WifiNetworkAgentSpecifier instances should never be "
+ + "compared");
+ }
+ return false;
+ }
+
+ /**
+ * Match {@link WifiNetworkSpecifier} in app's {@link NetworkRequest} with the
+ * {@link WifiNetworkAgentSpecifier} in wifi platform's {@link NetworkAgent}.
+ */
+ public boolean satisfiesNetworkSpecifier(@NonNull WifiNetworkSpecifier ns) {
+ // None of these should be null by construction.
+ // {@link WifiNetworkConfigBuilder} enforces non-null in {@link WifiNetworkSpecifier}.
+ // {@link WifiNetworkFactory} ensures non-null in {@link WifiNetworkAgentSpecifier}.
+ checkNotNull(ns);
+ checkNotNull(ns.ssidPatternMatcher);
+ checkNotNull(ns.bssidPatternMatcher);
+ checkNotNull(ns.wifiConfiguration.allowedKeyManagement);
+ checkNotNull(this.mWifiConfiguration.SSID);
+ checkNotNull(this.mWifiConfiguration.BSSID);
+ checkNotNull(this.mWifiConfiguration.allowedKeyManagement);
+
+ final String ssidWithQuotes = this.mWifiConfiguration.SSID;
+ checkState(ssidWithQuotes.startsWith("\"") && ssidWithQuotes.endsWith("\""));
+ final String ssidWithoutQuotes = ssidWithQuotes.substring(1, ssidWithQuotes.length() - 1);
+ if (!ns.ssidPatternMatcher.match(ssidWithoutQuotes)) {
+ return false;
+ }
+ final MacAddress bssid = MacAddress.fromString(this.mWifiConfiguration.BSSID);
+ final MacAddress matchBaseAddress = ns.bssidPatternMatcher.first;
+ final MacAddress matchMask = ns.bssidPatternMatcher.second;
+ if (!bssid.matches(matchBaseAddress, matchMask)) {
+ return false;
+ }
+ if (!ns.wifiConfiguration.allowedKeyManagement.equals(
+ this.mWifiConfiguration.allowedKeyManagement)) {
+ return false;
+ }
+ if (ns.requestorUid != this.mOriginalRequestorUid) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ mWifiConfiguration.SSID,
+ mWifiConfiguration.BSSID,
+ mWifiConfiguration.allowedKeyManagement,
+ mOriginalRequestorUid);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof WifiNetworkAgentSpecifier)) {
+ return false;
+ }
+ WifiNetworkAgentSpecifier lhs = (WifiNetworkAgentSpecifier) obj;
+ return Objects.equals(this.mWifiConfiguration.SSID, lhs.mWifiConfiguration.SSID)
+ && Objects.equals(this.mWifiConfiguration.BSSID, lhs.mWifiConfiguration.BSSID)
+ && Objects.equals(this.mWifiConfiguration.allowedKeyManagement,
+ lhs.mWifiConfiguration.allowedKeyManagement)
+ && mOriginalRequestorUid == lhs.mOriginalRequestorUid;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("WifiNetworkAgentSpecifier [");
+ sb.append(", WifiConfiguration=").append(
+ mWifiConfiguration == null ? null : mWifiConfiguration.configKey())
+ .append(", mOriginalRequestorUid=").append(mOriginalRequestorUid)
+ .append("]");
+ return sb.toString();
+ }
+
+ @Override
+ public void assertValidFromUid(int requestorUid) {
+ throw new IllegalStateException("WifiNetworkAgentSpecifier should never be used "
+ + "for requests.");
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java
new file mode 100644
index 000000000000..67e218972994
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkConfigBuilder.java
@@ -0,0 +1,511 @@
+/*
+ * 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.net.wifi;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.net.MacAddress;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.os.PatternMatcher;
+import android.os.Process;
+import android.text.TextUtils;
+import android.util.Pair;
+
+import java.nio.charset.CharsetEncoder;
+import java.nio.charset.StandardCharsets;
+import java.util.List;
+
+/**
+ * WifiNetworkConfigBuilder to use for creating Wi-Fi network configuration.
+ * <li>See {@link #buildNetworkSpecifier()} for creating a network specifier to use in
+ * {@link NetworkRequest}.</li>
+ * <li>See {@link #buildNetworkSuggestion()} for creating a network suggestion to use in
+ * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)}.</li>
+ */
+public class WifiNetworkConfigBuilder {
+ private static final String MATCH_ALL_SSID_PATTERN_PATH = ".*";
+ private static final String MATCH_EMPTY_SSID_PATTERN_PATH = "";
+ private static final Pair<MacAddress, MacAddress> MATCH_NO_BSSID_PATTERN =
+ new Pair(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS);
+ private static final Pair<MacAddress, MacAddress> MATCH_ALL_BSSID_PATTERN =
+ new Pair(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
+ private static final MacAddress MATCH_EXACT_BSSID_PATTERN_MASK =
+ MacAddress.BROADCAST_ADDRESS;
+ private static final int UNASSIGNED_PRIORITY = -1;
+
+ /**
+ * SSID pattern match specified by the app.
+ */
+ private @Nullable PatternMatcher mSsidPatternMatcher;
+ /**
+ * BSSID pattern match specified by the app.
+ * Pair of <BaseAddress, Mask>.
+ */
+ private @Nullable Pair<MacAddress, MacAddress> mBssidPatternMatcher;
+ /**
+ * Pre-shared key for use with WPA-PSK networks.
+ */
+ private @Nullable String mPskPassphrase;
+ /**
+ * The enterprise configuration details specifying the EAP method,
+ * certificates and other settings associated with the EAP.
+ */
+ private @Nullable WifiEnterpriseConfig mEnterpriseConfig;
+ /**
+ * This is a network that does not broadcast its SSID, so an
+ * SSID-specific probe request must be used for scans.
+ */
+ private boolean mIsHiddenSSID;
+ /**
+ * Whether app needs to log in to captive portal to obtain Internet access.
+ */
+ private boolean mIsAppInteractionRequired;
+ /**
+ * Whether user needs to log in to captive portal to obtain Internet access.
+ */
+ private boolean mIsUserInteractionRequired;
+ /**
+ * Whether this network is metered or not.
+ */
+ private boolean mIsMetered;
+ /**
+ * Priority of this network among other network suggestions provided by the app.
+ * The lower the number, the higher the priority (i.e value of 0 = highest priority).
+ */
+ private int mPriority;
+
+ public WifiNetworkConfigBuilder() {
+ mSsidPatternMatcher = null;
+ mBssidPatternMatcher = null;
+ mPskPassphrase = null;
+ mEnterpriseConfig = null;
+ mIsHiddenSSID = false;
+ mIsAppInteractionRequired = false;
+ mIsUserInteractionRequired = false;
+ mIsMetered = false;
+ mPriority = UNASSIGNED_PRIORITY;
+ }
+
+ /**
+ * Set the unicode SSID match pattern to use for filtering networks from scan results.
+ * <p>
+ * <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
+ * <li>Overrides any previous value set using {@link #setSsid(String)} or
+ * {@link #setSsidPattern(PatternMatcher)}.</li>
+ *
+ * @param ssidPattern Instance of {@link PatternMatcher} containing the UTF-8 encoded
+ * string pattern to use for matching the network's SSID.
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setSsidPattern(@NonNull PatternMatcher ssidPattern) {
+ checkNotNull(ssidPattern);
+ mSsidPatternMatcher = ssidPattern;
+ return this;
+ }
+
+ /**
+ * Set the unicode SSID for the network.
+ * <p>
+ * <li>For network requests ({@link NetworkSpecifier}), built using
+ * {@link #buildNetworkSpecifier}, sets the SSID to use for filtering networks from scan
+ * results. Will only match networks whose SSID is identical to the UTF-8 encoding of the
+ * specified value.</li>
+ * <li>For network suggestions ({@link WifiNetworkSuggestion}), built using
+ * {@link #buildNetworkSuggestion()}, sets the SSID for the network.</li>
+ * <li>Overrides any previous value set using {@link #setSsid(String)} or
+ * {@link #setSsidPattern(PatternMatcher)}.</li>
+ *
+ * @param ssid The SSID of the network. It must be valid Unicode.
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ * @throws IllegalArgumentException if the SSID is not valid unicode.
+ */
+ public WifiNetworkConfigBuilder setSsid(@NonNull String ssid) {
+ checkNotNull(ssid);
+ final CharsetEncoder unicodeEncoder = StandardCharsets.UTF_8.newEncoder();
+ if (!unicodeEncoder.canEncode(ssid)) {
+ throw new IllegalArgumentException("SSID is not a valid unicode string");
+ }
+ mSsidPatternMatcher = new PatternMatcher(ssid, PatternMatcher.PATTERN_LITERAL);
+ return this;
+ }
+
+ /**
+ * Set the BSSID match pattern to use for filtering networks from scan results.
+ * Will match all networks with BSSID which satisfies the following:
+ * {@code BSSID & mask == baseAddress}.
+ * <p>
+ * <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
+ * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
+ * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
+ *
+ * @param baseAddress Base address for BSSID pattern.
+ * @param mask Mask for BSSID pattern.
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setBssidPattern(
+ @NonNull MacAddress baseAddress, @NonNull MacAddress mask) {
+ checkNotNull(baseAddress, mask);
+ mBssidPatternMatcher = Pair.create(baseAddress, mask);
+ return this;
+ }
+
+ /**
+ * Set the BSSID to use for filtering networks from scan results. Will only match network whose
+ * BSSID is identical to the specified value.
+ * <p>
+ * <li>Only allowed for creating network specifier, i.e {@link #buildNetworkSpecifier()}. </li>
+ * <li>Overrides any previous value set using {@link #setBssid(MacAddress)} or
+ * {@link #setBssidPattern(MacAddress, MacAddress)}.</li>
+ *
+ * @param bssid BSSID of the network.
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setBssid(@NonNull MacAddress bssid) {
+ checkNotNull(bssid);
+ mBssidPatternMatcher = Pair.create(bssid, MATCH_EXACT_BSSID_PATTERN_MASK);
+ return this;
+ }
+
+ /**
+ * Set the ASCII PSK passphrase for this network. Needed for authenticating to
+ * WPA_PSK networks.
+ *
+ * @param pskPassphrase PSK passphrase of the network.
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ * @throws IllegalArgumentException if the passphrase is not ASCII encodable.
+ */
+ public WifiNetworkConfigBuilder setPskPassphrase(@NonNull String pskPassphrase) {
+ checkNotNull(pskPassphrase);
+ final CharsetEncoder asciiEncoder = StandardCharsets.US_ASCII.newEncoder();
+ if (!asciiEncoder.canEncode(pskPassphrase)) {
+ throw new IllegalArgumentException("passphrase not ASCII encodable");
+ }
+ mPskPassphrase = pskPassphrase;
+ return this;
+ }
+
+ /**
+ * Set the associated enterprise configuration for this network. Needed for authenticating to
+ * WPA_EAP networks. See {@link WifiEnterpriseConfig} for description.
+ *
+ * @param enterpriseConfig Instance of {@link WifiEnterpriseConfig}.
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setEnterpriseConfig(
+ @NonNull WifiEnterpriseConfig enterpriseConfig) {
+ checkNotNull(enterpriseConfig);
+ mEnterpriseConfig = new WifiEnterpriseConfig(enterpriseConfig);
+ return this;
+ }
+
+ /**
+ * Specifies whether this represents a hidden network.
+ * <p>
+ * <li>For network requests (see {@link NetworkSpecifier}), built using
+ * {@link #buildNetworkSpecifier}, setting this disallows the usage of
+ * {@link #setSsidPattern(PatternMatcher)} since hidden networks need to be explicitly
+ * probed for.</li>
+ * <li>If not set, defaults to false (i.e not a hidden network).</li>
+ *
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setIsHiddenSsid() {
+ mIsHiddenSSID = true;
+ return this;
+ }
+
+ /**
+ * Specifies whether the app needs to log in to a captive portal to obtain Internet access.
+ * <p>
+ * This will dictate if the associated pending intent in
+ * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)} will be sent after
+ * successfully connecting to the network.
+ * Use this for captive portal type networks where the app needs to authenticate the user
+ * before the device can access the network.
+ * This setting will be ignored if the {@code PendingIntent} used to add this network
+ * suggestion is null.
+ * <p>
+ * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
+ * <li>If not set, defaults to false (i.e no app interaction required).</li>
+ *
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setIsAppInteractionRequired() {
+ mIsAppInteractionRequired = true;
+ return this;
+ }
+
+ /**
+ * Specifies whether the user needs to log in to a captive portal to obtain Internet access.
+ * <p>
+ * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
+ * <li>If not set, defaults to false (i.e no user interaction required).</li>
+ *
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setIsUserInteractionRequired() {
+ mIsUserInteractionRequired = true;
+ return this;
+ }
+
+ /**
+ * Specify the priority of this network among other network suggestions provided by the same app
+ * (priorities have no impact on suggestions by different apps). The lower the number, the
+ * higher the priority (i.e value of 0 = highest priority).
+ * <p>
+ * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
+ * <li>If not set, defaults to -1 (i.e unassigned priority).</li>
+ *
+ * @param priority Integer number representing the priority among suggestions by the app.
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ * @throws IllegalArgumentException if the priority value is negative.
+ */
+ public WifiNetworkConfigBuilder setPriority(int priority) {
+ if (priority < 0) {
+ throw new IllegalArgumentException("Invalid priority value " + priority);
+ }
+ mPriority = priority;
+ return this;
+ }
+
+ /**
+ * Specifies whether this network is metered.
+ * <p>
+ * <li>Only allowed for creating network suggestion, i.e {@link #buildNetworkSuggestion()}.</li>
+ * <li>If not set, defaults to false (i.e not metered).</li>
+ *
+ * @return Instance of {@link WifiNetworkConfigBuilder} to enable chaining of the builder
+ * method.
+ */
+ public WifiNetworkConfigBuilder setIsMetered() {
+ mIsMetered = true;
+ return this;
+ }
+
+ /**
+ * Set defaults for the various low level credential type fields in the newly created
+ * WifiConfiguration object.
+ *
+ * See {@link com.android.server.wifi.WifiConfigManager#setDefaultsInWifiConfiguration(
+ * WifiConfiguration)}.
+ *
+ * @param configuration provided WifiConfiguration object.
+ */
+ private static void setDefaultsInWifiConfiguration(@NonNull WifiConfiguration configuration) {
+ configuration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
+ configuration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
+ configuration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
+ configuration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
+ }
+
+ private void setKeyMgmtInWifiConfiguration(@NonNull WifiConfiguration configuration) {
+ if (!TextUtils.isEmpty(mPskPassphrase)) {
+ // WPA_PSK network.
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ } else if (mEnterpriseConfig != null) {
+ // WPA_EAP network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_EAP);
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.IEEE8021X);
+ } else {
+ // Open network
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ }
+ }
+
+ /**
+ * Helper method to build WifiConfiguration object from the builder.
+ * @return Instance of {@link WifiConfiguration}.
+ */
+ private WifiConfiguration buildWifiConfiguration() {
+ final WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ setDefaultsInWifiConfiguration(wifiConfiguration);
+ // WifiConfiguration.SSID needs quotes around unicode SSID.
+ if (mSsidPatternMatcher.getType() == PatternMatcher.PATTERN_LITERAL) {
+ wifiConfiguration.SSID = "\"" + mSsidPatternMatcher.getPath() + "\"";
+ }
+ setKeyMgmtInWifiConfiguration(wifiConfiguration);
+ // WifiConfiguration.preSharedKey needs quotes around ASCII password.
+ if (mPskPassphrase != null) {
+ wifiConfiguration.preSharedKey = "\"" + mPskPassphrase + "\"";
+ }
+ wifiConfiguration.enterpriseConfig = mEnterpriseConfig;
+ wifiConfiguration.hiddenSSID = mIsHiddenSSID;
+ wifiConfiguration.priority = mPriority;
+ wifiConfiguration.meteredOverride =
+ mIsMetered ? WifiConfiguration.METERED_OVERRIDE_METERED
+ : WifiConfiguration.METERED_OVERRIDE_NONE;
+ return wifiConfiguration;
+ }
+
+ private boolean hasSetAnyPattern() {
+ return mSsidPatternMatcher != null || mBssidPatternMatcher != null;
+ }
+
+ private void setMatchAnyPatternIfUnset() {
+ if (mSsidPatternMatcher == null) {
+ mSsidPatternMatcher = new PatternMatcher(MATCH_ALL_SSID_PATTERN_PATH,
+ PatternMatcher.PATTERN_SIMPLE_GLOB);
+ }
+ if (mBssidPatternMatcher == null) {
+ mBssidPatternMatcher = MATCH_ALL_BSSID_PATTERN;
+ }
+ }
+
+ private boolean hasSetMatchNonePattern() {
+ if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_PREFIX
+ && mSsidPatternMatcher.getPath().equals(MATCH_EMPTY_SSID_PATTERN_PATH)) {
+ return true;
+ }
+ if (mBssidPatternMatcher.equals(MATCH_NO_BSSID_PATTERN)) {
+ return true;
+ }
+ return false;
+ }
+
+ private boolean hasSetMatchAllPattern() {
+ if ((mSsidPatternMatcher.match(MATCH_EMPTY_SSID_PATTERN_PATH))
+ && mBssidPatternMatcher.equals(MATCH_ALL_BSSID_PATTERN)) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Create a specifier object used to request a Wi-Fi network. The generated
+ * {@link NetworkSpecifier} should be used in
+ * {@link NetworkRequest.Builder#setNetworkSpecifier(NetworkSpecifier)} when building
+ * the {@link NetworkRequest}.
+ *<p>
+ * Note: Apps can set a combination of network match params:
+ * <li> SSID Pattern using {@link #setSsidPattern(PatternMatcher)} OR Specific SSID using
+ * {@link #setSsid(String)}. </li>
+ * AND/OR
+ * <li> BSSID Pattern using {@link #setBssidPattern(MacAddress, MacAddress)} OR Specific BSSID
+ * using {@link #setBssid(MacAddress)} </li>
+ * to trigger connection to a network that matches the set params.
+ * The system will find the set of networks matching the request and present the user
+ * with a system dialog which will allow the user to select a specific Wi-Fi network to connect
+ * to or to deny the request.
+ *</p>
+ *
+ * For example:
+ * To connect to an open network with a SSID prefix of "test" and a BSSID OUI of "10:03:23":
+ * {@code
+ * final NetworkSpecifier specifier =
+ * new WifiNetworkConfigBuilder()
+ * .setSsidPattern(new PatternMatcher("test", PatterMatcher.PATTERN_PREFIX))
+ * .setBssidPattern(MacAddress.fromString("10:03:23:00:00:00"),
+ * MacAddress.fromString("ff:ff:ff:00:00:00"))
+ * .buildNetworkSpecifier()
+ * final NetworkRequest request =
+ * new NetworkRequest.Builder()
+ * .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
+ * .setNetworkSpecifier(specifier)
+ * .build();
+ * final ConnectivityManager connectivityManager =
+ * context.getSystemService(Context.CONNECTIVITY_SERVICE);
+ * final NetworkCallback networkCallback = new NetworkCallback() {
+ * ...
+ * {@literal @}Override
+ * void onAvailable(...) {}
+ * // etc.
+ * };
+ * connectivityManager.requestNetwork(request, networkCallback);
+ * }
+ *
+ * @return Instance of {@link NetworkSpecifier}.
+ * @throws IllegalStateException on invalid params set.
+ */
+ public NetworkSpecifier buildNetworkSpecifier() {
+ if (!hasSetAnyPattern()) {
+ throw new IllegalStateException("one of setSsidPattern/setSsid/setBssidPattern/setBssid"
+ + " should be invoked for specifier");
+ }
+ setMatchAnyPatternIfUnset();
+ if (hasSetMatchNonePattern()) {
+ throw new IllegalStateException("cannot set match-none pattern for specifier");
+ }
+ if (hasSetMatchAllPattern()) {
+ throw new IllegalStateException("cannot set match-all pattern for specifier");
+ }
+ if (mIsHiddenSSID && mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL) {
+ throw new IllegalStateException("setSsid should also be invoked when "
+ + "setIsHiddenSsid is invoked for network specifier");
+ }
+ if (mIsAppInteractionRequired || mIsUserInteractionRequired
+ || mPriority != -1 || mIsMetered) {
+ throw new IllegalStateException("none of setIsAppInteractionRequired/"
+ + "setIsUserInteractionRequired/setPriority/setIsMetered are allowed for "
+ + "specifier");
+ }
+ if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) {
+ throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can"
+ + " be invoked for network specifier");
+ }
+
+ return new WifiNetworkSpecifier(
+ mSsidPatternMatcher,
+ mBssidPatternMatcher,
+ buildWifiConfiguration(),
+ Process.myUid());
+ }
+
+ /**
+ * Create a network suggestion object use in
+ * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)}.
+ * See {@link WifiNetworkSuggestion}.
+ *
+ * @return Instance of {@link WifiNetworkSuggestion}.
+ * @throws IllegalStateException on invalid params set.
+ */
+ public WifiNetworkSuggestion buildNetworkSuggestion() {
+ if (mSsidPatternMatcher == null) {
+ throw new IllegalStateException("setSsid should be invoked for suggestion");
+ }
+ if (mSsidPatternMatcher.getType() != PatternMatcher.PATTERN_LITERAL
+ || mBssidPatternMatcher != null) {
+ throw new IllegalStateException("none of setSsidPattern/setBssidPattern/setBssid are"
+ + " allowed for suggestion");
+ }
+ if (!TextUtils.isEmpty(mPskPassphrase) && mEnterpriseConfig != null) {
+ throw new IllegalStateException("only one of setPreSharedKey or setEnterpriseConfig can"
+ + "be invoked for suggestion");
+ }
+
+ return new WifiNetworkSuggestion(
+ buildWifiConfiguration(),
+ mIsAppInteractionRequired,
+ mIsUserInteractionRequired,
+ Process.myUid());
+
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSpecifier.java b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
new file mode 100644
index 000000000000..4348399b404b
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkSpecifier.java
@@ -0,0 +1,181 @@
+/*
+ * 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.net.wifi;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.NonNull;
+import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkSpecifier;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PatternMatcher;
+import android.util.Pair;
+
+import java.util.Objects;
+
+/**
+ * Network specifier object used to request a Wi-Fi network. Apps should use the
+ * {@link WifiNetworkConfigBuilder} class to create an instance.
+ * @hide
+ */
+public final class WifiNetworkSpecifier extends NetworkSpecifier implements Parcelable {
+ /**
+ * SSID pattern match specified by the app.
+ */
+ public final PatternMatcher ssidPatternMatcher;
+
+ /**
+ * BSSID pattern match specified by the app.
+ * Pair of <BaseAddress, Mask>.
+ */
+ public final Pair<MacAddress, MacAddress> bssidPatternMatcher;
+
+ /**
+ * Security credentials for the network.
+ * <p>
+ * Note: {@link WifiConfiguration#SSID} & {@link WifiConfiguration#BSSID} fields from
+ * WifiConfiguration are not used. Instead we use the {@link #ssidPatternMatcher} &
+ * {@link #bssidPatternMatcher} fields embedded directly
+ * within {@link WifiNetworkSpecifier}.
+ */
+ public final WifiConfiguration wifiConfiguration;
+
+ /**
+ * The UID of the process initializing this network specifier. Validated by receiver using
+ * checkUidIfNecessary() and is used by satisfiedBy() to determine whether the specifier
+ * matches the offered network.
+ */
+ public final int requestorUid;
+
+ public WifiNetworkSpecifier(@NonNull PatternMatcher ssidPatternMatcher,
+ @NonNull Pair<MacAddress, MacAddress> bssidPatternMatcher,
+ @NonNull WifiConfiguration wifiConfiguration,
+ int requestorUid) {
+ checkNotNull(ssidPatternMatcher);
+ checkNotNull(bssidPatternMatcher);
+ checkNotNull(wifiConfiguration);
+
+ this.ssidPatternMatcher = ssidPatternMatcher;
+ this.bssidPatternMatcher = bssidPatternMatcher;
+ this.wifiConfiguration = wifiConfiguration;
+ this.requestorUid = requestorUid;
+ }
+
+ public static final Creator<WifiNetworkSpecifier> CREATOR =
+ new Creator<WifiNetworkSpecifier>() {
+ @Override
+ public WifiNetworkSpecifier createFromParcel(Parcel in) {
+ PatternMatcher ssidPatternMatcher = in.readParcelable(/* classLoader */null);
+ MacAddress baseAddress = in.readParcelable(null);
+ MacAddress mask = in.readParcelable(null);
+ Pair<MacAddress, MacAddress> bssidPatternMatcher =
+ Pair.create(baseAddress, mask);
+ WifiConfiguration wifiConfiguration = in.readParcelable(null);
+ int requestorUid = in.readInt();
+ return new WifiNetworkSpecifier(ssidPatternMatcher, bssidPatternMatcher,
+ wifiConfiguration, requestorUid);
+ }
+
+ @Override
+ public WifiNetworkSpecifier[] newArray(int size) {
+ return new WifiNetworkSpecifier[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(ssidPatternMatcher, flags);
+ dest.writeParcelable(bssidPatternMatcher.first, flags);
+ dest.writeParcelable(bssidPatternMatcher.second, flags);
+ dest.writeParcelable(wifiConfiguration, flags);
+ dest.writeInt(requestorUid);
+ }
+
+ @Override
+ public boolean satisfiedBy(NetworkSpecifier other) {
+ if (this == other) {
+ return true;
+ }
+ // Any generic requests should be satisifed by a specific wifi network.
+ if (other == null || other instanceof MatchAllNetworkSpecifier) {
+ return true;
+ }
+ if (other instanceof WifiNetworkAgentSpecifier) {
+ return ((WifiNetworkAgentSpecifier) other).satisfiesNetworkSpecifier(this);
+ }
+ // Specific requests are checked for equality although testing for equality of 2 patterns do
+ // not make much sense!
+ return equals(other);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(
+ ssidPatternMatcher.getPath(),
+ ssidPatternMatcher.getType(),
+ bssidPatternMatcher,
+ wifiConfiguration.allowedKeyManagement,
+ requestorUid);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof WifiNetworkSpecifier)) {
+ return false;
+ }
+ WifiNetworkSpecifier lhs = (WifiNetworkSpecifier) obj;
+ return Objects.equals(this.ssidPatternMatcher.getPath(),
+ lhs.ssidPatternMatcher.getPath())
+ && Objects.equals(this.ssidPatternMatcher.getType(),
+ lhs.ssidPatternMatcher.getType())
+ && Objects.equals(this.bssidPatternMatcher,
+ lhs.bssidPatternMatcher)
+ && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
+ lhs.wifiConfiguration.allowedKeyManagement)
+ && requestorUid == lhs.requestorUid;
+ }
+
+ @Override
+ public String toString() {
+ return new StringBuilder()
+ .append("WifiNetworkSpecifierWifiNetworkSpecifier [")
+ .append(", SSID Match pattern=").append(ssidPatternMatcher)
+ .append(", BSSID Match pattern=").append(bssidPatternMatcher)
+ .append(", WifiConfiguration=").append(
+ wifiConfiguration == null ? null : wifiConfiguration.configKey())
+ .append(", requestorUid=").append(requestorUid)
+ .append("]")
+ .toString();
+ }
+
+ @Override
+ public void assertValidFromUid(int requestorUid) {
+ if (this.requestorUid != requestorUid) {
+ throw new SecurityException("mismatched UIDs");
+ }
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiNetworkSuggestion.java b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
new file mode 100644
index 000000000000..04b9cb5dfb8d
--- /dev/null
+++ b/wifi/java/android/net/wifi/WifiNetworkSuggestion.java
@@ -0,0 +1,143 @@
+/*
+ * 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.net.wifi;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.app.PendingIntent;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * The Network Suggestion object is used to provide a Wi-Fi network for consideration when
+ * auto-connecting to networks. Apps cannot directly create this object, they must use
+ * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} to obtain an instance
+ * of this object.
+ *<p>
+ * Apps can provide a list of such networks to the platform using
+ * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)}.
+ */
+public final class WifiNetworkSuggestion implements Parcelable {
+ /**
+ * Network configuration for the provided network.
+ * @hide
+ */
+ public final WifiConfiguration wifiConfiguration;
+
+ /**
+ * Whether app needs to log in to captive portal to obtain Internet access.
+ * This will dictate if the associated pending intent in
+ * {@link WifiManager#addNetworkSuggestions(List, PendingIntent)} needs to be sent after
+ * successfully connecting to the network.
+ * @hide
+ */
+ public final boolean isAppInteractionRequired;
+
+ /**
+ * Whether user needs to log in to captive portal to obtain Internet access.
+ * @hide
+ */
+ public final boolean isUserInteractionRequired;
+
+ /**
+ * The UID of the process initializing this network suggestion.
+ * @hide
+ */
+ public final int suggestorUid;
+
+ /** @hide */
+ public WifiNetworkSuggestion(WifiConfiguration wifiConfiguration,
+ boolean isAppInteractionRequired,
+ boolean isUserInteractionRequired,
+ int suggestorUid) {
+ checkNotNull(wifiConfiguration);
+
+ this.wifiConfiguration = wifiConfiguration;
+ this.isAppInteractionRequired = isAppInteractionRequired;
+ this.isUserInteractionRequired = isUserInteractionRequired;
+ this.suggestorUid = suggestorUid;
+ }
+
+ public static final Creator<WifiNetworkSuggestion> CREATOR =
+ new Creator<WifiNetworkSuggestion>() {
+ @Override
+ public WifiNetworkSuggestion createFromParcel(Parcel in) {
+ return new WifiNetworkSuggestion(
+ in.readParcelable(null), // wifiConfiguration
+ in.readBoolean(), // isAppInteractionRequired
+ in.readBoolean(), // isUserInteractionRequired
+ in.readInt() // suggestorUid
+ );
+ }
+
+ @Override
+ public WifiNetworkSuggestion[] newArray(int size) {
+ return new WifiNetworkSuggestion[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeParcelable(wifiConfiguration, flags);
+ dest.writeBoolean(isAppInteractionRequired);
+ dest.writeBoolean(isUserInteractionRequired);
+ dest.writeInt(suggestorUid);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(wifiConfiguration.SSID, wifiConfiguration.allowedKeyManagement,
+ suggestorUid);
+ }
+
+ /**
+ * Equals for network suggestions.
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof WifiNetworkSuggestion)) {
+ return false;
+ }
+ WifiNetworkSuggestion lhs = (WifiNetworkSuggestion) obj;
+ return Objects.equals(this.wifiConfiguration.SSID, lhs.wifiConfiguration.SSID)
+ && Objects.equals(this.wifiConfiguration.allowedKeyManagement,
+ lhs.wifiConfiguration.allowedKeyManagement)
+ && suggestorUid == lhs.suggestorUid;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("WifiNetworkSuggestion [")
+ .append(", WifiConfiguration=").append(wifiConfiguration)
+ .append(", isAppInteractionRequired=").append(isAppInteractionRequired)
+ .append(", isUserInteractionRequired=").append(isUserInteractionRequired)
+ .append(", suggestorUid=").append(suggestorUid)
+ .append("]");
+ return sb.toString();
+ }
+}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index 045291b4f4d4..529548f1d2b8 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -594,17 +594,17 @@ public class WifiScanner {
/** SSID of the network */
public String ssid;
/** Bitmask of the FLAG_XXX */
- public byte flags;
+ public byte flags = 0;
/** Bitmask of the ATUH_XXX */
- public byte authBitField;
+ public byte authBitField = 0;
+ /** frequencies on which the particular network needs to be scanned for */
+ public int[] frequencies = {};
/**
* default constructor for PnoNetwork
*/
public PnoNetwork(String ssid) {
this.ssid = ssid;
- flags = 0;
- authBitField = 0;
}
}
@@ -651,6 +651,7 @@ public class WifiScanner {
dest.writeString(networkList[i].ssid);
dest.writeByte(networkList[i].flags);
dest.writeByte(networkList[i].authBitField);
+ dest.writeIntArray(networkList[i].frequencies);
}
} else {
dest.writeInt(0);
@@ -677,6 +678,7 @@ public class WifiScanner {
PnoNetwork network = new PnoNetwork(ssid);
network.flags = in.readByte();
network.authBitField = in.readByte();
+ network.frequencies = in.createIntArray();
settings.networkList[i] = network;
}
return settings;
diff --git a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
index 3b9f93e503be..5f3e1b27672e 100644
--- a/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiConfigurationTest.java
@@ -155,7 +155,10 @@ public class WifiConfigurationTest {
@Test
public void testIsOpenNetwork_NotOpen_HasAuthType() {
for (int keyMgmt = 0; keyMgmt < WifiConfiguration.KeyMgmt.strings.length; keyMgmt++) {
- if (keyMgmt == WifiConfiguration.KeyMgmt.NONE) continue;
+ if (keyMgmt == WifiConfiguration.KeyMgmt.NONE
+ || keyMgmt == WifiConfiguration.KeyMgmt.OWE) {
+ continue;
+ }
WifiConfiguration config = new WifiConfiguration();
config.allowedKeyManagement.clear();
config.allowedKeyManagement.set(keyMgmt);
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index e40b657aded0..ea41bb39c4d5 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -43,6 +43,8 @@ import android.net.wifi.WifiManager.LocalOnlyHotspotCallback;
import android.net.wifi.WifiManager.LocalOnlyHotspotObserver;
import android.net.wifi.WifiManager.LocalOnlyHotspotReservation;
import android.net.wifi.WifiManager.LocalOnlyHotspotSubscription;
+import android.net.wifi.WifiManager.NetworkRequestMatchCallback;
+import android.net.wifi.WifiManager.NetworkRequestUserSelectionCallback;
import android.net.wifi.WifiManager.SoftApCallback;
import android.net.wifi.WifiManager.TrafficStateCallback;
import android.os.Handler;
@@ -59,6 +61,8 @@ import org.mockito.InOrder;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
+
/**
* Unit tests for {@link android.net.wifi.WifiManager}.
*/
@@ -67,16 +71,19 @@ public class WifiManagerTest {
private static final int ERROR_NOT_SET = -1;
private static final int ERROR_TEST_REASON = 5;
+ private static final int TEST_UID = 14553;
private static final String TEST_PACKAGE_NAME = "TestPackage";
private static final String TEST_COUNTRY_CODE = "US";
@Mock Context mContext;
- @Mock IWifiManager mWifiService;
+ @Mock
+ android.net.wifi.IWifiManager mWifiService;
@Mock ApplicationInfo mApplicationInfo;
@Mock WifiConfiguration mApConfig;
@Mock IBinder mAppBinder;
@Mock SoftApCallback mSoftApCallback;
@Mock TrafficStateCallback mTrafficStateCallback;
+ @Mock NetworkRequestMatchCallback mNetworkRequestMatchCallback;
private Handler mHandler;
private TestLooper mLooper;
@@ -1163,4 +1170,84 @@ i * Verify that a call to cancel WPS immediately returns a failure.
assertEquals(1, altLooper.dispatchAll());
verify(mTrafficStateCallback).onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT);
}
+
+ /**
+ * Verify the call to registerNetworkRequestMatchCallback goes to WifiServiceImpl.
+ */
+ @Test
+ public void registerNetworkRequestMatchCallbackCallGoesToWifiServiceImpl()
+ throws Exception {
+ when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
+ ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
+ mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
+ verify(mWifiService).registerNetworkRequestMatchCallback(
+ any(IBinder.class), callbackCaptor.capture(), anyInt());
+
+ INetworkRequestUserSelectionCallback iUserSelectionCallback =
+ mock(INetworkRequestUserSelectionCallback.class);
+
+ assertEquals(0, mLooper.dispatchAll());
+ callbackCaptor.getValue().onMatch(new ArrayList<WifiConfiguration>());
+ assertEquals(1, mLooper.dispatchAll());
+ verify(mNetworkRequestMatchCallback).onMatch(anyList());
+
+ callbackCaptor.getValue().onUserSelectionConnectSuccess(new WifiConfiguration());
+ assertEquals(1, mLooper.dispatchAll());
+ verify(mNetworkRequestMatchCallback).onUserSelectionConnectSuccess(
+ any(WifiConfiguration.class));
+
+ callbackCaptor.getValue().onUserSelectionConnectFailure(new WifiConfiguration());
+ assertEquals(1, mLooper.dispatchAll());
+ verify(mNetworkRequestMatchCallback).onUserSelectionConnectFailure(
+ any(WifiConfiguration.class));
+ }
+
+ /**
+ * Verify the call to unregisterNetworkRequestMatchCallback goes to WifiServiceImpl.
+ */
+ @Test
+ public void unregisterNetworkRequestMatchCallbackCallGoesToWifiServiceImpl() throws Exception {
+ ArgumentCaptor<Integer> callbackIdentifier = ArgumentCaptor.forClass(Integer.class);
+ mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, mHandler);
+ verify(mWifiService).registerNetworkRequestMatchCallback(
+ any(IBinder.class), any(INetworkRequestMatchCallback.class),
+ callbackIdentifier.capture());
+
+ mWifiManager.unregisterNetworkRequestMatchCallback(mNetworkRequestMatchCallback);
+ verify(mWifiService).unregisterNetworkRequestMatchCallback(
+ eq((int) callbackIdentifier.getValue()));
+ }
+
+ /**
+ * Verify the call to NetworkRequestUserSelectionCallback goes to
+ * WifiServiceImpl.
+ */
+ @Test
+ public void networkRequestUserSelectionCallbackCallGoesToWifiServiceImpl()
+ throws Exception {
+ when(mContext.getMainLooper()).thenReturn(mLooper.getLooper());
+ ArgumentCaptor<INetworkRequestMatchCallback.Stub> callbackCaptor =
+ ArgumentCaptor.forClass(INetworkRequestMatchCallback.Stub.class);
+ mWifiManager.registerNetworkRequestMatchCallback(mNetworkRequestMatchCallback, null);
+ verify(mWifiService).registerNetworkRequestMatchCallback(
+ any(IBinder.class), callbackCaptor.capture(), anyInt());
+
+ INetworkRequestUserSelectionCallback iUserSelectionCallback =
+ mock(INetworkRequestUserSelectionCallback.class);
+ ArgumentCaptor<NetworkRequestUserSelectionCallback> userSelectionCallbackCaptor =
+ ArgumentCaptor.forClass(NetworkRequestUserSelectionCallback.class);
+ callbackCaptor.getValue().onUserSelectionCallbackRegistration(
+ iUserSelectionCallback);
+ assertEquals(1, mLooper.dispatchAll());
+ verify(mNetworkRequestMatchCallback).onUserSelectionCallbackRegistration(
+ userSelectionCallbackCaptor.capture());
+
+ WifiConfiguration selected = new WifiConfiguration();
+ userSelectionCallbackCaptor.getValue().select(selected);
+ verify(iUserSelectionCallback).select(selected);
+
+ userSelectionCallbackCaptor.getValue().reject();
+ verify(iUserSelectionCallback).reject();
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
new file mode 100644
index 000000000000..1b0007c9e732
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkAgentSpecifierTest.java
@@ -0,0 +1,453 @@
+/*
+ * 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.net.wifi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
+import android.net.NetworkRequest;
+import android.net.NetworkSpecifier;
+import android.os.Parcel;
+import android.os.PatternMatcher;
+import android.support.test.filters.SmallTest;
+import android.util.Pair;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiNetworkAgentSpecifier}.
+ */
+@SmallTest
+public class WifiNetworkAgentSpecifierTest {
+ private static final int TEST_UID = 5;
+ private static final int TEST_UID_1 = 8;
+ private static final String TEST_SSID = "Test123";
+ private static final String TEST_SSID_PATTERN = "Test";
+ private static final String TEST_SSID_1 = "456test";
+ private static final String TEST_BSSID = "12:12:12:aa:0b:c0";
+ private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
+ private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
+ private static final String TEST_BSSID_1 = "aa:cc:12:aa:0b:c0";
+ private static final String TEST_PRESHARED_KEY = "\"Test123\"";
+
+ /**
+ * Validate that parcel marshalling/unmarshalling works
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierParcel() {
+ WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
+
+ Parcel parcelW = Parcel.obtain();
+ specifier.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ WifiNetworkAgentSpecifier parcelSpecifier =
+ WifiNetworkAgentSpecifier.CREATOR.createFromParcel(parcelR);
+
+ assertEquals(specifier, parcelSpecifier);
+ }
+
+ /**
+ * Validate that the NetworkAgentSpecifier cannot be used in a {@link NetworkRequest} by apps.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkAgentSpecifierNotUsedInNetworkRequest() {
+ WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
+
+ specifier.assertValidFromUid(TEST_UID);
+ }
+
+ /**
+ * Validate NetworkAgentSpecifier equals with itself.
+ * a) Create network agent specifier 1 for WPA_PSK network
+ * b) Create network agent specifier 2 with the same params as specifier 1.
+ * c) Ensure that the specifier 2 equals specifier 1.
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierEqualsSame() {
+ WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
+ WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
+
+ assertTrue(specifier2.equals(specifier1));
+ }
+
+ /**
+ * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
+ * a) Create network agent specifier 1 for WPA_PSK network
+ * b) Create network agent specifier 2 with different key mgmt params.
+ * c) Ensure that the specifier 2 does not equal specifier 1.
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierDoesNotEqualsWhenKeyMgmtDifferent() {
+ WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
+ WifiNetworkAgentSpecifier specifier1 =
+ new WifiNetworkAgentSpecifier(
+ wifiConfiguration1,
+ TEST_UID);
+
+ WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
+ wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkAgentSpecifier specifier2 =
+ new WifiNetworkAgentSpecifier(
+ wifiConfiguration2,
+ TEST_UID);
+
+ assertFalse(specifier2.equals(specifier1));
+ }
+
+ /**
+ * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
+ * a) Create network agent specifier 1 for WPA_PSK network
+ * b) Create network agent specifier 2 with different SSID.
+ * c) Ensure that the specifier 2 does not equal specifier 1.
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenSsidDifferent() {
+ WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
+ WifiNetworkAgentSpecifier specifier1 =
+ new WifiNetworkAgentSpecifier(
+ wifiConfiguration1,
+ TEST_UID);
+
+ WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
+ wifiConfiguration2.SSID = TEST_SSID_1;
+ WifiNetworkAgentSpecifier specifier2 =
+ new WifiNetworkAgentSpecifier(
+ wifiConfiguration2,
+ TEST_UID);
+
+ assertFalse(specifier2.equals(specifier1));
+ }
+
+ /**
+ * Validate NetworkAgentSpecifier equals between instances of {@link WifiNetworkAgentSpecifier}.
+ * a) Create network agent specifier 1 for WPA_PSK network
+ * b) Create network agent specifier 2 with different BSSID.
+ * c) Ensure that the specifier 2 does not equal specifier 1.
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierDoesNotSatisifyWhenBssidDifferent() {
+ WifiConfiguration wifiConfiguration1 = createDefaultWifiConfiguration();
+ WifiNetworkAgentSpecifier specifier1 =
+ new WifiNetworkAgentSpecifier(
+ wifiConfiguration1,
+ TEST_UID);
+
+ WifiConfiguration wifiConfiguration2 = new WifiConfiguration(wifiConfiguration1);
+ wifiConfiguration2.BSSID = TEST_BSSID_1;
+ WifiNetworkAgentSpecifier specifier2 =
+ new WifiNetworkAgentSpecifier(
+ wifiConfiguration2,
+ TEST_UID);
+
+ assertFalse(specifier2.equals(specifier1));
+ }
+
+ /**
+ * Validate NetworkAgentSpecifier matching.
+ * a) Create a network agent specifier for WPA_PSK network
+ * b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
+ * specifiers.
+ */
+ @Test
+ public void testWifiNetworkAgentSpecifierSatisifiesNullAndAllMatch() {
+ WifiNetworkAgentSpecifier specifier = createDefaultNetworkAgentSpecifier();
+
+ assertTrue(specifier.satisfiedBy(null));
+ assertTrue(specifier.satisfiedBy(new MatchAllNetworkSpecifier()));
+ }
+
+ /**
+ * Validate NetworkAgentSpecifier matching with itself.
+ * a) Create network agent specifier 1 for WPA_PSK network
+ * b) Create network agent specifier 2 with the same params as specifier 1.
+ * c) Ensure that invoking {@link NetworkSpecifier#satisfiedBy(NetworkSpecifier)} on 2
+ * {@link WifiNetworkAgentSpecifier} throws an exception.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkAgentSpecifierDoesNotSatisifySame() {
+ WifiNetworkAgentSpecifier specifier1 = createDefaultNetworkAgentSpecifier();
+ WifiNetworkAgentSpecifier specifier2 = createDefaultNetworkAgentSpecifier();
+
+ assertTrue(specifier2.satisfiedBy(specifier1));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with matching SSID pattern.
+ * c) Ensure that the agent specifier is satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidPattern() {
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID);
+
+ assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with matching BSSID pattern.
+ * c) Ensure that the agent specifier is satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithBssidPattern() {
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID);
+
+ assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with matching SSID & BSSID pattern.
+ * c) Ensure that the agent specifier is satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierSatisfiesNetworkSpecifierWithSsidAndBssidPattern() {
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID);
+
+ assertTrue(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertTrue(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with non-matching SSID pattern.
+ * c) Ensure that the agent specifier is not satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidPattern() {
+ WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+ wifiConfigurationNetworkAgent.SSID = "\"" + TEST_SSID_1 + "\"";
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+ new WifiNetworkAgentSpecifier(
+ wifiConfigurationNetworkAgent,
+ TEST_UID);
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS);
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID);
+
+ assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with non-matching BSSID pattern.
+ * c) Ensure that the agent specifier is not satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithBssidPattern() {
+ WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+ wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+ new WifiNetworkAgentSpecifier(
+ wifiConfigurationNetworkAgent,
+ TEST_UID);
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID);
+
+ assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with non-matching SSID and BSSID pattern.
+ * c) Ensure that the agent specifier is not satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithSsidAndBssidPattern() {
+ WifiConfiguration wifiConfigurationNetworkAgent = createDefaultWifiConfiguration();
+ wifiConfigurationNetworkAgent.BSSID = TEST_BSSID_1;
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier =
+ new WifiNetworkAgentSpecifier(
+ wifiConfigurationNetworkAgent,
+ TEST_UID);
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID);
+
+ assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with matching SSID and BSSID pattern, but different key mgmt.
+ * c) Ensure that the agent specifier is not satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentKeyMgmt() {
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID);
+
+ assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ /**
+ * Validate {@link WifiNetworkAgentSpecifier} with {@link WifiNetworkSpecifier} matching.
+ * a) Create network agent specifier for WPA_PSK network
+ * b) Create network specifier with matching SSID and BSSID pattern, but different UID.
+ * c) Ensure that the agent specifier is not satisfied by specifier.
+ */
+ @Test
+ public void
+ testWifiNetworkAgentSpecifierDoesNotSatisfyNetworkSpecifierWithDifferentUid() {
+ WifiNetworkAgentSpecifier wifiNetworkAgentSpecifier = createDefaultNetworkAgentSpecifier();
+
+ PatternMatcher ssidPattern =
+ new PatternMatcher(TEST_SSID_PATTERN, PatternMatcher.PATTERN_PREFIX);
+ Pair<MacAddress, MacAddress> bssidPattern =
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK));
+ WifiConfiguration wificonfigurationNetworkSpecifier = new WifiConfiguration();
+ wificonfigurationNetworkSpecifier.allowedKeyManagement
+ .set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier(
+ ssidPattern,
+ bssidPattern,
+ wificonfigurationNetworkSpecifier,
+ TEST_UID_1);
+
+ assertFalse(wifiNetworkSpecifier.satisfiedBy(wifiNetworkAgentSpecifier));
+ assertFalse(wifiNetworkAgentSpecifier.satisfiedBy(wifiNetworkSpecifier));
+ }
+
+ private WifiConfiguration createDefaultWifiConfiguration() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.SSID = "\"" + TEST_SSID + "\"";
+ wifiConfiguration.BSSID = TEST_BSSID;
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+ return wifiConfiguration;
+ }
+
+ private WifiNetworkAgentSpecifier createDefaultNetworkAgentSpecifier() {
+ return new WifiNetworkAgentSpecifier(createDefaultWifiConfiguration(), TEST_UID);
+ }
+
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java
new file mode 100644
index 000000000000..8980ddba238b
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkConfigBuilderTest.java
@@ -0,0 +1,481 @@
+/*
+ * 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.net.wifi;
+
+import static android.os.PatternMatcher.PATTERN_LITERAL;
+import static android.os.PatternMatcher.PATTERN_PREFIX;
+import static android.os.PatternMatcher.PATTERN_SIMPLE_GLOB;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.net.MacAddress;
+import android.net.NetworkSpecifier;
+import android.os.PatternMatcher;
+import android.os.Process;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiNetworkConfigBuilder}.
+ */
+@SmallTest
+public class WifiNetworkConfigBuilderTest {
+ private static final String TEST_SSID = "Test123";
+ private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
+ private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
+ private static final String TEST_BSSID = "12:12:12:12:12:12";
+ private static final String TEST_PRESHARED_KEY = "Test123";
+
+ /**
+ * Validate correctness of WifiNetworkSpecifier object created by
+ * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for open network with SSID pattern.
+ */
+ @Test
+ public void testWifiNetworkSpecifierBuilderForOpenNetworkWithSsidPattern() {
+ NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
+ .buildNetworkSpecifier();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals(Process.myUid(), wifiNetworkSpecifier.requestorUid);
+ assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
+ assertEquals(PATTERN_PREFIX, wifiNetworkSpecifier.ssidPatternMatcher.getType());
+ assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.first);
+ assertEquals(MacAddress.ALL_ZEROS_ADDRESS, wifiNetworkSpecifier.bssidPatternMatcher.second);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.NONE));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
+ .get(WifiConfiguration.Protocol.RSN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
+ .get(WifiConfiguration.AuthAlgorithm.OPEN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
+ .get(WifiConfiguration.PairwiseCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.TKIP));
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSpecifier object created by
+ * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for WPA_PSK network with BSSID
+ * pattern.
+ */
+ @Test
+ public void testWifiNetworkSpecifierBuilderForWpaPskNetworkWithBssidPattern() {
+ NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
+ .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK))
+ .setPskPassphrase(TEST_PRESHARED_KEY)
+ .buildNetworkSpecifier();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals(".*", wifiNetworkSpecifier.ssidPatternMatcher.getPath());
+ assertEquals(PATTERN_SIMPLE_GLOB, wifiNetworkSpecifier.ssidPatternMatcher.getType());
+ assertEquals(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ wifiNetworkSpecifier.bssidPatternMatcher.first);
+ assertEquals(MacAddress.fromString(TEST_BSSID_OUI_MASK),
+ wifiNetworkSpecifier.bssidPatternMatcher.second);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_PSK));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
+ .get(WifiConfiguration.Protocol.RSN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
+ .get(WifiConfiguration.AuthAlgorithm.OPEN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
+ .get(WifiConfiguration.PairwiseCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.TKIP));
+ assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
+ wifiNetworkSpecifier.wifiConfiguration.preSharedKey);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSpecifier object created by
+ * {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} for WPA_EAP network with
+ * SSID and BSSID pattern.
+ */
+ @Test
+ public void testWifiNetworkSpecifierBuilderForEnterpriseHiddenNetworkWithSsidAndBssid() {
+ WifiEnterpriseConfig enterpriseConfig = new WifiEnterpriseConfig();
+ enterpriseConfig.setEapMethod(WifiEnterpriseConfig.Eap.TLS);
+ enterpriseConfig.setPhase2Method(WifiEnterpriseConfig.Phase2.GTC);
+
+ NetworkSpecifier specifier = new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setBssid(MacAddress.fromString(TEST_BSSID))
+ .setEnterpriseConfig(enterpriseConfig)
+ .setIsHiddenSsid()
+ .buildNetworkSpecifier();
+
+ assertTrue(specifier instanceof WifiNetworkSpecifier);
+ WifiNetworkSpecifier wifiNetworkSpecifier = (WifiNetworkSpecifier) specifier;
+
+ assertEquals(TEST_SSID, wifiNetworkSpecifier.ssidPatternMatcher.getPath());
+ assertEquals(PATTERN_LITERAL, wifiNetworkSpecifier.ssidPatternMatcher.getType());
+ assertEquals(MacAddress.fromString(TEST_BSSID),
+ wifiNetworkSpecifier.bssidPatternMatcher.first);
+ assertEquals(MacAddress.BROADCAST_ADDRESS,
+ wifiNetworkSpecifier.bssidPatternMatcher.second);
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_EAP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.IEEE8021X));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedProtocols
+ .get(WifiConfiguration.Protocol.RSN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedAuthAlgorithms
+ .get(WifiConfiguration.AuthAlgorithm.OPEN));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedPairwiseCiphers
+ .get(WifiConfiguration.PairwiseCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.CCMP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.allowedGroupCiphers
+ .get(WifiConfiguration.GroupCipher.TKIP));
+ assertTrue(wifiNetworkSpecifier.wifiConfiguration.hiddenSSID);
+ assertEquals(enterpriseConfig.getEapMethod(),
+ wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getEapMethod());
+ assertEquals(enterpriseConfig.getPhase2Method(),
+ wifiNetworkSpecifier.wifiConfiguration.enterpriseConfig.getPhase2Method());
+ }
+
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#setSsid(String)} throws an exception
+ * when the string is not Unicode.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetSsidWithNonUnicodeString() {
+ new WifiNetworkConfigBuilder()
+ .setSsid("\ud800")
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} throws an exception
+ * when the string is not ASCII encodable.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testSetPskPassphraseWithNonAsciiString() {
+ new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setPskPassphrase("salvē")
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when neither SSID nor BSSID patterns were set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithNoSsidAndBssidPattern() {
+ new WifiNetworkConfigBuilder().buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when match-all SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern1() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_SIMPLE_GLOB))
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when match-all SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern2() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(".*", PatternMatcher.PATTERN_ADVANCED_GLOB))
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when match-all SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllSsidPattern3() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_PREFIX))
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when match-all BSSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchAllBssidPattern() {
+ new WifiNetworkConfigBuilder()
+ .setBssidPattern(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS)
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when match-none SSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchNoneSsidPattern() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher("", PatternMatcher.PATTERN_LITERAL))
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when match-none BSSID pattern is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMatchNoneBssidPattern() {
+ new WifiNetworkConfigBuilder()
+ .setBssidPattern(MacAddress.BROADCAST_ADDRESS, MacAddress.BROADCAST_ADDRESS)
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when SSID pattern is set for hidden network.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithBssidMatchPatternForHiddenNetwork() {
+ new WifiNetworkConfigBuilder()
+ .setBssidPattern(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK))
+ .setIsHiddenSsid()
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when both {@link WifiNetworkConfigBuilder#setPskPassphrase(String)} and
+ * {@link WifiNetworkConfigBuilder#setEnterpriseConfig(WifiEnterpriseConfig)} are invoked.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithBothPskPassphraseAndEnterpriseConfig() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setPskPassphrase(TEST_PRESHARED_KEY)
+ .setEnterpriseConfig(new WifiEnterpriseConfig())
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when SSID pattern is set for hidden network.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithSsidMatchPatternForHiddenNetwork() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PatternMatcher.PATTERN_PREFIX))
+ .setIsHiddenSsid()
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setIsAppInteractionRequired()} is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithRequiredAppInteraction() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setIsAppInteractionRequired()
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setIsUserInteractionRequired()} is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithRequiredUserInteraction() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setIsUserInteractionRequired()
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setPriority(int)} is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithSetPriority() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setPriority(4)
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSpecifier()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setIsMetered()} is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSpecifierBuilderWithMetered() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_LITERAL))
+ .setIsMetered()
+ .buildNetworkSpecifier();
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for Open network which requires
+ * app interaction.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForOpenNetworkWithReqAppInteraction() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setIsAppInteractionRequired()
+ .buildNetworkSuggestion();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.NONE));
+ assertTrue(suggestion.isAppInteractionRequired);
+ assertFalse(suggestion.isUserInteractionRequired);
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
+ suggestion.wifiConfiguration.meteredOverride);
+ assertEquals(-1, suggestion.wifiConfiguration.priority);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for WPA_EAP network which requires
+ * app interaction and has a priority of zero set.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpaEapNetworkWithPriorityAndReqAppInteraction() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setPskPassphrase(TEST_PRESHARED_KEY)
+ .setIsAppInteractionRequired()
+ .setPriority(0)
+ .buildNetworkSuggestion();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_PSK));
+ assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
+ suggestion.wifiConfiguration.preSharedKey);
+ assertTrue(suggestion.isAppInteractionRequired);
+ assertFalse(suggestion.isUserInteractionRequired);
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_NONE,
+ suggestion.wifiConfiguration.meteredOverride);
+ assertEquals(0, suggestion.wifiConfiguration.priority);
+ }
+
+ /**
+ * Validate correctness of WifiNetworkSuggestion object created by
+ * {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} for WPA_PSK network which requires
+ * user interaction and is metered.
+ */
+ @Test
+ public void testWifiNetworkSuggestionBuilderForWpaPskNetworkWithMeteredAndReqUserInteraction() {
+ WifiNetworkSuggestion suggestion = new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setPskPassphrase(TEST_PRESHARED_KEY)
+ .setIsUserInteractionRequired()
+ .setIsMetered()
+ .buildNetworkSuggestion();
+
+ assertEquals("\"" + TEST_SSID + "\"", suggestion.wifiConfiguration.SSID);
+ assertTrue(suggestion.wifiConfiguration.allowedKeyManagement
+ .get(WifiConfiguration.KeyMgmt.WPA_PSK));
+ assertEquals("\"" + TEST_PRESHARED_KEY + "\"",
+ suggestion.wifiConfiguration.preSharedKey);
+ assertFalse(suggestion.isAppInteractionRequired);
+ assertTrue(suggestion.isUserInteractionRequired);
+ assertEquals(WifiConfiguration.METERED_OVERRIDE_METERED,
+ suggestion.wifiConfiguration.meteredOverride);
+ assertEquals(-1, suggestion.wifiConfiguration.priority);
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setSsidPattern(PatternMatcher)} is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithSsidPattern() {
+ new WifiNetworkConfigBuilder()
+ .setSsidPattern(new PatternMatcher(TEST_SSID, PATTERN_PREFIX))
+ .buildNetworkSuggestion();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setBssid(MacAddress)} is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithBssidPattern() {
+ new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setBssidPattern(MacAddress.fromString(TEST_BSSID),
+ MacAddress.fromString(TEST_BSSID))
+ .buildNetworkSuggestion();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setBssidPattern(MacAddress, MacAddress)} is set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithBssid() {
+ new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setBssid(MacAddress.fromString(TEST_BSSID))
+ .buildNetworkSuggestion();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#buildNetworkSuggestion()} throws an exception
+ * when {@link WifiNetworkConfigBuilder#setSsid(String)} is not set.
+ */
+ @Test(expected = IllegalStateException.class)
+ public void testWifiNetworkSuggestionBuilderWithNoSsid() {
+ new WifiNetworkConfigBuilder()
+ .buildNetworkSuggestion();
+ }
+
+ /**
+ * Ensure {@link WifiNetworkConfigBuilder#setPriority(int)} throws an exception
+ * when the value is negative.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testWifiNetworkSuggestionBuilderWithInvalidPriority() {
+ new WifiNetworkConfigBuilder()
+ .setSsid(TEST_SSID)
+ .setPriority(-1)
+ .buildNetworkSuggestion();
+ }
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
new file mode 100644
index 000000000000..856f0c79a2e7
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSpecifierTest.java
@@ -0,0 +1,212 @@
+/*
+ * 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.net.wifi;
+
+import static android.os.PatternMatcher.PATTERN_LITERAL;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.net.MacAddress;
+import android.net.MatchAllNetworkSpecifier;
+import android.os.Parcel;
+import android.os.PatternMatcher;
+import android.support.test.filters.SmallTest;
+import android.util.Pair;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiNetworkSpecifier}.
+ */
+@SmallTest
+public class WifiNetworkSpecifierTest {
+ private static final int TEST_UID = 5;
+ private static final String TEST_SSID = "Test123";
+ private static final String TEST_BSSID_OUI_BASE_ADDRESS = "12:12:12:00:00:00";
+ private static final String TEST_BSSID_OUI_MASK = "ff:ff:ff:00:00:00";
+ private static final String TEST_PRESHARED_KEY = "\"Test123\"";
+
+ /**
+ * Validate that parcel marshalling/unmarshalling works
+ */
+ @Test
+ public void testWifiNetworkSpecifierParcel() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+ WifiNetworkSpecifier specifier =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration,
+ TEST_UID);
+
+ Parcel parcelW = Parcel.obtain();
+ specifier.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ WifiNetworkSpecifier parcelSpecifier =
+ WifiNetworkSpecifier.CREATOR.createFromParcel(parcelR);
+
+ assertEquals(specifier, parcelSpecifier);
+ }
+
+ /**
+ * Validate NetworkSpecifier matching.
+ * a) Create a network specifier for WPA_PSK network
+ * b) Ensure that the specifier matches {@code null} and {@link MatchAllNetworkSpecifier}
+ * specifiers.
+ */
+ @Test
+ public void testWifiNetworkSpecifierSatisfiesNullAndAllMatch() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+ WifiNetworkSpecifier specifier =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration,
+ TEST_UID);
+
+ assertTrue(specifier.satisfiedBy(null));
+ assertTrue(specifier.satisfiedBy(new MatchAllNetworkSpecifier()));
+ }
+
+ /**
+ * Validate NetworkSpecifier matching.
+ * a) Create network specifier 1 for WPA_PSK network
+ * b) Create network specifier 2 with the same params as specifier 1.
+ * c) Ensure that the specifier 2 is satisfied by specifier 1.
+ */
+ @Test
+ public void testWifiNetworkSpecifierSatisfiesSame() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+
+ WifiNetworkSpecifier specifier1 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration,
+ TEST_UID);
+
+ WifiNetworkSpecifier specifier2 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration,
+ TEST_UID);
+
+ assertTrue(specifier2.satisfiedBy(specifier1));
+ }
+
+ /**
+ * Validate NetworkSpecifier matching.
+ * a) Create network specifier 1 for WPA_PSK network
+ * b) Create network specifier 2 with different key mgmt params.
+ * c) Ensure that the specifier 2 is not satisfied by specifier 1.
+ */
+ @Test
+ public void testWifiNetworkSpecifierDoesNotSatisfyWhenKeyMgmtDifferent() {
+ WifiConfiguration wifiConfiguration1 = new WifiConfiguration();
+ wifiConfiguration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration1.preSharedKey = TEST_PRESHARED_KEY;
+
+ WifiNetworkSpecifier specifier1 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration1,
+ TEST_UID);
+
+ WifiConfiguration wifiConfiguration2 = new WifiConfiguration();
+ wifiConfiguration2.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkSpecifier specifier2 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration2,
+ TEST_UID);
+
+ assertFalse(specifier2.satisfiedBy(specifier1));
+ }
+
+ /**
+ * Validate NetworkSpecifier matching.
+ * a) Create network specifier 1 for WPA_PSK network
+ * b) Create network specifier 2 with different SSID pattern.
+ * c) Ensure that the specifier 2 is not satisfied by specifier 1.
+ */
+ @Test
+ public void testWifiNetworkSpecifierDoesNotSatisfyWhenSsidDifferent() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+
+ WifiNetworkSpecifier specifier1 =
+ new WifiNetworkSpecifier(new PatternMatcher("", PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration,
+ TEST_UID);
+
+ WifiNetworkSpecifier specifier2 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration,
+ TEST_UID);
+
+ assertFalse(specifier2.satisfiedBy(specifier1));
+ }
+
+ /**
+ * Validate NetworkSpecifier matching.
+ * a) Create network specifier 1 for WPA_PSK network
+ * b) Create network specifier 2 with different BSSID pattern.
+ * c) Ensure that the specifier 2 is not satisfied by specifier 1.
+ */
+ @Test
+ public void testWifiNetworkSpecifierDoesNotSatisfyWhenBssidDifferent() {
+ WifiConfiguration wifiConfiguration = new WifiConfiguration();
+ wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ wifiConfiguration.preSharedKey = TEST_PRESHARED_KEY;
+
+ WifiNetworkSpecifier specifier1 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.fromString(TEST_BSSID_OUI_BASE_ADDRESS),
+ MacAddress.fromString(TEST_BSSID_OUI_MASK)),
+ wifiConfiguration,
+ TEST_UID);
+
+ WifiNetworkSpecifier specifier2 =
+ new WifiNetworkSpecifier(new PatternMatcher(TEST_SSID, PATTERN_LITERAL),
+ Pair.create(MacAddress.ALL_ZEROS_ADDRESS, MacAddress.ALL_ZEROS_ADDRESS),
+ wifiConfiguration,
+ TEST_UID);
+
+ assertFalse(specifier2.satisfiedBy(specifier1));
+ }
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
new file mode 100644
index 000000000000..6bab60dd480b
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/WifiNetworkSuggestionTest.java
@@ -0,0 +1,146 @@
+/*
+ * 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.net.wifi;
+
+import static org.junit.Assert.*;
+
+import android.os.Parcel;
+import android.support.test.filters.SmallTest;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.WifiNetworkSuggestion}.
+ */
+@SmallTest
+public class WifiNetworkSuggestionTest {
+ private static final String TEST_SSID = "\"Test123\"";
+ private static final String TEST_SSID_1 = "\"Test1234\"";
+
+ /**
+ * Check that parcel marshalling/unmarshalling works
+ */
+ @Test
+ public void testWifiNetworkSuggestionParcel() {
+ WifiConfiguration configuration = new WifiConfiguration();
+ configuration.SSID = TEST_SSID;
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkSuggestion suggestion =
+ new WifiNetworkSuggestion(configuration, false, true, 0);
+
+ Parcel parcelW = Parcel.obtain();
+ suggestion.writeToParcel(parcelW, 0);
+ byte[] bytes = parcelW.marshall();
+ parcelW.recycle();
+
+ Parcel parcelR = Parcel.obtain();
+ parcelR.unmarshall(bytes, 0, bytes.length);
+ parcelR.setDataPosition(0);
+ WifiNetworkSuggestion parcelSuggestion =
+ WifiNetworkSuggestion.CREATOR.createFromParcel(parcelR);
+
+ // Two suggestion objects are considered equal if they point to the same network (i.e same
+ // SSID + keyMgmt + same UID). |isAppInteractionRequired| & |isUserInteractionRequired| are
+ // not considered for equality and hence needs to be checked for explicitly below.
+ assertEquals(suggestion, parcelSuggestion);
+ assertEquals(suggestion.isAppInteractionRequired,
+ parcelSuggestion.isAppInteractionRequired);
+ assertEquals(suggestion.isUserInteractionRequired,
+ parcelSuggestion.isUserInteractionRequired);
+ }
+
+ /**
+ * Check NetworkSuggestion equals returns {@code true} for 2 network suggestions with the same
+ * SSID, key mgmt and UID.
+ */
+ @Test
+ public void testWifiNetworkSuggestionEqualsSame() {
+ WifiConfiguration configuration = new WifiConfiguration();
+ configuration.SSID = TEST_SSID;
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSuggestion suggestion =
+ new WifiNetworkSuggestion(configuration, true, false, 0);
+
+ WifiConfiguration configuration1 = new WifiConfiguration();
+ configuration1.SSID = TEST_SSID;
+ configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSuggestion suggestion1 =
+ new WifiNetworkSuggestion(configuration1, false, true, 0);
+
+ assertEquals(suggestion, suggestion1);
+ }
+
+ /**
+ * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
+ * key mgmt and UID, but different SSID.
+ */
+ @Test
+ public void testWifiNetworkSuggestionEqualsFailsWhenSsidIsDifferent() {
+ WifiConfiguration configuration = new WifiConfiguration();
+ configuration.SSID = TEST_SSID;
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkSuggestion suggestion =
+ new WifiNetworkSuggestion(configuration, false, false, 0);
+
+ WifiConfiguration configuration1 = new WifiConfiguration();
+ configuration1.SSID = TEST_SSID_1;
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkSuggestion suggestion1 =
+ new WifiNetworkSuggestion(configuration1, false, false, 0);
+
+ assertNotEquals(suggestion, suggestion1);
+ }
+
+ /**
+ * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
+ * SSID and UID, but different key mgmt.
+ */
+ @Test
+ public void testWifiNetworkSuggestionEqualsFailsWhenKeyMgmtIsDifferent() {
+ WifiConfiguration configuration = new WifiConfiguration();
+ configuration.SSID = TEST_SSID;
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkSuggestion suggestion =
+ new WifiNetworkSuggestion(configuration, false, false, 0);
+
+ WifiConfiguration configuration1 = new WifiConfiguration();
+ configuration1.SSID = TEST_SSID;
+ configuration1.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
+ WifiNetworkSuggestion suggestion1 =
+ new WifiNetworkSuggestion(configuration1, false, false, 0);
+
+ assertNotEquals(suggestion, suggestion1);
+ }
+
+ /**
+ * Check NetworkSuggestion equals returns {@code false} for 2 network suggestions with the same
+ * SSID and key mgmt, but different UID.
+ */
+ @Test
+ public void testWifiNetworkSuggestionEqualsFailsWhenUidIsDifferent() {
+ WifiConfiguration configuration = new WifiConfiguration();
+ configuration.SSID = TEST_SSID;
+ configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
+ WifiNetworkSuggestion suggestion =
+ new WifiNetworkSuggestion(configuration, false, false, 0);
+
+ WifiNetworkSuggestion suggestion1 =
+ new WifiNetworkSuggestion(configuration, false, false, 1);
+
+ assertNotEquals(suggestion, suggestion1);
+ }
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiScannerTest.java b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
index 96d5a5167480..da42dcf623c2 100644
--- a/wifi/tests/src/android/net/wifi/WifiScannerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiScannerTest.java
@@ -17,16 +17,20 @@
package android.net.wifi;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.validateMockitoUsage;
import static org.mockito.Mockito.when;
import android.content.Context;
+import android.net.wifi.WifiScanner.PnoSettings;
+import android.net.wifi.WifiScanner.PnoSettings.PnoNetwork;
+import android.net.wifi.WifiScanner.ScanSettings;
import android.os.Handler;
import android.os.Parcel;
import android.os.test.TestLooper;
import android.support.test.filters.SmallTest;
-import android.net.wifi.WifiScanner.ScanSettings;
import com.android.internal.util.test.BidirectionalAsyncChannelServer;
@@ -36,6 +40,8 @@ import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.Arrays;
+
/**
* Unit tests for {@link android.net.wifi.WifiScanner}.
@@ -47,6 +53,19 @@ public class WifiScannerTest {
@Mock
private IWifiScanner mService;
+ private static final boolean TEST_PNOSETTINGS_IS_CONNECTED = false;
+ private static final int TEST_PNOSETTINGS_MIN_5GHZ_RSSI = -60;
+ private static final int TEST_PNOSETTINGS_MIN_2GHZ_RSSI = -70;
+ private static final int TEST_PNOSETTINGS_INITIAL_SCORE_MAX = 50;
+ private static final int TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS = 10;
+ private static final int TEST_PNOSETTINGS_SAME_NETWORK_BONUS = 11;
+ private static final int TEST_PNOSETTINGS_SECURE_BONUS = 12;
+ private static final int TEST_PNOSETTINGS_BAND_5GHZ_BONUS = 13;
+ private static final String TEST_SSID_1 = "TEST1";
+ private static final String TEST_SSID_2 = "TEST2";
+ private static final int[] TEST_FREQUENCIES_1 = {};
+ private static final int[] TEST_FREQUENCIES_2 = {2500, 5124};
+
private WifiScanner mWifiScanner;
private TestLooper mLooper;
private Handler mHandler;
@@ -120,4 +139,68 @@ public class WifiScannerTest {
return ScanSettings.CREATOR.createFromParcel(parcel);
}
+ /**
+ * PnoSettings object can be serialized and deserialized, while keeping the
+ * values unchanged.
+ */
+ @Test
+ public void canSerializeAndDeserializePnoSettings() throws Exception {
+
+ PnoSettings pnoSettings = new PnoSettings();
+
+ PnoNetwork pnoNetwork1 = new PnoNetwork(TEST_SSID_1);
+ PnoNetwork pnoNetwork2 = new PnoNetwork(TEST_SSID_2);
+ pnoNetwork1.frequencies = TEST_FREQUENCIES_1;
+ pnoNetwork2.frequencies = TEST_FREQUENCIES_2;
+
+ pnoSettings.networkList = new PnoNetwork[]{pnoNetwork1, pnoNetwork2};
+ pnoSettings.isConnected = TEST_PNOSETTINGS_IS_CONNECTED;
+ pnoSettings.min5GHzRssi = TEST_PNOSETTINGS_MIN_5GHZ_RSSI;
+ pnoSettings.min24GHzRssi = TEST_PNOSETTINGS_MIN_2GHZ_RSSI;
+ pnoSettings.initialScoreMax = TEST_PNOSETTINGS_INITIAL_SCORE_MAX;
+ pnoSettings.currentConnectionBonus = TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS;
+ pnoSettings.sameNetworkBonus = TEST_PNOSETTINGS_SAME_NETWORK_BONUS;
+ pnoSettings.secureBonus = TEST_PNOSETTINGS_SECURE_BONUS;
+ pnoSettings.band5GHzBonus = TEST_PNOSETTINGS_BAND_5GHZ_BONUS;
+
+ Parcel parcel = Parcel.obtain();
+ pnoSettings.writeToParcel(parcel, 0);
+ // Rewind the pointer to the head of the parcel.
+ parcel.setDataPosition(0);
+ PnoSettings pnoSettingsDeserialized =
+ pnoSettings.CREATOR.createFromParcel(parcel);
+
+ assertNotNull(pnoSettingsDeserialized);
+ assertEquals(TEST_PNOSETTINGS_IS_CONNECTED, pnoSettingsDeserialized.isConnected);
+ assertEquals(TEST_PNOSETTINGS_MIN_5GHZ_RSSI, pnoSettingsDeserialized.min5GHzRssi);
+ assertEquals(TEST_PNOSETTINGS_MIN_2GHZ_RSSI, pnoSettingsDeserialized.min24GHzRssi);
+ assertEquals(TEST_PNOSETTINGS_INITIAL_SCORE_MAX, pnoSettingsDeserialized.initialScoreMax);
+ assertEquals(TEST_PNOSETTINGS_CURRENT_CONNECTION_BONUS,
+ pnoSettingsDeserialized.currentConnectionBonus);
+ assertEquals(TEST_PNOSETTINGS_SAME_NETWORK_BONUS,
+ pnoSettingsDeserialized.sameNetworkBonus);
+ assertEquals(TEST_PNOSETTINGS_SECURE_BONUS, pnoSettingsDeserialized.secureBonus);
+ assertEquals(TEST_PNOSETTINGS_BAND_5GHZ_BONUS, pnoSettingsDeserialized.band5GHzBonus);
+
+ // Test parsing of PnoNetwork
+ assertEquals(pnoSettings.networkList.length, pnoSettingsDeserialized.networkList.length);
+ for (int i = 0; i < pnoSettings.networkList.length; i++) {
+ PnoNetwork expected = pnoSettings.networkList[i];
+ PnoNetwork actual = pnoSettingsDeserialized.networkList[i];
+ assertEquals(expected.ssid, actual.ssid);
+ assertEquals(expected.flags, actual.flags);
+ assertEquals(expected.authBitField, actual.authBitField);
+ assertTrue(Arrays.equals(expected.frequencies, actual.frequencies));
+ }
+ }
+
+ /**
+ * Make sure that frequencies is not null by default.
+ */
+ @Test
+ public void pnoNetworkFrequencyIsNotNull() throws Exception {
+ PnoNetwork pnoNetwork = new PnoNetwork(TEST_SSID_1);
+ assertNotNull(pnoNetwork.frequencies);
+ }
+
}