summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt10
-rw-r--r--api/test-current.txt1
-rw-r--r--cmds/bootanimation/BootAnimation.cpp8
-rw-r--r--cmds/locksettings/TEST_MAPPING15
-rw-r--r--cmds/statsd/tools/dogfood/Android.bp37
-rw-r--r--cmds/statsd/tools/dogfood/AndroidManifest.xml43
-rw-r--r--cmds/statsd/tools/dogfood/res/drawable-hdpi/ic_launcher.pngbin7783 -> 0 bytes
-rw-r--r--cmds/statsd/tools/dogfood/res/drawable-mdpi/ic_launcher.pngbin3760 -> 0 bytes
-rw-r--r--cmds/statsd/tools/dogfood/res/drawable-xhdpi/ic_launcher.pngbin12356 -> 0 bytes
-rw-r--r--cmds/statsd/tools/dogfood/res/drawable-xxhdpi/ic_launcher.pngbin24780 -> 0 bytes
-rw-r--r--cmds/statsd/tools/dogfood/res/layout/activity_main.xml162
-rw-r--r--cmds/statsd/tools/dogfood/res/raw/statsd_baseline_config109
-rw-r--r--cmds/statsd/tools/dogfood/res/values/strings.xml57
-rw-r--r--cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/DisplayProtoUtils.java158
-rw-r--r--cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java361
-rw-r--r--cmds/statsd/tools/loadtest/Android.bp37
-rw-r--r--cmds/statsd/tools/loadtest/AndroidManifest.xml44
-rw-r--r--cmds/statsd/tools/loadtest/res/drawable-hdpi/ic_launcher.pngbin7783 -> 0 bytes
-rw-r--r--cmds/statsd/tools/loadtest/res/drawable-mdpi/ic_launcher.pngbin3760 -> 0 bytes
-rw-r--r--cmds/statsd/tools/loadtest/res/drawable-xhdpi/ic_launcher.pngbin12356 -> 0 bytes
-rw-r--r--cmds/statsd/tools/loadtest/res/drawable-xxhdpi/ic_launcher.pngbin24780 -> 0 bytes
-rw-r--r--cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml208
-rw-r--r--cmds/statsd/tools/loadtest/res/layout/spinner_item.xml10
-rwxr-xr-xcmds/statsd/tools/loadtest/res/raw/loadtest_configbin2087 -> 0 bytes
-rw-r--r--cmds/statsd/tools/loadtest/res/values/integers.xml24
-rw-r--r--cmds/statsd/tools/loadtest/res/values/strings.xml36
-rwxr-xr-xcmds/statsd/tools/loadtest/run_loadtest.sh99
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryDataRecorder.java56
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryStatsParser.java113
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ConfigFactory.java314
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java169
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java756
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemInfoParser.java69
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java53
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java70
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java116
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java174
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfParser.java27
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java165
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java62
-rw-r--r--cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ValidationRecorder.java93
-rw-r--r--config/boot-profile.txt0
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java4
-rw-r--r--core/java/android/accessibilityservice/GestureDescription.java40
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl2
-rw-r--r--core/java/android/app/ActivityView.java8
-rw-r--r--core/java/android/app/IActivityTaskManager.aidl1
-rw-r--r--core/java/android/app/Notification.java9
-rw-r--r--core/java/android/bluetooth/BluetoothHeadsetClient.java58
-rw-r--r--core/java/android/content/pm/PackageManager.java24
-rw-r--r--core/java/android/content/pm/PackageParser.java82
-rw-r--r--core/java/android/os/SharedMemory.java10
-rw-r--r--core/java/android/provider/CalendarContract.java8
-rw-r--r--core/java/android/text/format/TimeFormatter.java69
-rw-r--r--core/java/android/text/format/TimeMigrationUtils.java40
-rw-r--r--core/java/android/util/FeatureFlagUtils.java2
-rw-r--r--core/java/android/view/IRecentsAnimationController.aidl44
-rw-r--r--core/java/android/view/IRecentsAnimationRunner.aidl2
-rw-r--r--core/java/android/view/SurfaceView.java39
-rw-r--r--core/java/android/view/ViewRootImpl.java183
-rw-r--r--core/java/android/widget/TabWidget.java2
-rw-r--r--core/java/android/widget/ViewAnimator.java5
-rw-r--r--core/java/com/android/internal/os/KernelWakelockReader.java135
-rw-r--r--core/jni/android/graphics/Picture.cpp5
-rw-r--r--core/jni/android_os_Debug.cpp2
-rw-r--r--core/proto/OWNERS2
-rw-r--r--core/proto/android/app/settings_enums.proto7
-rw-r--r--core/res/AndroidManifest.xml69
-rw-r--r--core/res/res/values/attrs_manifest.xml14
-rw-r--r--core/res/res/values/config.xml6
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/android/text/format/TimeMigrationUtilsTest.java120
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java2
-rw-r--r--core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java177
-rw-r--r--graphics/java/android/graphics/RenderNode.java4
-rw-r--r--libs/hwui/SkiaCanvas.cpp7
-rw-r--r--libs/hwui/SkiaCanvas.h4
-rw-r--r--libs/hwui/hwui/Canvas.h15
-rw-r--r--libs/hwui/tests/unit/SkiaCanvasTests.cpp2
-rw-r--r--media/native/midi/amidi.cpp28
-rw-r--r--media/native/midi/include/amidi/AMidi.h32
-rw-r--r--packages/CarSystemUI/res/values/dimens.xml6
-rw-r--r--packages/CtsShim/build/Android.mk3
-rw-r--r--packages/SystemUI/plugin/ExamplePlugin/Android.bp1
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java70
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java11
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java9
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java (renamed from packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java)27
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java6
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java66
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemBars.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java45
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt36
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt61
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java18
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java16
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java30
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java152
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelExpansionListener.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java23
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java3
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java13
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java11
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java19
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java20
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java8
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/CustomScrollView.java4
-rw-r--r--services/autofill/java/com/android/server/autofill/ui/SaveUi.java8
-rw-r--r--services/core/Android.bp9
-rw-r--r--services/core/java/com/android/server/BluetoothManagerService.java3
-rw-r--r--services/core/java/com/android/server/DropBoxManagerService.java6
-rw-r--r--services/core/java/com/android/server/UiModeManagerService.java18
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerShellCommand.java15
-rw-r--r--services/core/java/com/android/server/am/OomAdjuster.java21
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricServiceBase.java12
-rw-r--r--services/core/java/com/android/server/biometrics/EnrollClient.java10
-rw-r--r--services/core/java/com/android/server/biometrics/LoggableMonitor.java2
-rw-r--r--services/core/java/com/android/server/biometrics/face/FaceService.java36
-rw-r--r--services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java4
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java19
-rw-r--r--services/core/java/com/android/server/compat/IPlatformCompat.aidl57
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java52
-rw-r--r--services/core/java/com/android/server/content/SyncManager.java10
-rw-r--r--services/core/java/com/android/server/job/controllers/JobStatus.java10
-rw-r--r--services/core/java/com/android/server/location/GnssLocationProvider.java6
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsStorage.java14
-rw-r--r--services/core/java/com/android/server/locksettings/TEST_MAPPING15
-rw-r--r--services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java33
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerServiceImpl.java44
-rw-r--r--services/core/java/com/android/server/pm/PackageAbiHelper.java85
-rw-r--r--services/core/java/com/android/server/pm/PackageAbiHelperImpl.java542
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java595
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java15
-rw-r--r--services/core/java/com/android/server/pm/ShortcutService.java6
-rw-r--r--services/core/java/com/android/server/pm/TEST_MAPPING14
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java12
-rw-r--r--services/core/java/com/android/server/wm/ActivityRecord.java49
-rw-r--r--services/core/java/com/android/server/wm/ActivityStack.java54
-rw-r--r--services/core/java/com/android/server/wm/ActivityStackSupervisor.java7
-rw-r--r--services/core/java/com/android/server/wm/ActivityTaskManagerService.java49
-rw-r--r--services/core/java/com/android/server/wm/AppTaskImpl.java9
-rw-r--r--services/core/java/com/android/server/wm/AppWindowToken.java9
-rw-r--r--services/core/java/com/android/server/wm/DisplayWindowSettings.java28
-rw-r--r--services/core/java/com/android/server/wm/KeyguardController.java35
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimation.java16
-rw-r--r--services/core/java/com/android/server/wm/RecentsAnimationController.java188
-rw-r--r--services/core/java/com/android/server/wm/ScreenRotationAnimation.java1
-rw-r--r--services/core/java/com/android/server/wm/TaskRecord.java5
-rw-r--r--services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java2
-rw-r--r--services/core/java/com/android/server/wm/TaskStack.java10
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerInternal.java5
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java11
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java9
-rw-r--r--services/core/jni/com_android_server_input_InputManagerService.cpp11
-rw-r--r--services/core/xsd/Android.bp8
-rw-r--r--services/core/xsd/platform-compat-config.xsd51
-rw-r--r--services/core/xsd/platform-compat-schema/current.txt31
-rw-r--r--services/core/xsd/platform-compat-schema/last_current.txt0
-rw-r--r--services/core/xsd/platform-compat-schema/last_removed.txt0
-rw-r--r--services/core/xsd/platform-compat-schema/removed.txt1
-rw-r--r--services/java/com/android/server/SystemServer.java6
-rw-r--r--services/robotests/Android.bp53
-rw-r--r--services/robotests/Android.mk89
-rw-r--r--services/robotests/AndroidManifest.xml24
-rw-r--r--services/robotests/backup/Android.bp53
-rw-r--r--services/robotests/backup/Android.mk84
-rw-r--r--services/robotests/backup/AndroidManifest.xml24
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java86
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java122
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java154
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java105
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ScanTests.java520
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java70
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java37
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java9
-rw-r--r--services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java39
-rw-r--r--startop/apps/test/Android.bp1
-rwxr-xr-xstartop/scripts/iorap/compiler.py123
-rw-r--r--startop/scripts/iorap/compiler_test.py14
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pbbin0 -> 28375 bytes
-rw-r--r--startop/scripts/iorap/test_fixtures/compiler/test_result_systrace748
-rw-r--r--startop/scripts/lib/cmd_utils.py12
-rwxr-xr-xtelephony/java/android/telephony/CarrierConfigManager.java89
-rw-r--r--telephony/java/android/telephony/ims/ImsException.java14
-rw-r--r--telephony/java/android/telephony/ims/ImsMmTelManager.java179
-rw-r--r--telephony/java/android/telephony/ims/aidl/IImsConfig.aidl3
-rw-r--r--telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java13
-rw-r--r--tools/aapt2/link/ManifestFixer.cpp3
-rw-r--r--tools/preload2/Android.bp50
-rw-r--r--tools/preload2/preload-tool37
-rw-r--r--tools/preload2/src/com/android/preload/ClientUtils.java224
-rw-r--r--tools/preload2/src/com/android/preload/DeviceUtils.java420
-rw-r--r--tools/preload2/src/com/android/preload/DumpData.java91
-rw-r--r--tools/preload2/src/com/android/preload/DumpDataIO.java141
-rw-r--r--tools/preload2/src/com/android/preload/DumpTableModel.java93
-rw-r--r--tools/preload2/src/com/android/preload/Main.java341
-rw-r--r--tools/preload2/src/com/android/preload/actions/AbstractThreadedAction.java39
-rw-r--r--tools/preload2/src/com/android/preload/actions/AbstractThreadedDeviceSpecificAction.java45
-rw-r--r--tools/preload2/src/com/android/preload/actions/ClearTableAction.java37
-rw-r--r--tools/preload2/src/com/android/preload/actions/ComputeThresholdAction.java148
-rw-r--r--tools/preload2/src/com/android/preload/actions/ComputeThresholdXAction.java41
-rw-r--r--tools/preload2/src/com/android/preload/actions/DeviceSpecific.java38
-rw-r--r--tools/preload2/src/com/android/preload/actions/ExportAction.java62
-rw-r--r--tools/preload2/src/com/android/preload/actions/ImportAction.java68
-rw-r--r--tools/preload2/src/com/android/preload/actions/ReloadListAction.java68
-rw-r--r--tools/preload2/src/com/android/preload/actions/RunMonkeyAction.java124
-rw-r--r--tools/preload2/src/com/android/preload/actions/ScanAllPackagesAction.java63
-rw-r--r--tools/preload2/src/com/android/preload/actions/ScanPackageAction.java97
-rw-r--r--tools/preload2/src/com/android/preload/actions/ShowDataAction.java94
-rw-r--r--tools/preload2/src/com/android/preload/actions/WritePreloadedClassesAction.java60
-rw-r--r--tools/preload2/src/com/android/preload/classdataretrieval/ClassDataRetriever.java29
-rw-r--r--tools/preload2/src/com/android/preload/classdataretrieval/hprof/GeneralHprofDumpHandler.java70
-rw-r--r--tools/preload2/src/com/android/preload/classdataretrieval/hprof/Hprof.java228
-rw-r--r--tools/preload2/src/com/android/preload/classdataretrieval/jdwp/JDWPClassDataRetriever.java221
-rw-r--r--tools/preload2/src/com/android/preload/classdataretrieval/jdwp/PreloadDebugeeWrapper.java40
-rw-r--r--tools/preload2/src/com/android/preload/ui/IUI.java45
-rw-r--r--tools/preload2/src/com/android/preload/ui/NullProgressMonitor.java39
-rw-r--r--tools/preload2/src/com/android/preload/ui/SequenceUI.java222
-rw-r--r--tools/preload2/src/com/android/preload/ui/SwingUI.java291
251 files changed, 5244 insertions, 9167 deletions
diff --git a/api/current.txt b/api/current.txt
index a7b38a5d5b10..363ce8238f94 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2966,6 +2966,7 @@ package android.accessibilityservice {
}
public final class GestureDescription {
+ method public int getDisplayId();
method public static long getMaxGestureDuration();
method public static int getMaxStrokeCount();
method public android.accessibilityservice.GestureDescription.StrokeDescription getStroke(@IntRange(from=0) int);
@@ -2976,6 +2977,7 @@ package android.accessibilityservice {
ctor public GestureDescription.Builder();
method public android.accessibilityservice.GestureDescription.Builder addStroke(@NonNull android.accessibilityservice.GestureDescription.StrokeDescription);
method public android.accessibilityservice.GestureDescription build();
+ method @NonNull public android.accessibilityservice.GestureDescription.Builder setDisplayId(int);
}
public static class GestureDescription.StrokeDescription {
@@ -11757,6 +11759,9 @@ package android.content.pm {
field public static final String FEATURE_SENSOR_RELATIVE_HUMIDITY = "android.hardware.sensor.relative_humidity";
field public static final String FEATURE_SENSOR_STEP_COUNTER = "android.hardware.sensor.stepcounter";
field public static final String FEATURE_SENSOR_STEP_DETECTOR = "android.hardware.sensor.stepdetector";
+ field public static final String FEATURE_SE_OMAPI_ESE = "android.hardware.se.omapi.ese";
+ field public static final String FEATURE_SE_OMAPI_SD = "android.hardware.se.omapi.sd";
+ field public static final String FEATURE_SE_OMAPI_UICC = "android.hardware.se.omapi.uicc";
field public static final String FEATURE_SIP = "android.software.sip";
field public static final String FEATURE_SIP_VOIP = "android.software.sip.voip";
field public static final String FEATURE_STRONGBOX_KEYSTORE = "android.hardware.strongbox_keystore";
@@ -43991,6 +43996,7 @@ package android.telephony {
public class CarrierConfigManager {
method @Nullable public android.os.PersistableBundle getConfig();
+ method @Nullable public android.os.PersistableBundle getConfigByComponentForSubId(String, int);
method @Nullable public android.os.PersistableBundle getConfigForSubId(int);
method public static boolean isConfigForIdentifiedCarrier(android.os.PersistableBundle);
method public void notifyConfigChangedForSubId(int);
@@ -44168,6 +44174,10 @@ package android.telephony {
field public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
}
+ public static final class CarrierConfigManager.Ims {
+ field public static final String KEY_PREFIX = "ims.";
+ }
+
public abstract class CellIdentity implements android.os.Parcelable {
method public int describeContents();
method @Nullable public CharSequence getOperatorAlphaLong();
diff --git a/api/test-current.txt b/api/test-current.txt
index b393fccdb366..2624eee7d7d1 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3028,6 +3028,7 @@ package android.util {
field public static final String PERSIST_PREFIX = "persist.sys.fflag.override.";
field public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
field public static final String SEAMLESS_TRANSFER = "settings_seamless_transfer";
+ field public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2";
}
public class TimeUtils {
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 30f4ad4c5c69..db384baff4d7 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -63,6 +63,10 @@
#include "BootAnimation.h"
+#define ANIM_PATH_MAX 255
+#define STR(x) #x
+#define STRTO(x) STR(x)
+
namespace android {
static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip";
@@ -96,7 +100,7 @@ static constexpr size_t FONT_NUM_ROWS = FONT_NUM_CHARS / FONT_NUM_COLS;
static const int TEXT_CENTER_VALUE = INT_MAX;
static const int TEXT_MISSING_VALUE = INT_MIN;
static const char EXIT_PROP_NAME[] = "service.bootanim.exit";
-static const int ANIM_ENTRY_NAME_MAX = 256;
+static const int ANIM_ENTRY_NAME_MAX = ANIM_PATH_MAX + 1;
static constexpr size_t TEXT_POS_LEN_MAX = 16;
// ---------------------------------------------------------------------------
@@ -694,7 +698,7 @@ bool BootAnimation::parseAnimationDesc(Animation& animation)
animation.width = width;
animation.height = height;
animation.fps = fps;
- } else if (sscanf(l, " %c %d %d %s #%6s %16s %16s",
+ } else if (sscanf(l, " %c %d %d %" STRTO(ANIM_PATH_MAX) "s #%6s %16s %16s",
&pathType, &count, &pause, path, color, clockPos1, clockPos2) >= 4) {
//SLOGD("> type=%c, count=%d, pause=%d, path=%s, color=%s, clockPos1=%s, clockPos2=%s",
// pathType, count, pause, path, color, clockPos1, clockPos2);
diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING
new file mode 100644
index 000000000000..c1cba5f7f22d
--- /dev/null
+++ b/cmds/locksettings/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsDevicePolicyManagerTestCases",
+ "options": [
+ {
+ "include-annotation": "com.android.cts.devicepolicy.annotations.LockSettingsTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/cmds/statsd/tools/dogfood/Android.bp b/cmds/statsd/tools/dogfood/Android.bp
deleted file mode 100644
index bb494a6025af..000000000000
--- a/cmds/statsd/tools/dogfood/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//
-
-android_app {
- name: "StatsdDogfood",
- platform_apis: true,
-
- srcs: ["src/**/*.java"],
-
- resource_dirs: ["res"],
- static_libs: [
- "platformprotoslite",
- "statsdprotolite",
- ],
-
- privileged: true,
- dex_preopt: {
- enabled: false,
- },
- certificate: "platform",
- optimize: {
- enabled: false,
- },
-}
diff --git a/cmds/statsd/tools/dogfood/AndroidManifest.xml b/cmds/statsd/tools/dogfood/AndroidManifest.xml
deleted file mode 100644
index 52673fbdcf92..000000000000
--- a/cmds/statsd/tools/dogfood/AndroidManifest.xml
+++ /dev/null
@@ -1,43 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.statsd.dogfood"
- android:sharedUserId="android.uid.system"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-permission android:name="android.permission.DUMP" />
-
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name"
- android:launchMode="singleTop" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
-
- <service android:name=".MainActivity$ReceiverIntentService" android:exported="true" />
- </application>
-</manifest>
diff --git a/cmds/statsd/tools/dogfood/res/drawable-hdpi/ic_launcher.png b/cmds/statsd/tools/dogfood/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 55621cc1074f..000000000000
--- a/cmds/statsd/tools/dogfood/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/dogfood/res/drawable-mdpi/ic_launcher.png b/cmds/statsd/tools/dogfood/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 11ec2068be19..000000000000
--- a/cmds/statsd/tools/dogfood/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/dogfood/res/drawable-xhdpi/ic_launcher.png b/cmds/statsd/tools/dogfood/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 7c02b784aa5d..000000000000
--- a/cmds/statsd/tools/dogfood/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/dogfood/res/drawable-xxhdpi/ic_launcher.png b/cmds/statsd/tools/dogfood/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644
index 915d91441349..000000000000
--- a/cmds/statsd/tools/dogfood/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/dogfood/res/layout/activity_main.xml b/cmds/statsd/tools/dogfood/res/layout/activity_main.xml
deleted file mode 100644
index 784ed40ce2c2..000000000000
--- a/cmds/statsd/tools/dogfood/res/layout/activity_main.xml
+++ /dev/null
@@ -1,162 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2007, 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.
-*/
--->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical">
-
- <Button
- android:id="@+id/push_config"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:color/holo_green_light"
- android:text="@string/push_config"/>
- <Button
- android:id="@+id/set_receiver"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:color/holo_green_light"
- android:text="@string/set_receiver"/>
- <Button
- android:id="@+id/remove_receiver"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:color/holo_green_light"
- android:text="@string/remove_receiver"/>
-
- <LinearLayout android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button android:id="@+id/app_a_wake_lock_acquire1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_a_get_wl1"/>
- <Button android:id="@+id/app_a_wake_lock_release1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_a_release_wl1"/>
- </LinearLayout>
-
- <LinearLayout android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button android:id="@+id/app_a_wake_lock_acquire2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_a_get_wl2"/>
- <Button android:id="@+id/app_a_wake_lock_release2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_a_release_wl2"/>
- </LinearLayout>
-
- <LinearLayout android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button android:id="@+id/app_b_wake_lock_acquire1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_b_get_wl1"/>
- <Button android:id="@+id/app_b_wake_lock_release1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_b_release_wl1"/>
- </LinearLayout>
- <LinearLayout android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button android:id="@+id/app_b_wake_lock_acquire2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_b_get_wl2"/>
- <Button android:id="@+id/app_b_wake_lock_release2"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/app_b_release_wl2"/>
- </LinearLayout>
-
- <LinearLayout android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button android:id="@+id/plug"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/plug"/>
-
- <Button android:id="@+id/unplug"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/unplug"/>
- </LinearLayout>
-
- <LinearLayout android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <Button android:id="@+id/screen_on"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/screen_on"/>
-
- <Button android:id="@+id/screen_off"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/screen_off"/>
- </LinearLayout>
-
- <LinearLayout android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
-
- <Button
- android:id="@+id/custom_start"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/custom_start" />
-
- <Button
- android:id="@+id/custom_stop"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/custom_stop" />
- </LinearLayout>
-
- <Button android:id="@+id/dump"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="@android:color/holo_purple"
- android:text="@string/dump"/>
-
- <TextView
- android:id="@+id/header"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:text="@string/report_header"/>
-
- <TextView
- android:id="@+id/report_text"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
-</ScrollView> \ No newline at end of file
diff --git a/cmds/statsd/tools/dogfood/res/raw/statsd_baseline_config b/cmds/statsd/tools/dogfood/res/raw/statsd_baseline_config
deleted file mode 100644
index d05006124994..000000000000
--- a/cmds/statsd/tools/dogfood/res/raw/statsd_baseline_config
+++ /dev/null
@@ -1,109 +0,0 @@
-¹ÓõÕ¯¤”årÝèåâÕ»éÉ7¬ìŸ‘Ψê­.–´šÄÁŒç¶ÚšäÑùôºZªÑ€¸ëÐé­í‘˜‹Ý™ûÆŽ6ˆ™ÁÖ΂õ›Ã¥¼à¨É—ÿQÝàåÈ߀äÍ@ÆÙÑ„ÓІ„èѿ̲±™¨lŸÄ€ìúˆÖ­ü¶ú̳Šéâ‡ãà§ØÈË´Ù%ó­ÓÚ«¹¼ÜyÛ®±ë¸«”º?­¹•繡¸Œ€â鿨ŒÙœ®‘)çæ©Á”§äéîÀ‚Ò®ö‡.ÐÙ•°‹ÁÈy"'(WòóÀ–ðßæ¬ùÕàÀ™ýëZ”ÔÆ™Ž¤š¹»"
- (2!ûÄߪæþªâÚ 
-V¢¦€¡’€Ç€¡ùÕàÀ™ýëZÈ‹ÄÂë¢Ä¯Ø"
- (2 ª–¨Œ×ÿ¹¡k 
-V‡úÌòá㿘>ùÕàÀ™ýëZáž‹â‘Ý»ä"
- (2!÷‘–ä–Œ¿¯ 
-WØõé¼ÃóÀàþùÕàÀ™ýëZ°ÔØùΣ‘¯"
- (2!Ïä†÷ɯ 
-VÚœäÌþ½¬jùÕàÀ™ýëZ³Ö‰Ó¾ ½Ñ"
- (2!Ÿ¡ªˆëôùÇ 
-V¨¾ñ≎̅ùÕàÀ™ýëZ“Ðåÿèåò?"
- (2!½šòÐ䤿Œ 
-U…£²†µÜ‡‘_ùÕàÀ™ýëZñîôÒ‡¤´†z"
- (2!é’¬¸ç¼‡Óª 
-K‘ã´¶üÅçúñ±Ë壆¨D”ÔÆ™Ž¤š¹»"
-#(2ûÄߪæþªâÚ#Ië§ì·ºê•Æúñ±Ë壆¨DÈ‹ÄÂë¢Ä¯Ø"
-#(2ª–¨Œ×ÿ¹¡k#JÙ¢Öúƒ†ðúñ±Ë壆¨Dáž‹â‘Ý»ä"
-#(2÷‘–ä–Œ¿¯#JãýØåóªü)úñ±Ë壆¨D°ÔØùΣ‘¯"
-#(2Ïä†÷ɯ#KËÅÝÇž¹Åãúñ±Ë壆¨D³Ö‰Ó¾ ½Ñ"
-#(2Ÿ¡ªˆëôùÇ#Jɳ¸ó€„ø‘Ãúñ±Ë壆¨D“Ðåÿèåò?"
-#(2½šòÐ䤿Œ#J•–ó«ðô¤Þïúñ±Ë壆¨DñîôÒ‡¤´†z"
-#(2é’¬¸ç¼‡Óª#J•ºÔ¯•…Î’:›ºô¿Úó¾kŒÓÜ¢¾ÌÊ"
-(2ûÄߪæþªâÚI»ÓòÓí‰àÖ
-›ºô¿Úó¾kǮ›ŸÊŸäâ"
-(2ª–¨Œ×ÿ¹¡kJÖÐük÷y›ºô¿Úó¾kÿ‚¾žÃ“’§õ"
-(2÷‘–ä–Œ¿¯JøÿÊ“åøË¨›ºô¿Úó¾k˜ý˜‘¢ŒÐÀI"
-(2Ïä†÷ɯKõ­ß°—’ì¾×›ºô¿Úó¾kì‘áÒîŸÙÍá"
-(2Ÿ¡ªˆëôùÇJà¸ëòä¥û݈›ºô¿Úó¾kôé‹¿¿¸ßÄ"
-(2½šòÐ䤿ŒJУŒð†¬µÙ›ºô¿Úó¾k‰±Öйˆ–Ôõ"
-(2é’¬¸ç¼‡ÓªK—ÍË é÷ÐM鮣öü©µŒÓÜ¢¾ÌÊ"
-(2ûÄߪæþªâÚJÌŽë á«¡´{鮣öü©µǮ›ŸÊŸäâ"
-(2ª–¨Œ×ÿ¹¡kL˜†ŒÏØì¡‹³鮣öü©µÿ‚¾žÃ“’§õ"
-(2÷‘–ä–Œ¿¯Ká°Ñàƒ½†¶ý鮣öü©µ˜ý˜‘¢ŒÐÀI"
-(2Ïä†÷ɯKÛ”Ÿò§…ÂÁY鮣öü©µì‘áÒîŸÙÍá"
-(2Ÿ¡ªˆëôùÇKϜݗÞç±ù¥鮣öü©µôé‹¿¿¸ßÄ"
-(2½šòÐ䤿ŒKÚÖ•·‰­–B鮣öü©µ‰±Öйˆ–Ôõ"
-(2é’¬¸ç¼‡Óª,Ä®öèÀƒ‘âÌ¥•€†ÜÖ×AÐÙ•°‹ÁÈy"
-(€õ»•÷¾ÓçȪŠéñðȃŹ~”‰àÉ­®¶f"(2é’¬¸ç¼‡Óª2½šòÐ䤿Œ2Ÿ¡ªˆëôùÇLشͼá™þþæ¿É¶ˆœ‚æð±ûÄߪæþªâÚ"
--(2ûÄߪæþªâÚ-JÉ¥˜‘Ûüˆ‹ò¿É¶ˆœ‚æð±ª–¨Œ×ÿ¹¡k"
--(2ª–¨Œ×ÿ¹¡k-L¡©äÞ¨ô¶ø½¿É¶ˆœ‚æð±÷‘–ä–Œ¿¯"
--(2÷‘–ä–Œ¿¯-L‡õÇþ¡¾ÚÈþ¿É¶ˆœ‚æð±Ïä†÷ɯ"
--(2Ïä†÷ɯ-L—î«ãïÚ½û¬¿É¶ˆœ‚æð±Ÿ¡ªˆëôùÇ"
--(2Ÿ¡ªˆëôùÇ-LñÍý‚ÿô­¿É¶ˆœ‚æð±½šòÐ䤿Œ"
--(2½šòÐ䤿Œ-K‹òʰ«»íè|¿É¶ˆœ‚æð±é’¬¸ç¼‡Óª"
--(2é’¬¸ç¼‡Óª-"9äëæÚòœ§=̨…¥”ìãÏ‘N ÐÙ•°‹ÁÈy* ‘N0@":­šˆž‚έñÐ̨…¥”ìãÏ‘N ÐÙ•°‹ÁÈy* ‘N0@":ù»Žôç¾ãˆÐ̨…¥”ìãÏ‘N ÐÙ•°‹ÁÈy* ‘N0@"9›™›ŸÝ†—ãS̨…¥”ìãÏ‘N ÐÙ•°‹ÁÈy* ‘N0@":‹ããùŸáŽôºßñ¼ûÌ•˜“N ÐÙ•°‹ÁÈy* “N0@":ç΀àë Œƒôºßñ¼ûÌ•˜“N ÐÙ•°‹ÁÈy* “N0@":™˜µøÖ²Äìõôºßñ¼ûÌ•˜“N ÐÙ•°‹ÁÈy* “N0@":¬Öœ¥¥ÃÆŒÑôºßñ¼ûÌ•˜“N ÐÙ•°‹ÁÈy* “N0@"5ôÇ™±¶Ï¢‘ò•™ÔéŠñ˜Èu›N ÐÙ•°‹ÁÈy*›N0@"4«÷µÿ󲂜e•™ÔéŠñ˜Èu›N ÐÙ•°‹ÁÈy*›N0@"4å¢úˆÑÙúý•™ÔéŠñ˜Èu›N ÐÙ•°‹ÁÈy*›N0@"+ž—Õõ‰î¶±~‡î‚ÒÔÊ´ËœN ÐÙ•°‹ÁÈy0@",‘ó‚³ïÙù¦‚‡î‚ÒÔÊ´ËœN ÐÙ•°‹ÁÈy0@"+òßù¥·«Äà;‡î‚ÒÔÊ´ËœN ÐÙ•°‹ÁÈy0@",ÓûÅñÒ¢ô§Â‡î‚ÒÔÊ´ËœN ÐÙ•°‹ÁÈy0@"+¨²°žò³ƒ¨R‡î‚ÒÔÊ´ËœN ÐÙ•°‹ÁÈy0@"+ÞìøݱþÖq‡î‚ÒÔÊ´ËœN ÐÙ•°‹ÁÈy0@",͉šæÜ­ŽÄÀ‡î‚ÒÔÊ´ËœN ÐÙ•°‹ÁÈy0@"3Ä»±ê¾¸ô°˜þËÉÇåãÃ2 ÐÙ•°‹ÁÈy*0@"‰ѽËñɤ¡™a˜þËÉÇåãÃ2 ”‰àÉ­®¶f*0:é’¬¸ç¼‡Óª:½šòÐ䤿Œ:Ÿ¡ªˆëôùÇ@":ÃêåÒýéó¦ï‘ŽÁ°×ËÇÅß–N ÐÙ•°‹ÁÈy* –N0@":Àš‚ÑÀí£Ï‹‘ŽÁ°×ËÇÅß–N ÐÙ•°‹ÁÈy* –N0@"9¾¢ðÛßÒëéø›²Ö·ÔÈšN ÐÙ•°‹ÁÈy* šN0@"9÷´ç鼯Š~½ ¤„¹®Ð§¨˜N ÐÙ•°‹ÁÈy* ˜N0@2YÝæÆËò ‚ú‘»óÓ¤ãËÕ”ÔÆ™Ž¤š¹»"!ûÄߪæþªâÚ 
-(2
- 82X°öòΪáŠþ„»óÓ¤ãËÕÈ‹ÄÂë¢Ä¯Ø" ª–¨Œ×ÿ¹¡k 
-(2
- 82X°ç¦ùºŒó·0»óÓ¤ãËÕáž‹â‘Ý»ä"!÷‘–ä–Œ¿¯ 
-(2
- 82Yôæï°Þ¼  ”»óÓ¤ãËÕ°ÔØùΣ‘¯"!Ïä†÷ɯ 
-(2
- 82Y¡Î°Ãåüý»óÓ¤ãËÕ³Ö‰Ó¾ ½Ñ"!Ÿ¡ªˆëôùÇ 
-(2
- 82XÕ¤ô®Ã£ÇÓÈ»óÓ¤ãËÕ“Ðåÿèåò?"!½šòÐ䤿Œ 
-(2
- 82XÖÂªßøæÌÊ»óÓ¤ãËÕñîôÒ‡¤´†z"!é’¬¸ç¼‡Óª 
-(2
- 825’ÌíûÍõ÷Æ­»óÓ¤ãËÕ®Èùé€ù’±W(2
- 82X²¹÷߆ŒÀ¶`»óÓ¤ãËÕ”ÔÆ™Ž¤š¹»"!ûÄߪæþªâÚ 
-(2
- 82W÷ÞŸÉÔ ëÍd»óÓ¤ãËÕÈ‹ÄÂë¢Ä¯Ø" ª–¨Œ×ÿ¹¡k 
-(2
- 82XäÁš´¤·ñì.»óÓ¤ãËÕáž‹â‘Ý»ä"!÷‘–ä–Œ¿¯ 
-(2
- 82YîæÍçâ»óÓ¤ãËÕ°ÔØùΣ‘¯"!Ïä†÷ɯ 
-(2
- 82Y˜²Ì´×³ìóÓ¤ãËÕ³Ö‰Ó¾ ½Ñ"!Ÿ¡ªˆëôùÇ 
-(2
- 82W¾¯†‘§È“¿P»óÓ¤ãËÕ“Ðåÿèåò?"!½šòÐ䤿Œ 
-(2
- 82XÂÀ¶òšË˜‚ð»óÓ¤ãËÕñîôÒ‡¤´†z"!é’¬¸ç¼‡Óª 
-(2
- 82U—îïÛ²¸¸†µ»óÓ¤ãËÕ”ÔÆ™Ž¤š¹»"!ûÄߪæþªâÚ 
-(2 
-82Tû¯ûû²¶ýñ§»óÓ¤ãËÕÈ‹ÄÂë¢Ä¯Ø" ª–¨Œ×ÿ¹¡k 
-(2 
-82T†ñù™ŸÈ¨«»óÓ¤ãËÕáž‹â‘Ý»ä"!÷‘–ä–Œ¿¯ 
-(2 
-82T҈πŸ¯‰ŠD»óÓ¤ãËÕ°ÔØùΣ‘¯"!Ïä†÷ɯ 
-(2 
-82Uš¤Ë„阿ö†»óÓ¤ãËÕ³Ö‰Ó¾ ½Ñ"!Ÿ¡ªˆëôùÇ 
-(2 
-82SË©ËÞ¯öÈÞ&»óÓ¤ãËÕ“Ðåÿèåò?"!½šòÐ䤿Œ 
-(2 
-82TάóýᔺèÞ»óÓ¤ãËÕñîôÒ‡¤´†z"!é’¬¸ç¼‡Óª 
-(2 
-82#àšÉ±ûÿ±»óÓ¤ãËÕ®Èùé€ù’±W(82#ÞžÞïƒ÷“…±œ–±ÃŸ€ÀâFÐÙ•°‹ÁÈy(82"䣞ƒƒ¿Èòrœ–±ÃŸ€ÀâFÐÙ•°‹ÁÈy(82*¦‚ó©ÂÊÓŒ3œ–±ÃŸ€ÀâFÐÙ•°‹ÁÈy(2%82*ÅМ½à®ÄŠœ–±ÃŸ€ÀâFÐÙ•°‹ÁÈy(2%82"‡è‘²†ÙÓÂ+œ–±ÃŸ€ÀâFÐÙ•°‹ÁÈy(82J›»ÜŽáø©ÔӈƄת¶£«ŒÓÜ¢¾ÌÊ"ûÄߪæþªâÚ'(2'82H®Ñä‚Òš„ÝqˆÆ„ת¶£«Ǯ›ŸÊŸäâ"ª–¨Œ×ÿ¹¡k'(2'82JêýÂÄ…Œ™ÉˆƄת¶£«ÿ‚¾žÃ“’§õ"÷‘–ä–Œ¿¯'(2'82Iâ븛ÚðÖóˆÆ„ת¶£«˜ý˜‘¢ŒÐÀI"Ïä†÷ɯ'(2'82Iÿ±å¨ ïÉ­KˆÆ„ת¶£«ì‘áÒîŸÙÍá"Ÿ¡ªˆëôùÇ'(2'82Hý©ëÞ¥é÷“\ˆÆ„ת¶£«ôé‹¿¿¸ßÄ"½šòÐ䤿Œ'(2'82JÁ°Õ즊ý…¯ˆÆ„ת¶£«‰±Öйˆ–Ôõ"é’¬¸ç¼‡Óª'(2'82ƒ˜Êã•ÿÊÙÚ·æúŸÌ½‚¡”‰àÉ­®¶f"é’¬¸ç¼‡Óª"½šòÐ䤿Œ"Ÿ¡ªˆëôùÇ(282‚ÊùÑèÂóžàY·æúŸÌ½‚¡”‰àÉ­®¶f"é’¬¸ç¼‡Óª"½šòÐ䤿Œ"Ÿ¡ªˆëôùÇ(282MÚËñ´ä‡¼Ä'ª ÿçû¤é刌ÓÜ¢¾ÌÊ"ûÄߪæþªâÚ(2
-82LŽÏ—ꤦݯ5ª ÿçû¤éåˆǮ›ŸÊŸäâ"ª–¨Œ×ÿ¹¡k(2
-82Nø‚ÍÁœÆÚª ÿçû¤éåˆÿ‚¾žÃ“’§õ"÷‘–ä–Œ¿¯(2
-82LŸ¿ŽöåèÆ)ª ÿçû¤é刘ý˜‘¢ŒÐÀI"Ïä†÷ɯ(2
-82NþÝÒÿ§Ù¡±˜ª ÿçû¤éåˆì‘áÒîŸÙÍá"Ÿ¡ªˆëôùÇ(2
-82M³­Ñ×饊ÿ¦ª ÿçû¤éåˆôé‹¿¿¸ßÄ"½šòÐ䤿Œ(2
-82M–ÎÜ‹ó¯Ë„ª ÿçû¤é刉±Öйˆ–Ôõ"é’¬¸ç¼‡Óª(2
-82ƒÍê´ýÞÁöª ÿçû¤é刔‰àÉ­®¶f"é’¬¸ç¼‡Óª"½šòÐ䤿Œ"Ÿ¡ªˆëôùÇ(282,Ü›ä¤ö¸Åˆºª ÿçû¤éåˆÐÙ•°‹ÁÈy(282+Ù¼‡úýõ‰—êâÓ»ä¾ÙÙ9ÐÙ•°‹ÁÈy(282.ƒÚæË›Õ²“^âÓ»ä¾ÙÙ9ÐÙ•°‹ÁÈy(2
-82/òìšÀ·ÄŒÃ#óª·Žð–äÑŠÐÙ•°‹ÁÈy(2
-82+¢ØþËÄÝßíyóª·Žð–äÑŠÐÙ•°‹ÁÈy(282"йʢäÞ†#½³ úùš±KÐÙ•°‹ÁÈy(82I¾Œ…û±ªÓþν³ úùš±KŒÓÜ¢¾ÌÊ"ûÄߪæþªâÚ(282HÞ­ûÅŠëŽî½³ úùš±KǮ›ŸÊŸäâ"ª–¨Œ×ÿ¹¡k(282HÚÇÍý›ôÍô_½³ úùš±Kÿ‚¾žÃ“’§õ"÷‘–ä–Œ¿¯(282Gá”ܰ§¼Üï{½³ úùš±K˜ý˜‘¢ŒÐÀI"Ïä†÷ɯ(282IŒú’ìÌšŒÿ½³ úùš±Kì‘áÒîŸÙÍá"Ÿ¡ªˆëôùÇ(282HðÒ¬¼ïˆâ½³ úùš±Kôé‹¿¿¸ßÄ"½šòÐ䤿Œ(282Hˆ¼ÂÁŒ‚ªŠE½³ úùš±K‰±Öйˆ–Ôõ"é’¬¸ç¼‡Óª(282 ðÚžºÖèà몖¨Œ×ÿ¹¡k(282"…ïèÙŸåóþÎûÄߪæþªâÚ(282!ÆÉ¨‡âž¯‰÷‘–ä–Œ¿¯(282"Õ™õê×Ì·›‹Ïä†÷ɯ(282!Þíó¾ó¿ÚªˆëôùÇ(282!ž¥ÌÔѾۛL½šòÐ䤿Œ(282!„±ÂææÄÁOé’¬¸ç¼‡Óª(282+¦‚ýª¬¢˜þǪ–¨Œ×ÿ¹¡kÐÙ•°‹ÁÈy(282+Ó®¿Œïɳ=ûÄߪæþªâÚÐÙ•°‹ÁÈy(282+ØŽ„Øø¨²c÷‘–ä–Œ¿¯ÐÙ•°‹ÁÈy(282,ýŒ®ê£ÀËŠÏä†÷ɯÐÙ•°‹ÁÈy(282+’ÐÝç’묩uŸ¡ªˆëôùÇÐÙ•°‹ÁÈy(282,ÌÅ„„ŒúÔÞ ½šòÐ䤿ŒÐÙ•°‹ÁÈy(282,ÿªØ¦ƒ®èý»é’¬¸ç¼‡ÓªÐÙ•°‹ÁÈy(282#©Ô†«¹ÛÈÊœä”Û›ÅËèÄÐÙ•°‹ÁÈy(82,‡¼ã™“ЧÓœä”Û›ÅËèÄÐÙ•°‹ÁÈy(2 82#ëÜÄêÖª©ÞùÃýب°Ï=ÐÙ•°‹ÁÈy(82I¬Í˜ÝïÚÈéùÃýب°Ï=ŒÓÜ¢¾ÌÊ"ûÄߪæþªâÚ(282Hã;ܲÍË®øùÃýب°Ï=Ǯ›ŸÊŸäâ"ª–¨Œ×ÿ¹¡k(282IÌ™¹ý¢ÞúŒ…ùÃýب°Ï=ÿ‚¾žÃ“’§õ"÷‘–ä–Œ¿¯(282GÚ´¯Ðèà £YùÃýب°Ï=˜ý˜‘¢ŒÐÀI"Ïä†÷ɯ(282IƒÈæÑ€¸µ§µùÃýب°Ï=ì‘áÒîŸÙÍá"Ÿ¡ªˆëôùÇ(282Gׇã É­ÈùÃýب°Ï=ôé‹¿¿¸ßÄ"½šòÐ䤿Œ(282HÁµÏ›é¥¸ãUùÃýب°Ï=‰±Öйˆ–Ôõ"é’¬¸ç¼‡Óª(282"§±¿Œ·¾íé„ò݃‰…Ï™sÐÙ•°‹ÁÈy(82I®‰Å„ÿ··„ò݃‰…Ï™sŒÓÜ¢¾ÌÊ"ûÄߪæþªâÚ(282H°ªåÛòÿ™˜„ò݃‰…Ï™sǮ›ŸÊŸäâ"ª–¨Œ×ÿ¹¡k(282HÖïˆÇ÷ðî’
-„ò݃‰…Ï™sÿ‚¾žÃ“’§õ"÷‘–ä–Œ¿¯(282Gæü•о°‹„ò݃‰…Ï™s˜ý˜‘¢ŒÐÀI"Ïä†÷ɯ(282HáŒêË ûÜÝ „ò݃‰…Ï™sì‘áÒîŸÙÍá"Ÿ¡ªˆëôùÇ(282Gµü­ŒºÊ¥„ò݃‰…Ï™sôé‹¿¿¸ßÄ"½šòÐ䤿Œ(282HÏææŸÞñ˜È'„ò݃‰…Ï™s‰±Öйˆ–Ôõ"é’¬¸ç¼‡Óª(282#䪧¸ëð»ÍÖ“®ß®þÏ¿ÐÙ•°‹ÁÈy(82HâÈòŸ‚Ϫ¶;“®ß®þÏ¿ŒÓÜ¢¾ÌÊ"ûÄߪæþªâÚ(282GÅöôŽåËà@“®ß®þÏ¿Ǯ›ŸÊŸäâ"ª–¨Œ×ÿ¹¡k(282H±¤ñþÜÀ«‡-“®ß®þÏ¿ÿ‚¾žÃ“’§õ"÷‘–ä–Œ¿¯(282GЇ¶­ÇéíËI“®ß®þÏ¿˜ý˜‘¢ŒÐÀI"Ïä†÷ɯ(282H¶ÛŽˆÊÜÇÔ
-“®ß®þÏ¿ì‘áÒîŸÙÍá"Ÿ¡ªˆëôùÇ(282Gñå°ì’³¯Ç“®ß®þÏ¿ôé‹¿¿¸ßÄ"½šòÐ䤿Œ(282H¥×©ë¹ÖÕÅb“®ß®þÏ¿‰±Öйˆ–Ôõ"é’¬¸ç¼‡Óª(282#¼ù´–ºîª¡Ÿ¤øÝŽ£î“KÐÙ•°‹ÁÈy(82H…üÖ½ßÇЃqŸ¤øÝŽ£î“KŒÓÜ¢¾ÌÊ"ûÄߪæþªâÚ(282GÀê÷ÅÒ×´øŸ¤øÝŽ£î“KǮ›ŸÊŸäâ"ª–¨Œ×ÿ¹¡k(282Iô ¨ø­Í¹€Ÿ¤øÝŽ£î“Kÿ‚¾žÃ“’§õ"÷‘–ä–Œ¿¯(282HÍÆýö®£ÏåËŸ¤øÝŽ£î“K˜ý˜‘¢ŒÐÀI"Ïä†÷ɯ(282H¿¾Š “ʽ៤øÝŽ£î“Kì‘áÒîŸÙÍá"Ÿ¡ªˆëôùÇ(282GºÉ¬¦“ÆçÜpŸ¤øÝŽ£î“Kôé‹¿¿¸ßÄ"½šòÐ䤿Œ(282H•úŸþî¯ø6Ÿ¤øÝŽ£î“K‰±Öйˆ–Ôõ"é’¬¸ç¼‡Óª(28:â鿨ŒÙœ®‘*:ÔØ’¯—꓌’ („:ðÿÈ€ÀíÐð© (¬:ì¹ó¢â¯¢ÚÌ (Ü :ôïÆ þ©ƒ„ø (À :õµ…çÈηŽB (¤ :¸Î½Èìù„ (:¶›èõÖð®÷m (è:¨ÆºÀõµÈï¹ (”
-:ãï©Ê½˜š¡® (¼:¥Ã¯œí…â¥w (ø
-:å½ÈÂÏò“Þó (ˆ:¶Æèܦ™¥ìß(
-(
-(
-(
-(
- B.ª ÿçû¤éåˆ!ÂŒÝëð ¢Ý›ºô¿Úó¾k2
-B"󄽾؜ߞ}™ºŽÔ–í”"žÈ¶ž•ÞŠè(
-B-âÓ»ä¾ÙÙ9!µêЊîÄa鮣öü©µ2
-B,·æúŸÌ½‚¡ûó⿼‘ÿÿƒ«ŸˆÇŽ¿¡
diff --git a/cmds/statsd/tools/dogfood/res/values/strings.xml b/cmds/statsd/tools/dogfood/res/values/strings.xml
deleted file mode 100644
index 60948a181a1b..000000000000
--- a/cmds/statsd/tools/dogfood/res/values/strings.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2007, 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>
-
- <string name="app_name">Statsd Dogfood</string>
-
- <string name="statsd_running">Statsd Running</string>
- <string name="statsd_not_running">Statsd NOT Running</string>
-
- <string name="push_config">Push baseline config</string>
- <string name="set_receiver">Set pendingintent</string>
- <string name="remove_receiver">Remove pendingintent</string>
-
- <string name="app_a_foreground">App A foreground</string>
- <string name="app_b_foreground">App B foreground</string>
-
-
- <string name="app_a_get_wl1">App A get wl_1</string>
- <string name="app_a_release_wl1">App A release wl_1</string>
-
- <string name="app_a_get_wl2">App A get wl_2</string>
- <string name="app_a_release_wl2">App A release wl_2</string>
-
- <string name="app_b_get_wl1">App B get wl_1</string>
- <string name="app_b_release_wl1">App B release wl_1</string>
-
- <string name="app_b_get_wl2">App B get wl_2</string>
- <string name="app_b_release_wl2">App B release wl_2</string>
-
- <string name="plug">Plug</string>
- <string name="unplug">Unplug</string>
-
- <string name="screen_on">Screen On</string>
- <string name="screen_off">Screen Off</string>
-
- <string name="custom_start">App hook start</string>
- <string name="custom_stop">App hook stop</string>
-
- <string name="dump">DumpReport</string>
- <string name="report_header">Report details</string>
-</resources>
diff --git a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/DisplayProtoUtils.java b/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/DisplayProtoUtils.java
deleted file mode 100644
index b6b16e40a4b2..000000000000
--- a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/DisplayProtoUtils.java
+++ /dev/null
@@ -1,158 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.dogfood;
-
-import android.text.format.DateFormat;
-
-import com.android.os.StatsLog;
-
-import java.util.List;
-
-public class DisplayProtoUtils {
- public static void displayLogReport(StringBuilder sb, StatsLog.ConfigMetricsReportList reports) {
- sb.append("ConfigKey: ");
- if (reports.hasConfigKey()) {
- com.android.os.StatsLog.ConfigMetricsReportList.ConfigKey key = reports.getConfigKey();
- sb.append("\tuid: ").append(key.getUid()).append(" name: ").append(key.getId())
- .append("\n");
- }
-
- for (StatsLog.ConfigMetricsReport report : reports.getReportsList()) {
- sb.append("StatsLogReport size: ").append(report.getMetricsCount()).append("\n");
- sb.append("Last report time:").append(getDateStr(report.getLastReportElapsedNanos())).
- append("\n");
- sb.append("Current report time:").append(getDateStr(report.getCurrentReportElapsedNanos())).
- append("\n");
- for (StatsLog.StatsLogReport log : report.getMetricsList()) {
- sb.append("\n\n");
- sb.append("metric id: ").append(log.getMetricId()).append("\n");
-
- switch (log.getDataCase()) {
- case DURATION_METRICS:
- sb.append("Duration metric data\n");
- displayDurationMetricData(sb, log);
- break;
- case EVENT_METRICS:
- sb.append("Event metric data\n");
- displayEventMetricData(sb, log);
- break;
- case COUNT_METRICS:
- sb.append("Count metric data\n");
- displayCountMetricData(sb, log);
- break;
- case GAUGE_METRICS:
- sb.append("Gauge metric data\n");
- displayGaugeMetricData(sb, log);
- break;
- case VALUE_METRICS:
- sb.append("Value metric data\n");
- displayValueMetricData(sb, log);
- break;
- case DATA_NOT_SET:
- sb.append("No metric data\n");
- break;
- }
- }
- }
- }
-
- public static String getDateStr(long nanoSec) {
- return DateFormat.format("dd/MM hh:mm:ss", nanoSec/1000000).toString();
- }
-
- private static void displayDimension(StringBuilder sb, StatsLog.DimensionsValue dimensionValue) {
- sb.append(dimensionValue.getField()).append(":");
- if (dimensionValue.hasValueBool()) {
- sb.append(dimensionValue.getValueBool());
- } else if (dimensionValue.hasValueFloat()) {
- sb.append(dimensionValue.getValueFloat());
- } else if (dimensionValue.hasValueInt()) {
- sb.append(dimensionValue.getValueInt());
- } else if (dimensionValue.hasValueStr()) {
- sb.append(dimensionValue.getValueStr());
- } else if (dimensionValue.hasValueTuple()) {
- sb.append("{");
- for (StatsLog.DimensionsValue child :
- dimensionValue.getValueTuple().getDimensionsValueList()) {
- displayDimension(sb, child);
- }
- sb.append("}");
- }
- sb.append(" ");
- }
-
- public static void displayDurationMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- StatsLog.StatsLogReport.DurationMetricDataWrapper durationMetricDataWrapper
- = log.getDurationMetrics();
- sb.append("Dimension size: ").append(durationMetricDataWrapper.getDataCount()).append("\n");
- for (StatsLog.DurationMetricData duration : durationMetricDataWrapper.getDataList()) {
- sb.append("dimension_in_what: ");
- displayDimension(sb, duration.getDimensionsInWhat());
- sb.append("\n");
- if (duration.hasDimensionsInCondition()) {
- sb.append("dimension_in_condition: ");
- displayDimension(sb, duration.getDimensionsInCondition());
- sb.append("\n");
- }
-
- for (StatsLog.DurationBucketInfo info : duration.getBucketInfoList()) {
- sb.append("\t[").append(getDateStr(info.getStartBucketElapsedNanos())).append("-")
- .append(getDateStr(info.getEndBucketElapsedNanos())).append("] -> ")
- .append(info.getDurationNanos()).append(" ns\n");
- }
- }
- }
-
- public static void displayEventMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- sb.append("Contains ").append(log.getEventMetrics().getDataCount()).append(" events\n");
- StatsLog.StatsLogReport.EventMetricDataWrapper eventMetricDataWrapper =
- log.getEventMetrics();
- for (StatsLog.EventMetricData event : eventMetricDataWrapper.getDataList()) {
- sb.append(getDateStr(event.getElapsedTimestampNanos())).append(": ");
- sb.append(event.getAtom().getPushedCase().toString()).append("\n");
- }
- }
-
- public static void displayCountMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- StatsLog.StatsLogReport.CountMetricDataWrapper countMetricDataWrapper
- = log.getCountMetrics();
- sb.append("Dimension size: ").append(countMetricDataWrapper.getDataCount()).append("\n");
- for (StatsLog.CountMetricData count : countMetricDataWrapper.getDataList()) {
- sb.append("dimension_in_what: ");
- displayDimension(sb, count.getDimensionsInWhat());
- sb.append("\n");
- if (count.hasDimensionsInCondition()) {
- sb.append("dimension_in_condition: ");
- displayDimension(sb, count.getDimensionsInCondition());
- sb.append("\n");
- }
-
- for (StatsLog.CountBucketInfo info : count.getBucketInfoList()) {
- sb.append("\t[").append(getDateStr(info.getStartBucketElapsedNanos())).append("-")
- .append(getDateStr(info.getEndBucketElapsedNanos())).append("] -> ")
- .append(info.getCount()).append("\n");
- }
- }
- }
-
- public static void displayGaugeMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- sb.append("Display me!");
- }
-
- public static void displayValueMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- sb.append("Display me!");
- }
-}
diff --git a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java b/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
deleted file mode 100644
index 4f4dd011e419..000000000000
--- a/cmds/statsd/tools/dogfood/src/com/android/statsd/dogfood/MainActivity.java
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.dogfood;
-
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.app.IntentService;
-import android.app.StatsManager;
-import android.app.StatsManager.StatsUnavailableException;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.util.Log;
-import android.util.StatsLog;
-import android.view.View;
-import android.widget.TextView;
-import android.widget.Toast;
-import android.os.IStatsManager;
-import android.os.ServiceManager;
-
-import java.io.InputStream;
-
-import static com.android.statsd.dogfood.DisplayProtoUtils.displayLogReport;
-
-public class MainActivity extends Activity {
- private final static String TAG = "StatsdDogfood";
- private final static long CONFIG_ID = 987654321;
-
- final int[] mUids = {11111111, 2222222};
- StatsManager mStatsManager;
- TextView mReportText;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- setContentView(R.layout.activity_main);
-
- findViewById(R.id.app_a_wake_lock_acquire1).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockAcquire(0, "wl_1");
- }
- });
-
- findViewById(R.id.app_b_wake_lock_acquire1).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockAcquire(1, "wl_1");
- }
- });
-
- findViewById(R.id.app_a_wake_lock_acquire2).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockAcquire(0, "wl_2");
- }
- });
-
- findViewById(R.id.app_b_wake_lock_acquire2).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockAcquire(1, "wl_2");
- }
- });
-
- findViewById(R.id.app_a_wake_lock_release1).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockRelease(0, "wl_1");
- }
- });
-
-
- findViewById(R.id.app_b_wake_lock_release1).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockRelease(1, "wl_1");
- }
- });
-
- findViewById(R.id.app_a_wake_lock_release2).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockRelease(0, "wl_2");
- }
- });
-
-
- findViewById(R.id.app_b_wake_lock_release2).setOnClickListener(
- new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- onWakeLockRelease(1, "wl_2");
- }
- });
-
-
- findViewById(R.id.plug).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED,
- StatsLog.PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_AC);
- }
- });
-
- findViewById(R.id.unplug).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED,
- StatsLog.PLUGGED_STATE_CHANGED__STATE__BATTERY_PLUGGED_NONE);
- }
- });
-
- findViewById(R.id.screen_on).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON);
- }
- });
-
- findViewById(R.id.screen_off).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF);
- }
- });
-
- findViewById(R.id.custom_start).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- StatsLog.logStart(8);
- }
- });
-
- findViewById(R.id.custom_stop).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- StatsLog.logStop(8);
- }
- });
-
- mReportText = (TextView) findViewById(R.id.report_text);
-
- findViewById(R.id.dump).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (!statsdRunning()) {
- return;
- }
- if (mStatsManager != null) {
- try {
- byte[] data = mStatsManager.getReports(CONFIG_ID);
- if (data != null) {
- displayData(data);
- return;
- }
- } catch (StatsUnavailableException e) {
- Log.e(TAG, "Failed to get data from statsd", e);
- }
- mReportText.setText("Failed!");
- }
- }
- });
-
- findViewById(R.id.push_config).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- try {
- if (!statsdRunning()) {
- return;
- }
- Resources res = getResources();
- InputStream inputStream = res.openRawResource(R.raw.statsd_baseline_config);
-
- byte[] config = new byte[inputStream.available()];
- inputStream.read(config);
- if (mStatsManager != null) {
- try {
- mStatsManager.addConfig(CONFIG_ID, config);
- Toast.makeText(
- MainActivity.this, "Config pushed", Toast.LENGTH_LONG).show();
- } catch (StatsUnavailableException | IllegalArgumentException e) {
- Toast.makeText(MainActivity.this, "Config push FAILED!",
- Toast.LENGTH_LONG).show();
- }
- }
- } catch (Exception e) {
- Toast.makeText(MainActivity.this, "failed to read config", Toast.LENGTH_LONG);
- }
- }
- });
-
- PendingIntent pi = PendingIntent.getService(this, 0,
- new Intent(this, ReceiverIntentService.class), PendingIntent.FLAG_UPDATE_CURRENT);
- findViewById(R.id.set_receiver).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- try {
- if (!statsdRunning()) {
- return;
- }
- if (mStatsManager != null) {
- try {
- mStatsManager.setFetchReportsOperation(pi, CONFIG_ID);
- Toast.makeText(MainActivity.this,
- "Receiver specified to pending intent", Toast.LENGTH_LONG)
- .show();
- } catch (StatsUnavailableException e) {
- Toast.makeText(MainActivity.this, "Statsd did not set receiver",
- Toast.LENGTH_LONG)
- .show();
- }
- }
- } catch (Exception e) {
- Toast.makeText(MainActivity.this, "failed to set receiver", Toast.LENGTH_LONG);
- }
- }
- });
- findViewById(R.id.remove_receiver).setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- try {
- if (!statsdRunning()) {
- return;
- }
- if (mStatsManager != null) {
- try {
- mStatsManager.setFetchReportsOperation(null, CONFIG_ID);
- Toast.makeText(MainActivity.this, "Receiver remove", Toast.LENGTH_LONG)
- .show();
- } catch (StatsUnavailableException e) {
- Toast.makeText(MainActivity.this, "Statsd did not remove receiver",
- Toast.LENGTH_LONG)
- .show();
- }
- }
- } catch (Exception e) {
- Toast.makeText(
- MainActivity.this, "failed to remove receiver", Toast.LENGTH_LONG);
- }
- }
- });
- mStatsManager = (StatsManager) getSystemService("stats");
- }
-
- private boolean statsdRunning() {
- if (IStatsManager.Stub.asInterface(ServiceManager.getService("stats")) == null) {
- Log.d(TAG, "Statsd not running");
- Toast.makeText(MainActivity.this, "Statsd NOT running!", Toast.LENGTH_LONG).show();
- return false;
- }
- return true;
- }
-
- @Override
- public void onNewIntent(Intent intent) {
- Log.d(TAG, "new intent: " + intent.getIntExtra("pkg", 0));
- int pkg = intent.getIntExtra("pkg", 0);
- String name = intent.getStringExtra("name");
- if (intent.hasExtra("acquire")) {
- onWakeLockAcquire(pkg, name);
- } else if (intent.hasExtra("release")) {
- onWakeLockRelease(pkg, name);
- }
- }
-
- private void displayData(byte[] data) {
- com.android.os.StatsLog.ConfigMetricsReportList reports = null;
- boolean good = false;
- if (data != null) {
- try {
- reports = com.android.os.StatsLog.ConfigMetricsReportList.parseFrom(data);
- good = true;
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- // display it in the text view.
- }
- }
- int size = data == null ? 0 : data.length;
- StringBuilder sb = new StringBuilder();
- sb.append(good ? "Proto parsing OK!" : "Proto parsing Error!");
- sb.append(" size:").append(size).append("\n");
-
- if (good && reports != null) {
- displayLogReport(sb, reports);
- mReportText.setText(sb.toString());
- }
- }
-
-
- private void onWakeLockAcquire(int id, String name) {
- if (id > 1) {
- Log.d(TAG, "invalid pkg id");
- return;
- }
- int[] uids = new int[]{mUids[id]};
- String[] tags = new String[]{"acquire"};
- StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
- StatsLog.WAKELOCK_STATE_CHANGED__TYPE__PARTIAL_WAKE_LOCK, name,
- StatsLog.WAKELOCK_STATE_CHANGED__STATE__ACQUIRE);
- StringBuilder sb = new StringBuilder();
- sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
- .append(", ").append(name).append(", 1);");
- Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
- }
-
- private void onWakeLockRelease(int id, String name) {
- if (id > 1) {
- Log.d(TAG, "invalid pkg id");
- return;
- }
- int[] uids = new int[]{mUids[id]};
- String[] tags = new String[]{"release"};
- StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, uids, tags,
- StatsLog.WAKELOCK_STATE_CHANGED__TYPE__PARTIAL_WAKE_LOCK, name,
- StatsLog.WAKELOCK_STATE_CHANGED__STATE__RELEASE);
- StringBuilder sb = new StringBuilder();
- sb.append("StagsLog.write(10, ").append(mUids[id]).append(", ").append(0)
- .append(", ").append(name).append(", 0);");
- Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
- }
-
- public static class ReceiverIntentService extends IntentService {
- public ReceiverIntentService() {
- super("ReceiverIntentService");
- }
-
- /**
- * The IntentService calls this method from the default worker thread with
- * the intent that started the service. When this method returns, IntentService
- * stops the service, as appropriate.
- */
- @Override
- protected void onHandleIntent(Intent intent) {
- Log.i(TAG, "Received notification that we should call getData");
- }
- }
-}
diff --git a/cmds/statsd/tools/loadtest/Android.bp b/cmds/statsd/tools/loadtest/Android.bp
deleted file mode 100644
index bf87fc51dce1..000000000000
--- a/cmds/statsd/tools/loadtest/Android.bp
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//
-//
-
-android_app {
- name: "StatsdLoadtest",
- platform_apis: true,
-
- srcs: ["src/**/*.java"],
-
- resource_dirs: ["res"],
- static_libs: [
- "platformprotoslite",
- "statsdprotolite",
- ],
-
- certificate: "platform",
- privileged: true,
- dex_preopt: {
- enabled: false,
- },
- optimize: {
- enabled: false,
- },
-}
diff --git a/cmds/statsd/tools/loadtest/AndroidManifest.xml b/cmds/statsd/tools/loadtest/AndroidManifest.xml
deleted file mode 100644
index 2bf8ca95d846..000000000000
--- a/cmds/statsd/tools/loadtest/AndroidManifest.xml
+++ /dev/null
@@ -1,44 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2007, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-** http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.statsd.loadtest"
- android:sharedUserId="android.uid.system"
- android:versionCode="1"
- android:versionName="1.0" >
-
- <uses-permission android:name="android.permission.DUMP" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name" >
- <activity
- android:name=".LoadtestActivity"
- android:label="@string/app_name"
- android:launchMode="singleTop" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <receiver android:name=".LoadtestActivity$PusherAlarmReceiver" />
- <receiver android:name=".LoadtestActivity$StopperAlarmReceiver"/>
- <receiver android:name=".PerfData$PerfAlarmReceiver"/>
- </application>
-</manifest>
diff --git a/cmds/statsd/tools/loadtest/res/drawable-hdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-hdpi/ic_launcher.png
deleted file mode 100644
index 55621cc1074f..000000000000
--- a/cmds/statsd/tools/loadtest/res/drawable-hdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/drawable-mdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-mdpi/ic_launcher.png
deleted file mode 100644
index 11ec2068be19..000000000000
--- a/cmds/statsd/tools/loadtest/res/drawable-mdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/drawable-xhdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-xhdpi/ic_launcher.png
deleted file mode 100644
index 7c02b784aa5d..000000000000
--- a/cmds/statsd/tools/loadtest/res/drawable-xhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/drawable-xxhdpi/ic_launcher.png b/cmds/statsd/tools/loadtest/res/drawable-xxhdpi/ic_launcher.png
deleted file mode 100644
index 915d91441349..000000000000
--- a/cmds/statsd/tools/loadtest/res/drawable-xxhdpi/ic_launcher.png
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml b/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml
deleted file mode 100644
index d6f804734385..000000000000
--- a/cmds/statsd/tools/loadtest/res/layout/activity_loadtest.xml
+++ /dev/null
@@ -1,208 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2007, 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.
-*/
--->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent" >
-
- <LinearLayout
- android:id="@+id/outside"
- android:clickable="true"
- android:focusable="true"
- android:focusableInTouchMode="true"
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_marginRight="10dp"
- android:layout_marginLeft="10dp"
- android:orientation="vertical">
- <requestFocus />
-
- <LinearLayout
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <TextView
- android:textSize="30dp"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/replication_label" />
- <EditText
- android:id="@+id/replication"
- android:inputType="number"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLength="4"
- android:text="@integer/replication_default"
- android:textSize="30dp"/>
- </LinearLayout>
-
- <LinearLayout
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <TextView
- android:textSize="30dp"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/bucket_label" />
- <Spinner
- android:id="@+id/bucket_spinner"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:prompt="@string/bucket_label"/>
- </LinearLayout>
-
- <LinearLayout
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <TextView
- android:textSize="30dp"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/period_label" />
- <EditText
- android:id="@+id/period"
- android:inputType="number"
- android:layout_weight="1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:maxLength="3"
- android:text="@integer/period_default"
- android:textSize="30dp"/>
- </LinearLayout>
-
- <LinearLayout
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <TextView
- android:textSize="30dp"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/burst_label" />
- <EditText
- android:id="@+id/burst"
- android:inputType="number"
- android:layout_weight="1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:maxLength="4"
- android:text="@integer/burst_default"
- android:textSize="30dp"/>
- </LinearLayout>
-
- <LinearLayout
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="horizontal">
- <TextView
- android:textSize="30dp"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:text="@string/duration_label" />
- <EditText
- android:id="@+id/duration"
- android:inputType="number"
- android:layout_weight="1"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:maxLength="4"
- android:text="@integer/duration_default"
- android:textSize="30dp"/>
- </LinearLayout>
- <CheckBox
- android:id="@+id/placebo"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/placebo"
- android:checked="false" />
-
- <LinearLayout
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal">
- <CheckBox
- android:id="@+id/include_count"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/count"
- android:checked="true"/>
- <CheckBox
- android:id="@+id/include_duration"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/duration"
- android:checked="true"/>
- <CheckBox
- android:id="@+id/include_event"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/event"
- android:checked="true"/>
- <CheckBox
- android:id="@+id/include_value"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/value"
- android:checked="true"/>
- <CheckBox
- android:id="@+id/include_gauge"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="@string/gauge"
- android:checked="true"/>
- </LinearLayout>
-
- <Space
- android:layout_width="1dp"
- android:layout_height="30dp"/>
-
- <Button
- android:id="@+id/start_stop"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:background="#ffff0000"
- android:text="@string/start"
- android:textSize="50dp"/>
-
- <Space
- android:layout_width="1dp"
- android:layout_height="30dp"/>
-
- <Space
- android:layout_width="1dp"
- android:layout_height="30dp"/>
-
- <TextView
- android:id="@+id/report_text"
- android:gravity="center"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
-
- </LinearLayout>
-
-</ScrollView>
diff --git a/cmds/statsd/tools/loadtest/res/layout/spinner_item.xml b/cmds/statsd/tools/loadtest/res/layout/spinner_item.xml
deleted file mode 100644
index b03da06f7a77..000000000000
--- a/cmds/statsd/tools/loadtest/res/layout/spinner_item.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<TextView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:textSize="30dp"
- android:gravity="left"
- android:padding="5dip"
- />
diff --git a/cmds/statsd/tools/loadtest/res/raw/loadtest_config b/cmds/statsd/tools/loadtest/res/raw/loadtest_config
deleted file mode 100755
index 24221908cbeb..000000000000
--- a/cmds/statsd/tools/loadtest/res/raw/loadtest_config
+++ /dev/null
Binary files differ
diff --git a/cmds/statsd/tools/loadtest/res/values/integers.xml b/cmds/statsd/tools/loadtest/res/values/integers.xml
deleted file mode 100644
index c2407d3b85f2..000000000000
--- a/cmds/statsd/tools/loadtest/res/values/integers.xml
+++ /dev/null
@@ -1,24 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2007, 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>
- <integer name="burst_default">1</integer>
- <integer name="period_default">2</integer>
- <integer name="replication_default">1</integer>
- <integer name="duration_default">240</integer>
-</resources>
diff --git a/cmds/statsd/tools/loadtest/res/values/strings.xml b/cmds/statsd/tools/loadtest/res/values/strings.xml
deleted file mode 100644
index e8ae3f82a7e3..000000000000
--- a/cmds/statsd/tools/loadtest/res/values/strings.xml
+++ /dev/null
@@ -1,36 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2007, 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>
- <string name="app_name">Statsd Loadtest</string>
- <string name="bucket_label">bucket size (mins):&#160;</string>
- <string name="burst_label">burst:&#160;</string>
- <string name="bucket_default">FIVE_MINUTES</string>
- <string name="placebo">placebo</string>
- <string name="period_label">logging period (secs):&#160;</string>
- <string name="replication_label">metric replication:&#160;</string>
- <string name="duration_label">test duration (mins):&#160;</string>
- <string name="start"> &#160;Start&#160; </string>
- <string name="stop"> &#160;Stop&#160; </string>
- <string name="count"> count </string>
- <string name="duration"> duration </string>
- <string name="event"> event </string>
- <string name="value"> value </string>
- <string name="gauge"> gauge </string>
-
-</resources>
diff --git a/cmds/statsd/tools/loadtest/run_loadtest.sh b/cmds/statsd/tools/loadtest/run_loadtest.sh
deleted file mode 100755
index 3c93a0613183..000000000000
--- a/cmds/statsd/tools/loadtest/run_loadtest.sh
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/bin/sh
-#
-# Script that measures statsd's PSS under an increasing number of metrics.
-
-# Globals.
-pss=""
-pid=""
-
-# Starts the loadtest.
-start_loadtest() {
- echo "Starting loadtest"
- adb shell am start -n com.android.statsd.loadtest/.LoadtestActivity --es "type" "start"
-}
-
-# Stops the loadtest.
-stop_loadtest() {
- echo "Stopping loadtest"
- adb shell am start -n com.android.statsd.loadtest/.LoadtestActivity --es "type" "stop"
-}
-
-# Sets the metrics replication.
-# Arguments:
-# $1: The replication factor.
-set_replication() {
- adb shell am start -n com.android.statsd.loadtest/.LoadtestActivity --es "type" "set_replication" --ei "replication" "${1}"
- echo "Replication set to ${1}"
-}
-
-# Reads statsd's pid and PSS.
-update_pid_and_pss() {
- # Command that reads the PSS for statsd. This also gives us its pid.
- get_mem=$(adb shell dumpsys meminfo |grep statsd)
- # Looks for statsd's pid.
- regex="([0-9,]+)K: statsd \(pid ([0-9]+)\).*"
- if [[ $get_mem =~ $regex ]]; then
- pss=$(echo "${BASH_REMATCH[1]}" | tr -d , | sed 's/\.//g')
- pid=$(echo "${BASH_REMATCH[2]}")
- else
- echo $cmd doesnt match $regex
- fi
-}
-
-# Kills statsd.
-# Assumes the pid has been set.
-kill_statsd() {
- echo "Killing statsd (pid ${pid})"
- adb shell kill -9 "${pid}"
-}
-
-# Main loop.
-main() {
- start_time=$(date +%s)
- values=()
- stop_loadtest
-
- echo ""
- echo "********************* NEW LOADTEST ************************"
- update_pid_and_pss
- for replication in 1 2 4 8 16 32 64 128 256 512 1024 2048 4096
- do
- echo "**** Starting test at replication ${replication} ****"
-
- # (1) Restart statsd. This will ensure its state is empty.
- kill_statsd
- sleep 3 # wait a bit for it to restart
- update_pid_and_pss
- echo "Before the test, statsd's PSS is ${pss}"
-
- # (2) Set the replication.
- set_replication "${replication}"
- sleep 1 # wait a bit
-
- # (3) Start the loadtest.
- start_loadtest
-
- # (4) Wait several seconds, then read the PSS.
- sleep 100 && update_pid_and_pss
- echo "During the test, statsd's PSS is ${pss}"
- values+=(${pss})
-
- echo "Values: ${values[@]}"
-
- # (5) Stop loadtest.
- stop_loadtest
- sleep 2
-
- echo ""
- done
-
- end_time=$(date +%s)
- echo "Completed loadtest in $((${end_time} - ${start_time})) seconds."
-
- values_as_str=$(IFS=$'\n'; echo "${values[*]}")
- echo "The PSS values are:"
- echo "${values_as_str}"
- echo ""
-}
-
-main
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryDataRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryDataRecorder.java
deleted file mode 100644
index bab0c1e3f540..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryDataRecorder.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.util.Log;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import java.text.ParseException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class BatteryDataRecorder extends PerfDataRecorder {
- private static final String TAG = "loadtest.BatteryDataRecorder";
- private static final String DUMP_FILENAME = TAG + "_dump.tmp";
-
- public BatteryDataRecorder(boolean placebo, int replication, TimeUnit bucket, long periodSecs,
- int burst, boolean includeCountMetric, boolean includeDurationMetric,
- boolean includeEventMetric, boolean includeValueMetric, boolean includeGaugeMetric) {
- super(placebo, replication, bucket, periodSecs, burst, includeCountMetric,
- includeDurationMetric, includeEventMetric, includeValueMetric, includeGaugeMetric);
- }
-
- @Override
- public void startRecording(Context context) {
- // Reset batterystats.
- runDumpsysStats(context, DUMP_FILENAME, "batterystats", "--reset");
- }
-
- @Override
- public void onAlarm(Context context) {
- // Nothing to do as for battery, the whole data is in the final dumpsys call.
- }
-
- @Override
- public void stopRecording(Context context) {
- StringBuilder sb = new StringBuilder();
- // Don't use --checkin.
- runDumpsysStats(context, DUMP_FILENAME, "batterystats");
- readDumpData(context, DUMP_FILENAME, new BatteryStatsParser(), sb);
- writeData(context, "battery_", "time,battery_level", sb);
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryStatsParser.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryStatsParser.java
deleted file mode 100644
index 203d97acefd8..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/BatteryStatsParser.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.annotation.Nullable;
-import android.util.Log;
-import java.text.ParseException;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class BatteryStatsParser implements PerfParser {
-
- private static final Pattern LINE_PATTERN =
- Pattern.compile("\\s*\\+*(\\S*)\\s\\(\\d+\\)\\s(\\d\\d\\d)\\s.*");
- private static final Pattern TIME_PATTERN =
- Pattern.compile("(\\d+)?(h)?(\\d+)?(m)?(\\d+)?(s)?(\\d+)?(ms)?");
- private static final String TAG = "loadtest.BatteryStatsParser";
-
- private boolean mHistoryStarted;
- private boolean mHistoryEnded;
-
- public BatteryStatsParser() {
- }
-
- @Override
- @Nullable
- public String parseLine(String line) {
- if (mHistoryEnded) {
- return null;
- }
- if (!mHistoryStarted) {
- if (line.contains("Battery History")) {
- mHistoryStarted = true;
- }
- return null;
- }
- if (line.isEmpty()) {
- mHistoryEnded = true;
- return null;
- }
- Matcher lineMatcher = LINE_PATTERN.matcher(line);
- if (lineMatcher.find() && lineMatcher.group(1) != null && lineMatcher.group(2) != null) {
- if (lineMatcher.group(1).equals("0")) {
- return "0," + lineMatcher.group(2) + "\n";
- } else {
- Matcher timeMatcher = TIME_PATTERN.matcher(lineMatcher.group(1));
- if (timeMatcher.find()) {
- Long time = getTime(lineMatcher.group(1));
- if (time != null) {
- return time + "," + lineMatcher.group(2) + "\n";
- } else {
- return null; // bad time
- }
- } else {
- return null; // bad or no time
- }
- }
- }
- return null;
- }
-
- @Nullable
- private Long getTime(String group) {
- if ("0".equals(group)) {
- return 0L;
- }
- Matcher timeMatcher = TIME_PATTERN.matcher(group);
- if (!timeMatcher.find()) {
- return null;
- }
-
- // Get rid of "ms".
- String[] matches = group.split("ms", -1);
- if (matches.length > 1) {
- group = matches[0];
- }
-
- long time = 0L;
- matches = group.split("h");
- if (matches.length > 1) {
- time += Long.parseLong(matches[0]) * 60 * 60 * 1000; // hours
- group = matches[1];
- }
- matches = group.split("m");
- if (matches.length > 1) {
- time += Long.parseLong(matches[0]) * 60 * 1000; // minutes
- group = matches[1];
- }
- matches = group.split("s");
- if (matches.length > 1) {
- time += Long.parseLong(matches[0]) * 1000; // seconds
- group = matches[1];
- }
-
- if (!group.isEmpty()) {
- time += Long.parseLong(group); // milliseconds
- }
- return time;
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ConfigFactory.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ConfigFactory.java
deleted file mode 100644
index 2e0161be8096..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ConfigFactory.java
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import com.android.internal.os.StatsdConfigProto.Predicate;
-import com.android.internal.os.StatsdConfigProto.CountMetric;
-import com.android.internal.os.StatsdConfigProto.DurationMetric;
-import com.android.internal.os.StatsdConfigProto.MetricConditionLink;
-import com.android.internal.os.StatsdConfigProto.EventMetric;
-import com.android.internal.os.StatsdConfigProto.GaugeMetric;
-import com.android.internal.os.StatsdConfigProto.ValueMetric;
-import com.android.internal.os.StatsdConfigProto.FieldValueMatcher;
-import com.android.internal.os.StatsdConfigProto.AtomMatcher;
-import com.android.internal.os.StatsdConfigProto.SimplePredicate;
-import com.android.internal.os.StatsdConfigProto.StatsdConfig;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Creates StatsdConfig protos for loadtesting.
- */
-public class ConfigFactory {
- public static class ConfigMetadata {
- public final byte[] bytes;
- public final int numMetrics;
-
- public ConfigMetadata(byte[] bytes, int numMetrics) {
- this.bytes = bytes;
- this.numMetrics = numMetrics;
- }
- }
-
- public static final long CONFIG_ID = 123456789;
-
- private static final String TAG = "loadtest.ConfigFactory";
-
- private final StatsdConfig mTemplate;
-
- public ConfigFactory(Context context) {
- // Read the config template from the resoures.
- Resources res = context.getResources();
- byte[] template = null;
- StatsdConfig templateProto = null;
- try {
- InputStream inputStream = res.openRawResource(R.raw.loadtest_config);
- template = new byte[inputStream.available()];
- inputStream.read(template);
- templateProto = StatsdConfig.parseFrom(template);
- } catch (IOException e) {
- Log.e(TAG, "Unable to read or parse loadtest config template. Using an empty config.");
- }
- mTemplate = templateProto == null ? StatsdConfig.newBuilder().build() : templateProto;
-
- Log.d(TAG, "Loadtest template config: " + mTemplate);
- }
-
- /**
- * Generates a config.
- *
- * All configs are based on the same template.
- * That template is designed to make the most use of the set of atoms that {@code SequencePusher}
- * pushes, and to exercise as many of the metrics features as possible.
- * Furthermore, by passing a replication factor to this method, one can artificially inflate
- * the number of metrics in the config. One can also adjust the bucket size for aggregate
- * metrics.
- *
- * @param replication The number of times each metric is replicated in the config.
- * If the config template has n metrics, the generated config will have n * replication
- * ones
- * @param bucketMillis The bucket size, in milliseconds, for aggregate metrics
- * @param placebo If true, only return an empty config
- * @return The serialized config and the number of metrics.
- */
- public ConfigMetadata getConfig(int replication, TimeUnit bucket, boolean placebo,
- boolean includeCount, boolean includeDuration, boolean includeEvent,
- boolean includeValue, boolean includeGauge) {
- StatsdConfig.Builder config = StatsdConfig.newBuilder()
- .setId(CONFIG_ID);
- if (placebo) {
- replication = 0; // Config will be empty, aside from a name.
- }
- int numMetrics = 0;
- for (int i = 0; i < replication; i++) {
- // metrics
- if (includeEvent) {
- for (EventMetric metric : mTemplate.getEventMetricList()) {
- addEventMetric(metric, i, config);
- numMetrics++;
- }
- }
- if (includeCount) {
- for (CountMetric metric : mTemplate.getCountMetricList()) {
- addCountMetric(metric, i, bucket, config);
- numMetrics++;
- }
- }
- if (includeDuration) {
- for (DurationMetric metric : mTemplate.getDurationMetricList()) {
- addDurationMetric(metric, i, bucket, config);
- numMetrics++;
- }
- }
- if (includeGauge) {
- for (GaugeMetric metric : mTemplate.getGaugeMetricList()) {
- addGaugeMetric(metric, i, bucket, config);
- numMetrics++;
- }
- }
- if (includeValue) {
- for (ValueMetric metric : mTemplate.getValueMetricList()) {
- addValueMetric(metric, i, bucket, config);
- numMetrics++;
- }
- }
- // predicates
- for (Predicate predicate : mTemplate.getPredicateList()) {
- addPredicate(predicate, i, config);
- }
- // matchers
- for (AtomMatcher matcher : mTemplate.getAtomMatcherList()) {
- addMatcher(matcher, i, config);
- }
- }
-
- Log.d(TAG, "Loadtest config is : " + config.build());
- Log.d(TAG, "Generated config has " + numMetrics + " metrics");
-
- return new ConfigMetadata(config.build().toByteArray(), numMetrics);
- }
-
- /**
- * Creates {@link MetricConditionLink}s that are identical to the one passed to this method,
- * except that the names are appended with the provided suffix.
- */
- private List<MetricConditionLink> getLinks(
- List<MetricConditionLink> links, int suffix) {
- List<MetricConditionLink> newLinks = new ArrayList();
- for (MetricConditionLink link : links) {
- newLinks.add(link.toBuilder()
- .setCondition(link.getCondition() + suffix)
- .build());
- }
- return newLinks;
- }
-
- /**
- * Creates an {@link EventMetric} based on the template. Makes sure that all names are appended
- * with the provided suffix. Then adds that metric to the config.
- */
- private void addEventMetric(EventMetric template, int suffix, StatsdConfig.Builder config) {
- EventMetric.Builder metric = template.toBuilder()
- .setId(template.getId() + suffix)
- .setWhat(template.getWhat() + suffix);
- if (template.hasCondition()) {
- metric.setCondition(template.getCondition() + suffix);
- }
- if (template.getLinksCount() > 0) {
- List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
- metric.clearLinks();
- metric.addAllLinks(links);
- }
- config.addEventMetric(metric);
- }
-
- /**
- * Creates a {@link CountMetric} based on the template. Makes sure that all names are appended
- * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
- */
- private void addCountMetric(CountMetric template, int suffix, TimeUnit bucket,
- StatsdConfig.Builder config) {
- CountMetric.Builder metric = template.toBuilder()
- .setId(template.getId() + suffix)
- .setWhat(template.getWhat() + suffix);
- if (template.hasCondition()) {
- metric.setCondition(template.getCondition() + suffix);
- }
- if (template.getLinksCount() > 0) {
- List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
- metric.clearLinks();
- metric.addAllLinks(links);
- }
- metric.setBucket(bucket);
- config.addCountMetric(metric);
- }
-
- /**
- * Creates a {@link DurationMetric} based on the template. Makes sure that all names are appended
- * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
- */
- private void addDurationMetric(DurationMetric template, int suffix, TimeUnit bucket,
- StatsdConfig.Builder config) {
- DurationMetric.Builder metric = template.toBuilder()
- .setId(template.getId() + suffix)
- .setWhat(template.getWhat() + suffix);
- if (template.hasCondition()) {
- metric.setCondition(template.getCondition() + suffix);
- }
- if (template.getLinksCount() > 0) {
- List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
- metric.clearLinks();
- metric.addAllLinks(links);
- }
- metric.setBucket(bucket);
- config.addDurationMetric(metric);
- }
-
- /**
- * Creates a {@link GaugeMetric} based on the template. Makes sure that all names are appended
- * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
- */
- private void addGaugeMetric(GaugeMetric template, int suffix, TimeUnit bucket,
- StatsdConfig.Builder config) {
- GaugeMetric.Builder metric = template.toBuilder()
- .setId(template.getId() + suffix)
- .setWhat(template.getWhat() + suffix);
- if (template.hasCondition()) {
- metric.setCondition(template.getCondition() + suffix);
- }
- if (template.getLinksCount() > 0) {
- List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
- metric.clearLinks();
- metric.addAllLinks(links);
- }
- metric.setBucket(bucket);
- config.addGaugeMetric(metric);
- }
-
- /**
- * Creates a {@link ValueMetric} based on the template. Makes sure that all names are appended
- * with the provided suffix, and overrides the bucket size. Then adds that metric to the config.
- */
- private void addValueMetric(ValueMetric template, int suffix, TimeUnit bucket,
- StatsdConfig.Builder config) {
- ValueMetric.Builder metric = template.toBuilder()
- .setId(template.getId() + suffix)
- .setWhat(template.getWhat() + suffix);
- if (template.hasCondition()) {
- metric.setCondition(template.getCondition() + suffix);
- }
- if (template.getLinksCount() > 0) {
- List<MetricConditionLink> links = getLinks(template.getLinksList(), suffix);
- metric.clearLinks();
- metric.addAllLinks(links);
- }
- metric.setBucket(bucket);
- config.addValueMetric(metric);
- }
-
- /**
- * Creates a {@link Predicate} based on the template. Makes sure that all names
- * are appended with the provided suffix. Then adds that predicate to the config.
- */
- private void addPredicate(Predicate template, int suffix, StatsdConfig.Builder config) {
- Predicate.Builder predicate = template.toBuilder()
- .setId(template.getId() + suffix);
- if (template.hasCombination()) {
- Predicate.Combination.Builder cb = template.getCombination().toBuilder()
- .clearPredicate();
- for (long child : template.getCombination().getPredicateList()) {
- cb.addPredicate(child + suffix);
- }
- predicate.setCombination(cb.build());
- }
- if (template.hasSimplePredicate()) {
- SimplePredicate.Builder sc = template.getSimplePredicate().toBuilder()
- .setStart(template.getSimplePredicate().getStart() + suffix)
- .setStop(template.getSimplePredicate().getStop() + suffix);
- if (template.getSimplePredicate().hasStopAll()) {
- sc.setStopAll(template.getSimplePredicate().getStopAll() + suffix);
- }
- predicate.setSimplePredicate(sc.build());
- }
- config.addPredicate(predicate);
- }
-
- /**
- * Creates a {@link AtomMatcher} based on the template. Makes sure that all names
- * are appended with the provided suffix. Then adds that matcher to the config.
- */
- private void addMatcher(AtomMatcher template, int suffix, StatsdConfig.Builder config) {
- AtomMatcher.Builder matcher = template.toBuilder()
- .setId(template.getId() + suffix);
- if (template.hasCombination()) {
- AtomMatcher.Combination.Builder cb = template.getCombination().toBuilder()
- .clearMatcher();
- for (long child : template.getCombination().getMatcherList()) {
- cb.addMatcher(child + suffix);
- }
- matcher.setCombination(cb);
- }
- config.addAtomMatcher(matcher);
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java
deleted file mode 100644
index d55f3f31fd9f..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/DisplayProtoUtils.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.text.format.DateFormat;
-
-import com.android.os.StatsLog;
-
-import java.util.List;
-
-public class DisplayProtoUtils {
- private static final int MAX_NUM_METRICS_TO_DISPLAY = 10;
-
- public static void displayLogReport(StringBuilder sb, StatsLog.ConfigMetricsReportList reports) {
- sb.append("******************** Report ********************\n");
- if (reports.hasConfigKey()) {
- sb.append("ConfigKey: ");
- com.android.os.StatsLog.ConfigMetricsReportList.ConfigKey key = reports.getConfigKey();
- sb.append("\tuid: ").append(key.getUid()).append(" id: ").append(key.getId())
- .append("\n");
- }
-
- int numMetrics = 0;
- for (StatsLog.ConfigMetricsReport report : reports.getReportsList()) {
- sb.append("StatsLogReport size: ").append(report.getMetricsCount()).append("\n");
- sb.append("Last report time:").append(getDateStr(report.getLastReportElapsedNanos())).
- append("\n");
- sb.append("Current report time:").append(getDateStr(report.getCurrentReportElapsedNanos())).
- append("\n");
- for (StatsLog.StatsLogReport log : report.getMetricsList()) {
- numMetrics++;
- if (numMetrics > MAX_NUM_METRICS_TO_DISPLAY) {
- sb.append("... output truncated\n");
- sb.append("************************************************");
- return;
- }
- sb.append("\n");
- sb.append("metric id: ").append(log.getMetricId()).append("\n");
-
- switch (log.getDataCase()) {
- case DURATION_METRICS:
- sb.append("Duration metric data\n");
- displayDurationMetricData(sb, log);
- break;
- case EVENT_METRICS:
- sb.append("Event metric data\n");
- displayEventMetricData(sb, log);
- break;
- case COUNT_METRICS:
- sb.append("Count metric data\n");
- displayCountMetricData(sb, log);
- break;
- case GAUGE_METRICS:
- sb.append("Gauge metric data\n");
- displayGaugeMetricData(sb, log);
- break;
- case VALUE_METRICS:
- sb.append("Value metric data\n");
- displayValueMetricData(sb, log);
- break;
- case DATA_NOT_SET:
- sb.append("No metric data\n");
- break;
- }
- }
- }
- sb.append("************************************************");
- }
-
- public static String getDateStr(long nanoSec) {
- return DateFormat.format("dd/MM hh:mm:ss", nanoSec/1000000).toString();
- }
-
- private static void displayDimension(StringBuilder sb, StatsLog.DimensionsValue dimensionValue) {
- sb.append(dimensionValue.getField()).append(":");
- if (dimensionValue.hasValueBool()) {
- sb.append(dimensionValue.getValueBool());
- } else if (dimensionValue.hasValueFloat()) {
- sb.append(dimensionValue.getValueFloat());
- } else if (dimensionValue.hasValueInt()) {
- sb.append(dimensionValue.getValueInt());
- } else if (dimensionValue.hasValueStr()) {
- sb.append(dimensionValue.getValueStr());
- } else if (dimensionValue.hasValueTuple()) {
- sb.append("{");
- for (StatsLog.DimensionsValue child :
- dimensionValue.getValueTuple().getDimensionsValueList()) {
- displayDimension(sb, child);
- }
- sb.append("}");
- }
- sb.append(" ");
- }
-
- public static void displayDurationMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- StatsLog.StatsLogReport.DurationMetricDataWrapper durationMetricDataWrapper
- = log.getDurationMetrics();
- sb.append("Dimension size: ").append(durationMetricDataWrapper.getDataCount()).append("\n");
- for (StatsLog.DurationMetricData duration : durationMetricDataWrapper.getDataList()) {
- sb.append("dimension_in_what: ");
- displayDimension(sb, duration.getDimensionsInWhat());
- sb.append("\n");
- if (duration.hasDimensionsInCondition()) {
- sb.append("dimension_in_condition: ");
- displayDimension(sb, duration.getDimensionsInCondition());
- sb.append("\n");
- }
-
- for (StatsLog.DurationBucketInfo info : duration.getBucketInfoList()) {
- sb.append("\t[").append(getDateStr(info.getStartBucketElapsedNanos())).append("-")
- .append(getDateStr(info.getEndBucketElapsedNanos())).append("] -> ")
- .append(info.getDurationNanos()).append(" ns\n");
- }
- }
- }
-
- public static void displayEventMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- sb.append("Contains ").append(log.getEventMetrics().getDataCount()).append(" events\n");
- StatsLog.StatsLogReport.EventMetricDataWrapper eventMetricDataWrapper =
- log.getEventMetrics();
- for (StatsLog.EventMetricData event : eventMetricDataWrapper.getDataList()) {
- sb.append(getDateStr(event.getElapsedTimestampNanos())).append(": ");
- sb.append(event.getAtom().getPushedCase().toString()).append("\n");
- }
- }
-
- public static void displayCountMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- StatsLog.StatsLogReport.CountMetricDataWrapper countMetricDataWrapper
- = log.getCountMetrics();
- sb.append("Dimension size: ").append(countMetricDataWrapper.getDataCount()).append("\n");
- for (StatsLog.CountMetricData count : countMetricDataWrapper.getDataList()) {
- sb.append("dimension_in_what: ");
- displayDimension(sb, count.getDimensionsInWhat());
- sb.append("\n");
- if (count.hasDimensionsInCondition()) {
- sb.append("dimension_in_condition: ");
- displayDimension(sb, count.getDimensionsInCondition());
- sb.append("\n");
- }
-
- for (StatsLog.CountBucketInfo info : count.getBucketInfoList()) {
- sb.append("\t[").append(getDateStr(info.getStartBucketElapsedNanos())).append("-")
- .append(getDateStr(info.getEndBucketElapsedNanos())).append("] -> ")
- .append(info.getCount()).append("\n");
- }
- }
- }
-
- public static void displayGaugeMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- sb.append("Display me!");
- }
-
- public static void displayValueMetricData(StringBuilder sb, StatsLog.StatsLogReport log) {
- sb.append("Display me!");
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java
deleted file mode 100644
index 769f78c726e8..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/LoadtestActivity.java
+++ /dev/null
@@ -1,756 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.annotation.Nullable;
-import android.app.Activity;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.app.StatsManager;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.graphics.Color;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IStatsManager;
-import android.os.PowerManager;
-import android.os.PowerManager.WakeLock;
-import android.os.ServiceManager;
-import android.os.SystemClock;
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.util.StatsLog;
-import android.view.View;
-import android.view.inputmethod.InputMethodManager;
-import android.view.MotionEvent;
-import android.view.View.OnFocusChangeListener;
-import android.widget.AdapterView;
-import android.widget.ArrayAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.EditText;
-import android.widget.Spinner;
-import android.widget.TextView;
-import android.widget.Toast;
-
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.ConfigMetricsReportList;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Runs a load test for statsd.
- * How it works:
- * <ul>
- * <li> Sets up and pushes a custom config with metrics that exercise a large swath of code paths.
- * <li> Periodically logs certain atoms into logd.
- * <li> Impact on battery can be printed to logcat, or a bug report can be filed and analyzed
- * in battery Historian.
- * </ul>
- * The load depends on how demanding the config is, as well as how frequently atoms are pushsed
- * to logd. Those are all controlled by 4 adjustable parameters:
- * <ul>
- * <li> The 'replication' parameter artificially multiplies the number of metrics in the config.
- * <li> The bucket size controls the time-bucketing the aggregate metrics.
- * <li> The period parameter controls how frequently atoms are pushed to logd.
- * <li> The 'burst' parameter controls how many atoms are pushed at the same time (per period).
- * </ul>
- */
-public class LoadtestActivity extends Activity implements AdapterView.OnItemSelectedListener {
-
- private static final String TAG = "loadtest.LoadtestActivity";
- public static final String TYPE = "type";
- private static final String PUSH_ALARM = "push_alarm";
- public static final String PERF_ALARM = "perf_alarm";
- private static final String SET_REPLICATION = "set_replication";
- private static final String REPLICATION = "replication";
- private static final String START = "start";
- private static final String STOP = "stop";
- private static final Map<String, TimeUnit> TIME_UNIT_MAP = initializeTimeUnitMap();
- private static final List<String> TIME_UNIT_LABELS = initializeTimeUnitLabels();
-
- public final static class PusherAlarmReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Intent activityIntent = new Intent(context, LoadtestActivity.class);
- activityIntent.putExtra(TYPE, PUSH_ALARM);
- context.startActivity(activityIntent);
- }
- }
-
- public final static class StopperAlarmReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Intent activityIntent = new Intent(context, LoadtestActivity.class);
- activityIntent.putExtra(TYPE, STOP);
- context.startActivity(activityIntent);
- }
- }
-
- private static Map<String, TimeUnit> initializeTimeUnitMap() {
- Map<String, TimeUnit> labels = new HashMap();
- labels.put("1m", TimeUnit.ONE_MINUTE);
- labels.put("5m", TimeUnit.FIVE_MINUTES);
- labels.put("10m", TimeUnit.TEN_MINUTES);
- labels.put("30m", TimeUnit.THIRTY_MINUTES);
- labels.put("1h", TimeUnit.ONE_HOUR);
- labels.put("3h", TimeUnit.THREE_HOURS);
- labels.put("6h", TimeUnit.SIX_HOURS);
- labels.put("12h", TimeUnit.TWELVE_HOURS);
- labels.put("1d", TimeUnit.ONE_DAY);
- labels.put("1s", TimeUnit.CTS);
- return labels;
- }
-
- private static List<String> initializeTimeUnitLabels() {
- List<String> labels = new ArrayList();
- labels.add("1s");
- labels.add("1m");
- labels.add("5m");
- labels.add("10m");
- labels.add("30m");
- labels.add("1h");
- labels.add("3h");
- labels.add("6h");
- labels.add("12h");
- labels.add("1d");
- return labels;
- }
-
- private AlarmManager mAlarmMgr;
-
- /**
- * Used to periodically log atoms to logd.
- */
- private PendingIntent mPushPendingIntent;
-
- /**
- * Used to end the loadtest.
- */
- private PendingIntent mStopPendingIntent;
-
- private Button mStartStop;
- private EditText mReplicationText;
- private Spinner mBucketSpinner;
- private EditText mPeriodText;
- private EditText mBurstText;
- private EditText mDurationText;
- private TextView mReportText;
- private CheckBox mPlaceboCheckBox;
- private CheckBox mCountMetricCheckBox;
- private CheckBox mDurationMetricCheckBox;
- private CheckBox mEventMetricCheckBox;
- private CheckBox mValueMetricCheckBox;
- private CheckBox mGaugeMetricCheckBox;
-
- /**
- * When the load test started.
- */
- private long mStartedTimeMillis;
-
- /**
- * For measuring perf data.
- */
- private PerfData mPerfData;
-
- /**
- * For communicating with statsd.
- */
- private StatsManager mStatsManager;
-
- private PowerManager mPowerManager;
- private WakeLock mWakeLock;
-
- /**
- * If true, we only measure the effect of the loadtest infrastructure. No atom are pushed and
- * the configuration is empty.
- */
- private boolean mPlacebo;
-
- /**
- * Whether to include CountMetric in the config.
- */
- private boolean mIncludeCountMetric;
-
- /**
- * Whether to include DurationMetric in the config.
- */
- private boolean mIncludeDurationMetric;
-
- /**
- * Whether to include EventMetric in the config.
- */
- private boolean mIncludeEventMetric;
-
- /**
- * Whether to include ValueMetric in the config.
- */
- private boolean mIncludeValueMetric;
-
- /**
- * Whether to include GaugeMetric in the config.
- */
- private boolean mIncludeGaugeMetric;
-
- /**
- * The burst size.
- */
- private int mBurst;
-
- /**
- * The metrics replication.
- */
- private int mReplication;
-
- /**
- * The period, in seconds, at which batches of atoms are pushed.
- */
- private long mPeriodSecs;
-
- /**
- * The bucket size, in minutes, for aggregate metrics.
- */
- private TimeUnit mBucket;
-
- /**
- * The duration, in minutes, of the loadtest.
- */
- private long mDurationMins;
-
- /**
- * Whether the loadtest has started.
- */
- private boolean mStarted = false;
-
- /**
- * Orchestrates the logging of pushed events into logd.
- */
- private SequencePusher mPusher;
-
- /**
- * Generates statsd configs.
- */
- private ConfigFactory mFactory;
-
- /**
- * For intra-minute periods.
- */
- private final Handler mHandler = new Handler();
-
- /**
- * Number of metrics in the current config.
- */
- private int mNumMetrics;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- Log.d(TAG, "Starting loadtest Activity");
-
- setContentView(R.layout.activity_loadtest);
- mReportText = (TextView) findViewById(R.id.report_text);
- initBurst();
- initReplication();
- initBucket();
- initPeriod();
- initDuration();
- initPlacebo();
- initMetricWhitelist();
-
- // Hide the keyboard outside edit texts.
- findViewById(R.id.outside).setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- InputMethodManager imm =
- (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
- if (getCurrentFocus() != null) {
- imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
- }
- return true;
- }
- });
-
- mStartStop = findViewById(R.id.start_stop);
- mStartStop.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- if (mStarted) {
- stopLoadtest();
- } else {
- startLoadtest();
- }
- }
- });
-
- mAlarmMgr = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
- mStatsManager = (StatsManager) getSystemService("stats");
- mPowerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
- mFactory = new ConfigFactory(this);
- stopLoadtest();
- mReportText.setText("");
- }
-
- @Override
- public void onNewIntent(Intent intent) {
- String type = intent.getStringExtra(TYPE);
- if (type == null) {
- return;
- }
- switch (type) {
- case PERF_ALARM:
- onPerfAlarm();
- break;
- case PUSH_ALARM:
- onAlarm();
- break;
- case SET_REPLICATION:
- if (intent.hasExtra(REPLICATION)) {
- setReplication(intent.getIntExtra(REPLICATION, 0));
- }
- break;
- case START:
- startLoadtest();
- break;
- case STOP:
- stopLoadtest();
- break;
- default:
- throw new IllegalArgumentException("Unknown type: " + type);
- }
- }
-
- @Override
- public void onDestroy() {
- Log.d(TAG, "Destroying");
- mPerfData.onDestroy();
- stopLoadtest();
- clearConfigs();
- super.onDestroy();
- }
-
- @Nullable
- public StatsdStatsReport getMetadata() {
- if (!statsdRunning()) {
- return null;
- }
- if (mStatsManager != null) {
- byte[] data;
- try {
- data = mStatsManager.getStatsMetadata();
- } catch (StatsManager.StatsUnavailableException e) {
- Log.e(TAG, "Failed to get data from statsd", e);
- return null;
- }
- if (data != null) {
- StatsdStatsReport report = null;
- boolean good = false;
- try {
- return StatsdStatsReport.parseFrom(data);
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- Log.d(TAG, "Bad StatsdStatsReport");
- }
- }
- }
- return null;
- }
-
- @Nullable
- public List<ConfigMetricsReport> getData() {
- if (!statsdRunning()) {
- return null;
- }
- if (mStatsManager != null) {
- byte[] data;
- try {
- data = mStatsManager.getReports(ConfigFactory.CONFIG_ID);
- } catch (StatsManager.StatsUnavailableException e) {
- Log.e(TAG, "Failed to get data from statsd", e);
- return null;
- }
- if (data != null) {
- ConfigMetricsReportList reports = null;
- try {
- reports = ConfigMetricsReportList.parseFrom(data);
- Log.d(TAG, "Num reports: " + reports.getReportsCount());
- StringBuilder sb = new StringBuilder();
- DisplayProtoUtils.displayLogReport(sb, reports);
- Log.d(TAG, sb.toString());
- } catch (com.google.protobuf.InvalidProtocolBufferException e) {
- Log.d(TAG, "Invalid data");
- }
- if (reports != null) {
- return reports.getReportsList();
- }
- }
- }
- return null;
- }
-
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- String item = parent.getItemAtPosition(position).toString();
-
- mBucket = TIME_UNIT_MAP.get(item);
- }
-
- @Override
- public void onNothingSelected(AdapterView<?> parent) {
- // Another interface callback
- }
-
- private void onPerfAlarm() {
- if (mPerfData != null) {
- mPerfData.onAlarm(this);
- }
- // Piggy-back on that alarm to show the elapsed time.
- long elapsedTimeMins = (long) Math.floor(
- (SystemClock.elapsedRealtime() - mStartedTimeMillis) / 60 / 1000);
- mReportText.setText("Loadtest in progress.\n"
- + "num metrics =" + mNumMetrics
- + "\nElapsed time = " + elapsedTimeMins + " min(s)");
- }
-
- private void onAlarm() {
- Log.d(TAG, "ON ALARM");
-
- // Set the next task.
- scheduleNext();
-
- // Do the work.
- mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "StatsdLoadTest");
- mWakeLock.acquire();
- if (mPusher != null) {
- mPusher.next();
- }
- mWakeLock.release();
- mWakeLock = null;
- }
-
- /**
- * Schedules the next cycle of pushing atoms into logd.
- */
- private void scheduleNext() {
- Intent intent = new Intent(this, PusherAlarmReceiver.class);
- intent.putExtra(TYPE, PUSH_ALARM);
- mPushPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
- long nextTime = SystemClock.elapsedRealtime() + mPeriodSecs * 1000;
- mAlarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextTime, mPushPendingIntent);
- }
-
- private synchronized void startLoadtest() {
- if (mStarted) {
- return;
- }
-
- // Clean up the state.
- stopLoadtest();
-
- // Prepare to push a sequence of atoms to logd.
- mPusher = new SequencePusher(mBurst, mPlacebo);
-
- // Create a config and push it to statsd.
- if (!setConfig(mFactory.getConfig(mReplication, mBucket, mPlacebo,
- mIncludeCountMetric, mIncludeDurationMetric, mIncludeEventMetric,
- mIncludeValueMetric, mIncludeGaugeMetric))) {
- return;
- }
-
- // Remember to stop in the future.
- Intent intent = new Intent(this, StopperAlarmReceiver.class);
- intent.putExtra(TYPE, STOP);
- mStopPendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
- long nextTime = SystemClock.elapsedRealtime() + mDurationMins * 60 * 1000;
- mAlarmMgr.setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP, nextTime, mStopPendingIntent);
-
- // Log atoms.
- scheduleNext();
-
- // Start tracking performance.
- mPerfData = new PerfData(this, mPlacebo, mReplication, mBucket, mPeriodSecs, mBurst,
- mIncludeCountMetric, mIncludeDurationMetric, mIncludeEventMetric, mIncludeValueMetric,
- mIncludeGaugeMetric);
- mPerfData.startRecording(this);
-
- mReportText.setText("Loadtest in progress.\nnum metrics =" + mNumMetrics);
- mStartedTimeMillis = SystemClock.elapsedRealtime();
-
- updateStarted(true);
- }
-
- private synchronized void stopLoadtest() {
- if (mPushPendingIntent != null) {
- Log.d(TAG, "Canceling pre-existing push alarm");
- mAlarmMgr.cancel(mPushPendingIntent);
- mPushPendingIntent = null;
- }
- if (mStopPendingIntent != null) {
- Log.d(TAG, "Canceling pre-existing stop alarm");
- mAlarmMgr.cancel(mStopPendingIntent);
- mStopPendingIntent = null;
- }
- if (mWakeLock != null) {
- mWakeLock.release();
- mWakeLock = null;
- }
- if (mPerfData != null) {
- mPerfData.stopRecording(this);
- mPerfData.onDestroy();
- mPerfData = null;
- }
-
- // Obtain the latest data and display it.
- getData();
-
- long elapsedTimeMins = (long) Math.floor(
- (SystemClock.elapsedRealtime() - mStartedTimeMillis) / 60 / 1000);
- mReportText.setText("Loadtest ended. Elapsed time = " + elapsedTimeMins + " min(s)");
- clearConfigs();
- updateStarted(false);
- }
-
- private synchronized void updateStarted(boolean started) {
- mStarted = started;
- mStartStop.setBackgroundColor(started ?
- Color.parseColor("#FFFF0000") : Color.parseColor("#FF00FF00"));
- mStartStop.setText(started ? getString(R.string.stop) : getString(R.string.start));
- updateControlsEnabled();
- }
-
- private void updateControlsEnabled() {
- mBurstText.setEnabled(!mPlacebo && !mStarted);
- mReplicationText.setEnabled(!mPlacebo && !mStarted);
- mPeriodText.setEnabled(!mStarted);
- mBucketSpinner.setEnabled(!mPlacebo && !mStarted);
- mDurationText.setEnabled(!mStarted);
- mPlaceboCheckBox.setEnabled(!mStarted);
-
- boolean enabled = !mStarted && !mPlaceboCheckBox.isChecked();
- mCountMetricCheckBox.setEnabled(enabled);
- mDurationMetricCheckBox.setEnabled(enabled);
- mEventMetricCheckBox.setEnabled(enabled);
- mValueMetricCheckBox.setEnabled(enabled);
- mGaugeMetricCheckBox.setEnabled(enabled);
- }
-
- private boolean statsdRunning() {
- if (IStatsManager.Stub.asInterface(ServiceManager.getService("stats")) == null) {
- Log.d(TAG, "Statsd not running");
- Toast.makeText(LoadtestActivity.this, "Statsd NOT running!", Toast.LENGTH_LONG).show();
- return false;
- }
- return true;
- }
-
- private int sanitizeInt(int val, int min, int max) {
- if (val > max) {
- val = max;
- } else if (val < min) {
- val = min;
- }
- return val;
- }
-
- private void clearConfigs() {
- // TODO: Clear all configs instead of specific ones.
- if (mStatsManager != null) {
- if (mStarted) {
- try {
- mStatsManager.removeConfig(ConfigFactory.CONFIG_ID);
- Log.d(TAG, "Removed loadtest statsd configs.");
- } catch (StatsManager.StatsUnavailableException e) {
- Log.e(TAG, "Failed to remove loadtest configs.", e);
- }
- }
- }
- }
-
- private boolean setConfig(ConfigFactory.ConfigMetadata configData) {
- if (mStatsManager != null) {
- try {
- mStatsManager.addConfig(ConfigFactory.CONFIG_ID, configData.bytes);
- mNumMetrics = configData.numMetrics;
- Log.d(TAG, "Config pushed to statsd");
- return true;
- } catch (StatsManager.StatsUnavailableException | IllegalArgumentException e) {
- Log.e(TAG, "Failed to push config to statsd", e);
- }
- }
- return false;
- }
-
- private synchronized void setReplication(int replication) {
- if (mStarted) {
- return;
- }
- mReplicationText.setText("" + replication);
- }
-
- private synchronized void setPeriodSecs(long periodSecs) {
- mPeriodSecs = periodSecs;
- }
-
- private synchronized void setBurst(int burst) {
- mBurst = burst;
- }
-
- private synchronized void setDurationMins(long durationMins) {
- mDurationMins = durationMins;
- }
-
-
- private void handleFocus(EditText editText) {
- /*
- editText.setOnFocusChangeListener(new OnFocusChangeListener() {
- @Override
- public void onFocusChange(View v, boolean hasFocus) {
- if (!hasFocus && editText.getText().toString().isEmpty()) {
- editText.setText("-1", TextView.BufferType.EDITABLE);
- }
- }
- });
- */
- }
-
- private void initBurst() {
- mBurst = getResources().getInteger(R.integer.burst_default);
- mBurstText = (EditText) findViewById(R.id.burst);
- mBurstText.addTextChangedListener(new NumericalWatcher(mBurstText, 0, 1000) {
- @Override
- public void onNewValue(int newValue) {
- setBurst(newValue);
- }
- });
- handleFocus(mBurstText);
- }
-
- private void initReplication() {
- mReplication = getResources().getInteger(R.integer.replication_default);
- mReplicationText = (EditText) findViewById(R.id.replication);
- mReplicationText.addTextChangedListener(new NumericalWatcher(mReplicationText, 1, 4096) {
- @Override
- public void onNewValue(int newValue) {
- mReplication = newValue;
- }
- });
- handleFocus(mReplicationText);
- }
-
- private void initBucket() {
- String defaultValue = getResources().getString(R.string.bucket_default);
- mBucket = TimeUnit.valueOf(defaultValue);
- mBucketSpinner = (Spinner) findViewById(R.id.bucket_spinner);
-
- ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(
- this, R.layout.spinner_item, TIME_UNIT_LABELS);
-
- mBucketSpinner.setAdapter(dataAdapter);
- mBucketSpinner.setOnItemSelectedListener(this);
-
- for (String label : TIME_UNIT_MAP.keySet()) {
- if (defaultValue.equals(TIME_UNIT_MAP.get(label).toString())) {
- mBucketSpinner.setSelection(dataAdapter.getPosition(label));
- }
- }
- }
-
- private void initPeriod() {
- mPeriodSecs = getResources().getInteger(R.integer.period_default);
- mPeriodText = (EditText) findViewById(R.id.period);
- mPeriodText.addTextChangedListener(new NumericalWatcher(mPeriodText, 1, 60) {
- @Override
- public void onNewValue(int newValue) {
- setPeriodSecs(newValue);
- }
- });
- handleFocus(mPeriodText);
- }
-
- private void initDuration() {
- mDurationMins = getResources().getInteger(R.integer.duration_default);
- mDurationText = (EditText) findViewById(R.id.duration);
- mDurationText.addTextChangedListener(new NumericalWatcher(mDurationText, 1, 24 * 60) {
- @Override
- public void onNewValue(int newValue) {
- setDurationMins(newValue);
- }
- });
- handleFocus(mDurationText);
- }
-
- private void initPlacebo() {
- mPlaceboCheckBox = findViewById(R.id.placebo);
- mPlacebo = false;
- mPlaceboCheckBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mPlacebo = mPlaceboCheckBox.isChecked();
- updateControlsEnabled();
- }
- });
- }
-
- private void initMetricWhitelist() {
- mCountMetricCheckBox = findViewById(R.id.include_count);
- mCountMetricCheckBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mIncludeCountMetric = mCountMetricCheckBox.isChecked();
- }
- });
- mDurationMetricCheckBox = findViewById(R.id.include_duration);
- mDurationMetricCheckBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mIncludeDurationMetric = mDurationMetricCheckBox.isChecked();
- }
- });
- mEventMetricCheckBox = findViewById(R.id.include_event);
- mEventMetricCheckBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mIncludeEventMetric = mEventMetricCheckBox.isChecked();
- }
- });
- mValueMetricCheckBox = findViewById(R.id.include_value);
- mValueMetricCheckBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mIncludeValueMetric = mValueMetricCheckBox.isChecked();
- }
- });
- mGaugeMetricCheckBox = findViewById(R.id.include_gauge);
- mGaugeMetricCheckBox.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View view) {
- mIncludeGaugeMetric = mGaugeMetricCheckBox.isChecked();
- }
- });
-
- mIncludeCountMetric = mCountMetricCheckBox.isChecked();
- mIncludeDurationMetric = mDurationMetricCheckBox.isChecked();
- mIncludeEventMetric = mEventMetricCheckBox.isChecked();
- mIncludeValueMetric = mValueMetricCheckBox.isChecked();
- mIncludeGaugeMetric = mGaugeMetricCheckBox.isChecked();
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemInfoParser.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemInfoParser.java
deleted file mode 100644
index 01eebf2ad1cf..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemInfoParser.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.annotation.Nullable;
-import android.os.SystemClock;
-import android.util.Log;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/** Parses PSS info from dumpsys meminfo */
-public class MemInfoParser implements PerfParser {
-
- private static final Pattern LINE_PATTERN =
- Pattern.compile("\\s*(\\d*,*\\d*)K:\\s(\\S*)\\s\\.*");
- private static final String PSS_BY_PROCESS = "Total PSS by process:";
- private static final String TAG = "loadtest.MemInfoParser";
-
- private boolean mPssStarted;
- private boolean mPssEnded;
- private final long mStartTimeMillis;
-
- public MemInfoParser(long startTimeMillis) {
- mStartTimeMillis = startTimeMillis;
- }
-
- @Override
- @Nullable
- public String parseLine(String line) {
- if (mPssEnded) {
- return null;
- }
- if (!mPssStarted) {
- if (line.contains(PSS_BY_PROCESS)) {
- mPssStarted = true;
- }
- return null;
- }
- if (line.isEmpty()) {
- mPssEnded = true;
- return null;
- }
- Matcher lineMatcher = LINE_PATTERN.matcher(line);
- if (lineMatcher.find() && lineMatcher.group(1) != null && lineMatcher.group(2) != null) {
- if (lineMatcher.group(2).equals("statsd")) {
- long timeDeltaMillis = SystemClock.elapsedRealtime() - mStartTimeMillis;
- return timeDeltaMillis + "," + convertToPss(lineMatcher.group(1));
- }
- }
- return null;
- }
-
- private String convertToPss(String input) {
- return input.replace(",", "");
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java
deleted file mode 100644
index af7bd4d35966..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/MemoryDataRecorder.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.content.Context;
-import android.os.SystemClock;
-import android.util.Log;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-
-public class MemoryDataRecorder extends PerfDataRecorder {
- private static final String TAG = "loadtest.MemoryDataDataRecorder";
- private static final String DUMP_FILENAME = TAG + "_dump.tmp";
-
- private long mStartTimeMillis;
- private StringBuilder mSb;
-
- public MemoryDataRecorder(boolean placebo, int replication, TimeUnit bucket, long periodSecs,
- int burst, boolean includeCountMetric, boolean includeDurationMetric,
- boolean includeEventMetric, boolean includeValueMetric, boolean includeGaugeMetric) {
- super(placebo, replication, bucket, periodSecs, burst, includeCountMetric,
- includeDurationMetric, includeEventMetric, includeValueMetric, includeGaugeMetric);
- }
-
- @Override
- public void startRecording(Context context) {
- mStartTimeMillis = SystemClock.elapsedRealtime();
- mSb = new StringBuilder();
- }
-
- @Override
- public void onAlarm(Context context) {
- runDumpsysStats(context, DUMP_FILENAME, "meminfo");
- readDumpData(context, DUMP_FILENAME, new MemInfoParser(mStartTimeMillis), mSb);
- }
-
- @Override
- public void stopRecording(Context context) {
- writeData(context, "meminfo_", "time,pss", mSb);
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java
deleted file mode 100644
index 555e6dd2d99d..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/NumericalWatcher.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.text.Editable;
-import android.text.TextWatcher;
-import android.util.Log;
-import android.widget.TextView;
-
-public abstract class NumericalWatcher implements TextWatcher {
-
- private static final String TAG = "loadtest.NumericalWatcher";
-
- private final TextView mTextView;
- private final int mMin;
- private final int mMax;
- private int currentValue = -1;
-
- public NumericalWatcher(TextView textView, int min, int max) {
- mTextView = textView;
- mMin = min;
- mMax = max;
- }
-
- public abstract void onNewValue(int newValue);
-
- @Override
- final public void afterTextChanged(Editable editable) {
- String s = mTextView.getText().toString();
- if (s.isEmpty()) {
- return;
- }
- int unsanitized = Integer.parseInt(s);
- int newValue = sanitize(unsanitized);
- if (currentValue != newValue || unsanitized != newValue) {
- currentValue = newValue;
- editable.clear();
- editable.append(newValue + "");
- }
- onNewValue(newValue);
- }
-
- @Override
- final public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
- @Override
- final public void onTextChanged(CharSequence s, int start, int before, int count) {}
-
- private int sanitize(int val) {
- if (val > mMax) {
- val = mMax;
- } else if (val < mMin) {
- val = mMin;
- }
- return val;
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java
deleted file mode 100644
index 7a01adedfaa4..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfData.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-
-import android.annotation.Nullable;
-import android.app.AlarmManager;
-import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.util.HashSet;
-import java.util.Set;
-
-/** Prints some information about the device via Dumpsys in order to evaluate health metrics. */
-public class PerfData extends PerfDataRecorder {
-
- private static final String TAG = "loadtest.PerfData";
-
- /** Polling period for performance snapshots like memory. */
- private static final long POLLING_PERIOD_MILLIS = 1 * 60 * 1000;
-
- public final static class PerfAlarmReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- Intent activityIntent = new Intent(context, LoadtestActivity.class);
- activityIntent.putExtra(LoadtestActivity.TYPE, LoadtestActivity.PERF_ALARM);
- context.startActivity(activityIntent);
- }
- }
-
- private AlarmManager mAlarmMgr;
-
- /** Used to periodically poll some dumpsys data. */
- private PendingIntent mPendingIntent;
-
- private final Set<PerfDataRecorder> mRecorders;
-
- public PerfData(LoadtestActivity loadtestActivity, boolean placebo, int replication,
- TimeUnit bucket, long periodSecs, int burst, boolean includeCountMetric,
- boolean includeDurationMetric, boolean includeEventMetric, boolean includeValueMetric,
- boolean includeGaugeMetric) {
- super(placebo, replication, bucket, periodSecs, burst, includeCountMetric,
- includeDurationMetric, includeEventMetric, includeValueMetric, includeGaugeMetric);
- mRecorders = new HashSet();
- mRecorders.add(new BatteryDataRecorder(placebo, replication, bucket, periodSecs, burst,
- includeCountMetric, includeDurationMetric, includeEventMetric, includeValueMetric,
- includeGaugeMetric));
- mRecorders.add(new MemoryDataRecorder(placebo, replication, bucket, periodSecs, burst,
- includeCountMetric, includeDurationMetric, includeEventMetric, includeValueMetric,
- includeGaugeMetric));
- mRecorders.add(new StatsdStatsRecorder(loadtestActivity, placebo, replication, bucket,
- periodSecs, burst, includeCountMetric, includeDurationMetric, includeEventMetric,
- includeValueMetric, includeGaugeMetric));
- mRecorders.add(new ValidationRecorder(loadtestActivity, placebo, replication, bucket,
- periodSecs, burst, includeCountMetric, includeDurationMetric, includeEventMetric,
- includeValueMetric, includeGaugeMetric));
- mAlarmMgr = (AlarmManager) loadtestActivity.getSystemService(Context.ALARM_SERVICE);
- }
-
- public void onDestroy() {
- if (mPendingIntent != null) {
- mAlarmMgr.cancel(mPendingIntent);
- mPendingIntent = null;
- }
- }
-
- @Override
- public void startRecording(Context context) {
- Intent intent = new Intent(context, PerfAlarmReceiver.class);
- intent.putExtra(LoadtestActivity.TYPE, LoadtestActivity.PERF_ALARM);
- mPendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
- mAlarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, -1 /* now */,
- POLLING_PERIOD_MILLIS, mPendingIntent);
-
- for (PerfDataRecorder recorder : mRecorders) {
- recorder.startRecording(context);
- }
- }
-
- @Override
- public void onAlarm(Context context) {
- for (PerfDataRecorder recorder : mRecorders) {
- recorder.onAlarm(context);
- }
- }
-
- @Override
- public void stopRecording(Context context) {
- if (mPendingIntent != null) {
- mAlarmMgr.cancel(mPendingIntent);
- mPendingIntent = null;
- }
-
- for (PerfDataRecorder recorder : mRecorders) {
- recorder.stopRecording(context);
- }
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java
deleted file mode 100644
index 8613ac1c4796..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfDataRecorder.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.annotation.Nullable;
-import android.content.Context;
-import android.os.Environment;
-import android.util.Log;
-import android.os.Debug;
-
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import java.io.BufferedReader;
-import java.io.Closeable;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-
-public abstract class PerfDataRecorder {
- private static final String TAG = "loadtest.PerfDataRecorder";
-
- protected final String mTimeAsString;
- protected final String mColumnSuffix;
-
- protected PerfDataRecorder(boolean placebo, int replication, TimeUnit bucket, long periodSecs,
- int burst, boolean includeCountMetric, boolean includeDurationMetric,
- boolean includeEventMetric, boolean includeValueMetric, boolean includeGaugeMetric) {
- mTimeAsString = new SimpleDateFormat("YYYY_MM_dd_HH_mm_ss").format(new Date());
- mColumnSuffix = getColumnSuffix(placebo, replication, bucket, periodSecs, burst,
- includeCountMetric, includeDurationMetric, includeEventMetric, includeValueMetric,
- includeGaugeMetric);
- }
-
- /** Starts recording performance data. */
- public abstract void startRecording(Context context);
-
- /** Called periodically. For the recorder to sample data, if needed. */
- public abstract void onAlarm(Context context);
-
- /** Stops recording performance data, and writes it to disk. */
- public abstract void stopRecording(Context context);
-
- /** Runs the dumpsys command. */
- protected void runDumpsysStats(Context context, String dumpFilename, String cmd,
- String... args) {
- boolean success = false;
- // Call dumpsys Dump statistics to a file.
- FileOutputStream fo = null;
- try {
- fo = context.openFileOutput(dumpFilename, Context.MODE_PRIVATE);
- if (!Debug.dumpService(cmd, fo.getFD(), args)) {
- Log.w(TAG, "Dumpsys failed.");
- }
- success = true;
- } catch (IOException | SecurityException | NullPointerException e) {
- // SecurityException may occur when trying to dump multi-user info.
- // NPE can occur during dumpService (root cause unknown).
- throw new RuntimeException(e);
- } finally {
- closeQuietly(fo);
- }
- }
-
- /**
- * Reads a text file and parses each line, one by one. The result of the parsing is stored
- * in the passed {@link StringBuffer}.
- */
- protected void readDumpData(Context context, String dumpFilename, PerfParser parser,
- StringBuilder sb) {
- FileInputStream fi = null;
- BufferedReader br = null;
- try {
- fi = context.openFileInput(dumpFilename);
- br = new BufferedReader(new InputStreamReader(fi));
- String line = br.readLine();
- while (line != null) {
- String recordLine = parser.parseLine(line);
- if (recordLine != null) {
- sb.append(recordLine).append('\n');
- }
- line = br.readLine();
- }
- } catch (IOException e) {
- throw new RuntimeException(e);
- } finally {
- closeQuietly(br);
- }
- }
-
- /** Writes CSV data to a file. */
- protected void writeData(Context context, String filePrefix, String columnPrefix,
- StringBuilder sb) {
- File dataFile = new File(getStorageDir(), filePrefix + mTimeAsString + ".csv");
-
- FileWriter writer = null;
- try {
- writer = new FileWriter(dataFile);
- writer.append(columnPrefix + mColumnSuffix + "\n");
- writer.append(sb.toString());
- writer.flush();
- Log.d(TAG, "Finished writing data at " + dataFile.getAbsolutePath());
- } catch (IOException e) {
- throw new RuntimeException(e);
- } finally {
- closeQuietly(writer);
- }
- }
-
- /** Gets the suffix to use in the column name for perf data. */
- private String getColumnSuffix(boolean placebo, int replication, TimeUnit bucket,
- long periodSecs, int burst, boolean includeCountMetric, boolean includeDurationMetric,
- boolean includeEventMetric, boolean includeValueMetric, boolean includeGaugeMetric) {
- if (placebo) {
- return "_placebo_p=" + periodSecs;
- }
- StringBuilder sb = new StringBuilder()
- .append("_r=" + replication)
- .append("_bkt=" + bucket)
- .append("_p=" + periodSecs)
- .append("_bst=" + burst)
- .append("_m=");
- if (includeCountMetric) {
- sb.append("c");
- }
- if (includeEventMetric) {
- sb.append("e");
- }
- if (includeDurationMetric) {
- sb.append("d");
- }
- if (includeGaugeMetric) {
- sb.append("g");
- }
- if (includeValueMetric) {
- sb.append("v");
- }
- return sb.toString();
- }
-
- private File getStorageDir() {
- File file = new File(Environment.getExternalStoragePublicDirectory(
- Environment.DIRECTORY_DOCUMENTS), "loadtest/" + mTimeAsString);
- if (!file.mkdirs()) {
- Log.e(TAG, "Directory not created");
- }
- return file;
- }
-
- private void closeQuietly(@Nullable Closeable c) {
- if (c != null) {
- try {
- c.close();
- } catch (IOException ignore) {
- }
- }
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfParser.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfParser.java
deleted file mode 100644
index e000918fa0f7..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/PerfParser.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.annotation.Nullable;
-
-public interface PerfParser {
-
- /**
- * Parses one line of the dumpsys output, and returns a string to write to the data file,
- * or null if no string should be written.
- */
- @Nullable String parseLine(String line);
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java
deleted file mode 100644
index 5dcce9acb401..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/SequencePusher.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.util.Log;
-import android.util.StatsLog;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Manages the pushing of atoms into logd for loadtesting.
- * We rely on small number of pushed atoms, and a config with metrics based on those atoms.
- * The atoms are:
- * <ul>
- * <li> BatteryLevelChanged - For EventMetric, CountMetric and GaugeMetric (no dimensions).
- * <li> BleScanResultReceived - For CountMetric and ValueMetric, sliced by uid.
- * <li> ChargingStateChanged - For DurationMetric (no dimension).
- * <li> GpsScanStateChanged - For DurationMetric, sliced by uid.
- * <li> ScreenStateChanged - For Conditions with no dimensions.
- * <li> AudioStateChanged - For Conditions with dimensions (uid).
- * </ul>
- * The sequence is played over and over at a given frequency.
- */
-public class SequencePusher {
- private static final String TAG = "SequencePusher";
-
- /** Some atoms are pushed in burst of {@code mBurst} events. */
- private final int mBurst;
-
- /** If this is true, we don't log anything in logd. */
- private final boolean mPlacebo;
-
- /** Current state in the automaton. */
- private int mCursor = 0;
-
- public SequencePusher(int burst, boolean placebo) {
- mBurst = burst;
- mPlacebo = placebo;
- }
-
- /**
- * Pushes the next atom to logd.
- * This follows a small automaton which makes the right events and conditions overlap:
- * (0) Push a burst of BatteryLevelChanged atoms.
- * (1) Push a burst of BleScanResultReceived atoms.
- * (2) Push ChargingStateChanged with BATTERY_STATUS_CHARGING once.
- * (3) Push a burst of GpsScanStateChanged atoms with ON, with a different uid each time.
- * (4) Push ChargingStateChanged with BATTERY_STATUS_NOT_CHARGING once.
- * (5) Push a burst GpsScanStateChanged atoms with OFF, with a different uid each time.
- * (6) Push ScreenStateChanged with STATE_ON once.
- * (7) Push a burst of AudioStateChanged with ON, with a different uid each time.
- * (8) Repeat steps (0)-(5).
- * (9) Push ScreenStateChanged with STATE_OFF once.
- * (10) Push a burst of AudioStateChanged with OFF, with a different uid each time.
- * and repeat.
- */
- public void next() {
- Log.d(TAG, "Next step: " + mCursor);
- if (mPlacebo) {
- return;
- }
- switch (mCursor) {
- case 0:
- case 8:
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, 50 + i /* battery_level */);
- }
- break;
- case 1:
- case 9:
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, i /* uid */,
- 100 /* num_of_results */);
- }
- break;
- case 2:
- case 10:
- StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
- StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_CHARGING
- /* charging_state */);
- break;
- case 3:
- case 11:
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */,
- StatsLog.GPS_SCAN_STATE_CHANGED__STATE__ON /* state */);
- }
- break;
- case 4:
- case 12:
- StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
- StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_NOT_CHARGING
- /* charging_state */);
- break;
- case 5:
- case 13:
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */,
- StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF /* state */);
- }
- break;
- case 6:
- StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_ON /* display_state */);
- break;
- case 7:
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */,
- StatsLog.AUDIO_STATE_CHANGED__STATE__ON /* state */);
- }
- break;
- case 14:
- StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF /* display_state */);
- break;
- case 15:
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */,
- StatsLog.AUDIO_STATE_CHANGED__STATE__OFF /* state */);
- }
- break;
- default:
- }
- mCursor++;
- if (mCursor > 15) {
- mCursor = 0;
- }
- }
-
- /**
- * Properly finishes in order to be close all conditions and durations.
- */
- public void finish() {
- // Screen goes back to off. This will ensure that conditions get back to false.
- StatsLog.write(StatsLog.SCREEN_STATE_CHANGED,
- StatsLog.SCREEN_STATE_CHANGED__STATE__DISPLAY_STATE_OFF /* display_state */);
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, i /* uid */,
- StatsLog.AUDIO_STATE_CHANGED__STATE__OFF /* state */);
- }
- // Stop charging, to ensure the corresponding durations are closed.
- StatsLog.write(StatsLog.CHARGING_STATE_CHANGED,
- StatsLog.CHARGING_STATE_CHANGED__STATE__BATTERY_STATUS_NOT_CHARGING
- /* charging_state */);
- // Stop scanning GPS, to ensure the corresponding conditions get back to false.
- for (int i = 0; i < mBurst; i++) {
- StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, i /* uid */,
- StatsLog.GPS_SCAN_STATE_CHANGED__STATE__OFF /* state */);
- }
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java
deleted file mode 100644
index 3939e7e0b2fa..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/StatsdStatsRecorder.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.content.Context;
-import com.android.os.StatsLog.StatsdStatsReport;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-
-public class StatsdStatsRecorder extends PerfDataRecorder {
- private static final String TAG = "loadtest.StatsdStatsRecorder";
-
- private final LoadtestActivity mLoadtestActivity;
-
- public StatsdStatsRecorder(LoadtestActivity loadtestActivity, boolean placebo, int replication,
- TimeUnit bucket, long periodSecs, int burst, boolean includeCountMetric,
- boolean includeDurationMetric, boolean includeEventMetric, boolean includeValueMetric,
- boolean includeGaugeMetric) {
- super(placebo, replication, bucket, periodSecs, burst, includeCountMetric,
- includeDurationMetric, includeEventMetric, includeValueMetric, includeGaugeMetric);
- mLoadtestActivity = loadtestActivity;
- }
-
- @Override
- public void startRecording(Context context) {
- // Nothing to do.
- }
-
- @Override
- public void onAlarm(Context context) {
- // Nothing to do.
- }
-
- @Override
- public void stopRecording(Context context) {
- StatsdStatsReport metadata = mLoadtestActivity.getMetadata();
- if (metadata != null) {
- int numConfigs = metadata.getConfigStatsCount();
- StringBuilder sb = new StringBuilder();
- StatsdStatsReport.ConfigStats configStats = metadata.getConfigStats(numConfigs - 1);
- sb.append("metric_count,")
- .append(configStats.getMetricCount() + "\n")
- .append("condition_count,")
- .append(configStats.getConditionCount() + "\n")
- .append("matcher_count,")
- .append(configStats.getMatcherCount() + "\n");
- writeData(context, "statsdstats_", "stat,value", sb);
- }
- }
-}
diff --git a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ValidationRecorder.java b/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ValidationRecorder.java
deleted file mode 100644
index d9f0ca9d2461..000000000000
--- a/cmds/statsd/tools/loadtest/src/com/android/statsd/loadtest/ValidationRecorder.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.statsd.loadtest;
-
-import android.content.Context;
-import android.util.Log;
-import com.android.os.StatsLog.ConfigMetricsReport;
-import com.android.os.StatsLog.EventMetricData;
-import com.android.os.StatsLog.StatsLogReport;
-import com.android.internal.os.StatsdConfigProto.TimeUnit;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * Checks the correctness of the stats.
- */
-public class ValidationRecorder extends PerfDataRecorder {
- private static final String TAG = "loadtest.ValidationRecorder";
-
- private final LoadtestActivity mLoadtestActivity;
-
- public ValidationRecorder(LoadtestActivity loadtestActivity, boolean placebo, int replication,
- TimeUnit bucket, long periodSecs, int burst, boolean includeCountMetric,
- boolean includeDurationMetric, boolean includeEventMetric, boolean includeValueMetric,
- boolean includeGaugeMetric) {
- super(placebo, replication, bucket, periodSecs, burst, includeCountMetric,
- includeDurationMetric, includeEventMetric, includeValueMetric, includeGaugeMetric);
- mLoadtestActivity = loadtestActivity;
- }
-
- @Override
- public void startRecording(Context context) {
- // Nothing to do.
- }
-
- @Override
- public void onAlarm(Context context) {
- validateData();
- }
-
- @Override
- public void stopRecording(Context context) {
- validateData();
- }
-
- private void validateData() {
- // The code below is commented out because it calls getData, which has the side-effect
- // of clearing statsd's data buffer.
- /*
- List<ConfigMetricsReport> reports = mLoadtestActivity.getData();
- if (reports != null) {
- Log.d(TAG, "GOT DATA");
- for (ConfigMetricsReport report : reports) {
- for (StatsLogReport logReport : report.getMetricsList()) {
- if (!logReport.hasMetricId()) {
- Log.e(TAG, "Metric missing name.");
- }
- }
- }
- }
- */
- }
-
- private void validateEventBatteryLevelChanges(StatsLogReport logReport) {
- Log.d(TAG, "Validating " + logReport.getMetricId());
- if (logReport.hasEventMetrics()) {
- Log.d(TAG, "Num events captured: " + logReport.getEventMetrics().getDataCount());
- for (EventMetricData data : logReport.getEventMetrics().getDataList()) {
- Log.d(TAG, " Event : " + data.getAtom());
- }
- } else {
- Log.d(TAG, "Metric is invalid");
- }
- }
-
- private void validateEventBatteryLevelChangesWhileScreenIsOn(StatsLogReport logReport) {
- Log.d(TAG, "Validating " + logReport.getMetricId());
- }
-}
diff --git a/config/boot-profile.txt b/config/boot-profile.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/config/boot-profile.txt
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index 4aafa53805e1..ffba11520856 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -777,8 +777,8 @@ public abstract class AccessibilityService extends Service {
callback, handler);
mGestureStatusCallbackInfos.put(mGestureStatusCallbackSequence, callbackInfo);
}
- connection.sendGesture(mGestureStatusCallbackSequence,
- new ParceledListSlice<>(steps));
+ connection.dispatchGesture(mGestureStatusCallbackSequence,
+ new ParceledListSlice<>(steps), gesture.getDisplayId());
}
} catch (RemoteException re) {
throw new RuntimeException(re);
diff --git a/core/java/android/accessibilityservice/GestureDescription.java b/core/java/android/accessibilityservice/GestureDescription.java
index a3e7ad5da9b1..3b79d217c513 100644
--- a/core/java/android/accessibilityservice/GestureDescription.java
+++ b/core/java/android/accessibilityservice/GestureDescription.java
@@ -23,6 +23,7 @@ import android.graphics.PathMeasure;
import android.graphics.RectF;
import android.os.Parcel;
import android.os.Parcelable;
+import android.view.Display;
import com.android.internal.util.Preconditions;
@@ -33,7 +34,7 @@ import java.util.List;
* Accessibility services with the
* {@link android.R.styleable#AccessibilityService_canPerformGestures} property can dispatch
* gestures. This class describes those gestures. Gestures are made up of one or more strokes.
- * Gestures are immutable once built.
+ * Gestures are immutable once built and will be dispatched to the specified display.
* <p>
* Spatial dimensions throughout are in screen pixels. Time is measured in milliseconds.
*/
@@ -48,6 +49,7 @@ public final class GestureDescription {
private final List<StrokeDescription> mStrokes = new ArrayList<>();
private final float[] mTempPos = new float[2];
+ private final int mDisplayId;
/**
* Get the upper limit for the number of strokes a gesture may contain.
@@ -67,10 +69,17 @@ public final class GestureDescription {
return MAX_GESTURE_DURATION_MS;
}
- private GestureDescription() {}
+ private GestureDescription() {
+ this(new ArrayList<>());
+ }
private GestureDescription(List<StrokeDescription> strokes) {
+ this(strokes, Display.DEFAULT_DISPLAY);
+ }
+
+ private GestureDescription(List<StrokeDescription> strokes, int displayId) {
mStrokes.addAll(strokes);
+ mDisplayId = displayId;
}
/**
@@ -94,6 +103,16 @@ public final class GestureDescription {
}
/**
+ * Returns the ID of the display this gesture is sent on, for use with
+ * {@link android.hardware.display.DisplayManager#getDisplay(int)}.
+ *
+ * @return The logical display id.
+ */
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
+ /**
* Return the smallest key point (where a path starts or ends) that is at least a specified
* offset
* @param offset the minimum start time
@@ -160,9 +179,10 @@ public final class GestureDescription {
public static class Builder {
private final List<StrokeDescription> mStrokes = new ArrayList<>();
+ private int mDisplayId = Display.DEFAULT_DISPLAY;
/**
- * Add a stroke to the gesture description. Up to
+ * Adds a stroke to the gesture description. Up to
* {@link GestureDescription#getMaxStrokeCount()} paths may be
* added to a gesture, and the total gesture duration (earliest path start time to latest
* path end time) may not exceed {@link GestureDescription#getMaxGestureDuration()}.
@@ -187,11 +207,23 @@ public final class GestureDescription {
return this;
}
+ /**
+ * Sets the id of the display to dispatch gestures.
+ *
+ * @param displayId The logical display id
+ *
+ * @return this
+ */
+ public @NonNull Builder setDisplayId(int displayId) {
+ mDisplayId = displayId;
+ return this;
+ }
+
public GestureDescription build() {
if (mStrokes.size() == 0) {
throw new IllegalStateException("Gestures must have at least one stroke");
}
- return new GestureDescription(mStrokes);
+ return new GestureDescription(mStrokes, mDisplayId);
}
}
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index c8e01321812c..1ca07dd6ed23 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -95,6 +95,8 @@ interface IAccessibilityServiceConnection {
void sendGesture(int sequence, in ParceledListSlice gestureSteps);
+ void dispatchGesture(int sequence, in ParceledListSlice gestureSteps, int displayId);
+
boolean isFingerprintGestureDetectionAvailable();
IBinder getOverlayWindowToken(int displayid);
diff --git a/core/java/android/app/ActivityView.java b/core/java/android/app/ActivityView.java
index 755f0476d9ba..415ec64dc126 100644
--- a/core/java/android/app/ActivityView.java
+++ b/core/java/android/app/ActivityView.java
@@ -386,9 +386,15 @@ public class ActivityView extends ViewGroup {
// Also report this geometry information to InputMethodManagerService.
// TODO(b/115693908): Unify this logic into the above WMS-based one.
+ // TODO(b/138175283): Address the location update when the host of this view is
+ // moving.
final Matrix matrix = new Matrix();
+ final int[] locationOnScreen = new int[2];
+ getLocationOnScreen(locationOnScreen);
+ final int dx = locationOnScreen[0];
+ final int dy = locationOnScreen[1];
matrix.set(getMatrix());
- matrix.postTranslate(x, y);
+ matrix.postTranslate(dx, dy);
mContext.getSystemService(InputMethodManager.class)
.reportActivityView(displayId, matrix);
}
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 2957309094f6..47b784b3eaaf 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -153,6 +153,7 @@ interface IActivityTaskManager {
void moveTaskToFront(in IApplicationThread app, in String callingPackage, int task,
int flags, in Bundle options);
int getTaskForActivity(in IBinder token, in boolean onlyRoot);
+ /** Finish all activities that were started for result from the specified activity. */
void finishSubActivity(in IBinder token, in String resultWho, int requestCode);
ParceledListSlice getRecentTasks(int maxNum, int flags, int userId);
boolean willActivityBeVisible(in IBinder token);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 5aa1f8f07f60..372eab259f4c 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5437,10 +5437,11 @@ public class Notification implements Parcelable
/**
* Construct a RemoteViews for the display in public contexts like on the lockscreen.
*
+ * @param isLowPriority is this notification low priority
* @hide
*/
@UnsupportedAppUsage
- public RemoteViews makePublicContentView() {
+ public RemoteViews makePublicContentView(boolean isLowPriority) {
if (mN.publicVersion != null) {
final Builder builder = recoverBuilder(mContext, mN.publicVersion);
return builder.createContentView();
@@ -5467,7 +5468,11 @@ public class Notification implements Parcelable
}
mN.extras = publicExtras;
RemoteViews view;
- view = makeNotificationHeader();
+ StandardTemplateParams params = mParams.reset().fillTextsFrom(this);
+ if (isLowPriority) {
+ params.forceDefaultColor();
+ }
+ view = makeNotificationHeader(params);
view.setBoolean(R.id.notification_header, "setExpandOnlyOnButton", true);
mN.extras = savedBundle;
mN.mLargeIcon = largeIcon;
diff --git a/core/java/android/bluetooth/BluetoothHeadsetClient.java b/core/java/android/bluetooth/BluetoothHeadsetClient.java
index 05833b5f571d..5d00f09501b0 100644
--- a/core/java/android/bluetooth/BluetoothHeadsetClient.java
+++ b/core/java/android/bluetooth/BluetoothHeadsetClient.java
@@ -126,6 +126,17 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
"android.bluetooth.headsetclient.profile.action.RESULT";
/**
+ * Intent that notifies about vendor specific event arrival. Events not defined in
+ * HFP spec will be matched with supported vendor event list and this intent will
+ * be broadcasted upon a match. Supported vendor events are of format of
+ * of "+eventCode" or "+eventCode=xxxx" or "+eventCode:=xxxx".
+ * Vendor event can be a response to an vendor specific command or unsolicited.
+ *
+ */
+ public static final String ACTION_VENDOR_SPECIFIC_HEADSETCLIENT_EVENT =
+ "android.bluetooth.headsetclient.profile.action.VENDOR_SPECIFIC_EVENT";
+
+ /**
* Intent that notifies about the number attached to the last voice tag
* recorded on AG.
*
@@ -243,6 +254,28 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
public static final String EXTRA_CME_CODE =
"android.bluetooth.headsetclient.extra.CME_CODE";
+ /**
+ * Extra for VENDOR_SPECIFIC_HEADSETCLIENT_EVENT intent that
+ * indicates vendor ID.
+ */
+ public static final String EXTRA_VENDOR_ID =
+ "android.bluetooth.headsetclient.extra.VENDOR_ID";
+
+ /**
+ * Extra for VENDOR_SPECIFIC_HEADSETCLIENT_EVENT intent that
+ * indicates vendor event code.
+ */
+ public static final String EXTRA_VENDOR_EVENT_CODE =
+ "android.bluetooth.headsetclient.extra.VENDOR_EVENT_CODE";
+
+ /**
+ * Extra for VENDOR_SPECIFIC_HEADSETCLIENT_EVENT intent that
+ * contains full vendor event including event code and full arguments.
+ */
+ public static final String EXTRA_VENDOR_EVENT_FULL_ARGS =
+ "android.bluetooth.headsetclient.extra.VENDOR_EVENT_FULL_ARGS";
+
+
/* Extras for AG_FEATURES, extras type is boolean */
// TODO verify if all of those are actually useful
/**
@@ -588,6 +621,31 @@ public final class BluetoothHeadsetClient implements BluetoothProfile {
}
/**
+ * Send vendor specific AT command.
+ *
+ * @param device remote device
+ * @param vendorId vendor number by Bluetooth SIG
+ * @param atCommand command to be sent. It start with + prefix and only one command at one time.
+ * @return <code>true</code> if command has been issued successfully; <code>false</code>
+ * otherwise.
+ */
+ public boolean sendVendorAtCommand(BluetoothDevice device, int vendorId,
+ String atCommand) {
+ if (DBG) log("sendVendorSpecificCommand()");
+ final IBluetoothHeadsetClient service =
+ getService();
+ if (service != null && isEnabled() && isValidDevice(device)) {
+ try {
+ return service.sendVendorAtCommand(device, vendorId, atCommand);
+ } catch (RemoteException e) {
+ Log.e(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+ if (service == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+
+ /**
* Stops voice recognition.
*
* @param device remote device
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 4d8a0c46508e..895eba6cdec2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2044,6 +2044,30 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports Open Mobile API capable UICC-based secure
+ * elements.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_SE_OMAPI_UICC = "android.hardware.se.omapi.uicc";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports Open Mobile API capable eSE-based secure
+ * elements.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_SE_OMAPI_ESE = "android.hardware.se.omapi.ese";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device supports Open Mobile API capable SD-based secure
+ * elements.
+ */
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_SE_OMAPI_SD = "android.hardware.se.omapi.sd";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device supports the OpenGL ES
* <a href="http://www.khronos.org/registry/gles/extensions/ANDROID/ANDROID_extension_pack_es31a.txt">
* Android Extension Pack</a>.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index e690a7fd783b..a4933ef1703f 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -66,6 +66,7 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
+import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
@@ -2445,6 +2446,8 @@ public class PackageParser {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
+ } else if (tagName.equals("queries")) {
+ parseQueries(pkg, res, parser, flags, outError);
} else {
Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName()
+ " at " + mArchiveSourcePath + " "
@@ -3538,6 +3541,9 @@ public class PackageParser {
owner.mRequiredAccountType = requiredAccountType;
}
+ owner.mForceQueryable =
+ sa.getBoolean(R.styleable.AndroidManifestApplication_forceQueryable, false);
+
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_debuggable,
false)) {
@@ -3953,7 +3959,6 @@ public class PackageParser {
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL;
}
XmlUtils.skipCurrentTag(parser);
-
} else {
if (!RIGID_PARSER) {
Slog.w(TAG, "Unknown element under <application>: " + tagName
@@ -4000,6 +4005,67 @@ public class PackageParser {
return true;
}
+ private boolean parseQueries(Package owner, Resources res, XmlResourceParser parser, int flags,
+ String[] outError)
+ throws IOException, XmlPullParserException {
+
+ final int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ if (parser.getName().equals("intent")) {
+ QueriesIntentInfo intentInfo = new QueriesIntentInfo();
+ if (!parseIntent(res, parser, true /*allowGlobs*/, true /*allowAutoVerify*/,
+ intentInfo, outError)) {
+ return false;
+ }
+ Intent intent = new Intent();
+ if (intentInfo.countActions() != 1) {
+ outError[0] = "intent tags must contain exactly one action.";
+ return false;
+ }
+ intent.setAction(intentInfo.getAction(0));
+ for (int i = 0, max = intentInfo.countCategories(); i < max; i++) {
+ intent.addCategory(intentInfo.getCategory(i));
+ }
+ Uri data = null;
+ String dataType = null;
+ if (intentInfo.countDataTypes() > 1) {
+ outError[0] = "intent tag may have at most one data type.";
+ return false;
+ }
+ if (intentInfo.countDataSchemes() > 1) {
+ outError[0] = "intent tag may have at most one data scheme.";
+ return false;
+ }
+ if (intentInfo.countDataTypes() == 1) {
+ data = Uri.fromParts(intentInfo.getDataType(0), "", null);
+ }
+ if (intentInfo.countDataSchemes() == 1) {
+ dataType = intentInfo.getDataScheme(0);
+ }
+ intent.setDataAndType(data, dataType);
+ owner.mQueriesIntents = ArrayUtils.add(owner.mQueriesIntents, intent);
+ } else if (parser.getName().equals("package")) {
+ final TypedArray sa = res.obtainAttributes(parser,
+ com.android.internal.R.styleable.AndroidManifestQueriesPackage);
+ final String packageName =
+ sa.getString(R.styleable.AndroidManifestQueriesPackage_name);
+ if (TextUtils.isEmpty(packageName)) {
+ outError[0] = "Package name is missing from package tag.";
+ return false;
+ }
+ owner.mQueriesPackages =
+ ArrayUtils.add(owner.mQueriesPackages, packageName.intern());
+ }
+ }
+ return true;
+ }
+
/**
* Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI
*/
@@ -6514,6 +6580,9 @@ public class PackageParser {
// The major version code declared for this package.
public int mVersionCodeMajor;
+ // Whether the package declares that it should be queryable by all normal apps on device.
+ public boolean mForceQueryable;
+
// Return long containing mVersionCode and mVersionCodeMajor.
public long getLongVersionCode() {
return PackageInfo.composeLongVersionCode(mVersionCodeMajor, mVersionCode);
@@ -6619,6 +6688,9 @@ public class PackageParser {
/** Whether or not the package is a stub and must be replaced by the full version. */
public boolean isStub;
+ public ArrayList<String> mQueriesPackages;
+ public ArrayList<Intent> mQueriesIntents;
+
@UnsupportedAppUsage
public Package(String packageName) {
this.packageName = packageName;
@@ -7122,6 +7194,9 @@ public class PackageParser {
use32bitAbi = (dest.readInt() == 1);
restrictUpdateHash = dest.createByteArray();
visibleToInstantApps = dest.readInt() == 1;
+ mForceQueryable = dest.readBoolean();
+ mQueriesIntents = dest.createTypedArrayList(Intent.CREATOR);
+ mQueriesPackages = dest.createStringArrayList();
}
private static void internStringArrayList(List<String> list) {
@@ -7247,6 +7322,9 @@ public class PackageParser {
dest.writeInt(use32bitAbi ? 1 : 0);
dest.writeByteArray(restrictUpdateHash);
dest.writeInt(visibleToInstantApps ? 1 : 0);
+ dest.writeBoolean(mForceQueryable);
+ dest.writeTypedList(mQueriesIntents);
+ dest.writeList(mQueriesPackages);
}
@@ -8257,6 +8335,8 @@ public class PackageParser {
}
}
+ public static final class QueriesIntentInfo extends IntentInfo {}
+
public final static class ActivityIntentInfo extends IntentInfo {
@UnsupportedAppUsage
public Activity activity;
diff --git a/core/java/android/os/SharedMemory.java b/core/java/android/os/SharedMemory.java
index 57a88012a31a..3e2ba3d3115f 100644
--- a/core/java/android/os/SharedMemory.java
+++ b/core/java/android/os/SharedMemory.java
@@ -62,7 +62,7 @@ public final class SharedMemory implements Parcelable, Closeable {
mMemoryRegistration = new MemoryRegistration(mSize);
mCleaner = Cleaner.create(mFileDescriptor,
- new Closer(mFileDescriptor, mMemoryRegistration));
+ new Closer(mFileDescriptor.getInt$(), mMemoryRegistration));
}
/**
@@ -290,10 +290,10 @@ public final class SharedMemory implements Parcelable, Closeable {
* Cleaner that closes the FD
*/
private static final class Closer implements Runnable {
- private FileDescriptor mFd;
+ private int mFd;
private MemoryRegistration mMemoryReference;
- private Closer(FileDescriptor fd, MemoryRegistration memoryReference) {
+ private Closer(int fd, MemoryRegistration memoryReference) {
mFd = fd;
mMemoryReference = memoryReference;
}
@@ -301,7 +301,9 @@ public final class SharedMemory implements Parcelable, Closeable {
@Override
public void run() {
try {
- Os.close(mFd);
+ FileDescriptor fd = new FileDescriptor();
+ fd.setInt$(mFd);
+ Os.close(fd);
} catch (ErrnoException e) { /* swallow error */ }
mMemoryReference.release();
mMemoryReference = null;
diff --git a/core/java/android/provider/CalendarContract.java b/core/java/android/provider/CalendarContract.java
index 2f68eb475e7a..d862d6022154 100644
--- a/core/java/android/provider/CalendarContract.java
+++ b/core/java/android/provider/CalendarContract.java
@@ -40,7 +40,7 @@ import android.database.DatabaseUtils;
import android.net.Uri;
import android.os.RemoteException;
import android.text.format.DateUtils;
-import android.text.format.Time;
+import android.text.format.TimeMigrationUtils;
import android.util.Log;
import com.android.internal.util.Preconditions;
@@ -1680,7 +1680,7 @@ public final class CalendarContract {
* <h3>Writing to Events</h3> There are further restrictions on all Updates
* and Inserts in the Events table:
* <ul>
- * <li>If allDay is set to 1 eventTimezone must be {@link Time#TIMEZONE_UTC}
+ * <li>If allDay is set to 1 eventTimezone must be "UTC"
* and the time must correspond to a midnight boundary.</li>
* <li>Exceptions are not allowed to recur. If rrule or rdate is not empty,
* original_id and original_sync_id must be empty.</li>
@@ -2608,9 +2608,7 @@ public final class CalendarContract {
@UnsupportedAppUsage
public static void scheduleAlarm(Context context, AlarmManager manager, long alarmTime) {
if (DEBUG) {
- Time time = new Time();
- time.set(alarmTime);
- String schedTime = time.format(" %a, %b %d, %Y %I:%M%P");
+ String schedTime = TimeMigrationUtils.formatMillisWithFixedFormat(alarmTime);
Log.d(TAG, "Schedule alarm at " + alarmTime + " " + schedTime);
}
diff --git a/core/java/android/text/format/TimeFormatter.java b/core/java/android/text/format/TimeFormatter.java
index 5a14092c95a8..f7fd89d7d819 100644
--- a/core/java/android/text/format/TimeFormatter.java
+++ b/core/java/android/text/format/TimeFormatter.java
@@ -26,6 +26,9 @@ import libcore.icu.LocaleData;
import libcore.util.ZoneInfo;
import java.nio.CharBuffer;
+import java.time.Instant;
+import java.time.LocalDateTime;
+import java.time.ZoneId;
import java.util.Formatter;
import java.util.Locale;
import java.util.TimeZone;
@@ -86,6 +89,59 @@ class TimeFormatter {
}
/**
+ * The implementation of {@link TimeMigrationUtils#formatMillisWithFixedFormat(long)} for
+ * 2038-safe formatting with the pattern "%Y-%m-%d %H:%M:%S" and including the historic
+ * incorrect digit localization behavior.
+ */
+ String formatMillisWithFixedFormat(long timeMillis) {
+ // This method is deliberately not a general purpose replacement for
+ // format(String, ZoneInfo.WallTime, ZoneInfo): It hard-codes the pattern used; many of the
+ // pattern characters supported by Time.format() have unusual behavior which would make
+ // using java.time.format or similar packages difficult. It would be a lot of work to share
+ // behavior and many internal Android usecases can be covered by this common pattern
+ // behavior.
+
+ // No need to worry about overflow / underflow: long millis is representable by Instant and
+ // LocalDateTime with room to spare.
+ Instant instant = Instant.ofEpochMilli(timeMillis);
+
+ // Date/times are calculated in the current system default time zone.
+ LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
+
+ // You'd think it would be as simple as:
+ // DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", locale);
+ // return formatter.format(localDateTime);
+ // but we retain Time's behavior around digits.
+
+ StringBuilder stringBuilder = new StringBuilder(19);
+
+ // This effectively uses the US locale because number localization is handled separately
+ // (see below).
+ stringBuilder.append(localDateTime.getYear());
+ stringBuilder.append('-');
+ append2DigitNumber(stringBuilder, localDateTime.getMonthValue());
+ stringBuilder.append('-');
+ append2DigitNumber(stringBuilder, localDateTime.getDayOfMonth());
+ stringBuilder.append(' ');
+ append2DigitNumber(stringBuilder, localDateTime.getHour());
+ stringBuilder.append(':');
+ append2DigitNumber(stringBuilder, localDateTime.getMinute());
+ stringBuilder.append(':');
+ append2DigitNumber(stringBuilder, localDateTime.getSecond());
+
+ String result = stringBuilder.toString();
+ return localizeDigits(result);
+ }
+
+ /** Zero-pads value as needed to achieve a 2-digit number. */
+ private static void append2DigitNumber(StringBuilder builder, int value) {
+ if (value < 10) {
+ builder.append('0');
+ }
+ builder.append(value);
+ }
+
+ /**
* Format the specified {@code wallTime} using {@code pattern}. The output is returned.
*/
public String format(String pattern, ZoneInfo.WallTime wallTime, ZoneInfo zoneInfo) {
@@ -99,12 +155,9 @@ class TimeFormatter {
formatInternal(pattern, wallTime, zoneInfo);
String result = stringBuilder.toString();
- // This behavior is the source of a bug since some formats are defined as being
- // in ASCII and not localized.
- if (localeData.zeroDigit != '0') {
- result = localizeDigits(result);
- }
- return result;
+ // The localizeDigits() behavior is the source of a bug since some formats are defined
+ // as being in ASCII and not localized.
+ return localizeDigits(result);
} finally {
outputBuilder = null;
numberFormatter = null;
@@ -112,6 +165,10 @@ class TimeFormatter {
}
private String localizeDigits(String s) {
+ if (localeData.zeroDigit == '0') {
+ return s;
+ }
+
int length = s.length();
int offsetToLocalizedDigits = localeData.zeroDigit - '0';
StringBuilder result = new StringBuilder(length);
diff --git a/core/java/android/text/format/TimeMigrationUtils.java b/core/java/android/text/format/TimeMigrationUtils.java
new file mode 100644
index 000000000000..17bac8d67b26
--- /dev/null
+++ b/core/java/android/text/format/TimeMigrationUtils.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.text.format;
+
+/**
+ * Logic to ease migration away from {@link Time} in Android internal code. {@link Time} is
+ * afflicted by the Y2038 issue and deprecated. The methods here are intended to allow minimal
+ * changes to classes that use {@link Time} for common behavior.
+ *
+ * @hide
+ */
+public class TimeMigrationUtils {
+
+ private TimeMigrationUtils() {}
+
+ /**
+ * A Y2038-safe replacement for various users of the {@link Time#format(String)} with the
+ * pattern "%Y-%m-%d %H:%M:%S". Note, this method retains the unusual localization behavior
+ * originally implemented by Time, which can lead to non-latin numbers being produced if the
+ * default locale does not use latin numbers.
+ */
+ public static String formatMillisWithFixedFormat(long timeMillis) {
+ // Delegate to TimeFormatter so that the unusual localization / threading behavior can be
+ // reused.
+ return new TimeFormatter().formatMillisWithFixedFormat(timeMillis);
+ }
+}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 5a9ab3811498..6aef5a5cf2a5 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -40,6 +40,7 @@ public class FeatureFlagUtils {
public static final String HEARING_AID_SETTINGS = "settings_bluetooth_hearing_aid";
public static final String SCREENRECORD_LONG_PRESS = "settings_screenrecord_long_press";
public static final String DYNAMIC_SYSTEM = "settings_dynamic_system";
+ public static final String SETTINGS_WIFITRACKER2 = "settings_wifitracker2";
private static final Map<String, String> DEFAULT_FLAGS;
@@ -56,6 +57,7 @@ public class FeatureFlagUtils {
DEFAULT_FLAGS.put(SCREENRECORD_LONG_PRESS, "false");
DEFAULT_FLAGS.put("settings_wifi_details_datausage_header", "false");
DEFAULT_FLAGS.put("settings_skip_direction_mutable", "true");
+ DEFAULT_FLAGS.put(SETTINGS_WIFITRACKER2, "false");
}
/**
diff --git a/core/java/android/view/IRecentsAnimationController.aidl b/core/java/android/view/IRecentsAnimationController.aidl
index 956161acd762..955be8d40c47 100644
--- a/core/java/android/view/IRecentsAnimationController.aidl
+++ b/core/java/android/view/IRecentsAnimationController.aidl
@@ -77,6 +77,21 @@ interface IRecentsAnimationController {
void hideCurrentInputMethod();
/**
+ * This call is deprecated, use #setDeferCancelUntilNextTransition() instead
+ * TODO(138144750): Remove this method once there are no callers
+ * @deprecated
+ */
+ void setCancelWithDeferredScreenshot(boolean screenshot);
+
+ /**
+ * Clean up the screenshot of previous task which was created during recents animation that
+ * was cancelled by a stack order change.
+ *
+ * @see {@link IRecentsAnimationRunner#onAnimationCanceled}
+ */
+ void cleanupScreenshot();
+
+ /**
* Set a state for controller whether would like to cancel recents animations with deferred
* task screenshot presentation.
*
@@ -86,22 +101,23 @@ interface IRecentsAnimationController {
* screenshot, so that Launcher can still control the leash lifecycle & make the next app
* transition animate smoothly without flickering.
*
- * @param screenshot When set {@code true}, means recents animation will be canceled when the
- * next app launch. System will take previous task's screenshot when the next
- * app transition starting, and skip previous task's animation.
- * Set {@code false} means will not take screenshot & skip animation
- * for previous task.
+ * @param defer When set {@code true}, means that the recents animation will defer canceling the
+ * animation when a stack order change is triggered until the subsequent app
+ * transition start and skip previous task's animation.
+ * When set to {@code false}, means that the recents animation will be canceled
+ * immediately when the stack order changes.
+ * @param screenshot When set {@code true}, means that the system will take previous task's
+ * screenshot and replace the contents of the leash with it when the next app
+ * transition starting. The runner must call #cleanupScreenshot() to end the
+ * recents animation.
+ * When set to {@code false}, means that the system will simply wait for the
+ * next app transition start to immediately cancel the recents animation. This
+ * can be useful when you want an immediate transition into a state where the
+ * task is shown in the home/recents activity (without waiting for a
+ * screenshot).
*
* @see #cleanupScreenshot()
* @see IRecentsAnimationRunner#onCancelled
*/
- void setCancelWithDeferredScreenshot(boolean screenshot);
-
- /**
- * Clean up the screenshot of previous task which was created during recents animation that
- * was cancelled by a stack order change.
- *
- * @see {@link IRecentsAnimationRunner#onAnimationCanceled}
- */
- void cleanupScreenshot();
+ void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot);
}
diff --git a/core/java/android/view/IRecentsAnimationRunner.aidl b/core/java/android/view/IRecentsAnimationRunner.aidl
index 9c652a8d990b..6cda60c80b7d 100644
--- a/core/java/android/view/IRecentsAnimationRunner.aidl
+++ b/core/java/android/view/IRecentsAnimationRunner.aidl
@@ -36,7 +36,7 @@ oneway interface IRecentsAnimationRunner {
* @param deferredWithScreenshot If set to {@code true}, the contents of the task will be
* replaced with a screenshot, such that the runner's leash is
* still active. As soon as the runner doesn't need the leash
- * anymore, it can call
+ * anymore, it must call
* {@link IRecentsAnimationController#cleanupScreenshot).
*
* @see {@link RecentsAnimationController#cleanupScreenshot}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 9cc6b287431e..1a6689838545 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -96,7 +96,7 @@ import java.util.concurrent.locks.ReentrantLock;
* artifacts may occur on previous versions of the platform when its window is
* positioned asynchronously.</p>
*/
-public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallback {
+public class SurfaceView extends View implements ViewRootImpl.SurfaceChangedCallback {
private static final String TAG = "SurfaceView";
private static final boolean DEBUG = false;
private static final boolean DEBUG_POSITION = false;
@@ -227,9 +227,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
mRequestedVisible = mViewVisibility && mWindowVisibility && !mWindowStopped;
}
- /** @hide */
- @Override
- public void windowStopped(boolean stopped) {
+ private void setWindowStopped(boolean stopped) {
mWindowStopped = stopped;
updateRequestedVisibility();
updateSurface();
@@ -239,7 +237,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
protected void onAttachedToWindow() {
super.onAttachedToWindow();
- getViewRootImpl().addWindowStoppedCallback(this);
+ getViewRootImpl().addSurfaceChangedCallback(this);
mWindowStopped = false;
mViewVisibility = getVisibility() == VISIBLE;
@@ -459,7 +457,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
// the lifecycle. Instead of attaching it to a view, he/she can just pass
// the SurfaceHolder forward, most live wallpapers do it.
if (viewRoot != null) {
- viewRoot.removeWindowStoppedCallback(this);
+ viewRoot.removeSurfaceChangedCallback(this);
}
mAttachedToWindow = false;
@@ -1349,4 +1347,33 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb
public SurfaceControl getSurfaceControl() {
return mSurfaceControl;
}
+
+ /**
+ * Set window stopped to false and update surface visibility when ViewRootImpl surface is
+ * created.
+ * @hide
+ */
+ @Override
+ public void surfaceCreated(SurfaceControl.Transaction t) {
+ setWindowStopped(false);
+ }
+
+ /**
+ * Set window stopped to true and update surface visibility when ViewRootImpl surface is
+ * destroyed.
+ * @hide
+ */
+ @Override
+ public void surfaceDestroyed() {
+ setWindowStopped(true);
+ }
+
+ /**
+ * Called when a valid ViewRootImpl surface is replaced by another valid surface.
+ * @hide
+ */
+ @Override
+ public void surfaceReplaced(SurfaceControl.Transaction t) {
+
+ }
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 613ddcf577ed..354cc9645635 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -478,6 +478,12 @@ public final class ViewRootImpl implements ViewParent,
private final SurfaceControl mSurfaceControl = new SurfaceControl();
/**
+ * Transaction object that can be used to synchronize child SurfaceControl changes with
+ * ViewRootImpl SurfaceControl changes by the server. The object is passed along with
+ * the SurfaceChangedCallback.
+ */
+ private final Transaction mSurfaceChangedTransaction = new Transaction();
+ /**
* Child surface of {@code mSurface} with the same bounds as its parent, and crop bounds
* are set to the parent's bounds adjusted for surface insets. This surface is created when
* {@link ViewRootImpl#createBoundsSurface(int)} is called.
@@ -1541,19 +1547,6 @@ public final class ViewRootImpl implements ViewParent,
mIsAmbientMode = ambient;
}
- interface WindowStoppedCallback {
- public void windowStopped(boolean stopped);
- }
- private final ArrayList<WindowStoppedCallback> mWindowStoppedCallbacks = new ArrayList<>();
-
- void addWindowStoppedCallback(WindowStoppedCallback c) {
- mWindowStoppedCallbacks.add(c);
- }
-
- void removeWindowStoppedCallback(WindowStoppedCallback c) {
- mWindowStoppedCallbacks.remove(c);
- }
-
void setWindowStopped(boolean stopped) {
checkThread();
if (mStopped != stopped) {
@@ -1570,14 +1563,11 @@ public final class ViewRootImpl implements ViewParent,
if (renderer != null) {
renderer.destroyHardwareResources(mView);
}
- }
-
- for (int i = 0; i < mWindowStoppedCallbacks.size(); i++) {
- mWindowStoppedCallbacks.get(i).windowStopped(stopped);
- }
- if (mStopped) {
- if (mSurfaceHolder != null && mSurface.isValid()) {
+ if (mSurface.isValid()) {
+ if (mSurfaceHolder != null) {
+ notifyHolderSurfaceDestroyed();
+ }
notifySurfaceDestroyed();
}
destroySurface();
@@ -1585,6 +1575,46 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ /** Register callbacks to be notified when the ViewRootImpl surface changes. */
+ interface SurfaceChangedCallback {
+ void surfaceCreated(Transaction t);
+ void surfaceReplaced(Transaction t);
+ void surfaceDestroyed();
+ }
+
+ private final ArrayList<SurfaceChangedCallback> mSurfaceChangedCallbacks = new ArrayList<>();
+ void addSurfaceChangedCallback(SurfaceChangedCallback c) {
+ mSurfaceChangedCallbacks.add(c);
+ }
+
+ void removeSurfaceChangedCallback(SurfaceChangedCallback c) {
+ mSurfaceChangedCallbacks.remove(c);
+ }
+
+ private void notifySurfaceCreated() {
+ for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) {
+ mSurfaceChangedCallbacks.get(i).surfaceCreated(mSurfaceChangedTransaction);
+ }
+ }
+
+ /**
+ * Notify listeners when the ViewRootImpl surface has been replaced. This callback will not be
+ * called if a new surface is created, only if the valid surface has been replaced with another
+ * valid surface.
+ */
+ private void notifySurfaceReplaced() {
+ for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) {
+ mSurfaceChangedCallbacks.get(i).surfaceReplaced(mSurfaceChangedTransaction);
+ }
+ }
+
+ private void notifySurfaceDestroyed() {
+ for (int i = 0; i < mSurfaceChangedCallbacks.size(); i++) {
+ mSurfaceChangedCallbacks.get(i).surfaceDestroyed();
+ }
+ }
+
+
/**
* Creates a surface as a child of {@code mSurface} with the same bounds as its parent and
* crop bounds set to the parent's bounds adjusted for surface insets.
@@ -1984,7 +2014,7 @@ public final class ViewRootImpl implements ViewParent,
mIsInTraversal = true;
mWillDrawSoon = true;
boolean windowSizeMayChange = false;
- boolean surfaceChanged = false;
+ final boolean windowAttributesChanged = mWindowAttributesChanged;
WindowManager.LayoutParams lp = mWindowAttributes;
int desiredWindowWidth;
@@ -2003,7 +2033,6 @@ public final class ViewRootImpl implements ViewParent,
WindowManager.LayoutParams params = null;
if (mWindowAttributesChanged) {
mWindowAttributesChanged = false;
- surfaceChanged = true;
params = lp;
}
CompatibilityInfo compatibilityInfo =
@@ -2244,6 +2273,10 @@ public final class ViewRootImpl implements ViewParent,
final boolean isViewVisible = viewVisibility == View.VISIBLE;
final boolean windowRelayoutWasForced = mForceNextWindowRelayout;
boolean surfaceSizeChanged = false;
+ boolean surfaceCreated = false;
+ boolean surfaceDestroyed = false;
+ /* True if surface generation id changes. */
+ boolean surfaceReplaced = false;
if (mFirst || windowShouldResize || insetsChanged ||
viewVisibilityChanged || params != null || mForceNextWindowRelayout) {
@@ -2325,10 +2358,14 @@ public final class ViewRootImpl implements ViewParent,
final boolean outsetsChanged = !mPendingOutsets.equals(mAttachInfo.mOutsets);
surfaceSizeChanged = (relayoutResult
& WindowManagerGlobal.RELAYOUT_RES_SURFACE_RESIZED) != 0;
- surfaceChanged |= surfaceSizeChanged;
final boolean alwaysConsumeSystemBarsChanged =
mPendingAlwaysConsumeSystemBars != mAttachInfo.mAlwaysConsumeSystemBars;
final boolean colorModeChanged = hasColorModeChanged(lp.getColorMode());
+ surfaceCreated = !hadSurface && mSurface.isValid();
+ surfaceDestroyed = hadSurface && !mSurface.isValid();
+ surfaceReplaced = (surfaceGenerationId != mSurface.getGenerationId())
+ && mSurface.isValid();
+
if (contentInsetsChanged) {
mAttachInfo.mContentInsets.set(mPendingContentInsets);
if (DEBUG_LAYOUT) Log.v(mTag, "Content insets changing to: "
@@ -2383,33 +2420,32 @@ public final class ViewRootImpl implements ViewParent,
lp.getColorMode() == ActivityInfo.COLOR_MODE_WIDE_COLOR_GAMUT);
}
- if (!hadSurface) {
- if (mSurface.isValid()) {
- // If we are creating a new surface, then we need to
- // completely redraw it.
- mFullRedrawNeeded = true;
- mPreviousTransparentRegion.setEmpty();
+ if (surfaceCreated) {
+ // If we are creating a new surface, then we need to
+ // completely redraw it.
+ mFullRedrawNeeded = true;
+ mPreviousTransparentRegion.setEmpty();
- // Only initialize up-front if transparent regions are not
- // requested, otherwise defer to see if the entire window
- // will be transparent
- if (mAttachInfo.mThreadedRenderer != null) {
- try {
- hwInitialized = mAttachInfo.mThreadedRenderer.initialize(
- mSurface);
- if (hwInitialized && (host.mPrivateFlags
- & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
- // Don't pre-allocate if transparent regions
- // are requested as they may not be needed
- mAttachInfo.mThreadedRenderer.allocateBuffers();
- }
- } catch (OutOfResourcesException e) {
- handleOutOfResourcesException(e);
- return;
+ // Only initialize up-front if transparent regions are not
+ // requested, otherwise defer to see if the entire window
+ // will be transparent
+ if (mAttachInfo.mThreadedRenderer != null) {
+ try {
+ hwInitialized = mAttachInfo.mThreadedRenderer.initialize(
+ mSurface);
+ if (hwInitialized && (host.mPrivateFlags
+ & View.PFLAG_REQUEST_TRANSPARENT_REGIONS) == 0) {
+ // Don't pre-allocate if transparent regions
+ // are requested as they may not be needed
+ mAttachInfo.mThreadedRenderer.allocateBuffers();
}
+ } catch (OutOfResourcesException e) {
+ handleOutOfResourcesException(e);
+ return;
}
}
- } else if (!mSurface.isValid()) {
+ notifySurfaceCreated();
+ } else if (surfaceDestroyed) {
// If the surface has been removed, then reset the scroll
// positions.
if (mLastScrolledFocus != null) {
@@ -2427,10 +2463,12 @@ public final class ViewRootImpl implements ViewParent,
mAttachInfo.mThreadedRenderer.isEnabled()) {
mAttachInfo.mThreadedRenderer.destroy();
}
- } else if ((surfaceGenerationId != mSurface.getGenerationId()
+ notifySurfaceDestroyed();
+ } else if ((surfaceReplaced
|| surfaceSizeChanged || windowRelayoutWasForced || colorModeChanged)
&& mSurfaceHolder == null
- && mAttachInfo.mThreadedRenderer != null) {
+ && mAttachInfo.mThreadedRenderer != null
+ && mSurface.isValid()) {
mFullRedrawNeeded = true;
try {
// Need to do updateSurface (which leads to CanvasContext::setSurface and
@@ -2448,6 +2486,10 @@ public final class ViewRootImpl implements ViewParent,
}
}
+ if (!surfaceCreated && surfaceReplaced) {
+ notifySurfaceReplaced();
+ }
+
final boolean freeformResizing = (relayoutResult
& WindowManagerGlobal.RELAYOUT_RES_DRAG_RESIZING_FREEFORM) != 0;
final boolean dockedResizing = (relayoutResult
@@ -2503,31 +2545,32 @@ public final class ViewRootImpl implements ViewParent,
}
mSurfaceHolder.setSurfaceFrameSize(mWidth, mHeight);
mSurfaceHolder.mSurfaceLock.unlock();
- if (mSurface.isValid()) {
- if (!hadSurface) {
- mSurfaceHolder.ungetCallbacks();
-
- mIsCreating = true;
- SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
- if (callbacks != null) {
- for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceCreated(mSurfaceHolder);
- }
+ if (surfaceCreated) {
+ mSurfaceHolder.ungetCallbacks();
+
+ mIsCreating = true;
+ SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceCreated(mSurfaceHolder);
}
- surfaceChanged = true;
}
- if (surfaceChanged || surfaceGenerationId != mSurface.getGenerationId()) {
- SurfaceHolder.Callback callbacks[] = mSurfaceHolder.getCallbacks();
- if (callbacks != null) {
- for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceChanged(mSurfaceHolder, lp.format,
- mWidth, mHeight);
- }
+ }
+
+ if ((surfaceCreated || surfaceReplaced || surfaceSizeChanged
+ || windowAttributesChanged) && mSurface.isValid()) {
+ SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
+ if (callbacks != null) {
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceChanged(mSurfaceHolder, lp.format,
+ mWidth, mHeight);
}
}
mIsCreating = false;
- } else if (hadSurface) {
- notifySurfaceDestroyed();
+ }
+
+ if (surfaceDestroyed) {
+ notifyHolderSurfaceDestroyed();
mSurfaceHolder.mSurfaceLock.lock();
try {
mSurfaceHolder.mSurface = new Surface();
@@ -2841,7 +2884,7 @@ public final class ViewRootImpl implements ViewParent,
}
}
- private void notifySurfaceDestroyed() {
+ private void notifyHolderSurfaceDestroyed() {
mSurfaceHolder.ungetCallbacks();
SurfaceHolder.Callback[] callbacks = mSurfaceHolder.getCallbacks();
if (callbacks != null) {
@@ -3447,7 +3490,7 @@ public final class ViewRootImpl implements ViewParent,
private void reportDrawFinished() {
try {
mDrawsNeededToReport = 0;
- mWindowSession.finishDrawing(mWindow, null /* postDrawTransaction */);
+ mWindowSession.finishDrawing(mWindow, mSurfaceChangedTransaction);
} catch (RemoteException e) {
// Have fun!
}
diff --git a/core/java/android/widget/TabWidget.java b/core/java/android/widget/TabWidget.java
index 49a0f39b3bad..4c67b080252a 100644
--- a/core/java/android/widget/TabWidget.java
+++ b/core/java/android/widget/TabWidget.java
@@ -433,7 +433,7 @@ public class TabWidget extends LinearLayout implements OnFocusChangeListener {
* to the next tabbed view, in this example).
* <p>
* To move both the focus AND the selected tab at once, please use
- * {@link #setCurrentTab}. Normally, the view logic takes care of
+ * {@link #focusCurrentTab}. Normally, the view logic takes care of
* adjusting the focus, so unless you're circumventing the UI,
* you'll probably just focus your interest here.
*
diff --git a/core/java/android/widget/ViewAnimator.java b/core/java/android/widget/ViewAnimator.java
index 80ea363a6ad6..d36f3434e8c8 100644
--- a/core/java/android/widget/ViewAnimator.java
+++ b/core/java/android/widget/ViewAnimator.java
@@ -57,6 +57,9 @@ public class ViewAnimator extends FrameLayout {
super(context, attrs);
TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ViewAnimator);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.ViewAnimator,
+ attrs, a, 0, 0);
+
int resource = a.getResourceId(com.android.internal.R.styleable.ViewAnimator_inAnimation, 0);
if (resource > 0) {
setInAnimation(context, resource);
@@ -90,6 +93,8 @@ public class ViewAnimator extends FrameLayout {
// attribute to override.
final TypedArray a = context.obtainStyledAttributes(attrs,
com.android.internal.R.styleable.FrameLayout);
+ saveAttributeDataForStyleable(context, com.android.internal.R.styleable.FrameLayout,
+ attrs, a, 0, 0);
final boolean measureAllChildren = a.getBoolean(
com.android.internal.R.styleable.FrameLayout_measureAllChildren, true);
setMeasureAllChildren(measureAllChildren);
diff --git a/core/java/com/android/internal/os/KernelWakelockReader.java b/core/java/com/android/internal/os/KernelWakelockReader.java
index 3ac58e018a45..d53fadacb609 100644
--- a/core/java/com/android/internal/os/KernelWakelockReader.java
+++ b/core/java/com/android/internal/os/KernelWakelockReader.java
@@ -27,6 +27,7 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
+import java.io.File;
import java.io.FileInputStream;
import java.util.Iterator;
@@ -38,6 +39,7 @@ public class KernelWakelockReader {
private static int sKernelWakelockUpdateVersion = 0;
private static final String sWakelockFile = "/proc/wakelocks";
private static final String sWakeupSourceFile = "/d/wakeup_sources";
+ private static final String sSysClassWakeupDir = "/sys/class/wakeup";
private static final int[] PROC_WAKELOCKS_FORMAT = new int[] {
Process.PROC_TAB_TERM|Process.PROC_OUT_STRING| // 0: name
@@ -71,99 +73,108 @@ public class KernelWakelockReader {
* @return the updated data.
*/
public final KernelWakelockStats readKernelWakelockStats(KernelWakelockStats staleStats) {
- byte[] buffer = new byte[32*1024];
- int len = 0;
- boolean wakeup_sources;
- final long startTime = SystemClock.uptimeMillis();
+ boolean useSystemSuspend = (new File(sSysClassWakeupDir)).exists();
- final int oldMask = StrictMode.allowThreadDiskReadsMask();
- try {
- FileInputStream is;
- try {
- is = new FileInputStream(sWakelockFile);
- wakeup_sources = false;
- } catch (java.io.FileNotFoundException e) {
+ if (useSystemSuspend) {
+ WakeLockInfo[] wlStats = null;
+ if (mSuspendControlService == null) {
try {
- is = new FileInputStream(sWakeupSourceFile);
- wakeup_sources = true;
- } catch (java.io.FileNotFoundException e2) {
- Slog.wtf(TAG, "neither " + sWakelockFile + " nor " +
- sWakeupSourceFile + " exists");
+ mSuspendControlService = ISuspendControlService.Stub.asInterface(
+ ServiceManager.getServiceOrThrow("suspend_control"));
+ } catch (ServiceNotFoundException e) {
+ Slog.wtf(TAG, "Required service suspend_control not available", e);
return null;
}
}
- int cnt;
- while ((cnt = is.read(buffer, len, buffer.length - len)) > 0) {
- len += cnt;
+ try {
+ wlStats = mSuspendControlService.getWakeLockStats();
+ updateVersion(staleStats);
+ updateWakelockStats(wlStats, staleStats);
+ } catch (RemoteException e) {
+ Slog.wtf(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
+ return null;
}
- is.close();
- } catch (java.io.IOException e) {
- Slog.wtf(TAG, "failed to read kernel wakelocks", e);
- return null;
- } finally {
- StrictMode.setThreadPolicyMask(oldMask);
- }
+ return removeOldStats(staleStats);
- final long readTime = SystemClock.uptimeMillis() - startTime;
- if (readTime > 100) {
- Slog.w(TAG, "Reading wakelock stats took " + readTime + "ms");
- }
+ } else {
+ byte[] buffer = new byte[32*1024];
+ int len = 0;
+ boolean wakeup_sources;
+ final long startTime = SystemClock.uptimeMillis();
- if (len > 0) {
- if (len >= buffer.length) {
- Slog.wtf(TAG, "Kernel wake locks exceeded buffer size " + buffer.length);
- }
- int i;
- for (i=0; i<len; i++) {
- if (buffer[i] == '\0') {
- len = i;
- break;
+ final int oldMask = StrictMode.allowThreadDiskReadsMask();
+ try {
+ FileInputStream is;
+ try {
+ is = new FileInputStream(sWakelockFile);
+ wakeup_sources = false;
+ } catch (java.io.FileNotFoundException e) {
+ try {
+ is = new FileInputStream(sWakeupSourceFile);
+ wakeup_sources = true;
+ } catch (java.io.FileNotFoundException e2) {
+ Slog.wtf(TAG, "neither " + sWakelockFile + " nor " +
+ sWakeupSourceFile + " exists");
+ return null;
+ }
}
- }
- }
- updateVersion(staleStats);
+ int cnt;
+ while ((cnt = is.read(buffer, len, buffer.length - len)) > 0) {
+ len += cnt;
+ }
- parseProcWakelocks(buffer, len, wakeup_sources, staleStats);
+ is.close();
+ } catch (java.io.IOException e) {
+ Slog.wtf(TAG, "failed to read kernel wakelocks", e);
+ return null;
+ } finally {
+ StrictMode.setThreadPolicyMask(oldMask);
+ }
- if (mSuspendControlService == null) {
- try {
- mSuspendControlService = ISuspendControlService.Stub.asInterface(
- ServiceManager.getServiceOrThrow("suspend_control"));
- } catch (ServiceNotFoundException e) {
- Slog.wtf(TAG, "Required service suspend_control not available", e);
+ final long readTime = SystemClock.uptimeMillis() - startTime;
+ if (readTime > 100) {
+ Slog.w(TAG, "Reading wakelock stats took " + readTime + "ms");
}
- }
- try {
- WakeLockInfo[] wlStats = mSuspendControlService.getWakeLockStats();
- getNativeWakelockStats(wlStats, staleStats);
- } catch (RemoteException e) {
- Slog.wtf(TAG, "Failed to obtain wakelock stats from ISuspendControlService", e);
- }
+ if (len > 0) {
+ if (len >= buffer.length) {
+ Slog.wtf(TAG, "Kernel wake locks exceeded buffer size " + buffer.length);
+ }
+ int i;
+ for (i=0; i<len; i++) {
+ if (buffer[i] == '\0') {
+ len = i;
+ break;
+ }
+ }
+ }
- return removeOldStats(staleStats);
+ updateVersion(staleStats);
+ parseProcWakelocks(buffer, len, wakeup_sources, staleStats);
+ return removeOldStats(staleStats);
+ }
}
/**
- * Reads native wakelock stats from SystemSuspend and updates staleStats with the new
- * information.
+ * Updates statleStats with stats from SystemSuspend.
* @param staleStats Existing object to update.
* @return the updated stats.
*/
@VisibleForTesting
- public KernelWakelockStats getNativeWakelockStats(WakeLockInfo[] wlStats,
+ public KernelWakelockStats updateWakelockStats(WakeLockInfo[] wlStats,
final KernelWakelockStats staleStats) {
for (WakeLockInfo info : wlStats) {
if (!staleStats.containsKey(info.name)) {
staleStats.put(info.name, new KernelWakelockStats.Entry((int) info.activeCount,
- info.totalTime, sKernelWakelockUpdateVersion));
+ info.totalTime * 1000 /* ms to us */, sKernelWakelockUpdateVersion));
} else {
KernelWakelockStats.Entry kwlStats = staleStats.get(info.name);
kwlStats.mCount = (int) info.activeCount;
- kwlStats.mTotalTime = info.totalTime;
+ // Convert milliseconds to microseconds
+ kwlStats.mTotalTime = info.totalTime * 1000;
kwlStats.mVersion = sKernelWakelockUpdateVersion;
}
}
diff --git a/core/jni/android/graphics/Picture.cpp b/core/jni/android/graphics/Picture.cpp
index d29857d0cf12..d1b952130e88 100644
--- a/core/jni/android/graphics/Picture.cpp
+++ b/core/jni/android/graphics/Picture.cpp
@@ -100,8 +100,9 @@ void Picture::draw(Canvas* canvas) {
this->endRecording();
SkASSERT(NULL != mPicture.get());
}
- if (NULL != mPicture.get()) {
- mPicture->playback(canvas->asSkCanvas());
+
+ if (mPicture) {
+ canvas->drawPicture(*mPicture);
}
}
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index c3e7a36bef78..13e1dfa00160 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -259,6 +259,8 @@ static void load_maps(int pid, stats_t* stats, bool* foundSwapPss)
which_heap = HEAP_NATIVE;
} else if (base::StartsWith(name, "[stack")) {
which_heap = HEAP_STACK;
+ } else if (base::StartsWith(name, "[anon:stack_and_tls:")) {
+ which_heap = HEAP_STACK;
} else if (base::EndsWith(name, ".so")) {
which_heap = HEAP_SO;
is_swappable = true;
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index a3d4798647be..71e386011253 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -7,7 +7,7 @@ yaochen@google.com
yro@google.com
# Settings UI
-per-file settings_enums.proto=zhfan@google.com
+per-file settings_enums.proto=tmfang@google.com
# Frameworks
ogunwale@google.com
diff --git a/core/proto/android/app/settings_enums.proto b/core/proto/android/app/settings_enums.proto
index c023438eecc2..3323095a6244 100644
--- a/core/proto/android/app/settings_enums.proto
+++ b/core/proto/android/app/settings_enums.proto
@@ -2401,4 +2401,11 @@ enum PageId {
// OS: Q
// Note: Gear icon is shown next to gesture navigation preference and opens sensitivity dialog
SETTINGS_GESTURE_NAV_BACK_SENSITIVITY_DLG = 1748;
+
+ // ---- End Q Constants, all Q constants go above this line ----
+ // OPEN: Settings > Network & Internet > Wi-Fi > Click new network
+ // CATEGORY: SETTINGS
+ // OS: R
+ SETTINGS_WIFI_CONFIGURE_NETWORK = 1800;
+
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 40acebc40abd..aa440d348a57 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -727,7 +727,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.SEND_SMS"
@@ -741,7 +741,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.RECEIVE_SMS"
@@ -755,7 +755,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.READ_SMS"
@@ -769,7 +769,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.RECEIVE_WAP_PUSH"
@@ -783,7 +783,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.RECEIVE_MMS"
@@ -806,7 +806,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
@hide Pending API council approval -->
@@ -852,7 +852,7 @@
targetSdkVersion}</a> is 4 or higher.
<p> This is a soft restricted permission which cannot be held by an app it its
- full form until the installer on record did not whitelist the permission.
+ full form until the installer on record whitelists the permission.
Specifically, if the permission is whitelisted the holder app can access
external storage and the visual and aural media collections while if the
permission is not whitelisted the holder app can only access to the visual
@@ -860,7 +860,7 @@
meaning that the whitelist state can be specified only at install time and
cannot change until the app is installed. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
- -->
+ <p>Protection level: dangerous -->
<permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_sdcardRead"
@@ -881,8 +881,9 @@
read/write files in your application-specific directories returned by
{@link android.content.Context#getExternalFilesDir} and
{@link android.content.Context#getExternalCacheDir}.
- <p>Is this permission is not whitelisted for an app that targets an API level before
+ <p>If this permission is not whitelisted for an app that targets an API level before
{@link android.os.Build.VERSION_CODES#Q} this permission cannot be granted to apps.</p>
+ <p>Protection level: dangerous</p>
-->
<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:permissionGroup="android.permission-group.UNDEFINED"
@@ -892,7 +893,8 @@
android:protectionLevel="dangerous" />
<!-- Allows an application to access any geographic locations persisted in the
- user's shared collection. -->
+ user's shared collection.
+ <p>Protection level: dangerous -->
<permission android:name="android.permission.ACCESS_MEDIA_LOCATION"
android:permissionGroup="android.permission-group.UNDEFINED"
android:label="@string/permlab_mediaLocation"
@@ -949,7 +951,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
@@ -995,7 +997,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.READ_CALL_LOG"
@@ -1019,7 +1021,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
-->
<permission android:name="android.permission.WRITE_CALL_LOG"
@@ -1035,7 +1037,7 @@
<p>Protection level: dangerous
<p> This is a hard restricted permission which cannot be held by an app until
- the installer on record did not whitelist the permission. For more details see
+ the installer on record whitelists the permission. For more details see
{@link android.content.pm.PackageInstaller.SessionParams#setWhitelistedRestrictedPermissions(Set)}.
@deprecated Applications should use {@link android.telecom.CallRedirectionService} instead
@@ -1694,7 +1696,7 @@
<!-- Allows applications to pair bluetooth devices without user interaction, and to
allow or disallow phonebook access or message access.
- This is not available to third party applications. -->
+ <p>Not for use by third-party applications. -->
<permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
android:protectionLevel="signature|privileged" />
@@ -2544,7 +2546,8 @@
android:protectionLevel="signature" />
<!-- Allows an application to modify the current configuration, such
- as locale. -->
+ as locale.
+ <p>Protection level: signature|privileged|development -->
<permission android:name="android.permission.CHANGE_CONFIGURATION"
android:protectionLevel="signature|privileged|development" />
@@ -2843,7 +2846,8 @@
<!-- ==================================== -->
<eat-comment />
- <!-- Allows access to the list of accounts in the Accounts Service. -->
+ <!-- Allows access to the list of accounts in the Accounts Service.
+ <p>Protection level: signature|privileged -->
<permission android:name="android.permission.GET_ACCOUNTS_PRIVILEGED"
android:protectionLevel="signature|privileged" />
@@ -3429,7 +3433,8 @@
android:protectionLevel="signature" />
<!-- Old permission for deleting an app's cache files, no longer used,
- but signals for us to quietly ignore calls instead of throwing an exception. -->
+ but signals for us to quietly ignore calls instead of throwing an exception.
+ <p>Protection level: signature|privileged -->
<permission android:name="android.permission.DELETE_CACHE_FILES"
android:protectionLevel="signature|privileged" />
@@ -3792,7 +3797,8 @@
<!-- Allows an application to collect component usage
statistics
<p>Declaring the permission implies intention to use the API and the user of the
- device can grant permission through the Settings application. -->
+ device can grant permission through the Settings application.
+ <p>Protection level: signature|privileged|development|appop -->
<permission android:name="android.permission.PACKAGE_USAGE_STATS"
android:protectionLevel="signature|privileged|development|appop" />
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
@@ -3815,14 +3821,14 @@
<!-- Permission an application must hold in order to use
{@link android.provider.Settings#ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS}.
- This is a normal permission: an app requesting it will always be granted the
- permission, without the user needing to approve or see it. -->
+ <p>Protection level: normal -->
<permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"
android:label="@string/permlab_requestIgnoreBatteryOptimizations"
android:description="@string/permdesc_requestIgnoreBatteryOptimizations"
android:protectionLevel="normal" />
- <!-- Allows an application to collect battery statistics -->
+ <!-- Allows an application to collect battery statistics
+ <p>Protection level: signature|privileged|development -->
<permission android:name="android.permission.BATTERY_STATS"
android:protectionLevel="signature|privileged|development" />
@@ -3852,7 +3858,8 @@
android:protectionLevel="signature" />
<!-- Must be required by a {@link android.widget.RemoteViewsService},
- to ensure that only the system can bind to it. -->
+ to ensure that only the system can bind to it.
+ <p>Protection level: signature|privileged -->
<permission android:name="android.permission.BIND_REMOTEVIEWS"
android:protectionLevel="signature|privileged" />
@@ -3894,7 +3901,8 @@
to the path in the provider where global search queries are
performed. This permission can not be held by regular applications;
it is used by applications to protect themselves from everyone else
- besides global search. -->
+ besides global search.
+ <p>Protection level: signature|privileged -->
<permission android:name="android.permission.GLOBAL_SEARCH"
android:protectionLevel="signature|privileged" />
@@ -4433,7 +4441,8 @@
<permission android:name="android.permission.MODIFY_THEME_OVERLAY"
android:protectionLevel="signature" />
- <!-- Allows an instant app to create foreground services. -->
+ <!-- Allows an instant app to create foreground services.
+ <p>Protection level: signature|development|instant|appop -->
<permission android:name="android.permission.INSTANT_APP_FOREGROUND_SERVICE"
android:protectionLevel="signature|development|instant|appop" />
@@ -4503,7 +4512,8 @@
<permission android:name="android.permission.MONITOR_DEFAULT_SMS_PACKAGE"
android:protectionLevel="signature|privileged" />
- <!-- A subclass of {@link android.service.carrier.CarrierMessagingClientService} must be protected with this permission. -->
+ <!-- A subclass of {@link android.service.carrier.CarrierMessagingClientService} must be protected with this permission.
+ <p>Protection level: signature -->
<permission android:name="android.permission.BIND_CARRIER_MESSAGING_CLIENT_SERVICE"
android:protectionLevel="signature" />
@@ -4535,13 +4545,15 @@
<permission android:name="android.permission.GRANT_PROFILE_OWNER_DEVICE_IDS_ACCESS"
android:protectionLevel="signature" />
- <!-- Allows financial apps to read filtered sms messages. -->
+ <!-- Allows financial apps to read filtered sms messages.
+ Protection level: signature|appop -->
<permission android:name="android.permission.SMS_FINANCIAL_TRANSACTIONS"
android:protectionLevel="signature|appop" />
<!-- Required for apps targeting {@link android.os.Build.VERSION_CODES#Q} that want to use
{@link android.app.Notification.Builder#setFullScreenIntent notification full screen
- intents}. -->
+ intents}.
+ <p>Protection level: normal -->
<permission android:name="android.permission.USE_FULL_SCREEN_INTENT"
android:protectionLevel="normal" />
@@ -4598,6 +4610,7 @@
android:supportsRtl="true"
android:theme="@style/Theme.DeviceDefault.Light.DarkActionBar"
android:defaultToDeviceProtectedStorage="true"
+ android:forceQueryable="true"
android:directBootAware="true">
<activity android:name="com.android.internal.app.ChooserActivity"
android:theme="@style/Theme.DeviceDefault.Resolver"
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index be6cdcf3f098..3ea8a778ba9b 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -1743,6 +1743,13 @@
- {@code true} for apps with targetSdkVersion < 29.
-->
<attr name="requestLegacyExternalStorage" format="boolean" />
+
+ <!-- If {@code true} this app declares that it should be visible to all other apps on
+ device, regardless of what they declare via the {@code queries} tags in their
+ manifest.
+
+ The default value is {@code false}. -->
+ <attr name="forceQueryable" format="boolean" />
</declare-styleable>
<!-- The <code>permission</code> tag declares a security permission that can be
used to control access from other packages to specific components or
@@ -1977,6 +1984,12 @@
<attr name="name" />
</declare-styleable>
+ <declare-styleable name="AndroidManifestQueries" parent="AndroidManifest" />
+ <declare-styleable name="AndroidManifestQueriesPackage" parent="AndroidManifestQueries">
+ <attr name="name" />
+ </declare-styleable>
+ <declare-styleable name="AndroidManifestQueriesIntent" parent="AndroidManifestQueries" />
+
<!-- The <code>static-library</code> tag declares that this apk is providing itself
as a static shared library for other applications to use. Any app can declare such
@@ -2477,6 +2490,7 @@
<!-- High dynamic range color mode. -->
<enum name="hdr" value="2" />
</attr>
+ <attr name="forceQueryable" format="boolean" />
</declare-styleable>
<!-- The <code>activity-alias</code> tag declares a new
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 3b1275354d1f..dce4bf3f1ed4 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1700,6 +1700,12 @@
<!-- Add packages here -->
</string-array>
+ <string-array name="config_forceQueryablePackages" translatable="false">
+ <item>com.android.settings</item>
+ <!-- Add packages here -->
+ </string-array>
+
+
<!-- Component name of the default wallpaper. This will be ImageWallpaper if not
specified -->
<string name="default_wallpaper_component" translatable="false">@null</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index d91bbd006318..123deeb421b7 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -786,6 +786,7 @@
<java-symbol type="string" name="widget_default_class_name" />
<java-symbol type="string" name="emergency_calls_only" />
<java-symbol type="array" name="config_ephemeralResolverPackage" />
+ <java-symbol type="array" name="config_forceQueryablePackages" />
<java-symbol type="string" name="eventTypeAnniversary" />
<java-symbol type="string" name="eventTypeBirthday" />
<java-symbol type="string" name="eventTypeCustom" />
diff --git a/core/tests/coretests/src/android/text/format/TimeMigrationUtilsTest.java b/core/tests/coretests/src/android/text/format/TimeMigrationUtilsTest.java
new file mode 100644
index 000000000000..b605520c659d
--- /dev/null
+++ b/core/tests/coretests/src/android/text/format/TimeMigrationUtilsTest.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.text.format;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Locale;
+import java.util.TimeZone;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class TimeMigrationUtilsTest {
+
+ private static final int ONE_DAY_IN_SECONDS = 24 * 60 * 60;
+
+ private Locale mDefaultLocale;
+ private TimeZone mDefaultTimeZone;
+
+ @Before
+ public void setUp() {
+ mDefaultLocale = Locale.getDefault();
+ mDefaultTimeZone = TimeZone.getDefault();
+ }
+
+ @After
+ public void tearDown() {
+ Locale.setDefault(mDefaultLocale);
+ TimeZone.setDefault(mDefaultTimeZone);
+ }
+
+ @Test
+ public void formatMillisWithFixedFormat_fixes2038Issue() {
+ Locale.setDefault(Locale.UK);
+ TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+
+ // The following cannot be represented properly using Time because they are outside of the
+ // supported range.
+ long y2038Issue1 = (((long) Integer.MIN_VALUE) - ONE_DAY_IN_SECONDS) * 1000L;
+ assertEquals(
+ "1901-12-12 20:45:52", TimeMigrationUtils.formatMillisWithFixedFormat(y2038Issue1));
+ long y2038Issue2 = (((long) Integer.MAX_VALUE) + ONE_DAY_IN_SECONDS) * 1000L;
+ assertEquals(
+ "2038-01-20 03:14:07", TimeMigrationUtils.formatMillisWithFixedFormat(y2038Issue2));
+ }
+
+ /**
+ * Compares TimeMigrationUtils.formatSimpleDateTime() with the code it is replacing.
+ */
+ @Test
+ public void formatMillisAsDateTime_matchesOldBehavior() {
+ // A selection of interesting locales.
+ Locale[] locales = new Locale[] {
+ Locale.US,
+ Locale.UK,
+ Locale.FRANCE,
+ Locale.JAPAN,
+ Locale.CHINA,
+ // Android supports RTL locales like arabic and arabic with latin numbers.
+ Locale.forLanguageTag("ar-AE"),
+ Locale.forLanguageTag("ar-AE-u-nu-latn"),
+ };
+ // A selection of interesting time zones.
+ String[] timeZoneIds = new String[] {
+ "UTC", "Europe/London", "America/New_York", "America/Los_Angeles", "Asia/Shanghai",
+ };
+ // Some arbitrary times when the two formatters should agree.
+ long[] timesMillis = new long[] {
+ System.currentTimeMillis(),
+ 0,
+ // The Time class only works in 32-bit range, the replacement works beyond that. To
+ // avoid messing around with offsets and complicating the test, below there are a
+ // day after / before the known limits.
+ (Integer.MIN_VALUE + ONE_DAY_IN_SECONDS) * 1000L,
+ (Integer.MAX_VALUE - ONE_DAY_IN_SECONDS) * 1000L,
+ };
+
+ for (Locale locale : locales) {
+ Locale.setDefault(locale);
+ for (String timeZoneId : timeZoneIds) {
+ TimeZone timeZone = TimeZone.getTimeZone(timeZoneId);
+ TimeZone.setDefault(timeZone);
+ for (long timeMillis : timesMillis) {
+ Time time = new Time();
+ time.set(timeMillis);
+ String oldResult = time.format("%Y-%m-%d %H:%M:%S");
+ String newResult = TimeMigrationUtils.formatMillisWithFixedFormat(timeMillis);
+ assertEquals(
+ "locale=" + locale + ", timeZoneId=" + timeZoneId
+ + ", timeMillis=" + timeMillis,
+ oldResult, newResult);
+ }
+ }
+ }
+ }
+}
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index adaae5cdba8d..682416c58c72 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -132,6 +132,8 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon
public void sendGesture(int sequence, ParceledListSlice gestureSteps) {}
+ public void dispatchGesture(int sequence, ParceledListSlice gestureSteps, int displayId) {}
+
public boolean isFingerprintGestureDetectionAvailable() {
return false;
}
diff --git a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
index 008085e38dbf..a93573724ba1 100644
--- a/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/KernelWakelockReaderTest.java
@@ -68,12 +68,7 @@ public class KernelWakelockReaderTest extends TestCase {
private WakeLockInfo createWakeLockInfo(String name, int activeCount, long totalTime) {
WakeLockInfo info = new WakeLockInfo();
info.name = name;
- info.pid = 1;
info.activeCount = activeCount;
- info.isActive = true;
- info.activeSince = 0;
- info.lastChange = 0;
- info.maxTime = 0;
info.totalTime = totalTime;
return info;
}
@@ -89,7 +84,7 @@ public class KernelWakelockReaderTest extends TestCase {
byte[] buffer, WakeLockInfo[] wlStats) {
mReader.updateVersion(staleStats);
mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats);
- mReader.getNativeWakelockStats(wlStats, staleStats);
+ mReader.updateWakelockStats(wlStats, staleStats);
return mReader.removeOldStats(staleStats);
}
@@ -101,7 +96,7 @@ public class KernelWakelockReaderTest extends TestCase {
mReader = new KernelWakelockReader();
}
-// ------------------------- Kernel Wakelock Stats Test ------------------------
+// ------------------------- Legacy Wakelock Stats Test ------------------------
@SmallTest
public void testParseEmptyFile() throws Exception {
KernelWakelockStats staleStats = mReader.parseProcWakelocks(new byte[0], 0, true,
@@ -196,10 +191,10 @@ public class KernelWakelockReaderTest extends TestCase {
assertFalse(staleStats.containsKey("Fakelock"));
}
-// -------------------- Native (SystemSuspend) Wakelock Stats Test -------------------
+// -------------------- SystemSuspend Wakelock Stats Test -------------------
@SmallTest
public void testEmptyWakeLockInfoList() {
- KernelWakelockStats staleStats = mReader.getNativeWakelockStats(new WakeLockInfo[0],
+ KernelWakelockStats staleStats = mReader.updateWakelockStats(new WakeLockInfo[0],
new KernelWakelockStats());
assertTrue(staleStats.isEmpty());
@@ -208,9 +203,9 @@ public class KernelWakelockReaderTest extends TestCase {
@SmallTest
public void testOneWakeLockInfo() {
WakeLockInfo[] wlStats = new WakeLockInfo[1];
- wlStats[0] = createWakeLockInfo("WakeLock", 20, 10000);
+ wlStats[0] = createWakeLockInfo("WakeLock", 20, 1000); // Milliseconds
- KernelWakelockStats staleStats = mReader.getNativeWakelockStats(wlStats,
+ KernelWakelockStats staleStats = mReader.updateWakelockStats(wlStats,
new KernelWakelockStats());
assertEquals(1, staleStats.size());
@@ -219,16 +214,16 @@ public class KernelWakelockReaderTest extends TestCase {
KernelWakelockStats.Entry entry = staleStats.get("WakeLock");
assertEquals(20, entry.mCount);
- assertEquals(10000, entry.mTotalTime);
+ assertEquals(1000 * 1000, entry.mTotalTime); // Microseconds
}
@SmallTest
public void testTwoWakeLockInfos() {
WakeLockInfo[] wlStats = new WakeLockInfo[2];
- wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000);
- wlStats[1] = createWakeLockInfo("WakeLock2", 20, 2000);
+ wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000); // Milliseconds
+ wlStats[1] = createWakeLockInfo("WakeLock2", 20, 2000); // Milliseconds
- KernelWakelockStats staleStats = mReader.getNativeWakelockStats(wlStats,
+ KernelWakelockStats staleStats = mReader.updateWakelockStats(wlStats,
new KernelWakelockStats());
assertEquals(2, staleStats.size());
@@ -238,17 +233,17 @@ public class KernelWakelockReaderTest extends TestCase {
KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
assertEquals(10, entry1.mCount);
- assertEquals(1000, entry1.mTotalTime);
+ assertEquals(1000 * 1000, entry1.mTotalTime); // Microseconds
KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
assertEquals(20, entry2.mCount);
- assertEquals(2000, entry2.mTotalTime);
+ assertEquals(2000 * 1000, entry2.mTotalTime); // Microseconds
}
@SmallTest
public void testWakeLockInfosBecomeStale() {
WakeLockInfo[] wlStats = new WakeLockInfo[1];
- wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000);
+ wlStats[0] = createWakeLockInfo("WakeLock1", 10, 1000); // Milliseconds
KernelWakelockStats staleStats = new KernelWakelockStats();
@@ -259,9 +254,9 @@ public class KernelWakelockReaderTest extends TestCase {
assertTrue(staleStats.containsKey("WakeLock1"));
KernelWakelockStats.Entry entry = staleStats.get("WakeLock1");
assertEquals(10, entry.mCount);
- assertEquals(1000, entry.mTotalTime);
+ assertEquals(1000 * 1000, entry.mTotalTime); // Microseconds
- wlStats[0] = createWakeLockInfo("WakeLock2", 20, 2000);
+ wlStats[0] = createWakeLockInfo("WakeLock2", 20, 2000); // Milliseconds
readKernelWakelockStats(staleStats, new byte[0], wlStats);
@@ -271,146 +266,6 @@ public class KernelWakelockReaderTest extends TestCase {
assertTrue(staleStats.containsKey("WakeLock2"));
entry = staleStats.get("WakeLock2");
assertEquals(20, entry.mCount);
- assertEquals(2000, entry.mTotalTime);
- }
-
-// -------------------- Aggregate Wakelock Stats Tests --------------------
- @SmallTest
- public void testAggregateStatsEmpty() throws Exception {
- KernelWakelockStats staleStats = new KernelWakelockStats();
-
- byte[] buffer = new byte[0];
- WakeLockInfo[] wlStats = new WakeLockInfo[0];
-
- readKernelWakelockStats(staleStats, buffer, wlStats);
-
- assertTrue(staleStats.isEmpty());
- }
-
- @SmallTest
- public void testAggregateStatsNoNativeWakelocks() throws Exception {
- KernelWakelockStats staleStats = new KernelWakelockStats();
-
- byte[] buffer = new ProcFileBuilder()
- .addLine("Wakelock", 34, 123) // Milliseconds
- .getBytes();
- WakeLockInfo[] wlStats = new WakeLockInfo[0];
-
- readKernelWakelockStats(staleStats, buffer, wlStats);
-
- assertEquals(1, staleStats.size());
-
- assertTrue(staleStats.containsKey("Wakelock"));
-
- KernelWakelockStats.Entry entry = staleStats.get("Wakelock");
- assertEquals(34, entry.mCount);
- assertEquals(1000 * 123, entry.mTotalTime); // Microseconds
- }
-
- @SmallTest
- public void testAggregateStatsNoKernelWakelocks() throws Exception {
- KernelWakelockStats staleStats = new KernelWakelockStats();
-
- byte[] buffer = new byte[0];
- WakeLockInfo[] wlStats = new WakeLockInfo[1];
- wlStats[0] = createWakeLockInfo("WakeLock", 10, 1000);
-
- readKernelWakelockStats(staleStats, buffer, wlStats);
-
- assertEquals(1, staleStats.size());
-
- assertTrue(staleStats.containsKey("WakeLock"));
-
- KernelWakelockStats.Entry entry = staleStats.get("WakeLock");
- assertEquals(10, entry.mCount);
- assertEquals(1000, entry.mTotalTime);
- }
-
- @SmallTest
- public void testAggregateStatsBothKernelAndNativeWakelocks() throws Exception {
- KernelWakelockStats staleStats = new KernelWakelockStats();
-
- byte[] buffer = new ProcFileBuilder()
- .addLine("WakeLock1", 34, 123) // Milliseconds
- .getBytes();
- WakeLockInfo[] wlStats = new WakeLockInfo[1];
- wlStats[0] = createWakeLockInfo("WakeLock2", 10, 1000);
-
- readKernelWakelockStats(staleStats, buffer, wlStats);
-
- assertEquals(2, staleStats.size());
-
- assertTrue(staleStats.containsKey("WakeLock1"));
- KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
- assertEquals(34, entry1.mCount);
- assertEquals(123 * 1000, entry1.mTotalTime); // Microseconds
-
- assertTrue(staleStats.containsKey("WakeLock2"));
- KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
- assertEquals(10, entry2.mCount);
- assertEquals(1000, entry2.mTotalTime);
- }
-
- @SmallTest
- public void testAggregateStatsUpdate() throws Exception {
- KernelWakelockStats staleStats = new KernelWakelockStats();
-
- byte[] buffer = new ProcFileBuilder()
- .addLine("WakeLock1", 34, 123) // Milliseconds
- .addLine("WakeLock2", 46, 345) // Milliseconds
- .getBytes();
- WakeLockInfo[] wlStats = new WakeLockInfo[2];
- wlStats[0] = createWakeLockInfo("WakeLock3", 10, 1000);
- wlStats[1] = createWakeLockInfo("WakeLock4", 20, 2000);
-
- readKernelWakelockStats(staleStats, buffer, wlStats);
-
- assertEquals(4, staleStats.size());
-
- assertTrue(staleStats.containsKey("WakeLock1"));
- assertTrue(staleStats.containsKey("WakeLock2"));
- assertTrue(staleStats.containsKey("WakeLock3"));
- assertTrue(staleStats.containsKey("WakeLock4"));
-
- KernelWakelockStats.Entry entry1 = staleStats.get("WakeLock1");
- assertEquals(34, entry1.mCount);
- assertEquals(123 * 1000, entry1.mTotalTime); // Microseconds
-
- KernelWakelockStats.Entry entry2 = staleStats.get("WakeLock2");
- assertEquals(46, entry2.mCount);
- assertEquals(345 * 1000, entry2.mTotalTime); // Microseconds
-
- KernelWakelockStats.Entry entry3 = staleStats.get("WakeLock3");
- assertEquals(10, entry3.mCount);
- assertEquals(1000, entry3.mTotalTime);
-
- KernelWakelockStats.Entry entry4 = staleStats.get("WakeLock4");
- assertEquals(20, entry4.mCount);
- assertEquals(2000, entry4.mTotalTime);
-
- buffer = new ProcFileBuilder()
- .addLine("WakeLock1", 45, 789) // Milliseconds
- .addLine("WakeLock1", 56, 123) // Milliseconds
- .getBytes();
- wlStats = new WakeLockInfo[1];
- wlStats[0] = createWakeLockInfo("WakeLock4", 40, 4000);
-
- readKernelWakelockStats(staleStats, buffer, wlStats);
-
- assertEquals(2, staleStats.size());
-
- assertTrue(staleStats.containsKey("WakeLock1"));
- assertTrue(staleStats.containsKey("WakeLock4"));
-
- assertFalse(staleStats.containsKey("WakeLock2"));
- assertFalse(staleStats.containsKey("WakeLock3"));
-
- entry1 = staleStats.get("WakeLock1");
- assertEquals(45 + 56, entry1.mCount);
- assertEquals((789 + 123) * 1000, entry1.mTotalTime); // Microseconds
-
- entry2 = staleStats.get("WakeLock4");
- assertEquals(40, entry2.mCount);
- assertEquals(4000, entry4.mTotalTime);
+ assertEquals(2000 * 1000, entry.mTotalTime); // Micro seconds
}
}
diff --git a/graphics/java/android/graphics/RenderNode.java b/graphics/java/android/graphics/RenderNode.java
index ae7fe6c46f2f..0e635c774c84 100644
--- a/graphics/java/android/graphics/RenderNode.java
+++ b/graphics/java/android/graphics/RenderNode.java
@@ -63,7 +63,7 @@ import java.lang.annotation.RetentionPolicy;
* <h3>Creating a RenderNode</h3>
* <pre class="prettyprint">
* RenderNode renderNode = new RenderNode("myRenderNode");
- * renderNode.setLeftTopRightBottom(0, 0, 50, 50); // Set the size to 50x50
+ * renderNode.setPosition(0, 0, 50, 50); // Set the size to 50x50
* RecordingCanvas canvas = renderNode.beginRecording();
* try {
* // Draw with the canvas
@@ -104,7 +104,7 @@ import java.lang.annotation.RetentionPolicy;
* <pre class="prettyprint">
* private void createDisplayList() {
* mRenderNode = new RenderNode("MyRenderNode");
- * mRenderNode.setLeftTopRightBottom(0, 0, width, height);
+ * mRenderNode.setPosition(0, 0, width, height);
* RecordingCanvas canvas = mRenderNode.beginRecording();
* try {
* for (Bitmap b : mBitmaps) {
diff --git a/libs/hwui/SkiaCanvas.cpp b/libs/hwui/SkiaCanvas.cpp
index 6ea6af8f2935..f01b1bfa780d 100644
--- a/libs/hwui/SkiaCanvas.cpp
+++ b/libs/hwui/SkiaCanvas.cpp
@@ -778,6 +778,13 @@ void SkiaCanvas::drawCircle(uirenderer::CanvasPropertyPrimitive* x,
mCanvas->drawDrawable(drawable.get());
}
+void SkiaCanvas::drawPicture(const SkPicture& picture) {
+ // TODO: Change to mCanvas->drawPicture()? SkCanvas::drawPicture seems to be
+ // where the logic is for playback vs. ref picture. Using picture.playback here
+ // to stay behavior-identical for now, but should revisit this at some point.
+ picture.playback(mCanvas);
+}
+
// ----------------------------------------------------------------------------
// Canvas draw operations: View System
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/SkiaCanvas.h b/libs/hwui/SkiaCanvas.h
index 05a6d0dda42d..799a89158298 100644
--- a/libs/hwui/SkiaCanvas.h
+++ b/libs/hwui/SkiaCanvas.h
@@ -46,8 +46,6 @@ public:
virtual ~SkiaCanvas();
- virtual SkCanvas* asSkCanvas() override { return mCanvas; }
-
virtual void resetRecording(int width, int height,
uirenderer::RenderNode* renderNode) override {
LOG_ALWAYS_FATAL("SkiaCanvas cannot be reset as a recording canvas");
@@ -155,9 +153,11 @@ public:
virtual void drawRenderNode(uirenderer::RenderNode* renderNode) override;
virtual void callDrawGLFunction(Functor* functor,
uirenderer::GlFunctorLifecycleListener* listener) override;
+ virtual void drawPicture(const SkPicture& picture) override;
protected:
SkiaCanvas();
+ SkCanvas* asSkCanvas() { return mCanvas; }
void reset(SkCanvas* skiaCanvas);
void drawDrawable(SkDrawable* drawable) { mCanvas->drawDrawable(drawable); }
diff --git a/libs/hwui/hwui/Canvas.h b/libs/hwui/hwui/Canvas.h
index ac8db216b059..ee4fa1d689ef 100644
--- a/libs/hwui/hwui/Canvas.h
+++ b/libs/hwui/hwui/Canvas.h
@@ -131,20 +131,6 @@ public:
*/
static void setCompatibilityVersion(int apiLevel);
- /**
- * Provides a Skia SkCanvas interface that acts as a proxy to this Canvas.
- * It is useful for testing and clients (e.g. Picture/Movie) that expect to
- * draw their contents into an SkCanvas.
- *
- * The SkCanvas returned is *only* valid until another Canvas call is made
- * that would change state (e.g. matrix or clip). Clients of asSkCanvas()
- * are responsible for *not* persisting this pointer.
- *
- * Further, the returned SkCanvas should NOT be unref'd and is valid until
- * this canvas is destroyed or a new bitmap is set.
- */
- virtual SkCanvas* asSkCanvas() = 0;
-
virtual void setBitmap(const SkBitmap& bitmap) = 0;
virtual bool isOpaque() = 0;
@@ -264,6 +250,7 @@ public:
const SkPaint* paint) = 0;
virtual double drawAnimatedImage(AnimatedImageDrawable* imgDrawable) = 0;
+ virtual void drawPicture(const SkPicture& picture) = 0;
/**
* Specifies if the positions passed to ::drawText are absolute or relative
diff --git a/libs/hwui/tests/unit/SkiaCanvasTests.cpp b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
index f6178aff0c2e..2ed1b25efc71 100644
--- a/libs/hwui/tests/unit/SkiaCanvasTests.cpp
+++ b/libs/hwui/tests/unit/SkiaCanvasTests.cpp
@@ -78,7 +78,7 @@ TEST(SkiaCanvas, colorSpaceXform) {
sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
// Playback to a software sRGB canvas. The result should be fully red.
- canvas.asSkCanvas()->drawPicture(picture);
+ canvas.drawPicture(*picture);
ASSERT_EQ(0xFF0000FF, *skBitmap.getAddr32(0, 0));
}
diff --git a/media/native/midi/amidi.cpp b/media/native/midi/amidi.cpp
index 1e9a194d76c8..357bb5e50eee 100644
--- a/media/native/midi/amidi.cpp
+++ b/media/native/midi/amidi.cpp
@@ -122,7 +122,7 @@ static std::mutex openMutex; // Ensure that the device can be connected just onc
* - AMEDIA_ERROR_INVALID_PARAMETER
* AMEDIA_ERROR_UNKNOWN
*/
-static media_status_t AMIDI_API AMIDI_getDeviceInfo(const AMidiDevice *device,
+static media_status_t AMIDI_getDeviceInfo(const AMidiDevice *device,
AMidiDeviceInfo *outDeviceInfoPtr) {
if (device == nullptr) {
return AMEDIA_ERROR_INVALID_PARAMETER;
@@ -142,7 +142,7 @@ static media_status_t AMIDI_API AMIDI_getDeviceInfo(const AMidiDevice *device,
return AMEDIA_OK;
}
-media_status_t AMIDI_API AMidiDevice_fromJava(JNIEnv *env, jobject j_midiDeviceObj,
+media_status_t AMidiDevice_fromJava(JNIEnv *env, jobject j_midiDeviceObj,
AMidiDevice** devicePtrPtr)
{
if (j_midiDeviceObj == nullptr) {
@@ -188,7 +188,7 @@ media_status_t AMIDI_API AMidiDevice_fromJava(JNIEnv *env, jobject j_midiDeviceO
return AMEDIA_OK;
}
-media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *device)
+media_status_t AMidiDevice_release(const AMidiDevice *device)
{
if (device == nullptr || device->midiDeviceObj == nullptr) {
return AMEDIA_ERROR_INVALID_PARAMETER;
@@ -217,21 +217,21 @@ media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *device)
return AMEDIA_OK;
}
-int32_t AMIDI_API AMidiDevice_getType(const AMidiDevice *device) {
+int32_t AMidiDevice_getType(const AMidiDevice *device) {
if (device == nullptr) {
return AMEDIA_ERROR_INVALID_PARAMETER;
}
return device->deviceInfo.type;
}
-ssize_t AMIDI_API AMidiDevice_getNumInputPorts(const AMidiDevice *device) {
+ssize_t AMidiDevice_getNumInputPorts(const AMidiDevice *device) {
if (device == nullptr) {
return AMEDIA_ERROR_INVALID_PARAMETER;
}
return device->deviceInfo.inputPortCount;
}
-ssize_t AMIDI_API AMidiDevice_getNumOutputPorts(const AMidiDevice *device) {
+ssize_t AMidiDevice_getNumOutputPorts(const AMidiDevice *device) {
if (device == nullptr) {
return AMEDIA_ERROR_INVALID_PARAMETER;
}
@@ -291,7 +291,7 @@ static void AMIDI_closePort(AMIDI_Port *port) {
/*
* Output (receiving) API
*/
-media_status_t AMIDI_API AMidiOutputPort_open(const AMidiDevice *device, int32_t portNumber,
+media_status_t AMidiOutputPort_open(const AMidiDevice *device, int32_t portNumber,
AMidiOutputPort **outOutputPortPtr) {
return AMIDI_openPort(device, portNumber, PORTTYPE_OUTPUT, (AMIDI_Port**)outOutputPortPtr);
}
@@ -350,7 +350,7 @@ private:
AMIDI_Port *mPort;
};
-ssize_t AMIDI_API AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int32_t *opcodePtr,
+ssize_t AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int32_t *opcodePtr,
uint8_t *buffer, size_t maxBytes, size_t* numBytesReceivedPtr, int64_t *timestampPtr) {
if (outputPort == nullptr || buffer == nullptr) {
@@ -361,19 +361,19 @@ ssize_t AMIDI_API AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int
numBytesReceivedPtr, timestampPtr);
}
-void AMIDI_API AMidiOutputPort_close(const AMidiOutputPort *outputPort) {
+void AMidiOutputPort_close(const AMidiOutputPort *outputPort) {
AMIDI_closePort((AMIDI_Port*)outputPort);
}
/*
* Input (sending) API
*/
-media_status_t AMIDI_API AMidiInputPort_open(const AMidiDevice *device, int32_t portNumber,
+media_status_t AMidiInputPort_open(const AMidiDevice *device, int32_t portNumber,
AMidiInputPort **outInputPortPtr) {
return AMIDI_openPort(device, portNumber, PORTTYPE_INPUT, (AMIDI_Port**)outInputPortPtr);
}
-void AMIDI_API AMidiInputPort_close(const AMidiInputPort *inputPort) {
+void AMidiInputPort_close(const AMidiInputPort *inputPort) {
AMIDI_closePort((AMIDI_Port*)inputPort);
}
@@ -386,12 +386,12 @@ static ssize_t AMIDI_makeSendBuffer(
return numBytes + AMIDI_PACKET_OVERHEAD;
}
-ssize_t AMIDI_API AMidiInputPort_send(const AMidiInputPort *inputPort, const uint8_t *buffer,
+ssize_t AMidiInputPort_send(const AMidiInputPort *inputPort, const uint8_t *buffer,
size_t numBytes) {
return AMidiInputPort_sendWithTimestamp(inputPort, buffer, numBytes, 0);
}
-ssize_t AMIDI_API AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPort,
+ssize_t AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPort,
const uint8_t *data, size_t numBytes, int64_t timestamp) {
if (inputPort == nullptr || data == nullptr) {
return AMEDIA_ERROR_INVALID_PARAMETER;
@@ -423,7 +423,7 @@ ssize_t AMIDI_API AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPo
return numSent;
}
-media_status_t AMIDI_API AMidiInputPort_sendFlush(const AMidiInputPort *inputPort) {
+media_status_t AMidiInputPort_sendFlush(const AMidiInputPort *inputPort) {
if (inputPort == nullptr) {
return AMEDIA_ERROR_INVALID_PARAMETER;
}
diff --git a/media/native/midi/include/amidi/AMidi.h b/media/native/midi/include/amidi/AMidi.h
index cbe410f46af9..76dec0f7e723 100644
--- a/media/native/midi/include/amidi/AMidi.h
+++ b/media/native/midi/include/amidi/AMidi.h
@@ -41,8 +41,6 @@ typedef struct AMidiDevice AMidiDevice;
typedef struct AMidiInputPort AMidiInputPort;
typedef struct AMidiOutputPort AMidiOutputPort;
-#define AMIDI_API __attribute__((visibility("default")))
-
/*
* Message Op Codes. Used to parse MIDI data packets
*/
@@ -61,6 +59,8 @@ enum {
AMIDI_DEVICE_TYPE_BLUETOOTH = 3 /* A MIDI device connected via BlueTooth */
};
+#if __ANDROID_API__ >= 29
+
/*
* Device API
*/
@@ -78,7 +78,7 @@ enum {
* is null or already connected to a native AMidiDevice
* @see AMEDIA_ERROR_UNKNOWN - an unknown error occurred.
*/
-media_status_t AMIDI_API AMidiDevice_fromJava(
+media_status_t AMidiDevice_fromJava(
JNIEnv *env, jobject midiDeviceObj, AMidiDevice **outDevicePtrPtr) __INTRODUCED_IN(29);
/**
@@ -93,7 +93,7 @@ media_status_t AMIDI_API AMidiDevice_fromJava(
* @see AMEDIA_ERROR_INVALID_OBJECT - the JNI interface initialization to the associated java MidiDevice failed.
* @see AMEDIA_ERROR_UNKNOWN - couldn't retrieve the device info.
*/
-media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *midiDevice) __INTRODUCED_IN(29);
+media_status_t AMidiDevice_release(const AMidiDevice *midiDevice) __INTRODUCED_IN(29);
/**
* Gets the MIDI device type.
@@ -108,7 +108,7 @@ media_status_t AMIDI_API AMidiDevice_release(const AMidiDevice *midiDevice) __IN
* @see AMEDIA_ERROR_INVALID_PARAMETER - the device parameter is NULL.
* @see AMEDIA_ERROR_UNKNOWN - Unknown error.
*/
-int32_t AMIDI_API AMidiDevice_getType(const AMidiDevice *device) __INTRODUCED_IN(29);
+int32_t AMidiDevice_getType(const AMidiDevice *device) __INTRODUCED_IN(29);
/**
* Gets the number of input (sending) ports available on the specified MIDI device.
@@ -120,7 +120,7 @@ int32_t AMIDI_API AMidiDevice_getType(const AMidiDevice *device) __INTRODUCED_IN
* @see AMEDIA_ERROR_INVALID_PARAMETER - the device parameter is NULL.
* @see AMEDIA_ERROR_UNKNOWN - couldn't retrieve the device info.
*/
-ssize_t AMIDI_API AMidiDevice_getNumInputPorts(const AMidiDevice *device) __INTRODUCED_IN(29);
+ssize_t AMidiDevice_getNumInputPorts(const AMidiDevice *device) __INTRODUCED_IN(29);
/**
* Gets the number of output (receiving) ports available on the specified MIDI device.
@@ -132,7 +132,7 @@ ssize_t AMIDI_API AMidiDevice_getNumInputPorts(const AMidiDevice *device) __INTR
* @see AMEDIA_ERROR_INVALID_PARAMETER - the device parameter is NULL.
* @see AMEDIA_ERROR_UNKNOWN - couldn't retrieve the device info.
*/
-ssize_t AMIDI_API AMidiDevice_getNumOutputPorts(const AMidiDevice *device) __INTRODUCED_IN(29);
+ssize_t AMidiDevice_getNumOutputPorts(const AMidiDevice *device) __INTRODUCED_IN(29);
/*
* API for receiving data from the Output port of a device.
@@ -150,7 +150,7 @@ ssize_t AMIDI_API AMidiDevice_getNumOutputPorts(const AMidiDevice *device) __INT
* @return AMEDIA_OK, or a negative error code:
* @see AMEDIA_ERROR_UNKNOWN - Unknown Error.
*/
-media_status_t AMIDI_API AMidiOutputPort_open(const AMidiDevice *device, int32_t portNumber,
+media_status_t AMidiOutputPort_open(const AMidiDevice *device, int32_t portNumber,
AMidiOutputPort **outOutputPortPtr) __INTRODUCED_IN(29);
/**
@@ -158,7 +158,7 @@ media_status_t AMIDI_API AMidiOutputPort_open(const AMidiDevice *device, int32_t
*
* @param outputPort The native API port identifier of the port.
*/
-void AMIDI_API AMidiOutputPort_close(const AMidiOutputPort *outputPort) __INTRODUCED_IN(29);
+void AMidiOutputPort_close(const AMidiOutputPort *outputPort) __INTRODUCED_IN(29);
/**
* Receives the next pending MIDI message. To retrieve all pending messages, the client should
@@ -178,7 +178,7 @@ void AMIDI_API AMidiOutputPort_close(const AMidiOutputPort *outputPort) __INTROD
* @return the number of messages received (either 0 or 1), or a negative error code:
* @see AMEDIA_ERROR_UNKNOWN - Unknown Error.
*/
-ssize_t AMIDI_API AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int32_t *opcodePtr,
+ssize_t AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int32_t *opcodePtr,
uint8_t *buffer, size_t maxBytes, size_t* numBytesReceivedPtr, int64_t *outTimestampPtr) __INTRODUCED_IN(29);
/*
@@ -197,7 +197,7 @@ ssize_t AMIDI_API AMidiOutputPort_receive(const AMidiOutputPort *outputPort, int
* @return AMEDIA_OK, or a negative error code:
* @see AMEDIA_ERROR_UNKNOWN - Unknown Error.
*/
-media_status_t AMIDI_API AMidiInputPort_open(const AMidiDevice *device, int32_t portNumber,
+media_status_t AMidiInputPort_open(const AMidiDevice *device, int32_t portNumber,
AMidiInputPort **outInputPortPtr) __INTRODUCED_IN(29);
/**
@@ -210,7 +210,7 @@ media_status_t AMIDI_API AMidiInputPort_open(const AMidiDevice *device, int32_t
* @return The number of bytes sent, which could be less than specified or a negative error code:
* @see AMEDIA_ERROR_INVALID_PARAMETER - The specified port was NULL, the specified buffer was NULL.
*/
-ssize_t AMIDI_API AMidiInputPort_send(const AMidiInputPort *inputPort, const uint8_t *buffer,
+ssize_t AMidiInputPort_send(const AMidiInputPort *inputPort, const uint8_t *buffer,
size_t numBytes) __INTRODUCED_IN(29);
/**
@@ -224,7 +224,7 @@ ssize_t AMIDI_API AMidiInputPort_send(const AMidiInputPort *inputPort, const uin
* @return The number of bytes sent, which could be less than specified or a negative error code:
* @see AMEDIA_ERROR_INVALID_PARAMETER - The specified port was NULL, the specified buffer was NULL.
*/
-ssize_t AMIDI_API AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPort,
+ssize_t AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPort,
const uint8_t *buffer, size_t numBytes, int64_t timestamp) __INTRODUCED_IN(29);
/**
@@ -238,14 +238,16 @@ ssize_t AMIDI_API AMidiInputPort_sendWithTimestamp(const AMidiInputPort *inputPo
* @see AMEDIA_ERROR_UNSUPPORTED - The FLUSH command couldn't
* be sent.
*/
-media_status_t AMIDI_API AMidiInputPort_sendFlush(const AMidiInputPort *inputPort) __INTRODUCED_IN(29);
+media_status_t AMidiInputPort_sendFlush(const AMidiInputPort *inputPort) __INTRODUCED_IN(29);
/**
* Closes the input port.
*
* @param inputPort Identifies the input (sending) port to close.
*/
-void AMIDI_API AMidiInputPort_close(const AMidiInputPort *inputPort) __INTRODUCED_IN(29);
+void AMidiInputPort_close(const AMidiInputPort *inputPort) __INTRODUCED_IN(29);
+
+#endif /* __ANDROID_API__ >= 29 */
#ifdef __cplusplus
}
diff --git a/packages/CarSystemUI/res/values/dimens.xml b/packages/CarSystemUI/res/values/dimens.xml
index 7592bd227a94..fb422aff51ef 100644
--- a/packages/CarSystemUI/res/values/dimens.xml
+++ b/packages/CarSystemUI/res/values/dimens.xml
@@ -114,10 +114,10 @@
<!-- Car notification shade-->
<dimen name="notification_shade_handle_bar_height">10dp</dimen>
<dimen name="notification_shade_handle_bar_radius">20dp</dimen>
- <dimen name="notification_shade_handle_bar_margin_start">500dp</dimen>
- <dimen name="notification_shade_handle_bar_margin_end">500dp</dimen>
+ <dimen name="notification_shade_handle_bar_margin_start">200dp</dimen>
+ <dimen name="notification_shade_handle_bar_margin_end">200dp</dimen>
<dimen name="notification_shade_handle_bar_margin_top">20dp</dimen>
<dimen name="notification_shade_handle_bar_margin_bottom">10dp</dimen>
- <dimen name="notification_shade_list_padding_bottom">0dp</dimen>
+ <dimen name="notification_shade_list_padding_bottom">50dp</dimen>
</resources>
diff --git a/packages/CtsShim/build/Android.mk b/packages/CtsShim/build/Android.mk
index 03eb0d9aad5a..0ef4654d72e7 100644
--- a/packages/CtsShim/build/Android.mk
+++ b/packages/CtsShim/build/Android.mk
@@ -65,6 +65,9 @@ LOCAL_FULL_MANIFEST_FILE := $(gen)
LOCAL_MULTILIB := both
LOCAL_JNI_SHARED_LIBRARIES := libshim_jni
+# Explicitly uncompress native libs rather than letting the build system doing it and destroy the
+# v2/v3 signature.
+LOCAL_USE_EMBEDDED_NATIVE_LIBS := true
LOCAL_USE_AAPT2 := true
diff --git a/packages/SystemUI/plugin/ExamplePlugin/Android.bp b/packages/SystemUI/plugin/ExamplePlugin/Android.bp
index a0eaf14f4a06..c6c80f3780a3 100644
--- a/packages/SystemUI/plugin/ExamplePlugin/Android.bp
+++ b/packages/SystemUI/plugin/ExamplePlugin/Android.bp
@@ -11,4 +11,5 @@ android_app {
srcs: ["src/**/*.java"],
+ platform_apis: true,
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
index 53403aa4dbf1..a7e3c59ce72e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginManagerImpl.java
@@ -171,15 +171,21 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener,
allowMultiple, mLooper, cls, this);
p.loadAll();
- mPluginMap.put(listener, p);
+ synchronized (this) {
+ mPluginMap.put(listener, p);
+ }
startListening();
}
public void removePluginListener(PluginListener<?> listener) {
- if (!mPluginMap.containsKey(listener)) return;
- mPluginMap.remove(listener).destroy();
- if (mPluginMap.size() == 0) {
- stopListening();
+ synchronized (this) {
+ if (!mPluginMap.containsKey(listener)) {
+ return;
+ }
+ mPluginMap.remove(listener).destroy();
+ if (mPluginMap.size() == 0) {
+ stopListening();
+ }
}
}
@@ -208,8 +214,10 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_USER_UNLOCKED.equals(intent.getAction())) {
- for (PluginInstanceManager manager : mPluginMap.values()) {
- manager.loadAll();
+ synchronized (this) {
+ for (PluginInstanceManager manager : mPluginMap.values()) {
+ manager.loadAll();
+ }
}
} else if (DISABLE_PLUGIN.equals(intent.getAction())) {
Uri uri = intent.getData();
@@ -274,13 +282,15 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
getPluginEnabler().setEnabled(componentName);
}
}
- if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
- for (PluginInstanceManager manager : mPluginMap.values()) {
- manager.onPackageChange(pkg);
- }
- } else {
- for (PluginInstanceManager manager : mPluginMap.values()) {
- manager.onPackageRemoved(pkg);
+ synchronized (this) {
+ if (!Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())) {
+ for (PluginInstanceManager manager : mPluginMap.values()) {
+ manager.onPackageChange(pkg);
+ }
+ } else {
+ for (PluginInstanceManager manager : mPluginMap.values()) {
+ manager.onPackageRemoved(pkg);
+ }
}
}
}
@@ -322,9 +332,11 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
}
public <T> boolean dependsOn(Plugin p, Class<T> cls) {
- for (int i = 0; i < mPluginMap.size(); i++) {
- if (mPluginMap.valueAt(i).dependsOn(p, cls)) {
- return true;
+ synchronized (this) {
+ for (int i = 0; i < mPluginMap.size(); i++) {
+ if (mPluginMap.valueAt(i).dependsOn(p, cls)) {
+ return true;
+ }
}
}
return false;
@@ -335,10 +347,12 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
}
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- pw.println(String.format(" plugin map (%d):", mPluginMap.size()));
- for (PluginListener listener: mPluginMap.keySet()) {
- pw.println(String.format(" %s -> %s",
- listener, mPluginMap.get(listener)));
+ synchronized (this) {
+ pw.println(String.format(" plugin map (%d):", mPluginMap.size()));
+ for (PluginListener listener : mPluginMap.keySet()) {
+ pw.println(String.format(" %s -> %s",
+ listener, mPluginMap.get(listener)));
+ }
}
}
@@ -418,8 +432,10 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
// We couldn't find any plugins involved in this crash, just to be safe
// disable all the plugins, so we can be sure that SysUI is running as
// best as possible.
- for (PluginInstanceManager manager : mPluginMap.values()) {
- disabledAny |= manager.disableAll();
+ synchronized (this) {
+ for (PluginInstanceManager manager : mPluginMap.values()) {
+ disabledAny |= manager.disableAll();
+ }
}
}
if (disabledAny) {
@@ -433,9 +449,11 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage
private boolean checkStack(Throwable throwable) {
if (throwable == null) return false;
boolean disabledAny = false;
- for (StackTraceElement element : throwable.getStackTrace()) {
- for (PluginInstanceManager manager : mPluginMap.values()) {
- disabledAny |= manager.checkAndDisable(element.getClassName());
+ synchronized (this) {
+ for (StackTraceElement element : throwable.getStackTrace()) {
+ for (PluginInstanceManager manager : mPluginMap.values()) {
+ disabledAny |= manager.checkAndDisable(element.getClassName());
+ }
}
}
return disabledAny | checkStack(throwable.getCause());
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index cc7863c0113b..2a890fe20d8a 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -80,6 +80,8 @@ public class QuickStepContract {
public static final int SYSUI_STATE_HOME_DISABLED = 1 << 8;
// The keyguard is showing, but occluded
public static final int SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED = 1 << 9;
+ // The search feature is disabled (either by SUW/SysUI/device policy)
+ public static final int SYSUI_STATE_SEARCH_DISABLED = 1 << 10;
@Retention(RetentionPolicy.SOURCE)
@IntDef({SYSUI_STATE_SCREEN_PINNING,
@@ -91,7 +93,8 @@ public class QuickStepContract {
SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING,
SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED,
SYSUI_STATE_OVERVIEW_DISABLED,
- SYSUI_STATE_HOME_DISABLED
+ SYSUI_STATE_HOME_DISABLED,
+ SYSUI_STATE_SEARCH_DISABLED
})
public @interface SystemUiStateFlags {}
@@ -100,6 +103,7 @@ public class QuickStepContract {
str.add((flags & SYSUI_STATE_SCREEN_PINNING) != 0 ? "screen_pinned" : "");
str.add((flags & SYSUI_STATE_OVERVIEW_DISABLED) != 0 ? "overview_disabled" : "");
str.add((flags & SYSUI_STATE_HOME_DISABLED) != 0 ? "home_disabled" : "");
+ str.add((flags & SYSUI_STATE_SEARCH_DISABLED) != 0 ? "search_disabled" : "");
str.add((flags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0 ? "navbar_hidden" : "");
str.add((flags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0 ? "notif_visible" : "");
str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0 ? "keygrd_visible" : "");
@@ -150,10 +154,11 @@ public class QuickStepContract {
* disabled.
*/
public static boolean isAssistantGestureDisabled(int sysuiStateFlags) {
- // Disable when in screen pinning, immersive, the bouncer is showing
+ // Disable when in screen pinning, immersive, the bouncer is showing, or search is disabled
int disableFlags = SYSUI_STATE_SCREEN_PINNING
| SYSUI_STATE_NAV_BAR_HIDDEN
- | SYSUI_STATE_BOUNCER_SHOWING;
+ | SYSUI_STATE_BOUNCER_SHOWING
+ | SYSUI_STATE_SEARCH_DISABLED;
if ((sysuiStateFlags & disableFlags) != 0) {
return true;
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
index d2fe5cd9ef64..2ef042210e67 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentsAnimationControllerCompat.java
@@ -91,6 +91,7 @@ public class RecentsAnimationControllerCompat {
}
}
+ @Deprecated
public void setCancelWithDeferredScreenshot(boolean screenshot) {
try {
mAnimationController.setCancelWithDeferredScreenshot(screenshot);
@@ -99,6 +100,14 @@ public class RecentsAnimationControllerCompat {
}
}
+ public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
+ try {
+ mAnimationController.setDeferCancelUntilNextTransition(defer, screenshot);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to set deferred cancel with screenshot", e);
+ }
+ }
+
public void cleanupScreenshot() {
try {
mAnimationController.cleanupScreenshot();
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java
index a5299038d3a9..326c2aa37175 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/RecentTaskInfoCompat.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/TaskInfoCompat.java
@@ -17,29 +17,32 @@
package com.android.systemui.shared.system;
import android.app.ActivityManager;
+import android.app.TaskInfo;
import android.content.ComponentName;
-public class RecentTaskInfoCompat {
+public class TaskInfoCompat {
- private ActivityManager.RecentTaskInfo mInfo;
+ public static int getUserId(TaskInfo info) {
+ return info.userId;
+ }
- public RecentTaskInfoCompat(ActivityManager.RecentTaskInfo info) {
- mInfo = info;
+ public static int getActivityType(TaskInfo info) {
+ return info.configuration.windowConfiguration.getActivityType();
}
- public int getUserId() {
- return mInfo.userId;
+ public static int getWindowingMode(TaskInfo info) {
+ return info.configuration.windowConfiguration.getWindowingMode();
}
- public boolean supportsSplitScreenMultiWindow() {
- return mInfo.supportsSplitScreenMultiWindow;
+ public static boolean supportsSplitScreenMultiWindow(TaskInfo info) {
+ return info.supportsSplitScreenMultiWindow;
}
- public ComponentName getTopActivity() {
- return mInfo.topActivity;
+ public static ComponentName getTopActivity(TaskInfo info) {
+ return info.topActivity;
}
- public ActivityManager.TaskDescription getTaskDescription() {
- return mInfo.taskDescription;
+ public static ActivityManager.TaskDescription getTaskDescription(TaskInfo info) {
+ return info.taskDescription;
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
index 2483192eb04e..5097216a7405 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitch.java
@@ -584,6 +584,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
@Override
public Animator onAppear(ViewGroup sceneRoot, View view, TransitionValues startValues,
TransitionValues endValues) {
+ if (!sceneRoot.isShown()) {
+ return null;
+ }
final float cutoff = mCutoff;
final int startVisibility = View.INVISIBLE;
final int endVisibility = (int) endValues.values.get(PROPNAME_VISIBILITY);
@@ -596,6 +599,9 @@ public class KeyguardClockSwitch extends RelativeLayout {
@Override
public Animator onDisappear(ViewGroup sceneRoot, View view, TransitionValues startValues,
TransitionValues endValues) {
+ if (!sceneRoot.isShown()) {
+ return null;
+ }
final float cutoff = 1f - mCutoff;
final int startVisibility = View.VISIBLE;
final int endVisibility = (int) endValues.values.get(PROPNAME_VISIBILITY);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 4ad262fee520..8059dcf33df7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -269,7 +269,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
*/
private void updateBiometricRetry() {
SecurityMode securityMode = getSecurityMode();
- mSwipeUpToRetry = mUnlockMethodCache.isUnlockingWithFacePossible()
+ mSwipeUpToRetry = mUnlockMethodCache.isFaceAuthEnabled()
&& securityMode != SecurityMode.SimPin
&& securityMode != SecurityMode.SimPuk
&& securityMode != SecurityMode.None;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index e219e24a8944..af4e61b3f6bc 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -89,6 +89,7 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
private final HashMap<View, PendingIntent> mClickActions;
private final ActivityStarter mActivityStarter;
private final ConfigurationController mConfigurationController;
+ private final LayoutTransition mLayoutTransition;
private Uri mKeyguardSliceUri;
@VisibleForTesting
TextView mTitle;
@@ -126,16 +127,16 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
mActivityStarter = activityStarter;
mConfigurationController = configurationController;
- LayoutTransition transition = new LayoutTransition();
- transition.setStagger(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION / 2);
- transition.setDuration(LayoutTransition.APPEARING, DEFAULT_ANIM_DURATION);
- transition.setDuration(LayoutTransition.DISAPPEARING, DEFAULT_ANIM_DURATION / 2);
- transition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
- transition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
- transition.setInterpolator(LayoutTransition.APPEARING, Interpolators.FAST_OUT_SLOW_IN);
- transition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
- transition.setAnimateParentHierarchy(false);
- setLayoutTransition(transition);
+ mLayoutTransition = new LayoutTransition();
+ mLayoutTransition.setStagger(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION / 2);
+ mLayoutTransition.setDuration(LayoutTransition.APPEARING, DEFAULT_ANIM_DURATION);
+ mLayoutTransition.setDuration(LayoutTransition.DISAPPEARING, DEFAULT_ANIM_DURATION / 2);
+ mLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_APPEARING);
+ mLayoutTransition.disableTransitionType(LayoutTransition.CHANGE_DISAPPEARING);
+ mLayoutTransition.setInterpolator(LayoutTransition.APPEARING,
+ Interpolators.FAST_OUT_SLOW_IN);
+ mLayoutTransition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
+ mLayoutTransition.setAnimateParentHierarchy(false);
}
@Override
@@ -174,6 +175,12 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
mConfigurationController.removeCallback(this);
}
+ @Override
+ public void onVisibilityAggregated(boolean isVisible) {
+ super.onVisibilityAggregated(isVisible);
+ setLayoutTransition(isVisible ? mLayoutTransition : null);
+ }
+
/**
* Returns whether the current visible slice has a title/header.
*/
@@ -419,6 +426,7 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
* their desired positions.
*/
private final Animation.AnimationListener mKeepAwakeListener;
+ private LayoutTransition mLayoutTransition;
private float mDarkAmount;
public Row(Context context) {
@@ -440,33 +448,41 @@ public class KeyguardSliceView extends LinearLayout implements View.OnClickListe
@Override
protected void onFinishInflate() {
- LayoutTransition transition = new LayoutTransition();
- transition.setDuration(DEFAULT_ANIM_DURATION);
+ mLayoutTransition = new LayoutTransition();
+ mLayoutTransition.setDuration(DEFAULT_ANIM_DURATION);
PropertyValuesHolder left = PropertyValuesHolder.ofInt("left", 0, 1);
PropertyValuesHolder right = PropertyValuesHolder.ofInt("right", 0, 1);
ObjectAnimator changeAnimator = ObjectAnimator.ofPropertyValuesHolder((Object) null,
left, right);
- transition.setAnimator(LayoutTransition.CHANGE_APPEARING, changeAnimator);
- transition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeAnimator);
- transition.setInterpolator(LayoutTransition.CHANGE_APPEARING,
+ mLayoutTransition.setAnimator(LayoutTransition.CHANGE_APPEARING, changeAnimator);
+ mLayoutTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING, changeAnimator);
+ mLayoutTransition.setInterpolator(LayoutTransition.CHANGE_APPEARING,
Interpolators.ACCELERATE_DECELERATE);
- transition.setInterpolator(LayoutTransition.CHANGE_DISAPPEARING,
+ mLayoutTransition.setInterpolator(LayoutTransition.CHANGE_DISAPPEARING,
Interpolators.ACCELERATE_DECELERATE);
- transition.setStartDelay(LayoutTransition.CHANGE_APPEARING, DEFAULT_ANIM_DURATION);
- transition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING, DEFAULT_ANIM_DURATION);
+ mLayoutTransition.setStartDelay(LayoutTransition.CHANGE_APPEARING,
+ DEFAULT_ANIM_DURATION);
+ mLayoutTransition.setStartDelay(LayoutTransition.CHANGE_DISAPPEARING,
+ DEFAULT_ANIM_DURATION);
ObjectAnimator appearAnimator = ObjectAnimator.ofFloat(null, "alpha", 0f, 1f);
- transition.setAnimator(LayoutTransition.APPEARING, appearAnimator);
- transition.setInterpolator(LayoutTransition.APPEARING, Interpolators.ALPHA_IN);
+ mLayoutTransition.setAnimator(LayoutTransition.APPEARING, appearAnimator);
+ mLayoutTransition.setInterpolator(LayoutTransition.APPEARING, Interpolators.ALPHA_IN);
ObjectAnimator disappearAnimator = ObjectAnimator.ofFloat(null, "alpha", 1f, 0f);
- transition.setInterpolator(LayoutTransition.DISAPPEARING, Interpolators.ALPHA_OUT);
- transition.setDuration(LayoutTransition.DISAPPEARING, DEFAULT_ANIM_DURATION / 4);
- transition.setAnimator(LayoutTransition.DISAPPEARING, disappearAnimator);
+ mLayoutTransition.setInterpolator(LayoutTransition.DISAPPEARING,
+ Interpolators.ALPHA_OUT);
+ mLayoutTransition.setDuration(LayoutTransition.DISAPPEARING, DEFAULT_ANIM_DURATION / 4);
+ mLayoutTransition.setAnimator(LayoutTransition.DISAPPEARING, disappearAnimator);
- transition.setAnimateParentHierarchy(false);
- setLayoutTransition(transition);
+ mLayoutTransition.setAnimateParentHierarchy(false);
+ }
+
+ @Override
+ public void onVisibilityAggregated(boolean isVisible) {
+ super.onVisibilityAggregated(isVisible);
+ setLayoutTransition(isVisible ? mLayoutTransition : null);
}
@Override
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index fd618b05f348..4e7b15715243 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -1783,13 +1783,15 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
&& mFpm.getEnrolledFingerprints(userId).size() > 0;
}
+ private boolean isUnlockWithFacePossible(int userId) {
+ return isFaceAuthEnabledForUser(userId) && !isFaceDisabled(userId);
+ }
+
/**
* If face hardware is available, user has enrolled and enabled auth via setting.
- * Not considering encryption or lock down state.
*/
- public boolean isUnlockWithFacePossible(int userId) {
+ public boolean isFaceAuthEnabledForUser(int userId) {
return mFaceManager != null && mFaceManager.isHardwareDetected()
- && !isFaceDisabled(userId)
&& mFaceManager.hasEnrolledTemplates(userId)
&& mFaceSettingEnabledForUser.get(userId);
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemBars.java b/packages/SystemUI/src/com/android/systemui/SystemBars.java
index 4285af08e734..c4c0fd6da124 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemBars.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemBars.java
@@ -46,6 +46,13 @@ public class SystemBars extends SystemUI {
}
}
+ @Override
+ public void onBootCompleted() {
+ if (mStatusBar != null) {
+ mStatusBar.onBootCompleted();
+ }
+ }
+
private void createStatusBarFromConfig() {
if (DEBUG) Log.d(TAG, "createStatusBarFromConfig");
final String clsName = mContext.getString(R.string.config_statusBarComponent);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
index a5857df8ba5a..ce67577ea483 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/BiometricDialogView.java
@@ -111,6 +111,9 @@ public abstract class BiometricDialogView extends LinearLayout {
protected boolean mRequireConfirmation;
private int mUserId; // used to determine if we should show work background
+ private boolean mCompletedAnimatingIn;
+ private boolean mPendingDismissDialog;
+
protected abstract int getHintStringResourceId();
protected abstract int getAuthenticatedAccessibilityResourceId();
protected abstract int getIconDescriptionResourceId();
@@ -332,6 +335,7 @@ public abstract class BiometricDialogView extends LinearLayout {
mDialog.setAlpha(1.0f);
mDialog.setTranslationY(0);
mLayout.setAlpha(1.0f);
+ mCompletedAnimatingIn = true;
} else {
// Dim the background and slide the dialog up
mDialog.setTranslationY(mAnimationTranslationOffset);
@@ -352,6 +356,12 @@ public abstract class BiometricDialogView extends LinearLayout {
}
public void startDismiss() {
+ if (!mCompletedAnimatingIn) {
+ Log.w(TAG, "startDismiss(): waiting for onDialogAnimatedIn");
+ mPendingDismissDialog = true;
+ return;
+ }
+
mAnimatingAway = true;
// This is where final cleanup should occur.
@@ -499,6 +509,13 @@ public abstract class BiometricDialogView extends LinearLayout {
}
public void onDialogAnimatedIn() {
+ mCompletedAnimatingIn = true;
+
+ if (mPendingDismissDialog) {
+ Log.d(TAG, "onDialogAnimatedIn(): mPendingDismissDialog=true, dismissing now");
+ startDismiss();
+ mPendingDismissDialog = false;
+ }
}
public void restoreState(Bundle bundle) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
index 729242e3144f..ae6cb5ce23d3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/FaceDialogView.java
@@ -460,6 +460,7 @@ public class FaceDialogView extends BiometricDialogView {
@Override
public void onDialogAnimatedIn() {
+ super.onDialogAnimatedIn();
mDialogAnimatedIn = true;
mIconController.startPulsing();
}
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
index cee01a4d3048..41f20ec28902 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/brightline/BrightLineFalsingManager.java
@@ -105,10 +105,12 @@ public class BrightLineFalsingManager implements FalsingManager {
}
private void sessionStart() {
- logDebug("Starting Session");
- mSessionStarted = true;
- registerSensors();
- mClassifiers.forEach(FalsingClassifier::onSessionStarted);
+ if (!mSessionStarted) {
+ logDebug("Starting Session");
+ mSessionStarted = true;
+ registerSensors();
+ mClassifiers.forEach(FalsingClassifier::onSessionStarted);
+ }
}
private void sessionEnd() {
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
index 5136682bb292..48f32cf04fb2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardSliceProvider.java
@@ -52,6 +52,7 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.NextAlarmController;
@@ -62,7 +63,6 @@ import com.android.systemui.util.wakelock.SettableWakeLock;
import com.android.systemui.util.wakelock.WakeLock;
import java.util.Date;
-import java.util.HashSet;
import java.util.Locale;
import java.util.TimeZone;
import java.util.concurrent.TimeUnit;
@@ -128,6 +128,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
private CharSequence mMediaTitle;
private CharSequence mMediaArtist;
protected boolean mDozing;
+ private int mStatusBarState;
private boolean mMediaIsVisible;
/**
@@ -231,7 +232,11 @@ public class KeyguardSliceProvider extends SliceProvider implements
protected boolean needsMediaLocked() {
boolean keepWhenAwake = mKeyguardBypassController != null
&& mKeyguardBypassController.getBypassEnabled() && mDozeParameters.getAlwaysOn();
- return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || keepWhenAwake);
+ // Show header if music is playing and the status bar is in the shade state. This way, an
+ // animation isn't necessary when pressing power and transitioning to AOD.
+ boolean keepWhenShade = mStatusBarState == StatusBarState.SHADE && mMediaIsVisible;
+ return !TextUtils.isEmpty(mMediaTitle) && mMediaIsVisible && (mDozing || keepWhenAwake
+ || keepWhenShade);
}
protected void addMediaLocked(ListBuilder listBuilder) {
@@ -458,7 +463,7 @@ public class KeyguardSliceProvider extends SliceProvider implements
synchronized (this) {
boolean nextVisible = NotificationMediaManager.isPlayingState(state);
mHandler.removeCallbacksAndMessages(mMediaToken);
- if (mMediaIsVisible && !nextVisible) {
+ if (mMediaIsVisible && !nextVisible && mStatusBarState != StatusBarState.SHADE) {
// We need to delay this event for a few millis when stopping to avoid jank in the
// animation. The media app might not send its update when buffering, and the slice
// would end up without a header for 0.5 second.
@@ -515,5 +520,14 @@ public class KeyguardSliceProvider extends SliceProvider implements
@Override
public void onStateChanged(int newState) {
+ final boolean notify;
+ synchronized (this) {
+ boolean needsMedia = needsMediaLocked();
+ mStatusBarState = newState;
+ notify = needsMedia != needsMediaLocked();
+ }
+ if (notify) {
+ notifyChange();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
index a9896f51369c..822a6669bd5c 100644
--- a/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
+++ b/packages/SystemUI/src/com/android/systemui/screenrecord/RecordingService.java
@@ -22,6 +22,8 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
+import android.content.ContentResolver;
+import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
@@ -48,6 +50,7 @@ import com.android.systemui.R;
import java.io.File;
import java.io.IOException;
+import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
@@ -158,19 +161,34 @@ public class RecordingService extends Service {
case ACTION_STOP:
stopRecording();
- // Move temp file to user directory
- File recordDir = new File(
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES),
- RECORD_DIR);
- recordDir.mkdirs();
-
String fileName = new SimpleDateFormat("'screen-'yyyyMMdd-HHmmss'.mp4'")
.format(new Date());
- Path path = new File(recordDir, fileName).toPath();
+ ContentValues values = new ContentValues();
+ values.put(MediaStore.Video.Media.DISPLAY_NAME, fileName);
+ values.put(MediaStore.Video.Media.MIME_TYPE, "video/mp4");
+ values.put(MediaStore.Video.Media.DATE_ADDED, System.currentTimeMillis());
+ values.put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis());
+
+ ContentResolver resolver = getContentResolver();
+ Uri collectionUri = MediaStore.Video.Media.getContentUri(
+ MediaStore.VOLUME_EXTERNAL_PRIMARY);
+ Uri itemUri = resolver.insert(collectionUri, values);
+
+ File recordDir = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES),
+ RECORD_DIR);
+ recordDir.mkdirs();
+ Path path = new File(recordDir, fileName).toPath();
try {
+ // Move file out of temp directory
Files.move(mTempFile.toPath(), path);
- Notification notification = createSaveNotification(path);
+
+ // Add to the mediastore
+ OutputStream os = resolver.openOutputStream(itemUri, "w");
+ Files.copy(path, os);
+ os.close();
+
+ Notification notification = createSaveNotification(itemUri, path);
notificationManager.notify(NOTIFICATION_ID, notification);
} catch (IOException e) {
e.printStackTrace();
@@ -352,13 +370,12 @@ public class RecordingService extends Service {
notificationManager.notify(NOTIFICATION_ID, mRecordingNotificationBuilder.build());
}
- private Notification createSaveNotification(Path path) {
- Uri saveUri = FileProvider.getUriForFile(this, FILE_PROVIDER, path.toFile());
- Log.d(TAG, "Screen recording saved to " + path.toString());
+ private Notification createSaveNotification(Uri uri, Path path) {
+ Log.d(TAG, "Screen recording saved to " + uri.toString() + ", " + path.toString());
Intent viewIntent = new Intent(Intent.ACTION_VIEW)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION)
- .setDataAndType(saveUri, "video/mp4");
+ .setDataAndType(uri, "video/mp4");
Notification.Action shareAction = new Notification.Action.Builder(
Icon.createWithResource(this, R.drawable.ic_android),
@@ -366,7 +383,7 @@ public class RecordingService extends Service {
PendingIntent.getService(
this,
REQUEST_CODE,
- getShareIntent(this, path.toString()),
+ getShareIntent(this, uri.toString()),
PendingIntent.FLAG_UPDATE_CURRENT))
.build();
@@ -376,7 +393,7 @@ public class RecordingService extends Service {
PendingIntent.getService(
this,
REQUEST_CODE,
- getDeleteIntent(this, path.toString()),
+ getDeleteIntent(this, uri.toString()),
PendingIntent.FLAG_UPDATE_CURRENT))
.build();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
index 0fe5f8a6af5a..4cc5b2144adc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManager.java
@@ -15,7 +15,6 @@
package com.android.systemui.statusbar;
import android.content.pm.UserInfo;
-import android.service.notification.StatusBarNotification;
import android.util.SparseArray;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
@@ -58,7 +57,7 @@ public interface NotificationLockscreenUserManager {
boolean shouldHideNotifications(int userId);
boolean shouldHideNotifications(String key);
- boolean shouldShowOnKeyguard(StatusBarNotification sbn);
+ boolean shouldShowOnKeyguard(NotificationEntry entry);
boolean isAnyProfilePublicMode();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 4ea1ed5b9451..e08a5ae07bd8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -33,7 +33,6 @@ import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
-import android.service.notification.StatusBarNotification;
import android.util.Log;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
@@ -302,7 +301,7 @@ public class NotificationLockscreenUserManagerImpl implements
Notification.VISIBILITY_SECRET;
}
- public boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
+ public boolean shouldShowOnKeyguard(NotificationEntry entry) {
if (getEntryManager() == null) {
Log.wtf(TAG, "mEntryManager was null!", new Throwable());
return false;
@@ -310,10 +309,10 @@ public class NotificationLockscreenUserManagerImpl implements
boolean exceedsPriorityThreshold;
if (NotificationUtils.useNewInterruptionModel(mContext)
&& hideSilentNotificationsOnLockscreen()) {
- exceedsPriorityThreshold = getEntryManager().getNotificationData().isHighPriority(sbn);
+ exceedsPriorityThreshold = entry.isTopBucket();
} else {
exceedsPriorityThreshold =
- !getEntryManager().getNotificationData().isAmbient(sbn.getKey());
+ !getEntryManager().getNotificationData().isAmbient(entry.key);
}
return mShowLockscreenNotifications && exceedsPriorityThreshold;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 22c91647d7f7..6e75c0375afc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -397,15 +397,13 @@ public class NotificationViewHierarchyManager implements DynamicPrivacyControlle
int userId = entry.notification.getUserId();
boolean suppressedSummary = mGroupManager.isSummaryOfSuppressedGroup(
entry.notification) && !entry.isRowRemoved();
- boolean showOnKeyguard = mLockscreenUserManager.shouldShowOnKeyguard(entry
- .notification);
+ boolean showOnKeyguard = mLockscreenUserManager.shouldShowOnKeyguard(entry);
if (!showOnKeyguard) {
// min priority notifications should show if their summary is showing
if (mGroupManager.isChildInGroupWithSummary(entry.notification)) {
NotificationEntry summary = mGroupManager.getLogicalGroupSummary(
entry.notification);
- if (summary != null && mLockscreenUserManager.shouldShowOnKeyguard(
- summary.notification)) {
+ if (summary != null && mLockscreenUserManager.shouldShowOnKeyguard(summary)) {
showOnKeyguard = true;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt
index ea474ced7632..314dc04e574f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/BypassHeadsUpNotifier.kt
@@ -21,6 +21,7 @@ import android.media.MediaMetadata
import android.provider.Settings
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.NotificationMediaManager
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -40,6 +41,7 @@ class BypassHeadsUpNotifier @Inject constructor(
private val bypassController: KeyguardBypassController,
private val statusBarStateController: StatusBarStateController,
private val headsUpManager: HeadsUpManagerPhone,
+ private val notificationLockscreenUserManager: NotificationLockscreenUserManager,
private val mediaManager: NotificationMediaManager,
tunerService: TunerService) : StatusBarStateController.StateListener,
NotificationMediaManager.MediaListener {
@@ -63,7 +65,7 @@ class BypassHeadsUpNotifier @Inject constructor(
enabled = Settings.Secure.getIntForUser(
context.contentResolver,
Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING,
- 1 /* default */,
+ 0 /* default */,
KeyguardUpdateMonitor.getCurrentUser()) != 0
}, Settings.Secure.SHOW_MEDIA_WHEN_BYPASSING)
}
@@ -79,9 +81,6 @@ class BypassHeadsUpNotifier @Inject constructor(
if (!NotificationMediaManager.isPlayingState(state)) {
newEntry = null
}
- if (newEntry?.isSensitive == true) {
- newEntry = null
- }
currentMediaEntry = newEntry
updateAutoHeadsUp(previous)
updateAutoHeadsUp(currentMediaEntry)
@@ -89,7 +88,7 @@ class BypassHeadsUpNotifier @Inject constructor(
private fun updateAutoHeadsUp(entry: NotificationEntry?) {
entry?.let {
- val autoHeadsUp = it == currentMediaEntry && canAutoHeadsUp()
+ val autoHeadsUp = it == currentMediaEntry && canAutoHeadsUp(it)
it.isAutoHeadsUp = autoHeadsUp
if (autoHeadsUp) {
headsUpManager.showNotification(it)
@@ -97,11 +96,36 @@ class BypassHeadsUpNotifier @Inject constructor(
}
}
+ /**
+ * @return {@code true} if this entry be autoHeadsUpped right now.
+ */
+ private fun canAutoHeadsUp(entry: NotificationEntry): Boolean {
+ if (!isAutoHeadsUpAllowed()) {
+ return false;
+ }
+ if (entry.isSensitive) {
+ // filter sensitive notifications
+ return false
+ }
+ if (!notificationLockscreenUserManager.shouldShowOnKeyguard(entry)) {
+ // filter notifications invisible on Keyguard
+ return false
+ }
+ if (!entryManager.notificationData.activeNotifications.contains(entry)) {
+ // filter notifications not the active list currently
+ return false
+ }
+ return true
+ }
+
override fun onStatePostChange() {
updateAutoHeadsUp(currentMediaEntry)
}
- private fun canAutoHeadsUp() : Boolean {
+ /**
+ * @return {@code true} if autoHeadsUp is possible right now.
+ */
+ private fun isAutoHeadsUpAllowed() : Boolean {
if (!enabled) {
return false
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index 6a3816c50330..6af1f5bca07f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.phone.DozeParameters
import com.android.systemui.statusbar.phone.HeadsUpManagerPhone
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.NotificationIconAreaController
+import com.android.systemui.statusbar.phone.PanelExpansionListener
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
import javax.inject.Inject
@@ -40,7 +41,8 @@ class NotificationWakeUpCoordinator @Inject constructor(
private val mHeadsUpManagerPhone: HeadsUpManagerPhone,
private val statusBarStateController: StatusBarStateController,
private val bypassController: KeyguardBypassController)
- : OnHeadsUpChangedListener, StatusBarStateController.StateListener {
+ : OnHeadsUpChangedListener, StatusBarStateController.StateListener,
+ PanelExpansionListener {
private val mNotificationVisibility
= object : FloatProperty<NotificationWakeUpCoordinator>("notificationVisibility") {
@@ -64,7 +66,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
private var mVisibilityAnimator: ObjectAnimator? = null
private var mVisibilityAmount = 0.0f
private var mLinearVisibilityAmount = 0.0f
- private var mWakingUp = false
private val mEntrySetToClearWhenFinished = mutableSetOf<NotificationEntry>()
private val mDozeParameters: DozeParameters
private var pulseExpanding: Boolean = false
@@ -73,6 +74,25 @@ class NotificationWakeUpCoordinator @Inject constructor(
var fullyAwake: Boolean = false
+ var wakingUp = false
+ set(value) {
+ field = value
+ willWakeUp = false
+ if (value) {
+ if (mNotificationsVisible && !mNotificationsVisibleForExpansion
+ && !bypassController.bypassEnabled) {
+ // We're waking up while pulsing, let's make sure the animation looks nice
+ mStackScroller.wakeUpFromPulse();
+ }
+ if (bypassController.bypassEnabled && !mNotificationsVisible) {
+ // Let's make sure our huns become visible once we are waking up in case
+ // they were blocked by the proximity sensor
+ updateNotificationVisibility(animate = shouldAnimateVisibility(),
+ increaseSpeed = false)
+ }
+ }
+ }
+
var willWakeUp = false
set(value) {
if (!value || mDozeAmount != 0.0f) {
@@ -80,7 +100,9 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
+ private var collapsedEnoughToHide: Boolean = false
lateinit var iconAreaController : NotificationIconAreaController
+
var pulsing: Boolean = false
set(value) {
field = value
@@ -102,7 +124,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
}
}
}
-
/**
* True if we can show pulsing heads up notifications
*/
@@ -112,8 +133,12 @@ class NotificationWakeUpCoordinator @Inject constructor(
var canShow = pulsing
if (bypassController.bypassEnabled) {
// We also allow pulsing on the lock screen!
- canShow = canShow || (mWakingUp || willWakeUp || fullyAwake)
+ canShow = canShow || (wakingUp || willWakeUp || fullyAwake)
&& statusBarStateController.state == StatusBarState.KEYGUARD
+ // We want to hide the notifications when collapsed too much
+ if (collapsedEnoughToHide) {
+ canShow = false
+ }
}
return canShow
}
@@ -160,7 +185,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
wakeUpListeners.add(listener);
}
- fun removeFullyHiddenChangedListener(listener: WakeUpListener) {
+ fun removeListener(listener: WakeUpListener) {
wakeUpListeners.remove(listener);
}
@@ -169,7 +194,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
var visible = mNotificationsVisibleForExpansion || mHeadsUpManagerPhone.hasNotifications()
visible = visible && canShowPulsingHuns
- if (!visible && mNotificationsVisible && (mWakingUp || willWakeUp) && mDozeAmount != 0.0f) {
+ if (!visible && mNotificationsVisible && (wakingUp || willWakeUp) && mDozeAmount != 0.0f) {
// let's not make notifications invisible while waking up, otherwise the animation
// is strange
return;
@@ -229,6 +254,18 @@ class NotificationWakeUpCoordinator @Inject constructor(
this.state = newState
}
+ override fun onPanelExpansionChanged(expansion: Float, tracking: Boolean) {
+ val collapsedEnough = expansion <= 0.9f
+ if (collapsedEnough != this.collapsedEnoughToHide) {
+ val couldShowPulsingHuns = canShowPulsingHuns;
+ this.collapsedEnoughToHide = collapsedEnough
+ if (couldShowPulsingHuns && !canShowPulsingHuns) {
+ updateNotificationVisibility(animate = true, increaseSpeed = true)
+ mHeadsUpManagerPhone.releaseAllImmediately()
+ }
+ }
+ }
+
private fun updateDozeAmountIfBypass(): Boolean {
if (bypassController.bypassEnabled) {
var amount = 1.0f;
@@ -307,16 +344,6 @@ class NotificationWakeUpCoordinator @Inject constructor(
return if (bypassController.bypassEnabled) 0.0f else overflow
}
- fun setWakingUp(wakingUp: Boolean) {
- willWakeUp = false
- mWakingUp = wakingUp
- if (wakingUp && mNotificationsVisible && !mNotificationsVisibleForExpansion
- && !bypassController.bypassEnabled) {
- // We're waking up while pulsing, let's make sure the animation looks nice
- mStackScroller.wakeUpFromPulse();
- }
- }
-
override fun onHeadsUpStateChanged(entry: NotificationEntry, isHeadsUp: Boolean) {
var animate = shouldAnimateVisibility()
if (!isHeadsUp) {
@@ -325,7 +352,7 @@ class NotificationWakeUpCoordinator @Inject constructor(
// if we animate, we see the shelf briefly visible. Instead we fully animate
// the notification and its background out
animate = false
- } else if (!mWakingUp && !willWakeUp){
+ } else if (!wakingUp && !willWakeUp){
// TODO: look that this is done properly and not by anyone else
entry.setHeadsUpAnimatingAway(true)
mEntrySetToClearWhenFinished.add(entry)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
index fca520fe0521..1ce493444e25 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java
@@ -25,7 +25,6 @@ import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.SnoozeCriterion;
import android.service.notification.StatusBarNotification;
import android.util.ArrayMap;
-import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
@@ -108,10 +107,19 @@ public class NotificationData {
boolean bSystemMax = bImportance >= NotificationManager.IMPORTANCE_HIGH
&& isSystemNotification(nb);
- boolean isHeadsUp = a.getRow().isHeadsUp();
- if (isHeadsUp != b.getRow().isHeadsUp()) {
- return isHeadsUp ? -1 : 1;
- } else if (isHeadsUp) {
+
+ boolean aHeadsUp = a.getRow().isHeadsUp();
+ boolean bHeadsUp = b.getRow().isHeadsUp();
+
+ // HACK: This should really go elsewhere, but it's currently not straightforward to
+ // extract the comparison code and we're guaranteed to touch every element, so this is
+ // the best place to set the buckets for the moment.
+ a.setIsTopBucket(aHeadsUp || aMedia || aSystemMax || a.isHighPriority());
+ b.setIsTopBucket(bHeadsUp || bMedia || bSystemMax || b.isHighPriority());
+
+ if (aHeadsUp != bHeadsUp) {
+ return aHeadsUp ? -1 : 1;
+ } else if (aHeadsUp) {
// Provide consistent ranking with headsUpManager
return mHeadsUpManager.compare(a, b);
} else if (aMedia != bMedia) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
index b19d2ca29c96..d71857082229 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationEntry.java
@@ -173,6 +173,9 @@ public final class NotificationEntry {
* the lock screen/status bar and in the top section in the shade.
*/
private boolean mHighPriority;
+
+ private boolean mIsTopBucket;
+
private boolean mSensitive = true;
private Runnable mOnSensitiveChangedListener;
private boolean mAutoHeadsUp;
@@ -224,6 +227,18 @@ public final class NotificationEntry {
this.mHighPriority = highPriority;
}
+ /**
+ * @return True if the notif should appear in the "top" or "important" section of notifications
+ * (as opposed to the "bottom" or "silent" section). This is usually the same as
+ * {@link #isHighPriority()}, but there are certain exceptions, such as media notifs.
+ */
+ public boolean isTopBucket() {
+ return mIsTopBucket;
+ }
+ public void setIsTopBucket(boolean isTopBucket) {
+ mIsTopBucket = isTopBucket;
+ }
+
public boolean isBubble() {
return (notification.getNotification().flags & FLAG_BUBBLE) != 0;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
index d057a1d2f20b..48a82957bf1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentInflater.java
@@ -349,7 +349,7 @@ public class NotificationContentInflater {
}
if ((reInflateFlags & FLAG_CONTENT_VIEW_PUBLIC) != 0) {
- result.newPublicView = builder.makePublicContentView();
+ result.newPublicView = builder.makePublicContentView(isLowPriority);
}
result.packageContext = packageContext;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
index 212808dae8e3..15cc72c2d7a1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationListContainer.java
@@ -184,4 +184,6 @@ public interface NotificationListContainer extends ExpandableView.OnHeightChange
default boolean containsView(View v) {
return true;
}
+
+ default void setWillExpand(boolean willExpand) {};
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
index 170a4d570688..d119fb79e4c6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.java
@@ -133,7 +133,7 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
if (child instanceof ExpandableNotificationRow
&& child.getVisibility() != View.GONE) {
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- if (!row.getEntry().isHighPriority()) {
+ if (!row.getEntry().isTopBucket()) {
firstGentleNotifIndex = i;
mFirstGentleNotif = row;
break;
@@ -248,7 +248,7 @@ class NotificationSectionsManager implements StackScrollAlgorithm.SectionProvide
View child = mParent.getChildAt(i);
if (child.getVisibility() != View.GONE && child instanceof ExpandableNotificationRow) {
ExpandableNotificationRow row = (ExpandableNotificationRow) child;
- if (!row.getEntry().isHighPriority()) {
+ if (!row.getEntry().isTopBucket()) {
break;
} else {
lastChildBeforeGap = row;
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 bec95201e4b2..18a51b9abd8c 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
@@ -499,6 +499,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
private boolean mAnimateBottomOnLayout;
private float mLastSentAppear;
private float mLastSentExpandedHeight;
+ private boolean mWillExpand;
@Inject
public NotificationStackScrollLayout(
@@ -2549,13 +2550,21 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
}
return;
}
- int minTopPosition = 0;
+ int minTopPosition;
NotificationSection lastSection = getLastVisibleSection();
boolean onKeyguard = mStatusBarState == StatusBarState.KEYGUARD;
if (!onKeyguard) {
minTopPosition = (int) (mTopPadding + mStackTranslation);
} else if (lastSection == null) {
minTopPosition = mTopPadding;
+ } else {
+ // The first sections could be empty while there could still be elements in later
+ // sections. The position of these first few sections is determined by the position of
+ // the first visible section.
+ NotificationSection firstVisibleSection = getFirstVisibleSection();
+ firstVisibleSection.updateBounds(0 /* minTopPosition*/, 0 /* minBottomPosition */,
+ false /* shiftPulsingWithFirst */);
+ minTopPosition = firstVisibleSection.getBounds().top;
}
boolean shiftPulsingWithFirst = mHeadsUpManager.getAllEntries().count() <= 1
&& (mAmbientState.isDozing()
@@ -4398,6 +4407,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mStateAnimator.setShadeExpanded(isExpanded);
mSwipeHelper.setIsExpanded(isExpanded);
if (changed) {
+ mWillExpand = false;
if (!mIsExpanded) {
mGroupManager.collapseAllGroups();
mExpandHelper.cancelImmediately();
@@ -5046,7 +5056,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
if (mAnimationsEnabled && (isHeadsUp || mHeadsUpGoingAwayAnimationsAllowed)) {
mHeadsUpChangeAnimations.add(new Pair<>(row, isHeadsUp));
mNeedsAnimation = true;
- if (!mIsExpanded && !isHeadsUp) {
+ if (!mIsExpanded && !mWillExpand && !isHeadsUp) {
row.setHeadsUpAnimatingAway(true);
}
requestChildrenUpdate();
@@ -5067,6 +5077,11 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
requestChildrenUpdate();
}
+ @Override
+ public void setWillExpand(boolean willExpand) {
+ mWillExpand = willExpand;
+ }
+
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void setTrackingHeadsUp(ExpandableNotificationRow row) {
mTrackingHeadsUp = row != null;
@@ -5667,6 +5682,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
// The bottom might change because we're using the final actual height of the view
mAnimateBottomOnLayout = true;
}
+ // Let's update the footer once the notifications have been updated (in the next frame)
+ post(this::updateFooter);
}
public void setOnPulseHeightChangedListener(Runnable listener) {
@@ -5737,7 +5754,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
currentIndex++;
boolean beforeSpeedBump;
if (mHighPriorityBeforeSpeedBump) {
- beforeSpeedBump = row.getEntry().isHighPriority();
+ beforeSpeedBump = row.getEntry().isTopBucket();
} else {
beforeSpeedBump = !row.getEntry().ambient;
}
@@ -5795,9 +5812,9 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
case ROWS_ALL:
return true;
case ROWS_HIGH_PRIORITY:
- return row.getEntry().isHighPriority();
+ return row.getEntry().isTopBucket();
case ROWS_GENTLE:
- return !row.getEntry().isHighPriority();
+ return !row.getEntry().isTopBucket();
default:
throw new IllegalArgumentException("Unknown selection: " + selection);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
index 46dd5e62ddda..f53c4e8c818e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceController.java
@@ -35,6 +35,7 @@ import com.android.systemui.statusbar.CrossFadeHelper;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
@@ -48,7 +49,7 @@ import java.util.function.Consumer;
* Controls the appearance of heads up notifications in the icon area and the header itself.
*/
public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
- DarkIconDispatcher.DarkReceiver {
+ DarkIconDispatcher.DarkReceiver, NotificationWakeUpCoordinator.WakeUpListener {
public static final int CONTENT_FADE_DURATION = 110;
public static final int CONTENT_FADE_DELAY = 100;
private final NotificationIconAreaController mNotificationIconAreaController;
@@ -67,6 +68,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
private final KeyguardBypassController mBypassController;
private final StatusBarStateController mStatusBarStateController;
private final CommandQueue mCommandQueue;
+ private final NotificationWakeUpCoordinator mWakeUpCoordinator;
@VisibleForTesting
float mExpandedHeight;
@VisibleForTesting
@@ -95,9 +97,10 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
HeadsUpManagerPhone headsUpManager,
View statusbarView,
SysuiStatusBarStateController statusBarStateController,
- KeyguardBypassController keyguardBypassController) {
+ KeyguardBypassController keyguardBypassController,
+ NotificationWakeUpCoordinator wakeUpCoordinator) {
this(notificationIconAreaController, headsUpManager, statusBarStateController,
- keyguardBypassController,
+ keyguardBypassController, wakeUpCoordinator,
statusbarView.findViewById(R.id.heads_up_status_bar_view),
statusbarView.findViewById(R.id.notification_stack_scroller),
statusbarView.findViewById(R.id.notification_panel),
@@ -112,6 +115,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
HeadsUpManagerPhone headsUpManager,
StatusBarStateController stateController,
KeyguardBypassController bypassController,
+ NotificationWakeUpCoordinator wakeUpCoordinator,
HeadsUpStatusBarView headsUpStatusBarView,
NotificationStackScrollLayout stackScroller,
NotificationPanelView panelView,
@@ -153,6 +157,8 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
});
mBypassController = bypassController;
mStatusBarStateController = stateController;
+ mWakeUpCoordinator = wakeUpCoordinator;
+ wakeUpCoordinator.addListener(this);
mCommandQueue = getComponent(headsUpStatusBarView.getContext(), CommandQueue.class);
mKeyguardMonitor = Dependency.get(KeyguardMonitor.class);
}
@@ -161,6 +167,7 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
public void destroy() {
mHeadsUpManager.removeListener(this);
mHeadsUpStatusBarView.setOnDrawingRectChangedListener(null);
+ mWakeUpCoordinator.removeListener(this);
mPanelView.removeTrackingHeadsUpListener(mSetTrackingHeadsUp);
mPanelView.removeVerticalTranslationListener(mUpdatePanelTranslation);
mPanelView.setHeadsUpAppearanceController(null);
@@ -289,6 +296,11 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
updateParentClipping(true /* shouldClip */);
});
}
+ // Show the status bar icons when the view gets shown / hidden
+ if (mStatusBarStateController.getState() != StatusBarState.SHADE) {
+ mCommandQueue.recomputeDisableFlags(
+ mHeadsUpStatusBarView.getContext().getDisplayId(), false);
+ }
}
}
@@ -362,10 +374,12 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
* @return if the heads up status bar view should be shown
*/
public boolean shouldBeVisible() {
- boolean canShow = !mIsExpanded;
+ boolean notificationsShown = !mWakeUpCoordinator.getNotificationsFullyHidden();
+ boolean canShow = !mIsExpanded && notificationsShown;
if (mBypassController.getBypassEnabled() &&
(mStatusBarStateController.getState() == StatusBarState.KEYGUARD
- || mKeyguardMonitor.isKeyguardGoingAway())) {
+ || mKeyguardMonitor.isKeyguardGoingAway())
+ && notificationsShown) {
canShow = true;
}
return canShow && mHeadsUpManager.hasPinnedHeadsUp();
@@ -377,15 +391,6 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
updateHeader(entry);
}
- @Override
- public void onHeadsUpPinnedModeChanged(boolean inPinnedMode) {
- if (mStatusBarStateController.getState() != StatusBarState.SHADE) {
- // Show the status bar icons when the pinned mode changes
- mCommandQueue.recomputeDisableFlags(
- mHeadsUpStatusBarView.getContext().getDisplayId(), false);
- }
- }
-
public void setAppearFraction(float expandedHeight, float appearFraction) {
boolean changed = expandedHeight != mExpandedHeight;
mExpandedHeight = expandedHeight;
@@ -451,4 +456,9 @@ public class HeadsUpAppearanceController implements OnHeadsUpChangedListener,
mAppearFraction = oldController.mAppearFraction;
}
}
+
+ @Override
+ public void onFullyHiddenChanged(boolean isFullyHidden) {
+ updateTopEntry();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index d6f8a606af55..c4d346ccaefb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -170,7 +170,7 @@ public class KeyguardBouncer {
// Split up the work over multiple frames.
DejankUtils.removeCallbacks(mResetRunnable);
- if (mUnlockMethodCache.isUnlockingWithFacePossible() && !needsFullscreenBouncer()
+ if (mUnlockMethodCache.isFaceAuthEnabled() && !needsFullscreenBouncer()
&& !mKeyguardUpdateMonitor.userNeedsStrongAuth()) {
mHandler.postDelayed(mShowRunnable, BOUNCER_FACE_DELAY);
} else {
@@ -207,14 +207,12 @@ public class KeyguardBouncer {
* @see #onFullyShown()
*/
private void onFullyHidden() {
- if (!mShowingSoon) {
- cancelShowRunnable();
- if (mRoot != null) {
- mRoot.setVisibility(View.INVISIBLE);
- }
- mFalsingManager.onBouncerHidden();
- DejankUtils.postAfterTraversal(mResetRunnable);
+ cancelShowRunnable();
+ if (mRoot != null) {
+ mRoot.setVisibility(View.INVISIBLE);
}
+ mFalsingManager.onBouncerHidden();
+ DejankUtils.postAfterTraversal(mResetRunnable);
}
private final Runnable mShowRunnable = new Runnable() {
@@ -349,7 +347,7 @@ public class KeyguardBouncer {
* {@link #show(boolean)} was called but we're not showing yet, or being dragged.
*/
public boolean inTransit() {
- return mShowingSoon || mExpansion != EXPANSION_HIDDEN;
+ return mShowingSoon || mExpansion != EXPANSION_HIDDEN && mExpansion != EXPANSION_VISIBLE;
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
index 0aec2b12fa92..70d3bff9b822 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
@@ -47,7 +47,7 @@ class KeyguardBypassController {
* If face unlock dismisses the lock screen or keeps user on keyguard for the current user.
*/
var bypassEnabled: Boolean = false
- get() = field && unlockMethodCache.isUnlockingWithFacePossible
+ get() = field && unlockMethodCache.isFaceAuthEnabled
private set
var bouncerShowing: Boolean = false
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 1360a084207b..c9c80d464b46 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -217,7 +217,7 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
mConfigurationController.removeCallback(this);
mKeyguardUpdateMonitor.removeCallback(mUpdateMonitorCallback);
mKeyguardMonitor.removeCallback(mKeyguardMonitorCallback);
- mWakeUpCoordinator.removeFullyHiddenChangedListener(this);
+ mWakeUpCoordinator.removeListener(this);
mUnlockMethodCache.removeListener(this);
if (mDockManager != null) {
mDockManager.removeListener(mDockEventListener);
@@ -323,14 +323,24 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
}
updateDarkTint();
+ updateIconVisibility();
+ updateClickability();
+
+ return true;
+ }
+
+ /**
+ * Update the icon visibility
+ * @return true if the visibility changed
+ */
+ private boolean updateIconVisibility() {
boolean onAodNotPulsingOrDocked = mDozing && (!mPulsing || mDocked);
boolean invisible = onAodNotPulsingOrDocked || mWakeAndUnlockRunning
|| mShowingLaunchAffordance;
if (mBypassController.getBypassEnabled() && !mBouncerShowingScrimmed) {
- if (mHeadsUpManager.isHeadsUpGoingAway()
- || mHeadsUpManager.hasPinnedHeadsUp()
- || (mStatusBarStateController.getState() == StatusBarState.KEYGUARD
- && !mWakeUpCoordinator.getNotificationsFullyHidden())) {
+ if ((mHeadsUpManager.isHeadsUpGoingAway() || mHeadsUpManager.hasPinnedHeadsUp())
+ && mStatusBarStateController.getState() == StatusBarState.KEYGUARD
+ && !mWakeUpCoordinator.getNotificationsFullyHidden()) {
invisible = true;
}
}
@@ -349,10 +359,9 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
.setDuration(233)
.start();
}
+ return true;
}
- updateClickability();
-
- return true;
+ return false;
}
private boolean canBlockUpdates() {
@@ -440,7 +449,10 @@ public class LockIcon extends KeyguardAffordanceView implements OnUserInfoChange
@Override
public void onFullyHiddenChanged(boolean isFullyHidden) {
if (mBypassController.getBypassEnabled()) {
- update();
+ boolean changed = updateIconVisibility();
+ if (changed) {
+ update();
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 22e3edb2bbd8..9296f7e32761 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -22,6 +22,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_H
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SEARCH_DISABLED;
import static com.android.systemui.shared.system.QuickStepContract.isGesturalMode;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
@@ -719,6 +720,8 @@ public class NavigationBarView extends FrameLayout implements
(mDisabledFlags & View.STATUS_BAR_DISABLE_RECENT) != 0, displayId);
mOverviewProxyService.setSystemUiStateFlag(SYSUI_STATE_HOME_DISABLED,
(mDisabledFlags & View.STATUS_BAR_DISABLE_HOME) != 0, displayId);
+ mOverviewProxyService.setSystemUiStateFlag(SYSUI_STATE_SEARCH_DISABLED,
+ (mDisabledFlags & View.STATUS_BAR_DISABLE_SEARCH) != 0, displayId);
if (mPanelView != null) {
mOverviewProxyService.setSystemUiStateFlag(SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED,
mPanelView.isFullyExpanded() && !mPanelView.isInSettings(), displayId);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
index 64fef55a21d3..1df9411019d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationModeController.java
@@ -32,8 +32,6 @@ import static com.android.systemui.shared.system.QuickStepContract.ACTION_ENABLE
import static com.android.systemui.shared.system.QuickStepContract.ACTION_ENABLE_GESTURE_NAV_RESULT;
import static com.android.systemui.shared.system.QuickStepContract.EXTRA_RESULT_INTENT;
-import android.app.Notification;
-import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.content.BroadcastReceiver;
@@ -42,7 +40,6 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.om.IOverlayManager;
-import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ApkAssets;
import android.os.PatternMatcher;
@@ -52,16 +49,13 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Secure;
-import android.text.TextUtils;
import android.util.Log;
import android.util.SparseBooleanArray;
import com.android.systemui.Dumpable;
-import com.android.systemui.R;
import com.android.systemui.UiOffloadThread;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.util.NotificationChannels;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -80,11 +74,6 @@ public class NavigationModeController implements Dumpable {
private static final String TAG = NavigationModeController.class.getSimpleName();
private static final boolean DEBUG = false;
- private static final int SYSTEM_APP_MASK =
- ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
- static final String SHARED_PREFERENCES_NAME = "navigation_mode_controller_preferences";
- static final String PREFS_SWITCHED_FROM_GESTURE_NAV_KEY = "switched_from_gesture_nav";
-
public interface ModeChangedListener {
void onNavigationModeChanged(int mode);
}
@@ -100,8 +89,6 @@ public class NavigationModeController implements Dumpable {
private int mMode = NAV_BAR_MODE_3BUTTON;
private ArrayList<ModeChangedListener> mListeners = new ArrayList<>();
- private String mLastDefaultLauncher;
-
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
@@ -112,18 +99,6 @@ public class NavigationModeController implements Dumpable {
}
updateCurrentInteractionMode(true /* notify */);
break;
- case ACTION_PREFERRED_ACTIVITY_CHANGED:
- if (DEBUG) {
- Log.d(TAG, "ACTION_PREFERRED_ACTIVITY_CHANGED");
- }
- final String launcher = getDefaultLauncherPackageName(mCurrentUserContext);
- // Check if it is a default launcher change
- if (!TextUtils.equals(mLastDefaultLauncher, launcher)) {
- switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
- showNotificationIfDefaultLauncherSupportsGestureNav();
- mLastDefaultLauncher = launcher;
- }
- break;
}
}
};
@@ -159,7 +134,6 @@ public class NavigationModeController implements Dumpable {
// Update the nav mode for the current user
updateCurrentInteractionMode(true /* notify */);
- switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
// When switching users, defer enabling the gestural nav overlay until the user
// is all set up
@@ -190,11 +164,7 @@ public class NavigationModeController implements Dumpable {
mContext.registerReceiverAsUser(mReceiver, UserHandle.ALL, preferredActivityFilter, null,
null);
- // We are only interested in launcher changes, so keeping track of the current default.
- mLastDefaultLauncher = getDefaultLauncherPackageName(mContext);
-
updateCurrentInteractionMode(false /* notify */);
- switchFromGestureNavModeIfNotSupportedByDefaultLauncher();
// Check if we need to defer enabling gestural nav
deferGesturalNavOverlayIfNecessary();
@@ -216,21 +186,13 @@ public class NavigationModeController implements Dumpable {
// Already in gesture mode
return true;
}
- final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
- if (supported == null || supported) {
- Log.d(TAG, "Switching system navigation to full-gesture mode:"
- + " defaultLauncher="
- + getDefaultLauncherPackageName(mCurrentUserContext)
- + " contextUser="
- + mCurrentUserContext.getUserId());
-
- setModeOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT);
- return true;
- } else {
- Log.e(TAG, "Gesture nav is not supported for defaultLauncher="
- + getDefaultLauncherPackageName(mCurrentUserContext));
- return false;
- }
+
+ Log.d(TAG, "Switching system navigation to full-gesture mode:"
+ + " contextUser="
+ + mCurrentUserContext.getUserId());
+
+ setModeOverlay(NAV_BAR_MODE_GESTURAL_OVERLAY, USER_CURRENT);
+ return true;
}
private boolean enableGestureNav(Intent intent) {
@@ -430,100 +392,6 @@ public class NavigationModeController implements Dumpable {
});
}
- private void switchFromGestureNavModeIfNotSupportedByDefaultLauncher() {
- if (getCurrentInteractionMode(mCurrentUserContext) != NAV_BAR_MODE_GESTURAL) {
- return;
- }
- final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
- if (supported == null || supported) {
- return;
- }
-
- Log.d(TAG, "Switching system navigation to 3-button mode:"
- + " defaultLauncher=" + getDefaultLauncherPackageName(mCurrentUserContext)
- + " contextUser=" + mCurrentUserContext.getUserId());
-
- setModeOverlay(NAV_BAR_MODE_3BUTTON_OVERLAY, USER_CURRENT);
- showNotification(mCurrentUserContext, R.string.notification_content_system_nav_changed);
- mCurrentUserContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
- .edit().putBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, true).apply();
- }
-
- private void showNotificationIfDefaultLauncherSupportsGestureNav() {
- boolean previouslySwitchedFromGestureNav = mCurrentUserContext
- .getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
- .getBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false);
- if (!previouslySwitchedFromGestureNav) {
- return;
- }
- if (getCurrentInteractionMode(mCurrentUserContext) == NAV_BAR_MODE_GESTURAL) {
- return;
- }
- final Boolean supported = isGestureNavSupportedByDefaultLauncher(mCurrentUserContext);
- if (supported == null || !supported) {
- return;
- }
-
- showNotification(mCurrentUserContext, R.string.notification_content_gesture_nav_available);
- mCurrentUserContext.getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
- .edit().putBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false).apply();
- }
-
- /**
- * Returns null if there is no default launcher set for the current user. Returns true if the
- * current default launcher supports Gesture Navigation. Returns false otherwise.
- */
- private Boolean isGestureNavSupportedByDefaultLauncher(Context context) {
- final String defaultLauncherPackageName = getDefaultLauncherPackageName(context);
- if (DEBUG) {
- Log.d(TAG, "isGestureNavSupportedByDefaultLauncher:"
- + " defaultLauncher=" + defaultLauncherPackageName
- + " contextUser=" + context.getUserId());
- }
- if (defaultLauncherPackageName == null) {
- return null;
- }
- if (isSystemApp(context, defaultLauncherPackageName)) {
- return true;
- }
- return false;
- }
-
- private String getDefaultLauncherPackageName(Context context) {
- final ComponentName cn = context.getPackageManager().getHomeActivities(new ArrayList<>());
- if (cn == null) {
- return null;
- }
- return cn.getPackageName();
- }
-
- /** Returns true if the app for the given package name is a system app for this device */
- private boolean isSystemApp(Context context, String packageName) {
- try {
- ApplicationInfo ai = context.getPackageManager().getApplicationInfo(packageName,
- PackageManager.GET_META_DATA);
- return ai != null && ((ai.flags & SYSTEM_APP_MASK) != 0);
- } catch (PackageManager.NameNotFoundException e) {
- return false;
- }
- }
-
- private void showNotification(Context context, int resId) {
- final CharSequence message = context.getResources().getString(resId);
- if (DEBUG) {
- Log.d(TAG, "showNotification: message=" + message);
- }
-
- final Notification.Builder builder =
- new Notification.Builder(mContext, NotificationChannels.ALERTS)
- .setContentText(message)
- .setStyle(new Notification.BigTextStyle())
- .setSmallIcon(R.drawable.ic_info)
- .setAutoCancel(true)
- .setContentIntent(PendingIntent.getActivity(context, 0, new Intent(), 0));
- context.getSystemService(NotificationManager.class).notify(TAG, 0, builder.build());
- }
-
@Override
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println("NavigationModeController:");
@@ -536,12 +404,6 @@ public class NavigationModeController implements Dumpable {
}
pw.println(" defaultOverlays=" + defaultOverlays);
dumpAssetPaths(mCurrentUserContext);
-
- pw.println(" defaultLauncher=" + mLastDefaultLauncher);
- boolean previouslySwitchedFromGestureNav = mCurrentUserContext
- .getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
- .getBoolean(PREFS_SWITCHED_FROM_GESTURE_NAV_KEY, false);
- pw.println(" previouslySwitchedFromGestureNav=" + previouslySwitchedFromGestureNav);
}
private void dumpAssetPaths(Context context) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
index d2159ca15b24..21de8a59836e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationIconAreaController.java
@@ -4,7 +4,6 @@ import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.graphics.Rect;
-import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -32,7 +31,6 @@ import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
-import com.android.systemui.tuner.TunerService;
import java.util.ArrayList;
import java.util.Objects;
@@ -58,7 +56,6 @@ public class NotificationIconAreaController implements DarkReceiver,
private final KeyguardBypassController mBypassController;
private final DozeParameters mDozeParameters;
- private boolean mShowSilentOnLockscreen = true;
private int mIconSize;
private int mIconHPadding;
private int mIconTint = Color.WHITE;
@@ -101,11 +98,6 @@ public class NotificationIconAreaController implements DarkReceiver,
initializeNotificationAreaViews(context);
reloadAodColor();
-
- TunerService tunerService = Dependency.get(TunerService.class);
- tunerService.addTunable((key, newValue) -> {
- mShowSilentOnLockscreen = "1".equals(newValue);
- }, Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS);
}
protected View inflateIconArea(LayoutInflater inflater) {
@@ -238,7 +230,7 @@ public class NotificationIconAreaController implements DarkReceiver,
}
protected boolean shouldShowNotificationIcon(NotificationEntry entry,
- boolean showAmbient, boolean showLowPriority, boolean hideDismissed,
+ boolean showAmbient, boolean hideDismissed,
boolean hideRepliedMessages, boolean hideCurrentMedia, boolean hideCenteredIcon,
boolean hidePulsing, boolean onlyShowCenteredIcon) {
@@ -257,9 +249,6 @@ public class NotificationIconAreaController implements DarkReceiver,
if (hideCurrentMedia && entry.key.equals(mMediaManager.getMediaNotificationKey())) {
return false;
}
- if (!showLowPriority && !entry.isHighPriority()) {
- return false;
- }
if (!entry.isTopLevelChild()) {
return false;
}
@@ -297,7 +286,6 @@ public class NotificationIconAreaController implements DarkReceiver,
private void updateShelfIcons() {
updateIconsForLayout(entry -> entry.expandedIcon, mShelfIcons,
true /* showAmbient */,
- true /* showLowPriority */,
false /* hideDismissed */,
false /* hideRepliedMessages */,
false /* hideCurrentMedia */,
@@ -309,7 +297,6 @@ public class NotificationIconAreaController implements DarkReceiver,
public void updateStatusBarIcons() {
updateIconsForLayout(entry -> entry.icon, mNotificationIcons,
false /* showAmbient */,
- true /* showLowPriority */,
true /* hideDismissed */,
true /* hideRepliedMessages */,
false /* hideCurrentMedia */,
@@ -321,7 +308,6 @@ public class NotificationIconAreaController implements DarkReceiver,
private void updateCenterIcon() {
updateIconsForLayout(entry -> entry.centeredIcon, mCenteredIcon,
false /* showAmbient */,
- true /* showLowPriority */,
false /* hideDismissed */,
false /* hideRepliedMessages */,
false /* hideCurrentMedia */,
@@ -333,7 +319,6 @@ public class NotificationIconAreaController implements DarkReceiver,
public void updateAodNotificationIcons() {
updateIconsForLayout(entry -> entry.aodIcon, mAodIcons,
false /* showAmbient */,
- mShowSilentOnLockscreen /* showLowPriority */,
true /* hideDismissed */,
true /* hideRepliedMessages */,
true /* hideCurrentMedia */,
@@ -353,7 +338,7 @@ public class NotificationIconAreaController implements DarkReceiver,
* @param hidePulsing should pulsing notifications be hidden
*/
private void updateIconsForLayout(Function<NotificationEntry, StatusBarIconView> function,
- NotificationIconContainer hostLayout, boolean showAmbient, boolean showLowPriority,
+ NotificationIconContainer hostLayout, boolean showAmbient,
boolean hideDismissed, boolean hideRepliedMessages, boolean hideCurrentMedia,
boolean hideCenteredIcon, boolean hidePulsing, boolean onlyShowCenteredIcon) {
ArrayList<StatusBarIconView> toShow = new ArrayList<>(
@@ -364,7 +349,7 @@ public class NotificationIconAreaController implements DarkReceiver,
View view = mNotificationScrollLayout.getChildAt(i);
if (view instanceof ExpandableNotificationRow) {
NotificationEntry ent = ((ExpandableNotificationRow) view).getEntry();
- if (shouldShowNotificationIcon(ent, showAmbient, showLowPriority, hideDismissed,
+ if (shouldShowNotificationIcon(ent, showAmbient, hideDismissed,
hideRepliedMessages, hideCurrentMedia, hideCenteredIcon, hidePulsing,
onlyShowCenteredIcon)) {
StatusBarIconView iconView = function.apply(ent);
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 971a7eeaca12..670deef19cf5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -454,6 +454,11 @@ public class NotificationPanelView extends PanelView implements
mPulseExpansionHandler.setUp(mNotificationStackScroller, this, mShadeController);
mWakeUpCoordinator.addListener(new NotificationWakeUpCoordinator.WakeUpListener() {
@Override
+ public void onFullyHiddenChanged(boolean isFullyHidden) {
+ updateKeyguardStatusBarForHeadsUp();
+ }
+
+ @Override
public void onPulseExpansionChanged(boolean expandingChanged) {
if (mKeyguardBypassController.getBypassEnabled()) {
// Position the notifications while dragging down while pulsing
@@ -803,8 +808,7 @@ public class NotificationPanelView extends PanelView implements
if (suppressedSummary) {
continue;
}
- if (!mLockscreenUserManager.shouldShowOnKeyguard(
- row.getStatusBarNotification())) {
+ if (!mLockscreenUserManager.shouldShowOnKeyguard(row.getEntry())) {
continue;
}
if (row.isRemoved()) {
@@ -1278,6 +1282,7 @@ public class NotificationPanelView extends PanelView implements
}
mExpectingSynthesizedDown = true;
onTrackingStarted();
+ updatePanelExpanded();
}
/**
@@ -1717,8 +1722,8 @@ public class NotificationPanelView extends PanelView implements
mStatusBar.executeRunnableDismissingKeyguard(null, null /* cancelAction */,
false /* dismissShade */, true /* afterKeyguardGone */, false /* deferred */);
}
- if (mExpansionListener != null) {
- mExpansionListener.onQsExpansionChanged(mQsMaxExpansionHeight != 0
+ for (int i = 0; i < mExpansionListeners.size(); i++) {
+ mExpansionListeners.get(i).onQsExpansionChanged(mQsMaxExpansionHeight != 0
? mQsExpansionHeight / mQsMaxExpansionHeight : 0);
}
if (DEBUG) {
@@ -2029,7 +2034,7 @@ public class NotificationPanelView extends PanelView implements
}
private void updatePanelExpanded() {
- boolean isExpanded = !isFullyCollapsed();
+ boolean isExpanded = !isFullyCollapsed() || mExpectingSynthesizedDown;
if (mPanelExpanded != isExpanded) {
mHeadsUpManager.setIsPanelExpanded(isExpanded);
mStatusBar.setPanelExpanded(isExpanded);
@@ -3374,24 +3379,4 @@ public class NotificationPanelView extends PanelView implements
mOnReinflationListener = onReinflationListener;
}
- /**
- * Panel and QS expansion callbacks.
- */
- public interface PanelExpansionListener {
- /**
- * Invoked whenever the notification panel expansion changes, at every animation frame.
- * This is the main expansion that happens when the user is swiping up to dismiss the
- * lock screen.
- *
- * @param expansion 0 when collapsed, 1 when expanded.
- * @param tracking {@code true} when the user is actively dragging the panel.
- */
- void onPanelExpansionChanged(float expansion, boolean tracking);
-
- /**
- * Invoked whenever the QS expansion changes, at every animation frame.
- * @param expansion 0 when collapsed, 1 when expanded.
- */
- void onQsExpansionChanged(float expansion);
- }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelExpansionListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelExpansionListener.java
new file mode 100644
index 000000000000..655a25d22337
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelExpansionListener.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.statusbar.phone;
+
+/**
+ * Panel and QS expansion callbacks.
+ */
+public interface PanelExpansionListener {
+ /**
+ * Invoked whenever the notification panel expansion changes, at every animation frame.
+ * This is the main expansion that happens when the user is swiping up to dismiss the
+ * lock screen.
+ *
+ * @param expansion 0 when collapsed, 1 when expanded.
+ * @param tracking {@code true} when the user is actively dragging the panel.
+ */
+ void onPanelExpansionChanged(float expansion, boolean tracking);
+
+ /**
+ * Invoked whenever the QS expansion changes, at every animation frame.
+ * @param expansion 0 when collapsed, 1 when expanded.
+ */
+ default void onQsExpansionChanged(float expansion) {};
+}
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 853faabbbc81..727f72b36ed8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -49,11 +49,11 @@ import com.android.systemui.statusbar.FlingAnimationUtils;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.VibratorHelper;
-import com.android.systemui.statusbar.phone.NotificationPanelView.PanelExpansionListener;
import com.android.systemui.statusbar.policy.KeyguardMonitor;
import java.io.FileDescriptor;
import java.io.PrintWriter;
+import java.util.ArrayList;
public abstract class PanelView extends FrameLayout {
public static final boolean DEBUG = PanelBar.DEBUG;
@@ -68,7 +68,7 @@ public abstract class PanelView extends FrameLayout {
private boolean mVibrateOnOpening;
protected boolean mLaunchingNotification;
private int mFixedDuration = NO_FIXED_DURATION;
- protected PanelExpansionListener mExpansionListener;
+ protected ArrayList<PanelExpansionListener> mExpansionListeners = new ArrayList<>();
private final void logf(String fmt, Object... args) {
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -1173,13 +1173,13 @@ public abstract class PanelView extends FrameLayout {
|| mPeekAnimator != null || mInstantExpanding
|| isPanelVisibleBecauseOfHeadsUp() || mTracking || mHeightAnimator != null);
}
- if (mExpansionListener != null) {
- mExpansionListener.onPanelExpansionChanged(mExpandedFraction, mTracking);
+ for (int i = 0; i < mExpansionListeners.size(); i++) {
+ mExpansionListeners.get(i).onPanelExpansionChanged(mExpandedFraction, mTracking);
}
}
- public void setExpansionListener(PanelExpansionListener panelExpansionListener) {
- mExpansionListener = panelExpansionListener;
+ public void addExpansionListener(PanelExpansionListener panelExpansionListener) {
+ mExpansionListeners.add(panelExpansionListener);
}
protected abstract boolean isPanelVisibleBecauseOfHeadsUp();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 1aec5e4d0b1d..b12bf5c39970 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -491,8 +491,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, OnCo
* away once the display turns on.
*/
public void prepareForGentleWakeUp() {
- if (mState == ScrimState.AOD && mDozeParameters.getAlwaysOn()) {
+ if (mState == ScrimState.AOD) {
mCurrentInFrontAlpha = 1f;
+ mCurrentInFrontTint = Color.BLACK;
+ mCurrentBehindTint = Color.BLACK;
mAnimateChange = false;
updateScrims();
mAnimateChange = true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
index 763e0d70469b..c706062d3bb3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -129,7 +129,10 @@ public enum ScrimState {
public void prepare(ScrimState previousState) {
mCurrentInFrontAlpha = 0f;
mCurrentBehindTint = Color.BLACK;
+ mCurrentInFrontTint = Color.BLACK;
mBlankScreen = mDisplayRequiresBlanking;
+ mAnimationDuration = mWakeLockScreenSensorActive
+ ? ScrimController.ANIMATION_DURATION_LONG : ScrimController.ANIMATION_DURATION;
}
@Override
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 f8e6aa3b844f..881fb9d85c9b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -813,6 +813,7 @@ public class StatusBar extends SystemUI implements DemoMode,
inflateShelf();
mNotificationIconAreaController.setupShelf(mNotificationShelf);
mNotificationPanel.setOnReinflationListener(mNotificationIconAreaController::initAodIcons);
+ mNotificationPanel.addExpansionListener(mWakeUpCoordinator);
Dependency.get(DarkIconDispatcher.class).addDarkReceiver(mNotificationIconAreaController);
// Allow plugins to reference DarkIconDispatcher and StatusBarStateController
@@ -855,7 +856,8 @@ public class StatusBar extends SystemUI implements DemoMode,
}
mHeadsUpAppearanceController = new HeadsUpAppearanceController(
mNotificationIconAreaController, mHeadsUpManager, mStatusBarWindow,
- mStatusBarStateController, mKeyguardBypassController);
+ mStatusBarStateController, mKeyguardBypassController,
+ mWakeUpCoordinator);
mHeadsUpAppearanceController.readFrom(oldController);
mStatusBarWindow.setStatusBarView(mStatusBarView);
updateAreThereNotifications();
@@ -1801,6 +1803,8 @@ public class StatusBar extends SystemUI implements DemoMode,
mVibratorHelper.vibrate(VibrationEffect.EFFECT_TICK);
}
mNotificationPanel.expand(true /* animate */);
+ ((NotificationListContainer) mStackScroller).setWillExpand(true);
+ mHeadsUpManager.unpinAll(true /* userUnpinned */);
mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN, 1);
} else if (!mNotificationPanel.isInSettings() && !mNotificationPanel.isExpanding()){
mNotificationPanel.flingSettings(0 /* velocity */,
@@ -1938,7 +1942,6 @@ public class StatusBar extends SystemUI implements DemoMode,
if (start) {
mNotificationPanel.startWaitingForOpenPanelGesture();
- setPanelExpanded(true);
} else {
mNotificationPanel.stopWaitingForOpenPanelGesture(velocity);
}
@@ -2387,6 +2390,10 @@ public class StatusBar extends SystemUI implements DemoMode,
mLightBarController.dump(fd, pw, args);
}
+ if (mUnlockMethodCache != null) {
+ mUnlockMethodCache.dump(pw);
+ }
+
if (mKeyguardBypassController != null) {
mKeyguardBypassController.dump(pw);
}
@@ -3562,6 +3569,9 @@ public class StatusBar extends SystemUI implements DemoMode,
userAllowsPrivateNotificationsInPublic(mLockscreenUserManager.getCurrentUserId())
|| !mLockscreenUserManager.shouldShowLockscreenNotifications()
|| mFalsingManager.shouldEnforceBouncer();
+ if (mKeyguardBypassController.getBypassEnabled()) {
+ fullShadeNeedsBouncer = false;
+ }
if (mLockscreenUserManager.isLockscreenPublicMode(userId) && fullShadeNeedsBouncer) {
mStatusBarStateController.setLeaveOpenOnKeyguardHide(true);
showBouncerIfKeyguard();
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 5ce1329d5a89..197c09d8b56e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -70,7 +70,7 @@ import java.util.ArrayList;
*/
public class StatusBarKeyguardViewManager implements RemoteInputController.Callback,
StatusBarStateController.StateListener, ConfigurationController.ConfigurationListener,
- NotificationPanelView.PanelExpansionListener, NavigationModeController.ModeChangedListener {
+ PanelExpansionListener, NavigationModeController.ModeChangedListener {
// When hiding the Keyguard with timing supplied from WindowManager, better be early than late.
private static final long HIDE_TIMING_CORRECTION_MS = - 16 * 3;
@@ -223,7 +223,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mViewMediatorCallback, mLockPatternUtils, container, dismissCallbackRegistry,
mExpansionCallback, falsingManager);
mNotificationPanelView = notificationPanelView;
- notificationPanelView.setExpansionListener(this);
+ notificationPanelView.addExpansionListener(this);
mBypassController = bypassController;
mNotificationContainer = notificationContainer;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index f1049f005dea..33b863fd0236 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -418,7 +418,7 @@ public class StatusBarWindowView extends FrameLayout {
if (mNotificationPanel.isFullyExpanded()
&& mStatusBarStateController.getState() == StatusBarState.KEYGUARD
&& !mService.isBouncerShowing()
- && !mBypassController.getBypassEnabled()
+ && (!mBypassController.getBypassEnabled() || mNotificationPanel.isQsExpanded())
&& !mService.isDozing()) {
intercept = mDragDownHelper.onInterceptTouchEvent(ev);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
index a71fcdbd9914..b1d6ca6e5580 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -28,6 +28,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
+import java.io.PrintWriter;
import java.util.ArrayList;
/**
@@ -51,7 +52,7 @@ public class UnlockMethodCache {
private boolean mTrustManaged;
private boolean mTrusted;
private boolean mDebugUnlocked = false;
- private boolean mIsUnlockingWithFacePossible;
+ private boolean mFaceAuthEnabled;
private UnlockMethodCache(Context ctx) {
mLockPatternUtils = new LockPatternUtils(ctx);
@@ -110,8 +111,8 @@ public class UnlockMethodCache {
/**
* If there are faces enrolled and user enabled face auth on keyguard.
*/
- public boolean isUnlockingWithFacePossible() {
- return mIsUnlockingWithFacePossible;
+ public boolean isFaceAuthEnabled() {
+ return mFaceAuthEnabled;
}
private void update(boolean updateAlways) {
@@ -122,16 +123,16 @@ public class UnlockMethodCache {
|| (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
- boolean isUnlockingWithFacePossible = mKeyguardUpdateMonitor.isUnlockWithFacePossible(user);
+ boolean faceAuthEnabled = mKeyguardUpdateMonitor.isFaceAuthEnabledForUser(user);
boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer
|| trustManaged != mTrustManaged
- || mIsUnlockingWithFacePossible != isUnlockingWithFacePossible;
+ || mFaceAuthEnabled != faceAuthEnabled;
if (changed || updateAlways) {
mSecure = secure;
mCanSkipBouncer = canSkipBouncer;
mTrusted = trusted;
mTrustManaged = trustManaged;
- mIsUnlockingWithFacePossible = isUnlockingWithFacePossible;
+ mFaceAuthEnabled = faceAuthEnabled;
notifyListeners();
}
Trace.endSection();
@@ -143,6 +144,16 @@ public class UnlockMethodCache {
}
}
+ public void dump(PrintWriter pw) {
+ pw.println("UnlockMethodCache");
+ pw.println(" mSecure: " + mSecure);
+ pw.println(" mCanSkipBouncer: " + mCanSkipBouncer);
+ pw.println(" mTrustManaged: " + mTrustManaged);
+ pw.println(" mTrusted: " + mTrusted);
+ pw.println(" mDebugUnlocked: " + mDebugUnlocked);
+ pw.println(" mFaceAuthEnabled: " + mFaceAuthEnabled);
+ }
+
private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
@Override
public void onUserSwitchComplete(int userId) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
index 893f3d184acb..9576cb2eec45 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardSliceProviderTest.java
@@ -48,6 +48,7 @@ import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.policy.ZenModeController;
@@ -197,6 +198,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
@Test
public void onMetadataChanged_updatesSlice() {
+ mProvider.onStateChanged(StatusBarState.KEYGUARD);
mProvider.onDozingChanged(true);
reset(mContentResolver);
mProvider.onMetadataOrStateChanged(mock(MediaMetadata.class), PlaybackState.STATE_PLAYING);
@@ -210,6 +212,7 @@ public class KeyguardSliceProviderTest extends SysuiTestCase {
@Test
public void onDozingChanged_updatesSliceIfMedia() {
+ mProvider.onStateChanged(StatusBarState.KEYGUARD);
mProvider.onMetadataOrStateChanged(mock(MediaMetadata.class), PlaybackState.STATE_PLAYING);
reset(mContentResolver);
// Show media when dozing
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
index 49a263a8d781..57dd8c94c790 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerTest.java
@@ -38,7 +38,6 @@ import android.os.Handler;
import android.os.Looper;
import android.os.UserManager;
import android.provider.Settings;
-import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -48,6 +47,7 @@ import com.android.systemui.Dependency;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
@@ -166,7 +166,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1);
when(mNotificationData.isHighPriority(any())).thenReturn(false);
- assertTrue(mLockscreenUserManager.shouldShowOnKeyguard(mock(StatusBarNotification.class)));
+ assertTrue(mLockscreenUserManager.shouldShowOnKeyguard(mock(NotificationEntry.class)));
}
@Test
@@ -179,7 +179,7 @@ public class NotificationLockscreenUserManagerTest extends SysuiTestCase {
Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0);
when(mNotificationData.isHighPriority(any())).thenReturn(false);
- assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(mock(StatusBarNotification.class)));
+ assertFalse(mLockscreenUserManager.shouldShowOnKeyguard(mock(NotificationEntry.class)));
}
private class TestNotificationLockscreenUserManager
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
index 73abda9a5da7..59d0f912d38e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManagerTest.java
@@ -263,6 +263,8 @@ public class NotificationSectionsManagerTest extends SysuiTestCase {
when(notifRow.getVisibility()).thenReturn(View.VISIBLE);
when(notifRow.getEntry().isHighPriority())
.thenReturn(children[i] == ChildType.HIPRI);
+ when(notifRow.getEntry().isTopBucket())
+ .thenReturn(children[i] == ChildType.HIPRI);
when(notifRow.getParent()).thenReturn(mNssl);
child = notifRow;
break;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
index 7d9920db36a4..4a41349ca195 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/BiometricsUnlockControllerTest.java
@@ -82,7 +82,7 @@ public class BiometricsUnlockControllerTest extends SysuiTestCase {
MockitoAnnotations.initMocks(this);
when(mStatusBarKeyguardViewManager.isShowing()).thenReturn(true);
when(mUpdateMonitor.isDeviceInteractive()).thenReturn(true);
- when(mUnlockMethodCache.isUnlockingWithFacePossible()).thenReturn(true);
+ when(mUnlockMethodCache.isFaceAuthEnabled()).thenReturn(true);
when(mKeyguardBypassController.onBiometricAuthenticated(any())).thenReturn(true);
when(mKeyguardBypassController.canPlaySubtleWindowAnimations()).thenReturn(true);
mContext.addMockSystemService(PowerManager.class, mPowerManager);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
index b45707ef6c10..a38094da3e1c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/HeadsUpAppearanceControllerTest.java
@@ -35,6 +35,7 @@ import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.HeadsUpStatusBarView;
import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
@@ -59,6 +60,7 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
private View mOperatorNameView;
private StatusBarStateController mStatusbarStateController;
private KeyguardBypassController mBypassController;
+ private NotificationWakeUpCoordinator mWakeUpCoordinator;
@Before
public void setUp() throws Exception {
@@ -72,11 +74,13 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
mOperatorNameView = new View(mContext);
mStatusbarStateController = mock(StatusBarStateController.class);
mBypassController = mock(KeyguardBypassController.class);
+ mWakeUpCoordinator = mock(NotificationWakeUpCoordinator.class);
mHeadsUpAppearanceController = new HeadsUpAppearanceController(
mock(NotificationIconAreaController.class),
mHeadsUpManager,
mStatusbarStateController,
mBypassController,
+ mWakeUpCoordinator,
mHeadsUpStatusBarView,
mStackScroller,
mPanelView,
@@ -153,6 +157,7 @@ public class HeadsUpAppearanceControllerTest extends SysuiTestCase {
mHeadsUpManager,
mStatusbarStateController,
mBypassController,
+ mWakeUpCoordinator,
mHeadsUpStatusBarView,
mStackScroller,
mPanelView,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
index 4e0ef56ad830..907e695f2513 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBouncerTest.java
@@ -379,7 +379,7 @@ public class KeyguardBouncerTest extends SysuiTestCase {
@Test
public void testShow_delaysIfFaceAuthIsRunning() {
- when(mUnlockMethodCache.isUnlockingWithFacePossible()).thenReturn(true);
+ when(mUnlockMethodCache.isFaceAuthEnabled()).thenReturn(true);
mBouncer.show(true /* reset */);
ArgumentCaptor<Runnable> showRunnable = ArgumentCaptor.forClass(Runnable.class);
@@ -394,4 +394,15 @@ public class KeyguardBouncerTest extends SysuiTestCase {
public void testRegisterUpdateMonitorCallback() {
verify(mKeyguardUpdateMonitor).registerCallback(any());
}
+
+ @Test
+ public void testInTransit_whenTranslation() {
+ mBouncer.show(true);
+ mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
+ assertThat(mBouncer.inTransit()).isFalse();
+ mBouncer.setExpansion(0.5f);
+ assertThat(mBouncer.inTransit()).isTrue();
+ mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
+ assertThat(mBouncer.inTransit()).isFalse();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
index d8e90a584058..0dbf30881ffe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java
@@ -225,11 +225,12 @@ public class ScrimControllerTest extends SysuiTestCase {
mScrimController.transitionTo(ScrimState.PULSING);
mScrimController.finishAnimationsImmediately();
- // Front scrim should be transparent
+ // Front scrim should be transparent, but tinted
// Back scrim should be semi-transparent so the user can see the wallpaper
// Pulse callback should have been invoked
assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
assertScrimTint(mScrimBehind, true /* tinted */);
+ assertScrimTint(mScrimInFront, true /* tinted */);
mScrimController.setWakeLockScreenSensorActive(true);
mScrimController.finishAnimationsImmediately();
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 2db7f0e108b4..123dfee03bd9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -89,7 +89,7 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
protected final Context mContext;
protected final SystemSupport mSystemSupport;
- private final WindowManagerInternal mWindowManagerService;
+ protected final WindowManagerInternal mWindowManagerService;
private final GlobalActionPerformer mGlobalActionPerformer;
private final AccessibilityWindowManager mA11yWindowManager;
private final DisplayManager mDisplayManager;
@@ -167,9 +167,10 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
@Nullable MagnificationSpec getCompatibleMagnificationSpecLocked(int windowId);
/**
- * @return The current injector of motion events, if one exists
+ * @param displayId The display id.
+ * @return The current injector of motion events used on the display, if one exists.
*/
- @Nullable MotionEventInjector getMotionEventInjectorLocked();
+ @Nullable MotionEventInjector getMotionEventInjectorForDisplayLocked(int displayId);
/**
* @return The current dispatcher for fingerprint gestures, if one exists
@@ -715,6 +716,10 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
}
@Override
+ public void dispatchGesture(int sequence, ParceledListSlice gestureSteps, int displayId) {
+ }
+
+ @Override
public boolean performAccessibilityAction(int accessibilityWindowId,
long accessibilityNodeId, int action, Bundle arguments, int interactionId,
IAccessibilityInteractionConnectionCallback callback, long interrogatingTid)
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index b6cbbacde118..5111bec4913b 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -114,7 +114,7 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
private final SparseArray<MagnificationGestureHandler> mMagnificationGestureHandler =
new SparseArray<>(0);
- private final SparseArray<MotionEventInjector> mMotionEventInjector = new SparseArray<>(0);
+ private final SparseArray<MotionEventInjector> mMotionEventInjectors = new SparseArray<>(0);
private AutoclickController mAutoclickController;
@@ -412,12 +412,14 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
MotionEventInjector injector = new MotionEventInjector(
mContext.getMainLooper());
addFirstEventHandler(displayId, injector);
- // TODO: Need to set MotionEventInjector per display.
- mAms.setMotionEventInjector(injector);
- mMotionEventInjector.put(displayId, injector);
+ mMotionEventInjectors.put(displayId, injector);
}
}
+ if ((mEnabledFeatures & FLAG_FEATURE_INJECT_MOTION_EVENTS) != 0) {
+ mAms.setMotionEventInjectors(mMotionEventInjectors);
+ }
+
if ((mEnabledFeatures & FLAG_FEATURE_FILTER_KEY_EVENTS) != 0) {
mKeyboardInterceptor = new KeyboardInterceptor(mAms,
LocalServices.getService(WindowManagerPolicy.class));
@@ -462,15 +464,14 @@ class AccessibilityInputFilter extends InputFilter implements EventStreamTransfo
}
private void disableFeatures() {
- for (int i = mMotionEventInjector.size() - 1; i >= 0; i--) {
- final MotionEventInjector injector = mMotionEventInjector.valueAt(i);
- // TODO: Need to set MotionEventInjector per display.
- mAms.setMotionEventInjector(null);
+ for (int i = mMotionEventInjectors.size() - 1; i >= 0; i--) {
+ final MotionEventInjector injector = mMotionEventInjectors.valueAt(i);
if (injector != null) {
injector.onDestroy();
}
}
- mMotionEventInjector.clear();
+ mAms.setMotionEventInjectors(null);
+ mMotionEventInjectors.clear();
if (mAutoclickController != null) {
mAutoclickController.onDestroy();
mAutoclickController = null;
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index a2204518e762..3db79b2da8a9 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -210,7 +210,7 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
private KeyEventDispatcher mKeyEventDispatcher;
- private MotionEventInjector mMotionEventInjector;
+ private SparseArray<MotionEventInjector> mMotionEventInjectors;
private FingerprintGestureDispatcher mFingerprintGestureDispatcher;
@@ -860,30 +860,34 @@ public class AccessibilityManagerService extends IAccessibilityManager.Stub
* Called by AccessibilityInputFilter when it creates or destroys the motionEventInjector.
* Not using a getter because the AccessibilityInputFilter isn't thread-safe
*
- * @param motionEventInjector The new value of the motionEventInjector. May be null.
+ * @param motionEventInjectors The array of motionEventInjectors. May be null.
+ *
*/
- void setMotionEventInjector(MotionEventInjector motionEventInjector) {
+ void setMotionEventInjectors(SparseArray<MotionEventInjector> motionEventInjectors) {
synchronized (mLock) {
- mMotionEventInjector = motionEventInjector;
+ mMotionEventInjectors = motionEventInjectors;
// We may be waiting on this object being set
mLock.notifyAll();
}
}
@Override
- public MotionEventInjector getMotionEventInjectorLocked() {
+ public @Nullable MotionEventInjector getMotionEventInjectorForDisplayLocked(int displayId) {
final long endMillis = SystemClock.uptimeMillis() + WAIT_MOTION_INJECTOR_TIMEOUT_MILLIS;
- while ((mMotionEventInjector == null) && (SystemClock.uptimeMillis() < endMillis)) {
+ MotionEventInjector motionEventInjector = null;
+ while ((mMotionEventInjectors == null) && (SystemClock.uptimeMillis() < endMillis)) {
try {
mLock.wait(endMillis - SystemClock.uptimeMillis());
} catch (InterruptedException ie) {
/* ignore */
}
}
- if (mMotionEventInjector == null) {
+ if (mMotionEventInjectors == null) {
Slog.e(LOG_TAG, "MotionEventInjector installation timed out");
+ } else {
+ motionEventInjector = mMotionEventInjectors.get(displayId);
}
- return mMotionEventInjector;
+ return motionEventInjector;
}
/**
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
index 02306c02fa6f..961168a46c7d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityServiceConnection.java
@@ -238,7 +238,6 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect
return (userState != null) ? userState.getSoftKeyboardShowMode() : 0;
}
-
@Override
public boolean isAccessibilityButtonAvailable() {
synchronized (mLock) {
@@ -354,12 +353,13 @@ class AccessibilityServiceConnection extends AbstractAccessibilityServiceConnect
}
@Override
- public void sendGesture(int sequence, ParceledListSlice gestureSteps) {
+ public void dispatchGesture(int sequence, ParceledListSlice gestureSteps, int displayId) {
+ final boolean isTouchableDisplay = mWindowManagerService.isTouchableDisplay(displayId);
synchronized (mLock) {
if (mSecurityPolicy.canPerformGestures(this)) {
MotionEventInjector motionEventInjector =
- mSystemSupport.getMotionEventInjectorLocked();
- if (motionEventInjector != null) {
+ mSystemSupport.getMotionEventInjectorForDisplayLocked(displayId);
+ if (motionEventInjector != null && isTouchableDisplay) {
motionEventInjector.injectEvents(
gestureSteps.getList(), mServiceInterface, sequence);
} else {
diff --git a/services/autofill/java/com/android/server/autofill/ui/CustomScrollView.java b/services/autofill/java/com/android/server/autofill/ui/CustomScrollView.java
index e68263a51415..813fc8d5f561 100644
--- a/services/autofill/java/com/android/server/autofill/ui/CustomScrollView.java
+++ b/services/autofill/java/com/android/server/autofill/ui/CustomScrollView.java
@@ -64,12 +64,13 @@ public class CustomScrollView extends ScrollView {
return;
}
+ mWidth = MeasureSpec.getSize(widthMeasureSpec);
calculateDimensions();
setMeasuredDimension(mWidth, mHeight);
}
private void calculateDimensions() {
- if (mWidth != -1) return;
+ if (mHeight != -1) return;
final TypedValue typedValue = new TypedValue();
final Point point = new Point();
@@ -81,7 +82,6 @@ public class CustomScrollView extends ScrollView {
final int childHeight = child.getMeasuredHeight();
final int maxHeight = (int) typedValue.getFraction(point.y, point.y);
- mWidth = point.x;
mHeight = Math.min(childHeight, maxHeight);
if (sDebug) {
Slog.d(TAG, "calculateDimensions(): maxHeight=" + maxHeight
diff --git a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
index 73f5cb8326ea..e2cdddb932d7 100644
--- a/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
+++ b/services/autofill/java/com/android/server/autofill/ui/SaveUi.java
@@ -165,7 +165,13 @@ final class SaveUi {
mComponentName = componentName;
mCompatMode = compatMode;
- context = new ContextThemeWrapper(context, mThemeId);
+ context = new ContextThemeWrapper(context, mThemeId) {
+ @Override
+ public void startActivity(Intent intent) {
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ super.startActivity(intent);
+ }
+ };
final LayoutInflater inflater = LayoutInflater.from(context);
final View view = inflater.inflate(R.layout.autofill_save, null);
diff --git a/services/core/Android.bp b/services/core/Android.bp
index 9855e4ea339a..9518196c40df 100644
--- a/services/core/Android.bp
+++ b/services/core/Android.bp
@@ -13,6 +13,7 @@ java_library_static {
},
srcs: [
"java/**/*.java",
+ ":platformcompat_aidl",
":dumpstate_aidl",
":idmap2_aidl",
":installd_aidl",
@@ -80,3 +81,11 @@ prebuilt_etc {
name: "gps_debug.conf",
src: "java/com/android/server/location/gps_debug.conf",
}
+
+filegroup {
+ name: "platformcompat_aidl",
+ srcs: [
+ "java/com/android/server/compat/IPlatformCompat.aidl",
+ ],
+ path: "java",
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 188d65494868..208b63888efb 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -1185,7 +1185,8 @@ class BluetoothManagerService extends IBluetoothManager.Stub {
if (isBluetoothDisallowed) {
return;
}
- if (mEnableExternal && isBluetoothPersistedStateOnBluetooth()) {
+ final boolean isSafeMode = mContext.getPackageManager().isSafeMode();
+ if (mEnableExternal && isBluetoothPersistedStateOnBluetooth() && !isSafeMode) {
if (DBG) {
Slog.d(TAG, "Auto-enabling Bluetooth.");
}
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index 9dead161390f..aeb3e7fd94de 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -41,7 +41,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.text.TextUtils;
-import android.text.format.Time;
+import android.text.format.TimeMigrationUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
@@ -582,11 +582,9 @@ public final class DropBoxManagerService extends SystemService {
}
int numFound = 0, numArgs = searchArgs.size();
- Time time = new Time();
out.append("\n");
for (EntryFile entry : mAllFiles.contents) {
- time.set(entry.timestampMillis);
- String date = time.format("%Y-%m-%d %H:%M:%S");
+ String date = TimeMigrationUtils.formatMillisWithFixedFormat(entry.timestampMillis);
boolean match = true;
for (int i = 0; i < numArgs && match; i++) {
String arg = searchArgs.get(i);
diff --git a/services/core/java/com/android/server/UiModeManagerService.java b/services/core/java/com/android/server/UiModeManagerService.java
index 30a356325ada..b9d7c687704c 100644
--- a/services/core/java/com/android/server/UiModeManagerService.java
+++ b/services/core/java/com/android/server/UiModeManagerService.java
@@ -48,7 +48,6 @@ import android.os.ShellCallback;
import android.os.ShellCommand;
import android.os.SystemProperties;
import android.os.UserHandle;
-import android.os.UserManager;
import android.provider.Settings.Secure;
import android.service.dreams.Sandman;
import android.service.vr.IVrManager;
@@ -218,6 +217,15 @@ final class UiModeManagerService extends SystemService {
}
};
+ private final ContentObserver mDarkThemeObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ int mode = Secure.getIntForUser(getContext().getContentResolver(), Secure.UI_NIGHT_MODE,
+ mNightMode, 0);
+ SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME, Integer.toString(mode));
+ }
+ };
+
@Override
public void onSwitchUser(int userHandle) {
super.onSwitchUser(userHandle);
@@ -293,6 +301,9 @@ final class UiModeManagerService extends SystemService {
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_USER_SWITCHED);
context.registerReceiver(new UserSwitchedReceiver(), filter, null, mHandler);
+
+ context.getContentResolver().registerContentObserver(Secure.getUriFor(Secure.UI_NIGHT_MODE),
+ false, mDarkThemeObserver, 0);
}
// Records whether setup wizard has happened or not and adds an observer for this user if not.
@@ -417,11 +428,6 @@ final class UiModeManagerService extends SystemService {
if (!mCarModeEnabled) {
Secure.putIntForUser(getContext().getContentResolver(),
Secure.UI_NIGHT_MODE, mode, user);
-
- if (UserManager.get(getContext()).isPrimaryUser()) {
- SystemProperties.set(SYSTEM_PROPERTY_DEVICE_THEME,
- Integer.toString(mode));
- }
}
mNightMode = mode;
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ff8c3e954460..268e813c12dd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2399,7 +2399,7 @@ public class ActivityManagerService extends IActivityManager.Stub
final ActiveUids activeUids = new ActiveUids(this, false /* postChangesToAtm */);
mProcessList.init(this, activeUids);
mLowMemDetector = null;
- mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids);
+ mOomAdjuster = new OomAdjuster(this, mProcessList, activeUids, handlerThread);
mIntentFirewall = hasHandlerThread
? new IntentFirewall(new IntentFirewallInterface(), mHandler) : null;
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 33070dc6b757..0dd719994de2 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -79,7 +79,6 @@ import android.os.SystemProperties;
import android.os.UserHandle;
import android.os.UserManager;
import android.text.TextUtils;
-import android.text.format.Time;
import android.util.ArrayMap;
import android.util.DebugUtils;
import android.util.DisplayMetrics;
@@ -98,12 +97,16 @@ import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URISyntaxException;
+import java.time.Clock;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -116,10 +119,14 @@ import javax.microedition.khronos.egl.EGLSurface;
final class ActivityManagerShellCommand extends ShellCommand {
public static final String NO_CLASS_ERROR_CODE = "Error type 3";
+
private static final String SHELL_PACKAGE_NAME = "com.android.shell";
private static final int USER_OPERATION_TIMEOUT_MS = 2 * 60 * 1000; // 2 minutes
+ private static final DateTimeFormatter LOG_NAME_TIME_FORMATTER =
+ DateTimeFormatter.ofPattern("yyyyMMdd-HHmmss", Locale.ROOT);
+
// IPC interface to activity manager -- don't need to do additional security checks.
final IActivityManager mInterface;
final IActivityTaskManager mTaskInterface;
@@ -922,9 +929,9 @@ final class ActivityManagerShellCommand extends ShellCommand {
String process = getNextArgRequired();
String heapFile = getNextArg();
if (heapFile == null) {
- final Time t = new Time();
- t.set(System.currentTimeMillis());
- heapFile = "/data/local/tmp/heapdump-" + t.format("%Y%m%d-%H%M%S") + ".prof";
+ LocalDateTime localDateTime = LocalDateTime.now(Clock.systemDefaultZone());
+ String logNameTimeString = LOG_NAME_TIME_FORMATTER.format(localDateTime);
+ heapFile = "/data/local/tmp/heapdump-" + logNameTimeString + ".prof";
}
pw.println("File: " + heapFile);
pw.flush();
diff --git a/services/core/java/com/android/server/am/OomAdjuster.java b/services/core/java/com/android/server/am/OomAdjuster.java
index a2613d87d923..770cb3da3362 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.java
+++ b/services/core/java/com/android/server/am/OomAdjuster.java
@@ -162,6 +162,21 @@ public final class OomAdjuster {
private final ProcessList mProcessList;
OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids) {
+ this(service, processList, activeUids, createAdjusterThread());
+ }
+
+ private static ServiceThread createAdjusterThread() {
+ // The process group is usually critical to the response time of foreground app, so the
+ // setter should apply it as soon as possible.
+ final ServiceThread adjusterThread =
+ new ServiceThread(TAG, TOP_APP_PRIORITY_BOOST, false /* allowIo */);
+ adjusterThread.start();
+ Process.setThreadGroupAndCpuset(adjusterThread.getThreadId(), THREAD_GROUP_TOP_APP);
+ return adjusterThread;
+ }
+
+ OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids,
+ ServiceThread adjusterThread) {
mService = service;
mProcessList = processList;
mActiveUids = activeUids;
@@ -170,12 +185,6 @@ public final class OomAdjuster {
mConstants = mService.mConstants;
mAppCompact = new AppCompactor(mService);
- // The process group is usually critical to the response time of foreground app, so the
- // setter should apply it as soon as possible.
- final ServiceThread adjusterThread = new ServiceThread(TAG, TOP_APP_PRIORITY_BOOST,
- false /* allowIo */);
- adjusterThread.start();
- Process.setThreadGroupAndCpuset(adjusterThread.getThreadId(), THREAD_GROUP_TOP_APP);
mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> {
final int pid = msg.arg1;
final int group = msg.arg2;
diff --git a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
index 20eb6180832c..f3f9754bd32b 100644
--- a/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
+++ b/services/core/java/com/android/server/biometrics/BiometricServiceBase.java
@@ -282,10 +282,10 @@ public abstract class BiometricServiceBase extends SystemService
public EnrollClientImpl(Context context, DaemonWrapper daemon, long halDeviceId,
IBinder token, ServiceListener listener, int userId, int groupId,
byte[] cryptoToken, boolean restricted, String owner,
- final int[] disabledFeatures) {
+ final int[] disabledFeatures, int timeoutSec) {
super(context, getConstants(), daemon, halDeviceId, token, listener,
userId, groupId, cryptoToken, restricted, owner, getBiometricUtils(),
- disabledFeatures);
+ disabledFeatures, timeoutSec);
}
@Override
@@ -912,8 +912,12 @@ public abstract class BiometricServiceBase extends SystemService
}
protected void setActiveUserInternal(int userId) {
- // Do not put on handler, since it should finish before returning to caller.
- updateActiveGroup(userId, null /* clientPackage */);
+ mHandler.post(() -> {
+ if (DEBUG) {
+ Slog.d(getTag(), "setActiveUser(" + userId + ")");
+ }
+ updateActiveGroup(userId, null /* clientPackage */);
+ });
}
protected void removeInternal(RemovalClient client) {
diff --git a/services/core/java/com/android/server/biometrics/EnrollClient.java b/services/core/java/com/android/server/biometrics/EnrollClient.java
index 854528f0654d..7ebb7c059b4c 100644
--- a/services/core/java/com/android/server/biometrics/EnrollClient.java
+++ b/services/core/java/com/android/server/biometrics/EnrollClient.java
@@ -31,11 +31,11 @@ import java.util.Arrays;
* A class to keep track of the enrollment state for a given client.
*/
public abstract class EnrollClient extends ClientMonitor {
- private static final long MS_PER_SEC = 1000;
- private static final int ENROLLMENT_TIMEOUT_MS = 60 * 1000; // 1 minute
private final byte[] mCryptoToken;
private final BiometricUtils mBiometricUtils;
private final int[] mDisabledFeatures;
+ private final int mTimeoutSec;
+
private long mEnrollmentStartTimeMs;
public abstract boolean shouldVibrate();
@@ -44,12 +44,13 @@ public abstract class EnrollClient extends ClientMonitor {
BiometricServiceBase.DaemonWrapper daemon, long halDeviceId, IBinder token,
BiometricServiceBase.ServiceListener listener, int userId, int groupId,
byte[] cryptoToken, boolean restricted, String owner, BiometricUtils utils,
- final int[] disabledFeatures) {
+ final int[] disabledFeatures, int timeoutSec) {
super(context, constants, daemon, halDeviceId, token, listener, userId, groupId, restricted,
owner, 0 /* cookie */);
mBiometricUtils = utils;
mCryptoToken = Arrays.copyOf(cryptoToken, cryptoToken.length);
mDisabledFeatures = Arrays.copyOf(disabledFeatures, disabledFeatures.length);
+ mTimeoutSec = timeoutSec;
}
@Override
@@ -94,14 +95,13 @@ public abstract class EnrollClient extends ClientMonitor {
@Override
public int start() {
mEnrollmentStartTimeMs = System.currentTimeMillis();
- final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
try {
final ArrayList<Integer> disabledFeatures = new ArrayList<>();
for (int i = 0; i < mDisabledFeatures.length; i++) {
disabledFeatures.add(mDisabledFeatures[i]);
}
- final int result = getDaemonWrapper().enroll(mCryptoToken, getGroupId(), timeout,
+ final int result = getDaemonWrapper().enroll(mCryptoToken, getGroupId(), mTimeoutSec,
disabledFeatures);
if (result != 0) {
Slog.w(getLogTag(), "startEnroll failed, result=" + result);
diff --git a/services/core/java/com/android/server/biometrics/LoggableMonitor.java b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
index 6c7cbc166241..ecf3864e3362 100644
--- a/services/core/java/com/android/server/biometrics/LoggableMonitor.java
+++ b/services/core/java/com/android/server/biometrics/LoggableMonitor.java
@@ -93,7 +93,7 @@ public abstract class LoggableMonitor {
statsAction(),
statsClient(),
acquiredInfo,
- 0 /* vendorCode */, // Don't log vendorCode for now
+ vendorCode,
Utils.isDebugEnabled(context, targetUserId));
}
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 a38abdc1bed0..9d51abeed114 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -329,6 +329,7 @@ public class FaceService extends BiometricServiceBase {
* Receives the incoming binder calls from FaceManager.
*/
private final class FaceServiceWrapper extends IFaceService.Stub {
+ private static final int ENROLL_TIMEOUT_SEC = 75;
/**
* The following methods contain common code which is shared in biometrics/common.
@@ -368,7 +369,8 @@ public class FaceService extends BiometricServiceBase {
final boolean restricted = isRestricted();
final EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper,
mHalDeviceId, token, new ServiceListenerImpl(receiver), mCurrentUserId,
- 0 /* groupId */, cryptoToken, restricted, opPackageName, disabledFeatures) {
+ 0 /* groupId */, cryptoToken, restricted, opPackageName, disabledFeatures,
+ ENROLL_TIMEOUT_SEC) {
@Override
public int[] getAcquireIgnorelist() {
@@ -609,27 +611,32 @@ public class FaceService extends BiometricServiceBase {
public void resetLockout(byte[] token) {
checkPermission(MANAGE_BIOMETRIC);
- if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
- Slog.w(TAG, "Ignoring lockout reset, no templates enrolled");
- return;
- }
+ mHandler.post(() -> {
+ if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
+ Slog.w(TAG, "Ignoring lockout reset, no templates enrolled");
+ return;
+ }
- Slog.d(TAG, "Resetting lockout for user: " + mCurrentUserId);
+ Slog.d(TAG, "Resetting lockout for user: " + mCurrentUserId);
- try {
- mDaemonWrapper.resetLockout(token);
- } catch (RemoteException e) {
- Slog.e(getTag(), "Unable to reset lockout", e);
- }
+ try {
+ mDaemonWrapper.resetLockout(token);
+ } catch (RemoteException e) {
+ Slog.e(getTag(), "Unable to reset lockout", e);
+ }
+ });
}
@Override
public void setFeature(int userId, int feature, boolean enabled, final byte[] token,
IFaceServiceReceiver receiver, final String opPackageName) {
checkPermission(MANAGE_BIOMETRIC);
- updateActiveGroup(userId, opPackageName);
mHandler.post(() -> {
+ if (DEBUG) {
+ Slog.d(TAG, "setFeature for user(" + userId + ")");
+ }
+ updateActiveGroup(userId, opPackageName);
if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
Slog.e(TAG, "No enrolled biometrics while setting feature: " + feature);
return;
@@ -660,9 +667,12 @@ public class FaceService extends BiometricServiceBase {
public void getFeature(int userId, int feature, IFaceServiceReceiver receiver,
final String opPackageName) {
checkPermission(MANAGE_BIOMETRIC);
- updateActiveGroup(userId, opPackageName);
mHandler.post(() -> {
+ if (DEBUG) {
+ Slog.d(TAG, "getFeature for user(" + userId + ")");
+ }
+ updateActiveGroup(userId, opPackageName);
// This should ideally return tri-state, but the user isn't shown settings unless
// they are enrolled so it's fine for now.
if (!FaceService.this.hasEnrolledBiometrics(mCurrentUserId)) {
diff --git a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
index 28336f459863..320e1022873c 100644
--- a/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/fingerprint/FingerprintService.java
@@ -176,6 +176,7 @@ public class FingerprintService extends BiometricServiceBase {
* Receives the incoming binder calls from FingerprintManager.
*/
private final class FingerprintServiceWrapper extends IFingerprintService.Stub {
+ private static final int ENROLL_TIMEOUT_SEC = 60;
/**
* The following methods contain common code which is shared in biometrics/common.
@@ -203,7 +204,8 @@ public class FingerprintService extends BiometricServiceBase {
final int groupId = userId; // default group for fingerprint enrollment
final EnrollClientImpl client = new EnrollClientImpl(getContext(), mDaemonWrapper,
mHalDeviceId, token, new ServiceListenerImpl(receiver), mCurrentUserId, groupId,
- cryptoToken, restricted, opPackageName, new int[0] /* disabledFeatures */) {
+ cryptoToken, restricted, opPackageName, new int[0] /* disabledFeatures */,
+ ENROLL_TIMEOUT_SEC) {
@Override
public boolean shouldVibrate() {
return true;
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index bcf1d80781a6..c59b0652af15 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -24,6 +24,7 @@ import android.util.LongSparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
+import java.io.PrintWriter;
/**
* This class maintains state relating to platform compatibility changes.
*
@@ -169,4 +170,22 @@ public final class CompatConfig {
return overrideExists;
}
+ /**
+ * Dumps the current list of compatibility config information.
+ *
+ * @param pw The {@link PrintWriter} instance to which the information will be dumped.
+ */
+ public void dumpConfig(PrintWriter pw) {
+ synchronized (mChanges) {
+ if (mChanges.size() == 0) {
+ pw.println("No compat overrides.");
+ return;
+ }
+ for (int i = 0; i < mChanges.size(); ++i) {
+ CompatChange c = mChanges.valueAt(i);
+ pw.println(c.toString());
+ }
+ }
+ }
+
}
diff --git a/services/core/java/com/android/server/compat/IPlatformCompat.aidl b/services/core/java/com/android/server/compat/IPlatformCompat.aidl
new file mode 100644
index 000000000000..8ab08f9047cb
--- /dev/null
+++ b/services/core/java/com/android/server/compat/IPlatformCompat.aidl
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.compat;
+
+import android.content.pm.ApplicationInfo;
+
+/**
+ * System private API for talking with the PlatformCompat service.
+ * {@hide}
+ */
+interface IPlatformCompat
+{
+
+ /**
+ * Reports that a compatibility change is affecting an app process now.
+ *
+ * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)},
+ * you do not need to call this API directly. The change will be reported for you in the case
+ * that {@link #isChangeEnabled(long, ApplicationInfo)} returns {@code true}.
+ *
+ * @param changeId The ID of the compatibility change taking effect.
+ * @param appInfo Representing the affected app.
+ */
+ void reportChange(long changeId, in ApplicationInfo appInfo);
+
+ /**
+ * Query if a given compatibility change is enabled for an app process. This method should
+ * be called when implementing functionality on behalf of the affected app.
+ *
+ * <p>If this method returns {@code true}, the calling code should implement the compatibility
+ * change, resulting in differing behaviour compared to earlier releases. If this method returns
+ * {@code false}, the calling code should behave as it did in earlier releases.
+ *
+ * <p>When this method returns {@code true}, it will also report the change as
+ * {@link #reportChange(long, ApplicationInfo)} would, so there is no need to call that method
+ * directly.
+ *
+ * @param changeId The ID of the compatibility change in question.
+ * @param appInfo Representing the app in question.
+ * @return {@code true} if the change is enabled for the current app.
+ */
+ boolean isChangeEnabled(long changeId, in ApplicationInfo appInfo);
+} \ No newline at end of file
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 456d15e4fba8..3eea194fd73e 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -16,52 +16,46 @@
package com.android.server.compat;
+import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.util.Slog;
+import com.android.internal.util.DumpUtils;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+
/**
* System server internal API for gating and reporting compatibility changes.
*/
-public class PlatformCompat {
+public class PlatformCompat extends IPlatformCompat.Stub {
private static final String TAG = "Compatibility";
- /**
- * Reports that a compatibility change is affecting an app process now.
- *
- * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, ApplicationInfo)},
- * you do not need to call this API directly. The change will be reported for you in the case
- * that {@link #isChangeEnabled(long, ApplicationInfo)} returns {@code true}.
- *
- * @param changeId The ID of the compatibility change taking effect.
- * @param appInfo Representing the affected app.
- */
- public static void reportChange(long changeId, ApplicationInfo appInfo) {
+ private final Context mContext;
+
+ public PlatformCompat(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void reportChange(long changeId, ApplicationInfo appInfo) {
Slog.d(TAG, "Compat change reported: " + changeId + "; UID " + appInfo.uid);
// TODO log via StatsLog
}
- /**
- * Query if a given compatibility change is enabled for an app process. This method should
- * be called when implementing functionality on behalf of the affected app.
- *
- * <p>If this method returns {@code true}, the calling code should implement the compatibility
- * change, resulting in differing behaviour compared to earlier releases. If this method returns
- * {@code false}, the calling code should behave as it did in earlier releases.
- *
- * <p>When this method returns {@code true}, it will also report the change as
- * {@link #reportChange(long, ApplicationInfo)} would, so there is no need to call that method
- * directly.
- *
- * @param changeId The ID of the compatibility change in question.
- * @param appInfo Representing the app in question.
- * @return {@code true} if the change is enabled for the current app.
- */
- public static boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
+ @Override
+ public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) {
reportChange(changeId, appInfo);
return true;
}
return false;
}
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
+ CompatConfig.get().dumpConfig(pw);
+ }
}
diff --git a/services/core/java/com/android/server/content/SyncManager.java b/services/core/java/com/android/server/content/SyncManager.java
index 64a05c94e39e..f6c49ed4d29e 100644
--- a/services/core/java/com/android/server/content/SyncManager.java
+++ b/services/core/java/com/android/server/content/SyncManager.java
@@ -86,7 +86,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.os.WorkSource;
import android.provider.Settings;
-import android.text.format.Time;
+import android.text.format.TimeMigrationUtils;
import android.util.EventLog;
import android.util.Log;
import android.util.Pair;
@@ -1993,9 +1993,7 @@ public class SyncManager {
if (time == 0) {
return "N/A";
}
- Time tobj = new Time();
- tobj.set(time);
- return tobj.format("%Y-%m-%d %H:%M:%S");
+ return TimeMigrationUtils.formatMillisWithFixedFormat(time);
}
private final static Comparator<SyncOperation> sOpDumpComparator = (op1, op2) -> {
@@ -2561,9 +2559,7 @@ public class SyncManager {
accountKey = "Unknown";
}
final long elapsedTime = item.elapsedTime;
- final Time time = new Time();
final long eventTime = item.eventTime;
- time.set(eventTime);
final String key = authorityName + "/" + accountKey;
final Long lastEventTime = lastTimeMap.get(key);
@@ -2628,9 +2624,7 @@ public class SyncManager {
authorityName = "Unknown";
accountKey = "Unknown";
}
- final Time time = new Time();
final long eventTime = item.eventTime;
- time.set(eventTime);
pw.printf(" #%-3d: %s %8s ",
i + 1,
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index d73c25336808..6f2b33453891 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -28,7 +28,7 @@ import android.net.Network;
import android.net.Uri;
import android.os.RemoteException;
import android.os.UserHandle;
-import android.text.format.Time;
+import android.text.format.TimeMigrationUtils;
import android.util.ArraySet;
import android.util.Pair;
import android.util.Slog;
@@ -1660,17 +1660,13 @@ public final class JobStatus {
if (numFailures != 0) {
pw.print(prefix); pw.print("Num failures: "); pw.println(numFailures);
}
- final Time t = new Time();
- final String format = "%Y-%m-%d %H:%M:%S";
if (mLastSuccessfulRunTime != 0) {
pw.print(prefix); pw.print("Last successful run: ");
- t.set(mLastSuccessfulRunTime);
- pw.println(t.format(format));
+ pw.println(TimeMigrationUtils.formatMillisWithFixedFormat(mLastSuccessfulRunTime));
}
if (mLastFailedRunTime != 0) {
pw.print(prefix); pw.print("Last failed run: ");
- t.set(mLastFailedRunTime);
- pw.println(t.format(format));
+ pw.println(TimeMigrationUtils.formatMillisWithFixedFormat(mLastFailedRunTime));
}
}
diff --git a/services/core/java/com/android/server/location/GnssLocationProvider.java b/services/core/java/com/android/server/location/GnssLocationProvider.java
index 6911b7c8f565..461f19bf8b08 100644
--- a/services/core/java/com/android/server/location/GnssLocationProvider.java
+++ b/services/core/java/com/android/server/location/GnssLocationProvider.java
@@ -1608,13 +1608,11 @@ public class GnssLocationProvider extends AbstractLocationProvider implements
if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
mHandler.post(() -> {
setupNativeGnssService(/* reinitializeGnssServiceHandle = */ true);
+ // resend configuration into the restarted HAL service.
+ reloadGpsProperties();
if (isGpsEnabled()) {
setGpsEnabled(false);
-
updateEnabled();
-
- // resend configuration into the restarted HAL service.
- reloadGpsProperties();
}
});
}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
index f0e431ee0354..84ae7c790a74 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java
@@ -48,6 +48,8 @@ import java.io.DataOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -390,6 +392,17 @@ class LockSettingsStorage {
return stored;
}
+ private void fsyncDirectory(File directory) {
+ try {
+ try (FileChannel file = FileChannel.open(directory.toPath(),
+ StandardOpenOption.READ)) {
+ file.force(true);
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Error syncing directory: " + directory, e);
+ }
+ }
+
private void writeFile(String name, byte[] hash) {
synchronized (mFileWriteLock) {
RandomAccessFile raf = null;
@@ -406,6 +419,7 @@ class LockSettingsStorage {
raf.write(hash, 0, hash.length);
}
raf.close();
+ fsyncDirectory((new File(name)).getAbsoluteFile().getParentFile());
} catch (IOException e) {
Slog.e(TAG, "Error writing to file " + e);
} finally {
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
new file mode 100644
index 000000000000..c1cba5f7f22d
--- /dev/null
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -0,0 +1,15 @@
+{
+ "presubmit": [
+ {
+ "name": "CtsDevicePolicyManagerTestCases",
+ "options": [
+ {
+ "include-annotation": "com.android.cts.devicepolicy.annotations.LockSettingsTest"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
index c54bfc01e031..0ad6c2a69556 100644
--- a/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
+++ b/services/core/java/com/android/server/locksettings/recoverablekeystore/PlatformKeyManager.java
@@ -19,6 +19,7 @@ package com.android.server.locksettings.recoverablekeystore;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.security.GateKeeper;
import android.security.keystore.AndroidKeyStoreSecretKey;
import android.security.keystore.KeyPermanentlyInvalidatedException;
@@ -437,25 +438,31 @@ public class PlatformKeyManager {
// so it may live in memory for some time.
SecretKey secretKey = generateAesKey();
- long secureUserId = getGateKeeperService().getSecureUserId(userId);
- // TODO(b/124095438): Propagate this failure instead of silently failing.
- if (secureUserId == GateKeeper.INVALID_SECURE_USER_ID) {
- Log.e(TAG, "No SID available for user " + userId);
- return;
- }
-
- // Store decryption key first since it is more likely to fail.
- mKeyStore.setEntry(
- decryptAlias,
- new KeyStore.SecretKeyEntry(secretKey),
+ KeyProtection.Builder decryptionKeyProtection =
new KeyProtection.Builder(KeyProperties.PURPOSE_DECRYPT)
.setUserAuthenticationRequired(true)
.setUserAuthenticationValidityDurationSeconds(
USER_AUTHENTICATION_VALIDITY_DURATION_SECONDS)
.setBlockModes(KeyProperties.BLOCK_MODE_GCM)
- .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
+ .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE);
+ if (userId != UserHandle.USER_SYSTEM) {
+ // Bind decryption key to secondary profile lock screen secret.
+ long secureUserId = getGateKeeperService().getSecureUserId(userId);
+ // TODO(b/124095438): Propagate this failure instead of silently failing.
+ if (secureUserId == GateKeeper.INVALID_SECURE_USER_ID) {
+ Log.e(TAG, "No SID available for user " + userId);
+ return;
+ }
+ decryptionKeyProtection
.setBoundToSpecificSecureUserId(secureUserId)
- .build());
+ // Ignore caller uid which always belongs to the primary profile.
+ .setCriticalToDeviceEncryption(true);
+ }
+ // Store decryption key first since it is more likely to fail.
+ mKeyStore.setEntry(
+ decryptAlias,
+ new KeyStore.SecretKeyEntry(secretKey),
+ decryptionKeyProtection.build());
mKeyStore.setEntry(
encryptAlias,
new KeyStore.SecretKeyEntry(secretKey),
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 6f28675d051b..934511bf88d1 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -296,22 +296,12 @@ final class OverlayManagerServiceImpl {
*/
private void updateAndRefreshOverlaysForTarget(@NonNull final String targetPackageName,
final int userId, final int flags) {
- final List<OverlayInfo> ois = new ArrayList<>();
-
- // Framework overlays added first because order matters when resolving a resource
- if (!"android".equals(targetPackageName)) {
- ois.addAll(mSettings.getOverlaysForTarget("android", userId));
- }
-
- // Then add the targeted, non-framework overlays which have higher priority
- ois.addAll(mSettings.getOverlaysForTarget(targetPackageName, userId));
-
- final List<String> enabledBaseCodePaths = new ArrayList<>(ois.size());
+ final List<OverlayInfo> targetOverlays = mSettings.getOverlaysForTarget(targetPackageName,
+ userId);
+ // Update the state for any overlay that targets this package.
boolean modified = false;
- final int n = ois.size();
- for (int i = 0; i < n; i++) {
- final OverlayInfo oi = ois.get(i);
+ for (final OverlayInfo oi : targetOverlays) {
final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName,
userId);
if (overlayPackage == null) {
@@ -324,25 +314,39 @@ final class OverlayManagerServiceImpl {
Slog.e(TAG, "failed to update settings", e);
modified |= mSettings.remove(oi.packageName, userId);
}
-
- if (oi.isEnabled() && overlayPackage.applicationInfo != null) {
- enabledBaseCodePaths.add(overlayPackage.applicationInfo.getBaseCodePath());
- }
}
}
if (!modified) {
+ // Update the overlay paths of the target within package manager if necessary.
+ final List<String> enabledOverlayPaths = new ArrayList<>(targetOverlays.size());
+
+ // Framework overlays are first in the overlay paths of a package within PackageManager.
+ for (final OverlayInfo oi : mSettings.getOverlaysForTarget("android", userId)) {
+ if (oi.isEnabled()) {
+ enabledOverlayPaths.add(oi.baseCodePath);
+ }
+ }
+
+ for (final OverlayInfo oi : targetOverlays) {
+ if (oi.isEnabled()) {
+ enabledOverlayPaths.add(oi.baseCodePath);
+ }
+ }
+
+ // TODO(): Use getEnabledOverlayPaths(userId, targetPackageName) instead of
+ // resourceDirs if in the future resourceDirs contains APKs other than overlays
PackageInfo packageInfo = mPackageManager.getPackageInfo(targetPackageName, userId);
ApplicationInfo appInfo = packageInfo == null ? null : packageInfo.applicationInfo;
String[] resourceDirs = appInfo == null ? null : appInfo.resourceDirs;
// If the lists aren't the same length, the enabled overlays have changed
- if (ArrayUtils.size(resourceDirs) != enabledBaseCodePaths.size()) {
+ if (ArrayUtils.size(resourceDirs) != enabledOverlayPaths.size()) {
modified = true;
} else if (resourceDirs != null) {
// If any element isn't equal, an overlay or the order of overlays has changed
for (int index = 0; index < resourceDirs.length; index++) {
- if (!resourceDirs[index].equals(enabledBaseCodePaths.get(index))) {
+ if (!resourceDirs[index].equals(enabledOverlayPaths.get(index))) {
modified = true;
break;
}
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java
new file mode 100644
index 000000000000..da4558277b95
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageParser;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.File;
+import java.util.List;
+import java.util.Set;
+
+@VisibleForTesting
+interface PackageAbiHelper {
+ /**
+ * Derive and set the location of native libraries for the given package,
+ * which varies depending on where and how the package was installed.
+ *
+ * WARNING: This API enables modifying of the package.
+ * TODO(b/137881067): Modify so that caller is responsible for setting pkg fields as necessary
+ */
+ void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir);
+
+ /**
+ * Calculate the abis and roots for a bundled app. These can uniquely
+ * be determined from the contents of the system partition, i.e whether
+ * it contains 64 or 32 bit shared libraries etc. We do not validate any
+ * of this information, and instead assume that the system was built
+ * sensibly.
+ *
+ * WARNING: This API enables modifying of the package.
+ * TODO(b/137881067): Modify so that caller is responsible for setting pkg fields as necessary
+ */
+ void setBundledAppAbisAndRoots(PackageParser.Package pkg,
+ PackageSetting pkgSetting);
+
+ /**
+ * Derive the ABI of a non-system package located at {@code scanFile}. This information
+ * is derived purely on the basis of the contents of {@code scanFile} and
+ * {@code cpuAbiOverride}.
+ *
+ * If {@code extractLibs} is true, native libraries are extracted from the app if required.
+ *
+ * WARNING: This API enables modifying of the package.
+ * TODO(b/137881067): Modify so that caller is responsible for setting pkg fields as necessary
+ */
+ void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
+ boolean extractLibs)
+ throws PackageManagerException;
+
+ /**
+ * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
+ * i.e, so that all packages can be run inside a single process if required.
+ *
+ * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
+ * this function will either try and make the ABI for all packages in
+ * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of
+ * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This
+ * variant is used when installing or updating a package that belongs to a shared user.
+ *
+ * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
+ * adds unnecessary complexity.
+ *
+ * WARNING: This API enables modifying of the package.
+ * TODO(b/137881067): Modify so that caller is responsible for setting pkg fields as necessary
+ */
+ @Nullable
+ List<String> adjustCpuAbisForSharedUser(
+ Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage);
+}
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
new file mode 100644
index 000000000000..4ecc888cb33c
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -0,0 +1,542 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
+import static android.content.pm.PackageParser.isApkFile;
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
+import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
+import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
+import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
+import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
+
+import android.annotation.Nullable;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.Trace;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.util.ArrayUtils;
+
+import dalvik.system.VMRuntime;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+final class PackageAbiHelperImpl implements PackageAbiHelper {
+
+ @Override
+ public void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
+ final ApplicationInfo info = pkg.applicationInfo;
+ final String codePath = pkg.codePath;
+ final File codeFile = new File(codePath);
+ final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
+
+ info.nativeLibraryRootDir = null;
+ info.nativeLibraryRootRequiresIsa = false;
+ info.nativeLibraryDir = null;
+ info.secondaryNativeLibraryDir = null;
+
+ if (isApkFile(codeFile)) {
+ // Monolithic install
+ if (bundledApp) {
+ // If "/system/lib64/apkname" exists, assume that is the per-package
+ // native library directory to use; otherwise use "/system/lib/apkname".
+ final String apkRoot = calculateBundledApkRoot(info.sourceDir);
+ final boolean is64Bit = VMRuntime.is64BitInstructionSet(
+ getPrimaryInstructionSet(info));
+
+ // This is a bundled system app so choose the path based on the ABI.
+ // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
+ // is just the default path.
+ final String apkName = deriveCodePathName(codePath);
+ final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
+ info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
+ apkName).getAbsolutePath();
+
+ if (info.secondaryCpuAbi != null) {
+ final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
+ info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
+ secondaryLibDir, apkName).getAbsolutePath();
+ }
+ } else {
+ final String apkName = deriveCodePathName(codePath);
+ info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
+ .getAbsolutePath();
+ }
+
+ info.nativeLibraryRootRequiresIsa = false;
+ info.nativeLibraryDir = info.nativeLibraryRootDir;
+ } else {
+ // Cluster install
+ info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
+ info.nativeLibraryRootRequiresIsa = true;
+
+ info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
+ getPrimaryInstructionSet(info)).getAbsolutePath();
+
+ if (info.secondaryCpuAbi != null) {
+ info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
+ VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
+ }
+ }
+ }
+
+ @Override
+ public void setBundledAppAbisAndRoots(PackageParser.Package pkg,
+ PackageSetting pkgSetting) {
+ final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
+
+ // If "/system/lib64/apkname" exists, assume that is the per-package
+ // native library directory to use; otherwise use "/system/lib/apkname".
+ final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
+ setBundledAppAbi(pkg, apkRoot, apkName);
+ // pkgSetting might be null during rescan following uninstall of updates
+ // to a bundled app, so accommodate that possibility. The settings in
+ // that case will be established later from the parsed package.
+ //
+ // If the settings aren't null, sync them up with what we've just derived.
+ // note that apkRoot isn't stored in the package settings.
+ if (pkgSetting != null) {
+ pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
+ pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
+ }
+ }
+
+ /**
+ * Deduces the ABI of a bundled app and sets the relevant fields on the
+ * parsed pkg object.
+ *
+ * @param apkRoot the root of the installed apk, something like {@code /system} or
+ * {@code /oem} under which system libraries are installed.
+ * @param apkName the name of the installed package.
+ */
+ private void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
+ final File codeFile = new File(pkg.codePath);
+
+ final boolean has64BitLibs;
+ final boolean has32BitLibs;
+ if (isApkFile(codeFile)) {
+ // Monolithic install
+ has64BitLibs =
+ (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
+ has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
+ } else {
+ // Cluster install
+ final File rootDir = new File(codeFile, LIB_DIR_NAME);
+ if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
+ && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
+ final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
+ has64BitLibs = (new File(rootDir, isa)).exists();
+ } else {
+ has64BitLibs = false;
+ }
+ if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
+ && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
+ final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
+ has32BitLibs = (new File(rootDir, isa)).exists();
+ } else {
+ has32BitLibs = false;
+ }
+ }
+
+ if (has64BitLibs && !has32BitLibs) {
+ // The package has 64 bit libs, but not 32 bit libs. Its primary
+ // ABI should be 64 bit. We can safely assume here that the bundled
+ // native libraries correspond to the most preferred ABI in the list.
+
+ pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+ pkg.applicationInfo.secondaryCpuAbi = null;
+ } else if (has32BitLibs && !has64BitLibs) {
+ // The package has 32 bit libs but not 64 bit libs. Its primary
+ // ABI should be 32 bit.
+
+ pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+ pkg.applicationInfo.secondaryCpuAbi = null;
+ } else if (has32BitLibs && has64BitLibs) {
+ // The application has both 64 and 32 bit bundled libraries. We check
+ // here that the app declares multiArch support, and warn if it doesn't.
+ //
+ // We will be lenient here and record both ABIs. The primary will be the
+ // ABI that's higher on the list, i.e, a device that's configured to prefer
+ // 64 bit apps will see a 64 bit primary ABI,
+
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
+ Slog.e(PackageManagerService.TAG,
+ "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
+ }
+
+ if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
+ pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+ pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+ } else {
+ pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
+ pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
+ }
+ } else {
+ pkg.applicationInfo.primaryCpuAbi = null;
+ pkg.applicationInfo.secondaryCpuAbi = null;
+ }
+ }
+
+ @Override
+ public void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
+ boolean extractLibs)
+ throws PackageManagerException {
+ // Give ourselves some initial paths; we'll come back for another
+ // pass once we've determined ABI below.
+ setNativeLibraryPaths(pkg, PackageManagerService.sAppLib32InstallDir);
+
+ // We shouldn't attempt to extract libs from system app when it was not updated.
+ if (PackageManagerService.isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
+ extractLibs = false;
+ }
+
+ final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
+ final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
+
+ NativeLibraryHelper.Handle handle = null;
+ try {
+ handle = NativeLibraryHelper.Handle.create(pkg);
+ // TODO(multiArch): This can be null for apps that didn't go through the
+ // usual installation process. We can calculate it again, like we
+ // do during install time.
+ //
+ // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
+ // unnecessary.
+ final File nativeLibraryRoot = new File(nativeLibraryRootStr);
+
+ // Null out the abis so that they can be recalculated.
+ pkg.applicationInfo.primaryCpuAbi = null;
+ pkg.applicationInfo.secondaryCpuAbi = null;
+ if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0) {
+ // Warn if we've set an abiOverride for multi-lib packages..
+ // By definition, we need to copy both 32 and 64 bit libraries for
+ // such packages.
+ if (pkg.cpuAbiOverride != null
+ && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
+ Slog.w(PackageManagerService.TAG,
+ "Ignoring abiOverride for multi arch application.");
+ }
+
+ int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
+ int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
+ if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
+ if (extractLibs) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+ abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+ nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
+ useIsaSpecificSubdirs);
+ } else {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+ abi32 = NativeLibraryHelper.findSupportedAbi(
+ handle, Build.SUPPORTED_32_BIT_ABIS);
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+
+ // Shared library native code should be in the APK zip aligned
+ if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Shared library native lib extraction not supported");
+ }
+
+ maybeThrowExceptionForMultiArchCopy(
+ "Error unpackaging 32 bit native libs for multiarch app.", abi32);
+
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
+ if (extractLibs) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+ abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+ nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
+ useIsaSpecificSubdirs);
+ } else {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+ abi64 = NativeLibraryHelper.findSupportedAbi(
+ handle, Build.SUPPORTED_64_BIT_ABIS);
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+
+ maybeThrowExceptionForMultiArchCopy(
+ "Error unpackaging 64 bit native libs for multiarch app.", abi64);
+
+ if (abi64 >= 0) {
+ // Shared library native libs should be in the APK zip aligned
+ if (extractLibs && pkg.isLibrary()) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Shared library native lib extraction not supported");
+ }
+ pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
+ }
+
+ if (abi32 >= 0) {
+ final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
+ if (abi64 >= 0) {
+ if (pkg.use32bitAbi) {
+ pkg.applicationInfo.secondaryCpuAbi =
+ pkg.applicationInfo.primaryCpuAbi;
+ pkg.applicationInfo.primaryCpuAbi = abi;
+ } else {
+ pkg.applicationInfo.secondaryCpuAbi = abi;
+ }
+ } else {
+ pkg.applicationInfo.primaryCpuAbi = abi;
+ }
+ }
+ } else {
+ String[] abiList = (cpuAbiOverride != null)
+ ? new String[]{cpuAbiOverride} : Build.SUPPORTED_ABIS;
+
+ // Enable gross and lame hacks for apps that are built with old
+ // SDK tools. We must scan their APKs for renderscript bitcode and
+ // not launch them if it's present. Don't bother checking on devices
+ // that don't have 64 bit support.
+ boolean needsRenderScriptOverride = false;
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null
+ && NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ needsRenderScriptOverride = true;
+ }
+
+ final int copyRet;
+ if (extractLibs) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
+ copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
+ nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
+ } else {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
+ copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+
+ if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Error unpackaging native libs for app, errorCode=" + copyRet);
+ }
+
+ if (copyRet >= 0) {
+ // Shared libraries that have native libs must be multi-architecture
+ if (pkg.isLibrary()) {
+ throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
+ "Shared library with native libs must be multiarch");
+ }
+ pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
+ } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES
+ && cpuAbiOverride != null) {
+ pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
+ } else if (needsRenderScriptOverride) {
+ pkg.applicationInfo.primaryCpuAbi = abiList[0];
+ }
+ }
+ } catch (IOException ioe) {
+ Slog.e(PackageManagerService.TAG, "Unable to get canonical file " + ioe.toString());
+ } finally {
+ IoUtils.closeQuietly(handle);
+ }
+
+ // Now that we've calculated the ABIs and determined if it's an internal app,
+ // we will go ahead and populate the nativeLibraryPath.
+ setNativeLibraryPaths(pkg, PackageManagerService.sAppLib32InstallDir);
+ }
+
+ /**
+ * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
+ * i.e, so that all packages can be run inside a single process if required.
+ *
+ * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
+ * this function will either try and make the ABI for all packages in
+ * {@code packagesForUser} match {@code scannedPackage} or will update the ABI of
+ * {@code scannedPackage} to match the ABI selected for {@code packagesForUser}. This
+ * variant is used when installing or updating a package that belongs to a shared user.
+ *
+ * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
+ * adds unnecessary complexity.
+ */
+ @Override
+ @Nullable
+ public List<String> adjustCpuAbisForSharedUser(
+ Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
+ List<String> changedAbiCodePath = null;
+ String requiredInstructionSet = null;
+ if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
+ requiredInstructionSet = VMRuntime.getInstructionSet(
+ scannedPackage.applicationInfo.primaryCpuAbi);
+ }
+
+ PackageSetting requirer = null;
+ for (PackageSetting ps : packagesForUser) {
+ // If packagesForUser contains scannedPackage, we skip it. This will happen
+ // when scannedPackage is an update of an existing package. Without this check,
+ // we will never be able to change the ABI of any package belonging to a shared
+ // user, even if it's compatible with other packages.
+ if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
+ if (ps.primaryCpuAbiString == null) {
+ continue;
+ }
+
+ final String instructionSet =
+ VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
+ if (requiredInstructionSet != null
+ && !instructionSet.equals(requiredInstructionSet)) {
+ // We have a mismatch between instruction sets (say arm vs arm64) warn about
+ // this but there's not much we can do.
+ String errorMessage = "Instruction set mismatch, "
+ + ((requirer == null) ? "[caller]" : requirer)
+ + " requires " + requiredInstructionSet + " whereas " + ps
+ + " requires " + instructionSet;
+ Slog.w(PackageManagerService.TAG, errorMessage);
+ }
+
+ if (requiredInstructionSet == null) {
+ requiredInstructionSet = instructionSet;
+ requirer = ps;
+ }
+ }
+ }
+
+ if (requiredInstructionSet != null) {
+ String adjustedAbi;
+ if (requirer != null) {
+ // requirer != null implies that either scannedPackage was null or that
+ // scannedPackage did not require an ABI, in which case we have to adjust
+ // scannedPackage to match the ABI of the set (which is the same as
+ // requirer's ABI)
+ adjustedAbi = requirer.primaryCpuAbiString;
+ if (scannedPackage != null) {
+ scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
+ }
+ } else {
+ // requirer == null implies that we're updating all ABIs in the set to
+ // match scannedPackage.
+ adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
+ }
+
+ for (PackageSetting ps : packagesForUser) {
+ if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
+ if (ps.primaryCpuAbiString != null) {
+ continue;
+ }
+
+ ps.primaryCpuAbiString = adjustedAbi;
+ if (ps.pkg != null && ps.pkg.applicationInfo != null
+ && !TextUtils.equals(
+ adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
+ ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
+ if (PackageManagerService.DEBUG_ABI_SELECTION) {
+ Slog.i(PackageManagerService.TAG,
+ "Adjusting ABI for " + ps.name + " to " + adjustedAbi
+ + " (requirer="
+ + (requirer != null ? requirer.pkg : "null")
+ + ", scannedPackage="
+ + (scannedPackage != null ? scannedPackage : "null")
+ + ")");
+ }
+ if (changedAbiCodePath == null) {
+ changedAbiCodePath = new ArrayList<>();
+ }
+ changedAbiCodePath.add(ps.codePathString);
+ }
+ }
+ }
+ }
+ return changedAbiCodePath;
+ }
+
+ private static String calculateBundledApkRoot(final String codePathString) {
+ final File codePath = new File(codePathString);
+ final File codeRoot;
+ if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
+ codeRoot = Environment.getRootDirectory();
+ } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
+ codeRoot = Environment.getOemDirectory();
+ } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
+ codeRoot = Environment.getVendorDirectory();
+ } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
+ codeRoot = Environment.getOdmDirectory();
+ } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
+ codeRoot = Environment.getProductDirectory();
+ } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
+ codeRoot = Environment.getSystemExtDirectory();
+ } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
+ codeRoot = Environment.getOdmDirectory();
+ } else {
+ // Unrecognized code path; take its top real segment as the apk root:
+ // e.g. /something/app/blah.apk => /something
+ try {
+ File f = codePath.getCanonicalFile();
+ File parent = f.getParentFile(); // non-null because codePath is a file
+ File tmp;
+ while ((tmp = parent.getParentFile()) != null) {
+ f = parent;
+ parent = tmp;
+ }
+ codeRoot = f;
+ Slog.w(PackageManagerService.TAG, "Unrecognized code path "
+ + codePath + " - using " + codeRoot);
+ } catch (IOException e) {
+ // Can't canonicalize the code path -- shenanigans?
+ Slog.w(PackageManagerService.TAG, "Can't canonicalize code path " + codePath);
+ return Environment.getRootDirectory().getPath();
+ }
+ }
+ return codeRoot.getPath();
+ }
+
+ // Utility method that returns the relative package path with respect
+ // to the installation directory. Like say for /data/data/com.test-1.apk
+ // string com.test-1 is returned.
+ private static String deriveCodePathName(String codePath) {
+ if (codePath == null) {
+ return null;
+ }
+ final File codeFile = new File(codePath);
+ final String name = codeFile.getName();
+ if (codeFile.isDirectory()) {
+ return name;
+ } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
+ final int lastDot = name.lastIndexOf('.');
+ return name.substring(0, lastDot);
+ } else {
+ Slog.w(PackageManagerService.TAG, "Odd, " + codePath + " doesn't look like an APK");
+ return null;
+ }
+ }
+
+ private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
+ PackageManagerException {
+ if (copyRet < 0) {
+ if (copyRet != PackageManager.NO_NATIVE_LIBRARIES
+ && copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
+ throw new PackageManagerException(copyRet, message);
+ }
+ }
+ }
+
+}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index c72b38aa0919..ebbb19349946 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -94,14 +94,12 @@ import static android.permission.PermissionManager.KILL_APP_REASON_GIDS_CHANGED;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_MANAGED_PROFILE;
import static com.android.internal.app.IntentForwarderActivity.FORWARD_INTENT_TO_PARENT;
-import static com.android.internal.content.NativeLibraryHelper.LIB64_DIR_NAME;
import static com.android.internal.content.NativeLibraryHelper.LIB_DIR_NAME;
import static com.android.server.pm.ComponentResolver.RESOLVE_PRIORITY_SORTER;
import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSet;
import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import static com.android.server.pm.InstructionSets.getPreferredInstructionSet;
-import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
import static com.android.server.pm.PackageManagerServiceCompilerMapping.getDefaultCompilerFilter;
import static com.android.server.pm.PackageManagerServiceUtils.compareSignatures;
import static com.android.server.pm.PackageManagerServiceUtils.compressedFileExists;
@@ -277,6 +275,7 @@ import android.view.Display;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.content.PackageHelper;
@@ -429,7 +428,7 @@ public class PackageManagerService extends IPackageManager.Stub
// user, but by default initialize to this.
public static final boolean DEBUG_DEXOPT = false;
- private static final boolean DEBUG_ABI_SELECTION = false;
+ static final boolean DEBUG_ABI_SELECTION = false;
private static final boolean DEBUG_INSTANT = Build.IS_DEBUGGABLE;
private static final boolean DEBUG_APP_DATA = false;
@@ -653,7 +652,8 @@ public class PackageManagerService extends IPackageManager.Stub
private static final File sAppInstallDir =
new File(Environment.getDataDirectory(), "app");
/** Directory where installed application's 32-bit native libraries are copied. */
- private static final File sAppLib32InstallDir =
+ @VisibleForTesting
+ static final File sAppLib32InstallDir =
new File(Environment.getDataDirectory(), "app-lib");
// ----------------------------------------------------------------
@@ -744,6 +744,30 @@ public class PackageManagerService extends IPackageManager.Stub
private final ApexManager mApexManager;
+ private final Injector mInjector;
+
+ /**
+ * Unit tests will instantiate and / or extend to mock dependencies / behaviors.
+ */
+ @VisibleForTesting
+ static class Injector {
+ private final UserManagerInternal mUserManager;
+ private final PackageAbiHelper mAbiHelper;
+
+ Injector(UserManagerInternal userManager, PackageAbiHelper abiHelper) {
+ mUserManager = userManager;
+ mAbiHelper = abiHelper;
+ }
+
+ public UserManagerInternal getUserManager() {
+ return mUserManager;
+ }
+
+ public PackageAbiHelper getAbiHelper() {
+ return mAbiHelper;
+ }
+ }
+
class PackageParserCallback implements PackageParser.Callback {
@Override public final boolean hasFeature(String feature) {
return PackageManagerService.this.hasSystemFeature(feature, 0);
@@ -2007,8 +2031,8 @@ public class PackageManagerService extends IPackageManager.Stub
// survive long enough to benefit of background optimizations.
for (int userId : firstUserIds) {
PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
- // There's a race currently where some install events may interleave with an uninstall.
- // This can lead to package info being null (b/36642664).
+ // There's a race currently where some install events may interleave with an
+ // uninstall. This can lead to package info being null (b/36642664).
if (info != null) {
mDexManager.notifyPackageInstalled(info, userId);
}
@@ -2078,6 +2102,7 @@ public class PackageManagerService extends IPackageManager.Stub
* external/removable/unprotected storage.
* @return {@link StorageEnum#TYPE_UNKNOWN} if the package is not stored externally or the
* corresponding {@link StorageEnum} storage type value if it is.
+ * corresponding {@link StorageEnum} storage type value if it is.
*/
private static int getPackageExternalStorageType(VolumeInfo packageVolume,
boolean packageIsExternal) {
@@ -2340,6 +2365,10 @@ public class PackageManagerService extends IPackageManager.Stub
mPermissionManager.getPermissionSettings(), mPackages);
}
}
+
+ // TODO(b/137961986): We should pass this via constructor, but would first need to create
+ // a packages lock that could also be passed in.
+ mInjector = new Injector(getUserManagerInternal(), new PackageAbiHelperImpl());
// CHECKSTYLE:ON IndentationCheck
t.traceEnd();
@@ -3048,7 +3077,8 @@ public class PackageManagerService extends IPackageManager.Stub
// the rest of the commands above) because there's precious little we
// can do about it. A settings error is reported, though.
final List<String> changedAbiCodePath =
- adjustCpuAbisForSharedUserLPw(setting.packages, null /*scannedPackage*/);
+ mInjector.getAbiHelper().adjustCpuAbisForSharedUser(
+ setting.packages, null /*scannedPackage*/);
if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) {
for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) {
final String codePathString = changedAbiCodePath.get(i);
@@ -8791,7 +8821,8 @@ public class PackageManagerService extends IPackageManager.Stub
null /* originalPkgSetting */, null, parseFlags, scanFlags,
(pkg == mPlatformPackage), user);
applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
- final ScanResult scanResult = scanPackageOnlyLI(request, mFactoryTest, -1L);
+ final ScanResult scanResult =
+ scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
scanResult.request.pkgSetting.updateFrom(scanResult.pkgSetting);
}
@@ -10151,7 +10182,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
/** The result of a package scan. */
- private static class ScanResult {
+ @VisibleForTesting
+ static class ScanResult {
/** The request that initiated the scan that produced this result. */
public final ScanRequest request;
/** Whether or not the package scan was successful */
@@ -10190,7 +10222,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
/** A package to be scanned */
- private static class ScanRequest {
+ @VisibleForTesting
+ static class ScanRequest {
/** The parsed package */
@NonNull public final PackageParser.Package pkg;
/** The package this package replaces */
@@ -10383,7 +10416,7 @@ public class PackageManagerService extends IPackageManager.Stub
pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
originalPkgSetting, realPkgName, parseFlags, scanFlags,
(pkg == mPlatformPackage), user);
- return scanPackageOnlyLI(request, mFactoryTest, currentTime);
+ return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
}
}
@@ -10609,15 +10642,21 @@ public class PackageManagerService extends IPackageManager.Stub
* method potentially modifies a live {@link PackageSetting} object representing
* the package being scanned. This will be resolved in the future.
*
+ * @param injector injector for acquiring dependencies
* @param request Information about the package to be scanned
* @param isUnderFactoryTest Whether or not the device is under factory test
* @param currentTime The current time, in millis
* @return The results of the scan
*/
@GuardedBy("mInstallLock")
- private static @NonNull ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
+ @VisibleForTesting
+ @NonNull
+ static ScanResult scanPackageOnlyLI(@NonNull ScanRequest request,
+ Injector injector,
boolean isUnderFactoryTest, long currentTime)
- throws PackageManagerException {
+ throws PackageManagerException {
+ final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
+ final UserManagerInternal userManager = injector.getUserManager();
final PackageParser.Package pkg = request.pkg;
PackageSetting pkgSetting = request.pkgSetting;
final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
@@ -10723,7 +10762,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (!createNewPackage) {
final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
- setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
+ setInstantAppForUser(userManager, pkgSetting, userId, instantApp, fullApp);
}
// TODO(patb): see if we can do away with disabled check here.
if (disabledPkgSetting != null
@@ -10769,7 +10808,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (needToDeriveAbi) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
final boolean extractNativeLibs = !pkg.isLibrary();
- derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
+ packageAbiHelper.derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
// Some system apps still use directory structure for native libraries
@@ -10777,8 +10816,8 @@ public class PackageManagerService extends IPackageManager.Stub
// structure. Try to detect abi based on directory structure.
if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
pkg.applicationInfo.primaryCpuAbi == null) {
- setBundledAppAbisAndRoots(pkg, pkgSetting);
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ packageAbiHelper.setBundledAppAbisAndRoots(pkg, pkgSetting);
+ packageAbiHelper.setNativeLibraryPaths(pkg, sAppLib32InstallDir);
}
} else {
// This is not a first boot or an upgrade, don't bother deriving the
@@ -10787,7 +10826,7 @@ public class PackageManagerService extends IPackageManager.Stub
pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ packageAbiHelper.setNativeLibraryPaths(pkg, sAppLib32InstallDir);
if (DEBUG_ABI_SELECTION) {
Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
@@ -10808,7 +10847,7 @@ public class PackageManagerService extends IPackageManager.Stub
// ABIs we've determined above. For non-moves, the path will be updated based on the
// ABIs we determined during compilation, but the path will depend on the final
// package path (after the rename away from the stage path).
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
+ packageAbiHelper.setNativeLibraryPaths(pkg, sAppLib32InstallDir);
}
// This is a special case for the "system" package, where the ABI is
@@ -10862,8 +10901,8 @@ public class PackageManagerService extends IPackageManager.Stub
// We also do this *before* we perform dexopt on this package, so that
// we can avoid redundant dexopts, and also to make sure we've got the
// code and package path correct.
- changedAbiCodePath =
- adjustCpuAbisForSharedUserLPw(pkgSetting.sharedUser.packages, pkg);
+ changedAbiCodePath = packageAbiHelper.adjustCpuAbisForSharedUser(
+ pkgSetting.sharedUser.packages, pkg);
}
if (isUnderFactoryTest && pkg.requestedPermissions.contains(
@@ -11713,264 +11752,6 @@ public class PackageManagerService extends IPackageManager.Stub
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- /**
- * Derive the ABI of a non-system package located at {@code scanFile}. This information
- * is derived purely on the basis of the contents of {@code scanFile} and
- * {@code cpuAbiOverride}.
- *
- * If {@code extractLibs} is true, native libraries are extracted from the app if required.
- */
- private static void derivePackageAbi(PackageParser.Package pkg, String cpuAbiOverride,
- boolean extractLibs)
- throws PackageManagerException {
- // Give ourselves some initial paths; we'll come back for another
- // pass once we've determined ABI below.
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
-
- // We shouldn't attempt to extract libs from system app when it was not updated.
- if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
- extractLibs = false;
- }
-
- final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir;
- final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa;
-
- NativeLibraryHelper.Handle handle = null;
- try {
- handle = NativeLibraryHelper.Handle.create(pkg);
- // TODO(multiArch): This can be null for apps that didn't go through the
- // usual installation process. We can calculate it again, like we
- // do during install time.
- //
- // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally
- // unnecessary.
- final File nativeLibraryRoot = new File(nativeLibraryRootStr);
-
- // Null out the abis so that they can be recalculated.
- pkg.applicationInfo.primaryCpuAbi = null;
- pkg.applicationInfo.secondaryCpuAbi = null;
- if (isMultiArch(pkg.applicationInfo)) {
- // Warn if we've set an abiOverride for multi-lib packages..
- // By definition, we need to copy both 32 and 64 bit libraries for
- // such packages.
- if (pkg.cpuAbiOverride != null
- && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
- Slog.w(TAG, "Ignoring abiOverride for multi arch application.");
- }
-
- int abi32 = PackageManager.NO_NATIVE_LIBRARIES;
- int abi64 = PackageManager.NO_NATIVE_LIBRARIES;
- if (Build.SUPPORTED_32_BIT_ABIS.length > 0) {
- if (extractLibs) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
- abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS,
- useIsaSpecificSubdirs);
- } else {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
- abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS);
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
- // Shared library native code should be in the APK zip aligned
- if (abi32 >= 0 && pkg.isLibrary() && extractLibs) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Shared library native lib extraction not supported");
- }
-
- maybeThrowExceptionForMultiArchCopy(
- "Error unpackaging 32 bit native libs for multiarch app.", abi32);
-
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0) {
- if (extractLibs) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
- abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS,
- useIsaSpecificSubdirs);
- } else {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
- abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS);
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
- maybeThrowExceptionForMultiArchCopy(
- "Error unpackaging 64 bit native libs for multiarch app.", abi64);
-
- if (abi64 >= 0) {
- // Shared library native libs should be in the APK zip aligned
- if (extractLibs && pkg.isLibrary()) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Shared library native lib extraction not supported");
- }
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64];
- }
-
- if (abi32 >= 0) {
- final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
- if (abi64 >= 0) {
- if (pkg.use32bitAbi) {
- pkg.applicationInfo.secondaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
- pkg.applicationInfo.primaryCpuAbi = abi;
- } else {
- pkg.applicationInfo.secondaryCpuAbi = abi;
- }
- } else {
- pkg.applicationInfo.primaryCpuAbi = abi;
- }
- }
- } else {
- String[] abiList = (cpuAbiOverride != null) ?
- new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS;
-
- // Enable gross and lame hacks for apps that are built with old
- // SDK tools. We must scan their APKs for renderscript bitcode and
- // not launch them if it's present. Don't bother checking on devices
- // that don't have 64 bit support.
- boolean needsRenderScriptOverride = false;
- if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null &&
- NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
- abiList = Build.SUPPORTED_32_BIT_ABIS;
- needsRenderScriptOverride = true;
- }
-
- final int copyRet;
- if (extractLibs) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "copyNativeBinaries");
- copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle,
- nativeLibraryRoot, abiList, useIsaSpecificSubdirs);
- } else {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "findSupportedAbi");
- copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList);
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
-
- if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Error unpackaging native libs for app, errorCode=" + copyRet);
- }
-
- if (copyRet >= 0) {
- // Shared libraries that have native libs must be multi-architecture
- if (pkg.isLibrary()) {
- throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
- "Shared library with native libs must be multiarch");
- }
- pkg.applicationInfo.primaryCpuAbi = abiList[copyRet];
- } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) {
- pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride;
- } else if (needsRenderScriptOverride) {
- pkg.applicationInfo.primaryCpuAbi = abiList[0];
- }
- }
- } catch (IOException ioe) {
- Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
- } finally {
- IoUtils.closeQuietly(handle);
- }
-
- // Now that we've calculated the ABIs and determined if it's an internal app,
- // we will go ahead and populate the nativeLibraryPath.
- setNativeLibraryPaths(pkg, sAppLib32InstallDir);
- }
-
- /**
- * Adjusts ABIs for a set of packages belonging to a shared user so that they all match.
- * i.e, so that all packages can be run inside a single process if required.
- *
- * Optionally, callers can pass in a parsed package via {@code newPackage} in which case
- * this function will either try and make the ABI for all packages in {@code packagesForUser}
- * match {@code scannedPackage} or will update the ABI of {@code scannedPackage} to match
- * the ABI selected for {@code packagesForUser}. This variant is used when installing or
- * updating a package that belongs to a shared user.
- *
- * NOTE: We currently only match for the primary CPU abi string. Matching the secondary
- * adds unnecessary complexity.
- */
- private static @Nullable List<String> adjustCpuAbisForSharedUserLPw(
- Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
- List<String> changedAbiCodePath = null;
- String requiredInstructionSet = null;
- if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
- requiredInstructionSet = VMRuntime.getInstructionSet(
- scannedPackage.applicationInfo.primaryCpuAbi);
- }
-
- PackageSetting requirer = null;
- for (PackageSetting ps : packagesForUser) {
- // If packagesForUser contains scannedPackage, we skip it. This will happen
- // when scannedPackage is an update of an existing package. Without this check,
- // we will never be able to change the ABI of any package belonging to a shared
- // user, even if it's compatible with other packages.
- if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
- if (ps.primaryCpuAbiString == null) {
- continue;
- }
-
- final String instructionSet = VMRuntime.getInstructionSet(ps.primaryCpuAbiString);
- if (requiredInstructionSet != null && !instructionSet.equals(requiredInstructionSet)) {
- // We have a mismatch between instruction sets (say arm vs arm64) warn about
- // this but there's not much we can do.
- String errorMessage = "Instruction set mismatch, "
- + ((requirer == null) ? "[caller]" : requirer)
- + " requires " + requiredInstructionSet + " whereas " + ps
- + " requires " + instructionSet;
- Slog.w(TAG, errorMessage);
- }
-
- if (requiredInstructionSet == null) {
- requiredInstructionSet = instructionSet;
- requirer = ps;
- }
- }
- }
-
- if (requiredInstructionSet != null) {
- String adjustedAbi;
- if (requirer != null) {
- // requirer != null implies that either scannedPackage was null or that scannedPackage
- // did not require an ABI, in which case we have to adjust scannedPackage to match
- // the ABI of the set (which is the same as requirer's ABI)
- adjustedAbi = requirer.primaryCpuAbiString;
- if (scannedPackage != null) {
- scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
- }
- } else {
- // requirer == null implies that we're updating all ABIs in the set to
- // match scannedPackage.
- adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
- }
-
- for (PackageSetting ps : packagesForUser) {
- if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
- if (ps.primaryCpuAbiString != null) {
- continue;
- }
-
- ps.primaryCpuAbiString = adjustedAbi;
- if (ps.pkg != null && ps.pkg.applicationInfo != null &&
- !TextUtils.equals(adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
- ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
- if (DEBUG_ABI_SELECTION) {
- Slog.i(TAG, "Adjusting ABI for " + ps.name + " to " + adjustedAbi
- + " (requirer="
- + (requirer != null ? requirer.pkg : "null")
- + ", scannedPackage="
- + (scannedPackage != null ? scannedPackage : "null")
- + ")");
- }
- if (changedAbiCodePath == null) {
- changedAbiCodePath = new ArrayList<>();
- }
- changedAbiCodePath.add(ps.codePathString);
- }
- }
- }
- }
- return changedAbiCodePath;
- }
-
private void setUpCustomResolverActivity(PackageParser.Package pkg) {
synchronized (mPackages) {
mResolverReplaced = true;
@@ -12022,207 +11803,6 @@ public class PackageManagerService extends IPackageManager.Stub
| IntentFilter.MATCH_ADJUSTMENT_NORMAL;
}
- private static String calculateBundledApkRoot(final String codePathString) {
- final File codePath = new File(codePathString);
- final File codeRoot;
- if (FileUtils.contains(Environment.getRootDirectory(), codePath)) {
- codeRoot = Environment.getRootDirectory();
- } else if (FileUtils.contains(Environment.getOemDirectory(), codePath)) {
- codeRoot = Environment.getOemDirectory();
- } else if (FileUtils.contains(Environment.getVendorDirectory(), codePath)) {
- codeRoot = Environment.getVendorDirectory();
- } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
- codeRoot = Environment.getOdmDirectory();
- } else if (FileUtils.contains(Environment.getProductDirectory(), codePath)) {
- codeRoot = Environment.getProductDirectory();
- } else if (FileUtils.contains(Environment.getSystemExtDirectory(), codePath)) {
- codeRoot = Environment.getSystemExtDirectory();
- } else if (FileUtils.contains(Environment.getOdmDirectory(), codePath)) {
- codeRoot = Environment.getOdmDirectory();
- } else {
- // Unrecognized code path; take its top real segment as the apk root:
- // e.g. /something/app/blah.apk => /something
- try {
- File f = codePath.getCanonicalFile();
- File parent = f.getParentFile(); // non-null because codePath is a file
- File tmp;
- while ((tmp = parent.getParentFile()) != null) {
- f = parent;
- parent = tmp;
- }
- codeRoot = f;
- Slog.w(TAG, "Unrecognized code path "
- + codePath + " - using " + codeRoot);
- } catch (IOException e) {
- // Can't canonicalize the code path -- shenanigans?
- Slog.w(TAG, "Can't canonicalize code path " + codePath);
- return Environment.getRootDirectory().getPath();
- }
- }
- return codeRoot.getPath();
- }
-
- /**
- * Derive and set the location of native libraries for the given package,
- * which varies depending on where and how the package was installed.
- */
- private static void setNativeLibraryPaths(PackageParser.Package pkg, File appLib32InstallDir) {
- final ApplicationInfo info = pkg.applicationInfo;
- final String codePath = pkg.codePath;
- final File codeFile = new File(codePath);
- final boolean bundledApp = info.isSystemApp() && !info.isUpdatedSystemApp();
-
- info.nativeLibraryRootDir = null;
- info.nativeLibraryRootRequiresIsa = false;
- info.nativeLibraryDir = null;
- info.secondaryNativeLibraryDir = null;
-
- if (isApkFile(codeFile)) {
- // Monolithic install
- if (bundledApp) {
- // If "/system/lib64/apkname" exists, assume that is the per-package
- // native library directory to use; otherwise use "/system/lib/apkname".
- final String apkRoot = calculateBundledApkRoot(info.sourceDir);
- final boolean is64Bit = VMRuntime.is64BitInstructionSet(
- getPrimaryInstructionSet(info));
-
- // This is a bundled system app so choose the path based on the ABI.
- // if it's a 64 bit abi, use lib64 otherwise use lib32. Note that this
- // is just the default path.
- final String apkName = deriveCodePathName(codePath);
- final String libDir = is64Bit ? LIB64_DIR_NAME : LIB_DIR_NAME;
- info.nativeLibraryRootDir = Environment.buildPath(new File(apkRoot), libDir,
- apkName).getAbsolutePath();
-
- if (info.secondaryCpuAbi != null) {
- final String secondaryLibDir = is64Bit ? LIB_DIR_NAME : LIB64_DIR_NAME;
- info.secondaryNativeLibraryDir = Environment.buildPath(new File(apkRoot),
- secondaryLibDir, apkName).getAbsolutePath();
- }
- } else {
- final String apkName = deriveCodePathName(codePath);
- info.nativeLibraryRootDir = new File(appLib32InstallDir, apkName)
- .getAbsolutePath();
- }
-
- info.nativeLibraryRootRequiresIsa = false;
- info.nativeLibraryDir = info.nativeLibraryRootDir;
- } else {
- // Cluster install
- info.nativeLibraryRootDir = new File(codeFile, LIB_DIR_NAME).getAbsolutePath();
- info.nativeLibraryRootRequiresIsa = true;
-
- info.nativeLibraryDir = new File(info.nativeLibraryRootDir,
- getPrimaryInstructionSet(info)).getAbsolutePath();
-
- if (info.secondaryCpuAbi != null) {
- info.secondaryNativeLibraryDir = new File(info.nativeLibraryRootDir,
- VMRuntime.getInstructionSet(info.secondaryCpuAbi)).getAbsolutePath();
- }
- }
- }
-
- /**
- * Calculate the abis and roots for a bundled app. These can uniquely
- * be determined from the contents of the system partition, i.e whether
- * it contains 64 or 32 bit shared libraries etc. We do not validate any
- * of this information, and instead assume that the system was built
- * sensibly.
- */
- private static void setBundledAppAbisAndRoots(PackageParser.Package pkg,
- PackageSetting pkgSetting) {
- final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
-
- // If "/system/lib64/apkname" exists, assume that is the per-package
- // native library directory to use; otherwise use "/system/lib/apkname".
- final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
- setBundledAppAbi(pkg, apkRoot, apkName);
- // pkgSetting might be null during rescan following uninstall of updates
- // to a bundled app, so accommodate that possibility. The settings in
- // that case will be established later from the parsed package.
- //
- // If the settings aren't null, sync them up with what we've just derived.
- // note that apkRoot isn't stored in the package settings.
- if (pkgSetting != null) {
- pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
- pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
- }
- }
-
- /**
- * Deduces the ABI of a bundled app and sets the relevant fields on the
- * parsed pkg object.
- *
- * @param apkRoot the root of the installed apk, something like {@code /system} or {@code /oem}
- * under which system libraries are installed.
- * @param apkName the name of the installed package.
- */
- private static void setBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
- final File codeFile = new File(pkg.codePath);
-
- final boolean has64BitLibs;
- final boolean has32BitLibs;
- if (isApkFile(codeFile)) {
- // Monolithic install
- has64BitLibs = (new File(apkRoot, new File(LIB64_DIR_NAME, apkName).getPath())).exists();
- has32BitLibs = (new File(apkRoot, new File(LIB_DIR_NAME, apkName).getPath())).exists();
- } else {
- // Cluster install
- final File rootDir = new File(codeFile, LIB_DIR_NAME);
- if (!ArrayUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS)
- && !TextUtils.isEmpty(Build.SUPPORTED_64_BIT_ABIS[0])) {
- final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_64_BIT_ABIS[0]);
- has64BitLibs = (new File(rootDir, isa)).exists();
- } else {
- has64BitLibs = false;
- }
- if (!ArrayUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS)
- && !TextUtils.isEmpty(Build.SUPPORTED_32_BIT_ABIS[0])) {
- final String isa = VMRuntime.getInstructionSet(Build.SUPPORTED_32_BIT_ABIS[0]);
- has32BitLibs = (new File(rootDir, isa)).exists();
- } else {
- has32BitLibs = false;
- }
- }
-
- if (has64BitLibs && !has32BitLibs) {
- // The package has 64 bit libs, but not 32 bit libs. Its primary
- // ABI should be 64 bit. We can safely assume here that the bundled
- // native libraries correspond to the most preferred ABI in the list.
-
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = null;
- } else if (has32BitLibs && !has64BitLibs) {
- // The package has 32 bit libs but not 64 bit libs. Its primary
- // ABI should be 32 bit.
-
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = null;
- } else if (has32BitLibs && has64BitLibs) {
- // The application has both 64 and 32 bit bundled libraries. We check
- // here that the app declares multiArch support, and warn if it doesn't.
- //
- // We will be lenient here and record both ABIs. The primary will be the
- // ABI that's higher on the list, i.e, a device that's configured to prefer
- // 64 bit apps will see a 64 bit primary ABI,
-
- if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
- Slog.e(TAG, "Package " + pkg + " has multiple bundled libs, but is not multiarch.");
- }
-
- if (VMRuntime.is64BitInstructionSet(getPreferredInstructionSet())) {
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
- } else {
- pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_32_BIT_ABIS[0];
- pkg.applicationInfo.secondaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[0];
- }
- } else {
- pkg.applicationInfo.primaryCpuAbi = null;
- pkg.applicationInfo.secondaryCpuAbi = null;
- }
- }
-
private void killApplication(String pkgName, int appId, String reason) {
killApplication(pkgName, appId, UserHandle.USER_ALL, reason);
}
@@ -12948,7 +12528,8 @@ public class PackageManagerService extends IPackageManager.Stub
// upgrade app from instant to full; we don't allow app downgrade
installed = true;
}
- setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
+ setInstantAppForUser(
+ getUserManagerInternal(), pkgSetting, userId, instantApp, fullApp);
}
if (installed) {
@@ -12996,8 +12577,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- static void setInstantAppForUser(PackageSetting pkgSetting, int userId,
- boolean instantApp, boolean fullApp) {
+ static void setInstantAppForUser(UserManagerInternal userManager, PackageSetting pkgSetting,
+ int userId, boolean instantApp, boolean fullApp) {
// no state specified; do nothing
if (!instantApp && !fullApp) {
return;
@@ -13009,7 +12590,7 @@ public class PackageManagerService extends IPackageManager.Stub
pkgSetting.setInstantApp(false /*instantApp*/, userId);
}
} else {
- for (int currentUserId : sUserManager.getUserIds()) {
+ for (int currentUserId : userManager.getUserIds()) {
if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
} else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
@@ -15201,16 +14782,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private static void maybeThrowExceptionForMultiArchCopy(String message, int copyRet) throws
- PackageManagerException {
- if (copyRet < 0) {
- if (copyRet != PackageManager.NO_NATIVE_LIBRARIES &&
- copyRet != PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS) {
- throw new PackageManagerException(copyRet, message);
- }
- }
- }
-
/**
* Logic to handle movement of existing installed applications.
*/
@@ -15337,26 +14908,6 @@ public class PackageManagerService extends IPackageManager.Stub
return result;
}
- // Utility method that returns the relative package path with respect
- // to the installation directory. Like say for /data/data/com.test-1.apk
- // string com.test-1 is returned.
- static String deriveCodePathName(String codePath) {
- if (codePath == null) {
- return null;
- }
- final File codeFile = new File(codePath);
- final String name = codeFile.getName();
- if (codeFile.isDirectory()) {
- return name;
- } else if (name.endsWith(".apk") || name.endsWith(".tmp")) {
- final int lastDot = name.lastIndexOf('.');
- return name.substring(0, lastDot);
- } else {
- Slog.w(TAG, "Odd, " + codePath + " doesn't look like an APK");
- return null;
- }
- }
-
static class PackageInstalledInfo {
String name;
int uid;
@@ -16288,7 +15839,8 @@ public class PackageManagerService extends IPackageManager.Stub
final PrepareResult prepareResult;
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "preparePackage");
- prepareResult = preparePackageLI(request.args, request.installResult);
+ prepareResult =
+ preparePackageLI(request.args, request.installResult);
} catch (PrepareFailure prepareFailure) {
request.installResult.setError(prepareFailure.error,
prepareFailure.getMessage());
@@ -16363,11 +15915,6 @@ public class PackageManagerService extends IPackageManager.Stub
commitPackagesLocked(commitRequest);
success = true;
} finally {
- for (PrepareResult result : prepareResults.values()) {
- if (result.freezer != null) {
- result.freezer.close();
- }
- }
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
@@ -16953,7 +16500,7 @@ public class PackageManagerService extends IPackageManager.Stub
String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
args.abiOverride : pkg.cpuAbiOverride);
final boolean extractNativeLibs = !pkg.isLibrary();
- derivePackageAbi(pkg, abiOverride, extractNativeLibs);
+ mInjector.getAbiHelper().derivePackageAbi(pkg, abiOverride, extractNativeLibs);
} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
@@ -17482,10 +17029,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private static boolean isMultiArch(ApplicationInfo info) {
- return (info.flags & ApplicationInfo.FLAG_MULTIARCH) != 0;
- }
-
private static boolean isExternal(PackageParser.Package pkg) {
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
@@ -17494,7 +17037,7 @@ public class PackageManagerService extends IPackageManager.Stub
return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
- private static boolean isSystemApp(PackageParser.Package pkg) {
+ static boolean isSystemApp(PackageParser.Package pkg) {
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 58f262c4c889..029673ffd87b 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -270,7 +270,8 @@ public abstract class PackageSettingBase extends SettingBase {
updateAvailable = orig.updateAvailable;
}
- private PackageUserState modifyUserState(int userId) {
+ @VisibleForTesting
+ PackageUserState modifyUserState(int userId) {
PackageUserState state = mUserState.get(userId);
if (state == null) {
state = new PackageUserState();
@@ -463,6 +464,18 @@ public abstract class PackageSettingBase extends SettingBase {
state.harmfulAppWarning = harmfulAppWarning;
}
+ void setUserState(int userId, PackageUserState otherState) {
+ setUserState(userId, otherState.ceDataInode, otherState.enabled, otherState.installed,
+ otherState.stopped, otherState.notLaunched, otherState.hidden,
+ otherState.distractionFlags, otherState.suspended, otherState.suspendingPackage,
+ otherState.dialogInfo, otherState.suspendedAppExtras,
+ otherState.suspendedLauncherExtras, otherState.instantApp,
+ otherState.virtualPreload, otherState.lastDisableAppCaller,
+ otherState.enabledComponents, otherState.disabledComponents,
+ otherState.domainVerificationStatus, otherState.appLinkGeneration,
+ otherState.installReason, otherState.harmfulAppWarning);
+ }
+
ArraySet<String> getEnabledComponents(int userId) {
return readUserState(userId).enabledComponents;
}
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index 2d8a2acd575f..ebba128b5f28 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -79,7 +79,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.text.TextUtils;
-import android.text.format.Time;
+import android.text.format.TimeMigrationUtils;
import android.util.ArraySet;
import android.util.AtomicFile;
import android.util.KeyValueListParser;
@@ -3981,9 +3981,7 @@ public class ShortcutService extends IShortcutService.Stub {
}
static String formatTime(long time) {
- Time tobj = new Time();
- tobj.set(time);
- return tobj.format("%Y-%m-%d %H:%M:%S");
+ return TimeMigrationUtils.formatMillisWithFixedFormat(time);
}
private void dumpCurrentTime(PrintWriter pw) {
diff --git a/services/core/java/com/android/server/pm/TEST_MAPPING b/services/core/java/com/android/server/pm/TEST_MAPPING
index b829f0b53086..f7b60c25ce4a 100644
--- a/services/core/java/com/android/server/pm/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/TEST_MAPPING
@@ -8,6 +8,20 @@
},
{
"name": "CtsCompilationTestCases"
+ },
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.pm."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
}
],
"postsubmit": [
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index 673ab6c5f095..03be8e119e03 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -54,6 +54,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
+import android.app.AppOpsManager;
import android.app.ApplicationPackageManager;
import android.app.IActivityManager;
import android.content.Context;
@@ -1447,7 +1448,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
/**
* Reverts user permission state changes (permissions and flags).
*
- * @param ps The package for which to reset.
+ * @param pkg The package for which to reset.
* @param userId The device user for which to do a reset.
*/
@GuardedBy("mPackages")
@@ -1521,6 +1522,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
};
+ final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
for (int i = 0; i < permissionCount; i++) {
final String permName = pkg.requestedPermissions.get(i);
final BasePermission bp;
@@ -1588,6 +1590,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
grantRuntimePermissionInternal(permName, packageName, false,
Process.SYSTEM_UID, userId, delayingPermCallback);
+ // Allow app op later as we are holding mPackages
+ // PermissionPolicyService will handle the app op for foreground/background
+ // permissions.
+ String appOp = AppOpsManager.permissionToOp(permName);
+ if (appOp != null) {
+ mHandler.post(() -> appOpsManager.setUidMode(appOp, uid,
+ AppOpsManager.MODE_ALLOWED));
+ }
// If permission review is enabled the permissions for a legacy apps
// are represented as constantly granted runtime ones, so don't revoke.
} else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 26b1f7b49aae..015464e94ffc 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -163,6 +163,7 @@ import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
import static org.xmlpull.v1.XmlPullParser.END_TAG;
import static org.xmlpull.v1.XmlPullParser.START_TAG;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Activity;
@@ -1630,22 +1631,52 @@ final class ActivityRecord extends ConfigurationContainer {
setSavedState(null /* savedState */);
}
+ /** Activity finish request was not executed. */
+ static final int FINISH_RESULT_CANCELLED = 0;
+ /** Activity finish was requested, activity will be fully removed later. */
+ static final int FINISH_RESULT_REQUESTED = 1;
+ /** Activity finish was requested, activity was removed from history. */
+ static final int FINISH_RESULT_REMOVED = 2;
+
+ /** Definition of possible results for activity finish request. */
+ @IntDef(prefix = { "FINISH_RESULT_" }, value = {
+ FINISH_RESULT_CANCELLED,
+ FINISH_RESULT_REQUESTED,
+ FINISH_RESULT_REMOVED,
+ })
+ @interface FinishRequest {}
+
/**
* See {@link #finishActivityLocked(int, Intent, String, boolean, boolean)}
*/
- boolean finishActivityLocked(int resultCode, Intent resultData, String reason, boolean oomAdj) {
+ @FinishRequest int finishActivityLocked(int resultCode, Intent resultData, String reason,
+ boolean oomAdj) {
return finishActivityLocked(resultCode, resultData, reason, oomAdj, !PAUSE_IMMEDIATELY);
}
/**
- * @return Returns true if this activity has been removed from the history
- * list, or false if it is still in the list and will be removed later.
+ * @return One of {@link FinishRequest} values:
+ * {@link #FINISH_RESULT_REMOVED} if this activity has been removed from the history list.
+ * {@link #FINISH_RESULT_REQUESTED} if removal process was started, but it is still in the list
+ * and will be removed from history later.
+ * {@link #FINISH_RESULT_CANCELLED} if activity is already finishing or in invalid state and the
+ * request to finish it was not ignored.
*/
- boolean finishActivityLocked(int resultCode, Intent resultData, String reason, boolean oomAdj,
- boolean pauseImmediately) {
+ @FinishRequest int finishActivityLocked(int resultCode, Intent resultData, String reason,
+ boolean oomAdj, boolean pauseImmediately) {
+ if (DEBUG_RESULTS || DEBUG_STATES) {
+ Slog.v(TAG_STATES, "Finishing activity r=" + this + ", result=" + resultCode
+ + ", data=" + resultData + ", reason=" + reason);
+ }
+
if (finishing) {
- Slog.w(TAG, "Duplicate finish request for " + this);
- return false;
+ Slog.w(TAG, "Duplicate finish request for r=" + this);
+ return FINISH_RESULT_CANCELLED;
+ }
+
+ if (!isInStackLocked()) {
+ Slog.w(TAG, "Finish request when not in stack for r=" + this);
+ return FINISH_RESULT_CANCELLED;
}
mAtmService.mWindowManager.deferSurfaceLayout();
@@ -1737,12 +1768,12 @@ final class ActivityRecord extends ConfigurationContainer {
taskOverlay.prepareActivityHideTransitionAnimation(transit);
}
}
- return removedActivity;
+ return removedActivity ? FINISH_RESULT_REMOVED : FINISH_RESULT_REQUESTED;
} else {
if (DEBUG_PAUSE) Slog.v(TAG_PAUSE, "Finish waiting for pause of: " + this);
}
- return false;
+ return FINISH_RESULT_REQUESTED;
} finally {
mAtmService.mWindowManager.continueSurfaceLayout();
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 81d8fa9554bc..17536e42acc8 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -58,6 +58,8 @@ import static com.android.server.wm.ActivityDisplay.POSITION_BOTTOM;
import static com.android.server.wm.ActivityDisplay.POSITION_TOP;
import static com.android.server.wm.ActivityRecord.FINISH_AFTER_VISIBLE;
import static com.android.server.wm.ActivityRecord.FINISH_IMMEDIATELY;
+import static com.android.server.wm.ActivityRecord.FINISH_RESULT_CANCELLED;
+import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REMOVED;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
@@ -1153,13 +1155,6 @@ class ActivityStack extends ConfigurationContainer {
return null;
}
- private TaskRecord bottomTask() {
- if (mTaskHistory.isEmpty()) {
- return null;
- }
- return mTaskHistory.get(0);
- }
-
TaskRecord taskForIdLocked(int id) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
@@ -2787,8 +2782,8 @@ class ActivityStack extends ConfigurationContainer {
!mLastNoHistoryActivity.finishing) {
if (DEBUG_STATES) Slog.d(TAG_STATES,
"no-history finish of " + mLastNoHistoryActivity + " on new resume");
- requestFinishActivityLocked(mLastNoHistoryActivity.appToken, Activity.RESULT_CANCELED,
- null, "resume-no-history", false);
+ mLastNoHistoryActivity.finishActivityLocked(Activity.RESULT_CANCELED,
+ null /* resultData */, "resume-no-history", false /* oomAdj */);
mLastNoHistoryActivity = null;
}
@@ -3023,8 +3018,8 @@ class ActivityStack extends ConfigurationContainer {
// If any exception gets thrown, toss away this
// activity and try the next one.
Slog.w(TAG, "Exception thrown during resume of " + next, e);
- requestFinishActivityLocked(next.appToken, Activity.RESULT_CANCELED, null,
- "resume-exception", true);
+ next.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+ "resume-exception", true /* oomAdj */);
return true;
}
} else {
@@ -3452,7 +3447,7 @@ class ActivityStack extends ConfigurationContainer {
if (DEBUG_TASKS) Slog.w(TAG_TASKS,
"resetTaskIntendedTask: calling finishActivity on " + p);
if (p.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
- "reset-task", false /* oomAdj */)) {
+ "reset-task", false /* oomAdj */) == FINISH_RESULT_REMOVED) {
end--;
srcPos--;
}
@@ -3760,10 +3755,9 @@ class ActivityStack extends ConfigurationContainer {
if (!r.finishing) {
if (!shouldSleepActivities()) {
if (DEBUG_STATES) Slog.d(TAG_STATES, "no-history finish of " + r);
- if (requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
- "stop-no-history", false)) {
- // If {@link requestFinishActivityLocked} returns {@code true},
- // {@link adjustFocusedActivityStack} would have been already called.
+ if (r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+ "stop-no-history", false /* oomAdj */) != FINISH_RESULT_CANCELLED) {
+ // {@link adjustFocusedActivityStack} must have been already called.
r.resumeKeyDispatchingLocked();
return;
}
@@ -3812,25 +3806,7 @@ class ActivityStack extends ConfigurationContainer {
}
}
- /**
- * @return Returns true if the activity is being finished, false if for
- * some reason it is being left as-is.
- */
- final boolean requestFinishActivityLocked(IBinder token, int resultCode,
- Intent resultData, String reason, boolean oomAdj) {
- ActivityRecord r = isInStackLocked(token);
- if (DEBUG_RESULTS || DEBUG_STATES) Slog.v(TAG_STATES,
- "Finishing activity token=" + token + " r="
- + ", result=" + resultCode + ", data=" + resultData
- + ", reason=" + reason);
- if (r == null) {
- return false;
- }
-
- r.finishActivityLocked(resultCode, resultData, reason, oomAdj);
- return true;
- }
-
+ /** Finish all activities that were started for result from the specified activity. */
final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
@@ -4052,8 +4028,8 @@ class ActivityStack extends ConfigurationContainer {
}
final long origId = Binder.clearCallingIdentity();
for (int i = start; i > finishTo; i--) {
- ActivityRecord r = activities.get(i);
- requestFinishActivityLocked(r.appToken, resultCode, resultData, "navigate-up", true);
+ final ActivityRecord r = activities.get(i);
+ r.finishActivityLocked(resultCode, resultData, "navigate-up", true /* oomAdj */);
// Only return the supplied result for the first activity finished
resultCode = Activity.RESULT_CANCELED;
resultData = null;
@@ -4090,8 +4066,8 @@ class ActivityStack extends ConfigurationContainer {
} catch (RemoteException e) {
foundParentInTask = false;
}
- requestFinishActivityLocked(parent.appToken, resultCode,
- resultData, "navigate-top", true);
+ parent.finishActivityLocked(resultCode, resultData, "navigate-top",
+ true /* oomAdj */);
}
}
Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index e49e991c2825..1c56a107ab9e 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -890,8 +890,8 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
Slog.e(TAG, "Second failure launching "
+ r.intent.getComponent().flattenToShortString() + ", giving up", e);
proc.appDied();
- stack.requestFinishActivityLocked(r.appToken, Activity.RESULT_CANCELED, null,
- "2nd-crash", false);
+ r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
+ "2nd-crash", false /* oomAdj */);
return false;
}
@@ -1191,8 +1191,7 @@ public class ActivityStackSupervisor implements RecentTasks.Callbacks {
final PackageInfo packageInfo;
try {
packageInfo = mService.mContext.getPackageManager()
- .getPackageInfoAsUser(callingPackage, PackageManager.GET_PERMISSIONS,
- UserHandle.getUserId(callingUid));
+ .getPackageInfo(callingPackage, PackageManager.GET_PERMISSIONS);
} catch (PackageManager.NameNotFoundException e) {
Slog.i(TAG, "Cannot find package info for " + callingPackage);
return ACTIVITY_RESTRICTION_NONE;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index fb393e60f93e..b351faf7e9f1 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -84,6 +84,7 @@ import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.PRE
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.SCREEN_COMPAT_PACKAGES;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.MODE;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
+import static com.android.server.wm.ActivityRecord.FINISH_RESULT_CANCELLED;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
@@ -1011,7 +1012,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public final int startActivities(IApplicationThread caller, String callingPackage,
Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
int userId) {
- assertPackageMatchesCallingUid(callingPackage);
final String reason = "startActivities";
enforceNotIsolatedCaller(reason);
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId, reason);
@@ -1031,11 +1031,10 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
true /*validateIncomingUser*/);
}
- private int startActivityAsUser(IApplicationThread caller, String callingPackage,
+ int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId,
boolean validateIncomingUser) {
- assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser,
@@ -1208,7 +1207,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
- assertPackageMatchesCallingUid(callingPackage);
final WaitResult res = new WaitResult();
synchronized (mGlobalLock) {
enforceNotIsolatedCaller("startActivityAndWait");
@@ -1236,7 +1234,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, Configuration config, Bundle bOptions, int userId) {
- assertPackageMatchesCallingUid(callingPackage);
synchronized (mGlobalLock) {
enforceNotIsolatedCaller("startActivityWithConfig");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
@@ -1286,7 +1283,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, IBinder permissionToken,
boolean ignoreTargetSecurity, int userId) {
- assertPackageMatchesCallingUid(callingPackage);
// This is very dangerous -- it allows you to perform a start activity (including
// permission grants) as any app that may launch one of your own activities. So we only
// allow this in two cases:
@@ -1416,7 +1412,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
Intent intent, String resolvedType, IVoiceInteractionSession session,
IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
Bundle bOptions, int userId) {
- assertPackageMatchesCallingUid(callingPackage);
mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startVoiceActivity()");
if (session == null || interactor == null) {
throw new NullPointerException("null session or interactor");
@@ -1440,7 +1435,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public int startAssistantActivity(String callingPackage, int callingPid, int callingUid,
Intent intent, String resolvedType, Bundle bOptions, int userId) {
- assertPackageMatchesCallingUid(callingPackage);
mAmInternal.enforceCallingPermission(BIND_VOICE_INTERACTION, "startAssistantActivity()");
userId = handleIncomingUser(callingPid, callingUid, userId, "startAssistantActivity");
@@ -1560,13 +1554,13 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
}
synchronized (mGlobalLock) {
- ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return true;
}
// Keep track of the root activity of the task before we finish it
final TaskRecord tr = r.getTaskRecord();
- ActivityRecord rootR = tr.getRootActivity();
+ final ActivityRecord rootR = tr.getRootActivity();
if (rootR == null) {
Slog.w(TAG, "Finishing task with all activities already finished");
}
@@ -1616,7 +1610,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// because we don't support returning them across task boundaries. Also, to
// keep backwards compatibility we remove the task from recents when finishing
// task with root activity.
- res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false,
+ res = mStackSupervisor.removeTaskByIdLocked(tr.taskId, false /* killProcess */,
finishWithRootActivity, "finish-activity");
if (!res) {
Slog.i(TAG, "Removing task failed to finish activity");
@@ -1624,8 +1618,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// Explicitly dismissing the activity so reset its relaunch flag.
r.mRelaunchReason = RELAUNCH_REASON_NONE;
} else {
- res = tr.getStack().requestFinishActivityLocked(token, resultCode,
- resultData, "app-request", true);
+ res = r.finishActivityLocked(resultCode, resultData, "app-request",
+ true /* oomAdj */) != FINISH_RESULT_CANCELLED;
if (!res) {
Slog.i(TAG, "Failed to finish by app-request");
}
@@ -1649,7 +1643,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
// Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
// can finish.
- final TaskRecord task = r.getTaskRecord();
if (getLockTaskController().activityBlockedFromFinish(r)) {
return false;
}
@@ -2367,9 +2360,15 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
void moveTaskToFrontLocked(@Nullable IApplicationThread appThread,
@Nullable String callingPackage, int taskId, int flags, SafeActivityOptions options,
boolean fromRecents) {
+
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
- assertPackageMatchesCallingUid(callingPackage);
+ if (!isSameApp(callingUid, callingPackage)) {
+ String msg = "Permission Denial: moveTaskToFrontLocked() from pid="
+ + Binder.getCallingPid() + " as package " + callingPackage;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
if (!checkAppSwitchAllowedLocked(callingPid, callingUid, -1, -1, "Task to front")) {
SafeActivityOptions.abort(options);
return;
@@ -2421,7 +2420,7 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
/**
* Return true if callingUid is system, or packageName belongs to that callingUid.
*/
- private boolean isSameApp(int callingUid, @Nullable String packageName) {
+ boolean isSameApp(int callingUid, @Nullable String packageName) {
try {
if (callingUid != 0 && callingUid != SYSTEM_UID) {
if (packageName == null) {
@@ -2438,21 +2437,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
return true;
}
- /**
- * Checks that the provided package name matches the current calling UID, throws a security
- * exception if it doesn't.
- */
- void assertPackageMatchesCallingUid(@Nullable String packageName) {
- final int callingUid = Binder.getCallingUid();
- if (isSameApp(callingUid, packageName)) {
- return;
- }
- final String msg = "Permission Denial: package=" + packageName
- + " does not belong to uid=" + callingUid;
- Slog.w(TAG, msg);
- throw new SecurityException(msg);
- }
-
boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
int callingPid, int callingUid, String name) {
if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
@@ -2986,7 +2970,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
@Override
public List<IBinder> getAppTasks(String callingPackage) {
int callingUid = Binder.getCallingUid();
- assertPackageMatchesCallingUid(callingPackage);
long ident = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -6093,7 +6076,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
SafeActivityOptions options, int userId, boolean validateIncomingUser,
PendingIntentRecord originatingPendingIntent,
boolean allowBackgroundActivityStart) {
- assertPackageMatchesCallingUid(callingPackage);
synchronized (mGlobalLock) {
return getActivityStartController().startActivitiesInPackage(uid, realCallingPid,
realCallingUid, callingPackage, intents, resolvedTypes, resultTo, options,
@@ -6109,7 +6091,6 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
int userId, TaskRecord inTask, String reason, boolean validateIncomingUser,
PendingIntentRecord originatingPendingIntent,
boolean allowBackgroundActivityStart) {
- assertPackageMatchesCallingUid(callingPackage);
synchronized (mGlobalLock) {
return getActivityStartController().startActivityInPackage(uid, realCallingPid,
realCallingUid, callingPackage, intent, resolvedType, resultTo, resultWho,
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index a8f7768efc87..1eb7455135c7 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -27,6 +27,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.UserHandle;
+import android.util.Slog;
/**
* An implementation of IAppTask, that allows an app to manage its own tasks via
@@ -96,7 +97,12 @@ class AppTaskImpl extends IAppTask.Stub {
// Will bring task to front if it already has a root activity.
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
- mService.assertPackageMatchesCallingUid(callingPackage);
+ if (!mService.isSameApp(callingUid, callingPackage)) {
+ String msg = "Permission Denial: moveToFront() from pid="
+ + Binder.getCallingPid() + " as package " + callingPackage;
+ Slog.w(TAG, msg);
+ throw new SecurityException(msg);
+ }
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mService.mGlobalLock) {
@@ -128,7 +134,6 @@ class AppTaskImpl extends IAppTask.Stub {
public int startActivity(IBinder whoThread, String callingPackage,
Intent intent, String resolvedType, Bundle bOptions) {
checkCaller();
- mService.assertPackageMatchesCallingUid(callingPackage);
int callingUser = UserHandle.getCallingUserId();
TaskRecord tr;
diff --git a/services/core/java/com/android/server/wm/AppWindowToken.java b/services/core/java/com/android/server/wm/AppWindowToken.java
index d15081ca2665..aefc152cb286 100644
--- a/services/core/java/com/android/server/wm/AppWindowToken.java
+++ b/services/core/java/com/android/server/wm/AppWindowToken.java
@@ -1015,6 +1015,8 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
void notifyAppStopped() {
if (DEBUG_ADD_REMOVE) Slog.v(TAG, "notifyAppStopped: " + this);
mAppStopped = true;
+ // Reset the last saved PiP snap fraction on app stop.
+ mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
destroySurfaces();
// Remove any starting window that was added for this app if they are still around.
removeStartingWindow();
@@ -2485,7 +2487,7 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
// transformed the task.
final RecentsAnimationController controller = mWmService.getRecentsAnimationController();
if (controller != null && controller.isAnimatingTask(getTask())
- && controller.shouldCancelWithDeferredScreenshot()) {
+ && controller.shouldDeferCancelUntilNextTransition()) {
return false;
}
@@ -3076,11 +3078,6 @@ class AppWindowToken extends WindowToken implements WindowManagerService.AppFree
@Override
void setHidden(boolean hidden) {
super.setHidden(hidden);
-
- if (hidden) {
- // Once the app window is hidden, reset the last saved PiP snap fraction
- mDisplayContent.mPinnedStackControllerLocked.resetReentrySnapFraction(this);
- }
scheduleAnimation();
}
diff --git a/services/core/java/com/android/server/wm/DisplayWindowSettings.java b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
index a46fa13adf4e..207e8ef728eb 100644
--- a/services/core/java/com/android/server/wm/DisplayWindowSettings.java
+++ b/services/core/java/com/android/server/wm/DisplayWindowSettings.java
@@ -30,6 +30,7 @@ import android.annotation.IntDef;
import android.annotation.Nullable;
import android.app.WindowConfiguration;
import android.os.Environment;
+import android.os.FileUtils;
import android.provider.Settings;
import android.util.AtomicFile;
import android.util.Slog;
@@ -64,6 +65,11 @@ import java.util.HashMap;
class DisplayWindowSettings {
private static final String TAG = TAG_WITH_CLASS_NAME ? "DisplayWindowSettings" : TAG_WM;
+ private static final String SYSTEM_DIRECTORY = "system";
+ private static final String DISPLAY_SETTINGS_FILE_NAME = "display_settings.xml";
+ private static final String VENDOR_DISPLAY_SETTINGS_PATH = "etc/" + DISPLAY_SETTINGS_FILE_NAME;
+ private static final String WM_DISPLAY_COMMIT_TAG = "wm-displays";
+
private static final int IDENTIFIER_UNIQUE_ID = 0;
private static final int IDENTIFIER_PORT = 1;
@IntDef(prefix = { "IDENTIFIER_" }, value = {
@@ -688,8 +694,26 @@ class DisplayWindowSettings {
private final AtomicFile mAtomicFile;
AtomicFileStorage() {
- final File folder = new File(Environment.getDataDirectory(), "system");
- mAtomicFile = new AtomicFile(new File(folder, "display_settings.xml"), "wm-displays");
+ final File folder = new File(Environment.getDataDirectory(), SYSTEM_DIRECTORY);
+ final File settingsFile = new File(folder, DISPLAY_SETTINGS_FILE_NAME);
+ // If display_settings.xml doesn't exist, try to copy the vendor's one instead
+ // in order to provide the vendor specific initialization.
+ if (!settingsFile.exists()) {
+ copyVendorSettings(settingsFile);
+ }
+ mAtomicFile = new AtomicFile(settingsFile, WM_DISPLAY_COMMIT_TAG);
+ }
+
+ private static void copyVendorSettings(File target) {
+ final File vendorFile = new File(Environment.getVendorDirectory(),
+ VENDOR_DISPLAY_SETTINGS_PATH);
+ if (vendorFile.canRead()) {
+ try {
+ FileUtils.copy(vendorFile, target);
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to copy vendor display_settings.xml");
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index 422b6e58e0ed..85ba95f7d6de 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -90,24 +90,11 @@ class KeyguardController {
}
/**
- * @return true if either Keyguard or AOD are showing, not going away, and not being occluded
- * on the given display, false otherwise.
+ * @return true if either 1) AOD is showing, or 2) Keyguard is showing, not going away, and not
+ * being occluded on the given display, false otherwise.
*/
boolean isKeyguardOrAodShowing(int displayId) {
- return (mKeyguardShowing || mAodShowing) && !mKeyguardGoingAway
- && !isDisplayOccluded(displayId);
- }
-
- /**
- * @return {@code true} for default display when AOD is showing. Otherwise, same as
- * {@link #isKeyguardOrAodShowing(int)}
- * TODO(b/125198167): Replace isKeyguardOrAodShowing() by this logic.
- */
- boolean isKeyguardUnoccludedOrAodShowing(int displayId) {
- if (displayId == DEFAULT_DISPLAY && mAodShowing) {
- return true;
- }
- return isKeyguardOrAodShowing(displayId);
+ return mAodShowing || isKeyguardShowing(displayId);
}
/**
@@ -115,7 +102,7 @@ class KeyguardController {
* display, false otherwise
*/
boolean isKeyguardShowing(int displayId) {
- return mKeyguardShowing && !mKeyguardGoingAway && !isDisplayOccluded(displayId);
+ return mKeyguardShowing && !mKeyguardGoingAway && !isKeyguardOccluded(displayId);
}
/**
@@ -328,7 +315,7 @@ class KeyguardController {
return;
}
- mWindowManager.onKeyguardOccludedChanged(isDisplayOccluded(DEFAULT_DISPLAY));
+ mWindowManager.onKeyguardOccludedChanged(isKeyguardOccluded(DEFAULT_DISPLAY));
if (isKeyguardLocked()) {
mWindowManager.deferSurfaceLayout();
try {
@@ -373,7 +360,7 @@ class KeyguardController {
}
}
- private boolean isDisplayOccluded(int displayId) {
+ private boolean isKeyguardOccluded(int displayId) {
return getDisplay(displayId).mOccluded;
}
@@ -391,13 +378,13 @@ class KeyguardController {
if (mBeforeUnoccludeTransit != TRANSIT_UNSET
&& dc.mAppTransition.getAppTransition() == TRANSIT_KEYGUARD_UNOCCLUDE
// TODO(b/113840485): Handle app transition for individual display.
- && isDisplayOccluded(DEFAULT_DISPLAY)) {
+ && isKeyguardOccluded(DEFAULT_DISPLAY)) {
// Reuse old transit in case we are occluding Keyguard again, meaning that we never
// actually occclude/unocclude Keyguard, but just run a normal transition.
return mBeforeUnoccludeTransit;
// TODO(b/113840485): Handle app transition for individual display.
- } else if (!isDisplayOccluded(DEFAULT_DISPLAY)) {
+ } else if (!isKeyguardOccluded(DEFAULT_DISPLAY)) {
// Save transit in case we dismiss/occlude Keyguard shortly after.
mBeforeUnoccludeTransit = dc.mAppTransition.getAppTransition();
@@ -409,7 +396,7 @@ class KeyguardController {
private void dismissDockedStackIfNeeded() {
// TODO(b/113840485): Handle docked stack for individual display.
- if (mKeyguardShowing && isDisplayOccluded(DEFAULT_DISPLAY)) {
+ if (mKeyguardShowing && isKeyguardOccluded(DEFAULT_DISPLAY)) {
// The lock screen is currently showing, but is occluded by a window that can
// show on top of the lock screen. In this can we want to dismiss the docked
// stack since it will be complicated/risky to try to put the activity on top
@@ -434,9 +421,9 @@ class KeyguardController {
private void updateKeyguardSleepToken(int displayId) {
final KeyguardDisplayState state = getDisplay(displayId);
- if (isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken == null) {
+ if (isKeyguardOrAodShowing(displayId) && state.mSleepToken == null) {
state.acquiredSleepToken();
- } else if (!isKeyguardUnoccludedOrAodShowing(displayId) && state.mSleepToken != null) {
+ } else if (!isKeyguardOrAodShowing(displayId) && state.mSleepToken != null) {
state.releaseSleepToken();
}
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index bf627ec5680c..0a3e7a4860d5 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -355,7 +355,7 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
// launch-behind state is restored. That also prevents the next transition
// type being disturbed if the visibility is updated after setting the next
// transition (the target activity will be one of closing apps).
- if (!controller.shouldCancelWithDeferredScreenshot()
+ if (!controller.shouldDeferCancelWithScreenshot()
&& !targetStack.isFocusedStackOnDisplay()) {
targetStack.ensureActivitiesVisibleLocked(null /* starting */,
0 /* starting */, false /* preserveWindows */);
@@ -415,16 +415,18 @@ class RecentsAnimation implements RecentsAnimationCallbacks,
final DisplayContent dc =
mService.mRootActivityContainer.getDefaultDisplay().mDisplayContent;
dc.mBoundsAnimationController.setAnimationType(
- controller.shouldCancelWithDeferredScreenshot() ? FADE_IN : BOUNDS);
+ controller.shouldDeferCancelUntilNextTransition() ? FADE_IN : BOUNDS);
- // Cancel running recents animation and screenshot previous task when the next
- // transition starts in below cases:
- // 1) The next launching task is not in recents animation task.
+ // We defer canceling the recents animation until the next app transition in the following
+ // cases:
+ // 1) The next launching task is not being animated by the recents animation
// 2) The next task is home activity. (i.e. pressing home key to back home in recents).
if ((!controller.isAnimatingTask(stack.getTaskStack().getTopChild())
|| controller.isTargetApp(stack.getTopActivity().mAppWindowToken))
- && controller.shouldCancelWithDeferredScreenshot()) {
- controller.cancelOnNextTransitionStart();
+ && controller.shouldDeferCancelUntilNextTransition()) {
+ // Always prepare an app transition since we rely on the transition callbacks to cleanup
+ mWindowManager.prepareAppTransition(TRANSIT_NONE, false);
+ controller.setCancelOnNextTransitionStart();
} else {
// Just cancel directly to unleash from launcher when the next launching task is the
// current top task.
diff --git a/services/core/java/com/android/server/wm/RecentsAnimationController.java b/services/core/java/com/android/server/wm/RecentsAnimationController.java
index 163be1ebd0ed..6ea4d580ea98 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimationController.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimationController.java
@@ -97,10 +97,9 @@ public class RecentsAnimationController implements DeathRecipient {
private final Runnable mFailsafeRunnable = () ->
cancelAnimation(REORDER_MOVE_TO_ORIGINAL_POSITION, "failSafeRunnable");
- final Object mLock = new Object();
-
// The recents component app token that is shown behind the visibile tasks
private AppWindowToken mTargetAppToken;
+ private DisplayContent mDisplayContent;
private int mTargetActivityType;
private Rect mMinimizedHomeBounds = new Rect();
@@ -124,25 +123,47 @@ public class RecentsAnimationController implements DeathRecipient {
private boolean mLinkedToDeathOfRunner;
- private boolean mCancelWithDeferredScreenshot;
-
+ // Whether to try to defer canceling from a stack order change until the next transition
+ private boolean mRequestDeferCancelUntilNextTransition;
+ // Whether to actually defer canceling until the next transition
private boolean mCancelOnNextTransitionStart;
+ // Whether to take a screenshot when handling a deferred cancel
+ private boolean mCancelDeferredWithScreenshot;
/**
* Animates the screenshot of task that used to be controlled by RecentsAnimation.
- * @see {@link #cancelOnNextTransitionStart}
+ * @see {@link #setCancelOnNextTransitionStart}
*/
SurfaceAnimator mRecentScreenshotAnimator;
+ /**
+ * An app transition listener to cancel the recents animation only after the app transition
+ * starts or is canceled.
+ */
final AppTransitionListener mAppTransitionListener = new AppTransitionListener() {
@Override
public int onAppTransitionStartingLocked(int transit, long duration,
long statusBarAnimationStartTime, long statusBarAnimationDuration) {
- onTransitionStart();
- mService.mRoot.getDisplayContent(mDisplayId).mAppTransition
- .unregisterListener(this);
+ continueDeferredCancel();
return 0;
}
+
+ @Override
+ public void onAppTransitionCancelledLocked(int transit) {
+ continueDeferredCancel();
+ }
+
+ private void continueDeferredCancel() {
+ mDisplayContent.mAppTransition.unregisterListener(this);
+ if (mCanceled) {
+ return;
+ }
+
+ if (mCancelOnNextTransitionStart) {
+ mCancelOnNextTransitionStart = false;
+ cancelAnimationWithScreenshot(mCancelDeferredWithScreenshot);
+ }
+ }
};
public interface RecentsAnimationCallbacks {
@@ -202,8 +223,7 @@ public class RecentsAnimationController implements DeathRecipient {
? REORDER_MOVE_TO_TOP
: REORDER_MOVE_TO_ORIGINAL_POSITION,
true /* runSynchronously */, sendUserLeaveHint);
- final DisplayContent dc = mService.mRoot.getDisplayContent(mDisplayId);
- dc.mBoundsAnimationController.setAnimationType(FADE_IN);
+ mDisplayContent.mBoundsAnimationController.setAnimationType(FADE_IN);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -240,8 +260,7 @@ public class RecentsAnimationController implements DeathRecipient {
}
mInputConsumerEnabled = enabled;
- final InputMonitor inputMonitor =
- mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
+ final InputMonitor inputMonitor = mDisplayContent.getInputMonitor();
inputMonitor.updateInputWindowsLw(true /*force*/);
mService.scheduleAnimationLocked();
}
@@ -282,15 +301,23 @@ public class RecentsAnimationController implements DeathRecipient {
}
@Override
+ @Deprecated
public void setCancelWithDeferredScreenshot(boolean screenshot) {
- synchronized (mLock) {
- setCancelWithDeferredScreenshotLocked(screenshot);
+ synchronized (mService.mGlobalLock) {
+ setDeferredCancel(true /* deferred */, screenshot);
+ }
+ }
+
+ @Override
+ public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
+ synchronized (mService.mGlobalLock) {
+ setDeferredCancel(defer, screenshot);
}
}
@Override
public void cleanupScreenshot() {
- synchronized (mLock) {
+ synchronized (mService.mGlobalLock) {
if (mRecentScreenshotAnimator != null) {
mRecentScreenshotAnimator.cancelAnimation();
mRecentScreenshotAnimator = null;
@@ -312,10 +339,7 @@ public class RecentsAnimationController implements DeathRecipient {
mCallbacks = callbacks;
mDisplayId = displayId;
mStatusBar = LocalServices.getService(StatusBarManagerInternal.class);
- }
-
- public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) {
- initialize(mService.mRoot.getDisplayContent(mDisplayId), targetActivityType, recentTaskIds);
+ mDisplayContent = service.mRoot.getDisplayContent(displayId);
}
/**
@@ -323,15 +347,15 @@ public class RecentsAnimationController implements DeathRecipient {
* because it may call cancelAnimation() which needs to properly clean up the controller
* in the window manager.
*/
- @VisibleForTesting
- void initialize(DisplayContent dc, int targetActivityType, SparseBooleanArray recentTaskIds) {
+ public void initialize(int targetActivityType, SparseBooleanArray recentTaskIds) {
mTargetActivityType = targetActivityType;
- dc.mAppTransition.registerListenerLocked(mAppTransitionListener);
+ mDisplayContent.mAppTransition.registerListenerLocked(mAppTransitionListener);
// Make leashes for each of the visible/target tasks and add it to the recents animation to
// be started
- final ArrayList<Task> visibleTasks = dc.getVisibleTasks();
- final TaskStack targetStack = dc.getStack(WINDOWING_MODE_UNDEFINED, targetActivityType);
+ final ArrayList<Task> visibleTasks = mDisplayContent.getVisibleTasks();
+ final TaskStack targetStack = mDisplayContent.getStack(WINDOWING_MODE_UNDEFINED,
+ targetActivityType);
if (targetStack != null) {
for (int i = targetStack.getChildCount() - 1; i >= 0; i--) {
final Task t = targetStack.getChildAt(i);
@@ -365,29 +389,31 @@ public class RecentsAnimationController implements DeathRecipient {
}
// Adjust the wallpaper visibility for the showing target activity
- final AppWindowToken recentsComponentAppToken = dc.getStack(WINDOWING_MODE_UNDEFINED,
- targetActivityType).getTopChild().getTopFullscreenAppToken();
+ final AppWindowToken recentsComponentAppToken =
+ targetStack.getTopChild().getTopFullscreenAppToken();
if (recentsComponentAppToken != null) {
if (DEBUG_RECENTS_ANIMATIONS) Slog.d(TAG, "setHomeApp("
+ recentsComponentAppToken.getName() + ")");
mTargetAppToken = recentsComponentAppToken;
if (recentsComponentAppToken.windowsCanBeWallpaperTarget()) {
- dc.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
- dc.setLayoutNeeded();
+ mDisplayContent.pendingLayoutChanges |= FINISH_LAYOUT_REDO_WALLPAPER;
+ mDisplayContent.setLayoutNeeded();
}
}
// Save the minimized home height
- final TaskStack dockedStack = dc.getSplitScreenPrimaryStackIgnoringVisibility();
- dc.getDockedDividerController().getHomeStackBoundsInDockedMode(
- dc.getConfiguration(),
+ final TaskStack dockedStack = mDisplayContent.getSplitScreenPrimaryStackIgnoringVisibility();
+ mDisplayContent.getDockedDividerController().getHomeStackBoundsInDockedMode(
+ mDisplayContent.getConfiguration(),
dockedStack == null ? DOCKED_INVALID : dockedStack.getDockSide(),
mMinimizedHomeBounds);
mService.mWindowPlacerLocked.performSurfacePlacement();
// Notify that the animation has started
- mStatusBar.onRecentsAnimationStateChanged(true /* running */);
+ if (mStatusBar != null) {
+ mStatusBar.onRecentsAnimationStateChanged(true /* running */);
+ }
}
@VisibleForTesting
@@ -441,8 +467,7 @@ public class RecentsAnimationController implements DeathRecipient {
// Perform layout if it was scheduled before to make sure that we get correct content
// insets for the target app window after a rotation
- final DisplayContent displayContent = mService.mRoot.getDisplayContent(mDisplayId);
- displayContent.performLayout(false /* initial */, false /* updateInputWindows */);
+ mDisplayContent.performLayout(false /* initial */, false /* updateInputWindows */);
final Rect minimizedHomeBounds = mTargetAppToken != null
&& mTargetAppToken.inSplitScreenSecondaryWindowingMode()
@@ -480,9 +505,8 @@ public class RecentsAnimationController implements DeathRecipient {
cancelAnimation(reorderMode, true /* runSynchronously */, false /* screenshot */, reason);
}
- void cancelAnimationWithScreenShot() {
- cancelAnimation(REORDER_KEEP_IN_PLACE, true /* sync */, true /* screenshot */,
- "stackOrderChanged");
+ void cancelAnimationWithScreenshot(boolean screenshot) {
+ cancelAnimation(REORDER_KEEP_IN_PLACE, true /* sync */, screenshot, "stackOrderChanged");
}
private void cancelAnimation(@ReorderMode int reorderMode, boolean runSynchronously,
@@ -496,21 +520,29 @@ public class RecentsAnimationController implements DeathRecipient {
}
mService.mH.removeCallbacks(mFailsafeRunnable);
mCanceled = true;
- try {
- if (screenshot) {
- // Screen shot previous task when next task starts transition.
- final Task task = mPendingAnimations.get(0).mTask;
- screenshotRecentTask(task, reorderMode, runSynchronously);
+
+ if (screenshot) {
+ // Screen shot previous task when next task starts transition and notify the runner.
+ // We will actually finish the animation once the runner calls cleanUpScreenshot().
+ final Task task = mPendingAnimations.get(0).mTask;
+ screenshotRecentTask(task, reorderMode, runSynchronously);
+ try {
mRunner.onAnimationCanceled(true /* deferredWithScreenshot */);
- return;
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to cancel recents animation", e);
+ }
+ } else {
+ // Otherwise, notify the runner and clean up the animation immediately
+ // Note: In the fallback case, this can trigger multiple onAnimationCancel() calls
+ // to the runner if we this actually triggers cancel twice on the caller
+ try {
+ mRunner.onAnimationCanceled(false /* deferredWithScreenshot */);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to cancel recents animation", e);
}
- mRunner.onAnimationCanceled(false /* deferredWithScreenshot */);
- } catch (RemoteException e) {
- Slog.e(TAG, "Failed to cancel recents animation", e);
+ mCallbacks.onAnimationFinished(reorderMode, runSynchronously,
+ false /* sendUserLeaveHint */);
}
- // Clean up and return to the previous app
- mCallbacks.onAnimationFinished(reorderMode, runSynchronously,
- false /* sendUserLeaveHint */);
}
}
@@ -523,27 +555,36 @@ public class RecentsAnimationController implements DeathRecipient {
* screenshot, so that Launcher can still control the leash lifecycle & make the next app
* transition animate smoothly without flickering.
*/
- void cancelOnNextTransitionStart() {
+ void setCancelOnNextTransitionStart() {
mCancelOnNextTransitionStart = true;
}
- void setCancelWithDeferredScreenshotLocked(boolean screenshot) {
- mCancelWithDeferredScreenshot = screenshot;
+ /**
+ * Requests that we attempt to defer the cancel until the next app transition if we are
+ * canceling from a stack order change. If {@param screenshot} is specified, then the system
+ * will replace the contents of the leash with a screenshot, which must be cleaned up when the
+ * runner calls cleanUpScreenshot().
+ */
+ void setDeferredCancel(boolean defer, boolean screenshot) {
+ mRequestDeferCancelUntilNextTransition = defer;
+ mCancelDeferredWithScreenshot = screenshot;
}
- boolean shouldCancelWithDeferredScreenshot() {
- return mCancelWithDeferredScreenshot;
+ /**
+ * @return Whether we should defer the cancel from a stack order change until the next app
+ * transition.
+ */
+ boolean shouldDeferCancelUntilNextTransition() {
+ return mRequestDeferCancelUntilNextTransition;
}
- void onTransitionStart() {
- if (mCanceled) {
- return;
- }
-
- if (mCancelOnNextTransitionStart) {
- mCancelOnNextTransitionStart = false;
- cancelAnimationWithScreenShot();
- }
+ /**
+ * @return Whether we should both defer the cancel from a stack order change until the next
+ * app transition, and also that the deferred cancel should replace the contents of the leash
+ * with a screenshot.
+ */
+ boolean shouldDeferCancelWithScreenshot() {
+ return mRequestDeferCancelUntilNextTransition && mCancelDeferredWithScreenshot;
}
void screenshotRecentTask(Task task, @ReorderMode int reorderMode, boolean runSynchronously) {
@@ -576,6 +617,7 @@ public class RecentsAnimationController implements DeathRecipient {
// Clear any pending failsafe runnables
mService.mH.removeCallbacks(mFailsafeRunnable);
+ mDisplayContent.mAppTransition.unregisterListener(mAppTransitionListener);
// Clear references to the runner
unlinkToDeathOfRunner();
@@ -589,21 +631,22 @@ public class RecentsAnimationController implements DeathRecipient {
}
// Update the input windows after the animation is complete
- final InputMonitor inputMonitor =
- mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
+ final InputMonitor inputMonitor = mDisplayContent.getInputMonitor();
inputMonitor.updateInputWindowsLw(true /*force*/);
// We have deferred all notifications to the target app as a part of the recents animation,
// so if we are actually transitioning there, notify again here
if (mTargetAppToken != null) {
if (reorderMode == REORDER_MOVE_TO_TOP || reorderMode == REORDER_KEEP_IN_PLACE) {
- mService.mRoot.getDisplayContent(mDisplayId)
- .mAppTransition.notifyAppTransitionFinishedLocked(mTargetAppToken.token);
+ mDisplayContent.mAppTransition.notifyAppTransitionFinishedLocked(
+ mTargetAppToken.token);
}
}
// Notify that the animation has ended
- mStatusBar.onRecentsAnimationStateChanged(false /* running */);
+ if (mStatusBar != null) {
+ mStatusBar.onRecentsAnimationStateChanged(false /* running */);
+ }
}
void scheduleFailsafe() {
@@ -630,8 +673,7 @@ public class RecentsAnimationController implements DeathRecipient {
synchronized (mService.getWindowManagerLock()) {
// Clear associated input consumers on runner death
- final InputMonitor inputMonitor =
- mService.mRoot.getDisplayContent(mDisplayId).getInputMonitor();
+ final InputMonitor inputMonitor = mDisplayContent.getInputMonitor();
inputMonitor.destroyInputConsumer(INPUT_CONSUMER_RECENTS_ANIMATION);
}
}
@@ -827,5 +869,11 @@ public class RecentsAnimationController implements DeathRecipient {
pw.print(innerPrefix); pw.println("mSplitScreenMinimized=" + mSplitScreenMinimized);
pw.print(innerPrefix); pw.println("mTargetAppToken=" + mTargetAppToken);
pw.print(innerPrefix); pw.println("isTargetOverWallpaper=" + isTargetOverWallpaper());
+ pw.print(innerPrefix); pw.println("mRequestDeferCancelUntilNextTransition="
+ + mRequestDeferCancelUntilNextTransition);
+ pw.print(innerPrefix); pw.println("mCancelOnNextTransitionStart="
+ + mCancelOnNextTransitionStart);
+ pw.print(innerPrefix); pw.println("mCancelDeferredWithScreenshot="
+ + mCancelDeferredWithScreenshot);
}
}
diff --git a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
index dc62877bca8d..b94a7dc781e8 100644
--- a/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
+++ b/services/core/java/com/android/server/wm/ScreenRotationAnimation.java
@@ -937,6 +937,7 @@ class ScreenRotationAnimation {
}
}
+ t.setEarlyWakeup();
setSnapshotTransform(t, mSnapshotFinalMatrix, mExitTransformation.getAlpha());
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 23515d8619dd..882f41152886 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -66,6 +66,7 @@ import static com.android.server.am.TaskRecordProto.ORIG_ACTIVITY;
import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
import static com.android.server.am.TaskRecordProto.STACK_ID;
+import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REMOVED;
import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
@@ -1419,7 +1420,7 @@ class TaskRecord extends ConfigurationContainer {
--activityNdx;
--numActivities;
} else if (r.finishActivityLocked(Activity.RESULT_CANCELED, null,
- reason, false /* oomAdj */, pauseImmediately)) {
+ reason, false /* oomAdj */, pauseImmediately) == FINISH_RESULT_REMOVED) {
--activityNdx;
--numActivities;
}
@@ -1474,7 +1475,7 @@ class TaskRecord extends ConfigurationContainer {
ret.updateOptionsLocked(opts);
}
if (r.finishActivityLocked(Activity.RESULT_CANCELED, null /* resultData */,
- "clear-task-stack", false /* oomAdj */)) {
+ "clear-task-stack", false /* oomAdj */) == FINISH_RESULT_REMOVED) {
--activityNdx;
--numActivities;
}
diff --git a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
index 1a571683de34..143543e8c74b 100644
--- a/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
+++ b/services/core/java/com/android/server/wm/TaskScreenshotAnimatable.java
@@ -28,7 +28,7 @@ import android.view.SurfaceSession;
* Class used by {@link RecentsAnimationController} to create a surface control with taking
* screenshot of task when canceling recents animation.
*
- * @see {@link RecentsAnimationController#cancelOnNextTransitionStart}
+ * @see {@link RecentsAnimationController#setCancelOnNextTransitionStart}
*/
class TaskScreenshotAnimatable implements SurfaceAnimator.Animatable {
private static final String TAG = "TaskScreenshotAnim";
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index eb45e73d47a4..79367a050d46 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -321,7 +321,9 @@ public class TaskStack extends WindowContainer<Task> implements
*/
private void setAnimationFinalBounds(Rect sourceHintBounds, Rect destBounds,
boolean toFullscreen) {
- mBoundsAnimatingRequested = true;
+ if (mAnimationType == BoundsAnimationController.BOUNDS) {
+ mBoundsAnimatingRequested = true;
+ }
mBoundsAnimatingToFullscreen = toFullscreen;
if (destBounds != null) {
mBoundsAnimationTarget.set(destBounds);
@@ -1586,8 +1588,10 @@ public class TaskStack extends WindowContainer<Task> implements
return false;
}
- mBoundsAnimatingRequested = false;
- mBoundsAnimating = true;
+ if (animationType == BoundsAnimationController.BOUNDS) {
+ mBoundsAnimatingRequested = false;
+ mBoundsAnimating = true;
+ }
mAnimationType = animationType;
// If we are changing UI mode, as in the PiP to fullscreen
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 636f4e6d09d0..05cfbd4e39d9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -511,4 +511,9 @@ public abstract class WindowManagerInternal {
*/
public abstract void removeNonHighRefreshRatePackage(@NonNull String packageName);
+ /**
+ * Checks if this display is touchable.
+ */
+ public abstract boolean isTouchableDisplay(int displayId);
+
}
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 70e446c51c43..fbdc54a2435b 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -7455,6 +7455,17 @@ public class WindowManagerService extends IWindowManager.Stub
.removeNonHighRefreshRatePackage(packageName));
}
}
+
+ @Override
+ public boolean isTouchableDisplay(int displayId) {
+ synchronized (mGlobalLock) {
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ final Configuration configuration =
+ displayContent != null ? displayContent.getConfiguration() : null;
+ return configuration != null
+ && configuration.touchscreen == Configuration.TOUCHSCREEN_FINGER;
+ }
+ }
}
void registerAppFreezeListener(AppFreezeListener listener) {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 3ba3280be7bb..41840a4c531c 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -729,12 +729,7 @@ class WindowStateAnimator {
if (!mService.mLimitedAlphaCompositing
|| (!PixelFormat.formatHasAlpha(mWin.mAttrs.format)
|| (mWin.isIdentityMatrix(mDsDx, mDtDx, mDtDy, mDsDy)))) {
- //Slog.i(TAG_WM, "Applying alpha transform");
- if (screenAnimation) {
- mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
- }
- } else {
- //Slog.i(TAG_WM, "Not applying alpha transform");
+ mShownAlpha *= screenRotationAnimation.getEnterTransformation().getAlpha();
}
if ((DEBUG_ANIM || WindowManagerService.localLOGV)
@@ -1299,7 +1294,7 @@ class WindowStateAnimator {
mSurfaceController.mSurfaceControl);
}
- mPostDrawTransaction.apply();
+ SurfaceControl.mergeToGlobalTransaction(mPostDrawTransaction);
return true;
}
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index 1c8c46c74002..466ca9315f6f 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -41,7 +41,6 @@
#include <utils/Looper.h>
#include <utils/threads.h>
#include <utils/Trace.h>
-#include <utils/SortedVector.h>
#include <binder/IServiceManager.h>
@@ -307,7 +306,7 @@ private:
wp<PointerController> pointerController;
// Input devices to be disabled
- SortedVector<int32_t> disabledInputDevices;
+ std::set<int32_t> disabledInputDevices;
// Associated Pointer controller display.
int32_t pointerDisplayId;
@@ -898,13 +897,13 @@ void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled)
{ // acquire lock
AutoMutex _l(mLock);
- ssize_t index = mLocked.disabledInputDevices.indexOf(deviceId);
- bool currentlyEnabled = index < 0;
+ auto it = mLocked.disabledInputDevices.find(deviceId);
+ bool currentlyEnabled = it == mLocked.disabledInputDevices.end();
if (!enabled && currentlyEnabled) {
- mLocked.disabledInputDevices.add(deviceId);
+ mLocked.disabledInputDevices.insert(deviceId);
}
if (enabled && !currentlyEnabled) {
- mLocked.disabledInputDevices.remove(deviceId);
+ mLocked.disabledInputDevices.erase(deviceId);
}
} // release lock
diff --git a/services/core/xsd/Android.bp b/services/core/xsd/Android.bp
index 98e4343e6e57..8b2cbbde2db8 100644
--- a/services/core/xsd/Android.bp
+++ b/services/core/xsd/Android.bp
@@ -4,3 +4,11 @@ xsd_config {
api_dir: "schema",
package_name: "com.android.server.pm.permission.configfile",
}
+
+
+xsd_config {
+ name: "platform-compat-config",
+ srcs: ["platform-compat-config.xsd"],
+ api_dir: "platform-compat-schema",
+ package_name: "com.android.server.compat.config",
+}
diff --git a/services/core/xsd/platform-compat-config.xsd b/services/core/xsd/platform-compat-config.xsd
new file mode 100644
index 000000000000..ee39e507aff1
--- /dev/null
+++ b/services/core/xsd/platform-compat-config.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright (C) 2019 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<!-- This defines the format of the XML file generated by
+ ~ com.android.compat.annotation.ChangeIdProcessor annotation processor (from
+ ~ tools/platform-compat), and is parsed in com/android/server/compat/CompatConfig.java.
+-->
+<xs:schema version="2.0" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:complexType name="change">
+ <xs:simpleContent>
+ <xs:extension base="xs:string">
+ <xs:attribute type="xs:long" name="id" use="required"/>
+ <xs:attribute type="xs:string" name="name" use="required"/>
+ <xs:attribute type="xs:boolean" name="disabled"/>
+ <xs:attribute type="xs:int" name="enableAfterTargetSdk"/>
+ </xs:extension>
+ </xs:simpleContent>
+ </xs:complexType>
+
+ <xs:element name="config">
+ <xs:complexType>
+ <xs:sequence>
+ <xs:element name="compat-change" type="change" maxOccurs="unbounded"
+ minOccurs="0"/>
+ </xs:sequence>
+ </xs:complexType>
+ <xs:unique name="UniqueId">
+ <xs:selector xpath="compat-change" />
+ <xs:field xpath="@id" />
+ </xs:unique>
+ </xs:element>
+</xs:schema>
+
+
+
+
diff --git a/services/core/xsd/platform-compat-schema/current.txt b/services/core/xsd/platform-compat-schema/current.txt
new file mode 100644
index 000000000000..84567851da2c
--- /dev/null
+++ b/services/core/xsd/platform-compat-schema/current.txt
@@ -0,0 +1,31 @@
+// Signature format: 2.0
+package com.android.server.compat.config {
+
+ public class Change {
+ ctor public Change();
+ method public boolean getDisabled();
+ method public int getEnableAfterTargetSdk();
+ method public long getId();
+ method public String getName();
+ method public String getValue();
+ method public void setDisabled(boolean);
+ method public void setEnableAfterTargetSdk(int);
+ method public void setId(long);
+ method public void setName(String);
+ method public void setValue(String);
+ }
+
+ public class Config {
+ ctor public Config();
+ method public java.util.List<com.android.server.compat.config.Change> getCompatChange();
+ }
+
+ public class XmlParser {
+ ctor public XmlParser();
+ method public static com.android.server.compat.config.Config read(java.io.InputStream) throws javax.xml.datatype.DatatypeConfigurationException, java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static String readText(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ method public static void skip(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
+ }
+
+}
+
diff --git a/services/core/xsd/platform-compat-schema/last_current.txt b/services/core/xsd/platform-compat-schema/last_current.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/services/core/xsd/platform-compat-schema/last_current.txt
diff --git a/services/core/xsd/platform-compat-schema/last_removed.txt b/services/core/xsd/platform-compat-schema/last_removed.txt
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/services/core/xsd/platform-compat-schema/last_removed.txt
diff --git a/services/core/xsd/platform-compat-schema/removed.txt b/services/core/xsd/platform-compat-schema/removed.txt
new file mode 100644
index 000000000000..d802177e249b
--- /dev/null
+++ b/services/core/xsd/platform-compat-schema/removed.txt
@@ -0,0 +1 @@
+// Signature format: 2.0
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index a04875f1a283..9fe44dc7b2f0 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -87,6 +87,7 @@ 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;
+import com.android.server.compat.PlatformCompat;
import com.android.server.connectivity.IpConnectivityMetrics;
import com.android.server.contentcapture.ContentCaptureManagerInternal;
import com.android.server.coverage.CoverageService;
@@ -1098,6 +1099,11 @@ public final class SystemServer {
t.traceBegin("SignedConfigService");
SignedConfigService.registerUpdateReceiver(mSystemContext);
t.traceEnd();
+
+ t.traceBegin("PlatformCompat");
+ ServiceManager.addService("platform_compat", new PlatformCompat(context));
+ t.traceEnd();
+
} catch (RuntimeException e) {
Slog.e("System", "******************************************");
Slog.e("System", "************ Failure starting core service", e);
diff --git a/services/robotests/Android.bp b/services/robotests/Android.bp
new file mode 100644
index 000000000000..3ce514a56b60
--- /dev/null
+++ b/services/robotests/Android.bp
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//##################################################################
+// FrameworksServicesLib app just for Robolectric test target #
+//##################################################################
+
+android_app {
+ name: "FrameworksServicesLib",
+ platform_apis: true,
+
+ privileged: true,
+
+ static_libs: [
+ "services.core",
+ "services.net",
+ ],
+}
+
+//##################################################################
+// FrameworksServicesLib Robolectric test target. #
+//##################################################################
+android_robolectric_test {
+ name: "FrameworksServicesRoboTests",
+
+ srcs: ["src/**/*.java"],
+
+ java_resource_dirs: ["config"],
+
+ // Include the testing libraries
+ libs: [
+ "platform-test-annotations",
+ "testng",
+ ],
+
+ instrumentation_for: "FrameworksServicesLib",
+}
+
+filegroup {
+ name: "FrameworksServicesRoboShadows",
+ srcs: ["src/com/android/server/testing/shadows/**/*.java"],
+}
diff --git a/services/robotests/Android.mk b/services/robotests/Android.mk
deleted file mode 100644
index 0cf0d3402dea..000000000000
--- a/services/robotests/Android.mk
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (C) 2016 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-###################################################################
-# FrameworksServicesLib app just for Robolectric test target #
-###################################################################
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := FrameworksServicesLib
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- services.core \
- services.net
-
-include $(BUILD_PACKAGE)
-
-###################################################################
-# FrameworksServicesLib Robolectric test target. #
-###################################################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := FrameworksServicesRoboTests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-LOCAL_RESOURCE_DIR := \
- $(LOCAL_PATH)/res
-
-LOCAL_JAVA_RESOURCE_DIRS := config
-
-# Include the testing libraries
-LOCAL_JAVA_LIBRARIES := \
- platform-test-annotations \
- robolectric_android-all-stub \
- Robolectric_all-target \
- mockito-robolectric-prebuilt \
- truth-prebuilt \
- testng
-
-LOCAL_INSTRUMENTATION_FOR := FrameworksServicesLib
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-###################################################################
-# FrameworksServicesLib runner target to run the previous target. #
-###################################################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := RunFrameworksServicesRoboTests
-
-LOCAL_JAVA_LIBRARIES := \
- FrameworksServicesRoboTests \
- platform-test-annotations \
- robolectric_android-all-stub \
- Robolectric_all-target \
- mockito-robolectric-prebuilt \
- truth-prebuilt \
- testng
-
-LOCAL_TEST_PACKAGE := FrameworksServicesLib
-
-LOCAL_ROBOTEST_FILES := $(call find-files-in-subdirs,$(LOCAL_PATH)/src,*Test.java,.)
-
-include external/robolectric-shadows/run_robotests.mk
-
-###################################################################
-# include subdir Android.mk files
-###################################################################
-include $(CLEAR_VARS)
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/services/robotests/AndroidManifest.xml b/services/robotests/AndroidManifest.xml
new file mode 100644
index 000000000000..828c8fade6fc
--- /dev/null
+++ b/services/robotests/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ coreApp="true"
+ package="com.android.server.robotests">
+
+ <application/>
+
+</manifest>
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
new file mode 100644
index 000000000000..9d384e90d253
--- /dev/null
+++ b/services/robotests/backup/Android.bp
@@ -0,0 +1,53 @@
+// 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.
+
+//##################################################################
+// BackupFrameworksServicesLib app just for Robolectric test target #
+//##################################################################
+android_app {
+ name: "BackupFrameworksServicesLib",
+ platform_apis: true,
+
+ privileged: true,
+
+ static_libs: [
+ "bmgr",
+ "bu",
+ "services.backup",
+ "services.core",
+ "services.net",
+ ],
+}
+
+//##################################################################
+// BackupFrameworksServicesLib Robolectric test target. #
+//##################################################################
+android_robolectric_test {
+ name: "BackupFrameworksServicesRoboTests",
+ srcs: [
+ "src/**/*.java",
+ ":FrameworksServicesRoboShadows",
+ ],
+
+ java_resource_dirs: ["config"],
+
+ // Include the testing libraries
+ libs: [
+ "platform-test-annotations",
+ "testng",
+ ],
+
+ instrumentation_for: "BackupFrameworksServicesLib",
+
+}
diff --git a/services/robotests/backup/Android.mk b/services/robotests/backup/Android.mk
deleted file mode 100644
index bd4ebbd393fa..000000000000
--- a/services/robotests/backup/Android.mk
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) 2018 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-
-###################################################################
-# BackupFrameworksServicesLib app just for Robolectric test target #
-###################################################################
-include $(CLEAR_VARS)
-
-LOCAL_PACKAGE_NAME := BackupFrameworksServicesLib
-LOCAL_PRIVATE_PLATFORM_APIS := true
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_PRIVILEGED_MODULE := true
-
-LOCAL_STATIC_JAVA_LIBRARIES := \
- bmgr \
- bu \
- services.backup \
- services.core \
- services.net
-
-include $(BUILD_PACKAGE)
-
-###################################################################
-# BackupFrameworksServicesLib Robolectric test target. #
-###################################################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := BackupFrameworksServicesRoboTests
-
-LOCAL_SRC_FILES := $(call all-java-files-under, src) \
- $(call all-java-files-under, ../src/com/android/server/testing/shadows)
-
-LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
-
-LOCAL_JAVA_RESOURCE_DIRS := config
-
-# Include the testing libraries
-LOCAL_JAVA_LIBRARIES := \
- platform-test-annotations \
- robolectric_android-all-stub \
- Robolectric_all-target \
- mockito-robolectric-prebuilt \
- truth-prebuilt \
- testng
-
-LOCAL_INSTRUMENTATION_FOR := BackupFrameworksServicesLib
-
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-###################################################################
-# BackupFrameworksServicesLib runner target to run the previous target. #
-###################################################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := RunBackupFrameworksServicesRoboTests
-
-LOCAL_JAVA_LIBRARIES := \
- BackupFrameworksServicesRoboTests \
- platform-test-annotations \
- robolectric_android-all-stub \
- Robolectric_all-target \
- mockito-robolectric-prebuilt \
- truth-prebuilt \
- testng
-
-LOCAL_TEST_PACKAGE := BackupFrameworksServicesLib
-
-include external/robolectric-shadows/run_robotests.mk
diff --git a/services/robotests/backup/AndroidManifest.xml b/services/robotests/backup/AndroidManifest.xml
new file mode 100644
index 000000000000..09323782a228
--- /dev/null
+++ b/services/robotests/backup/AndroidManifest.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ coreApp="true"
+ package="com.android.server.backup.robotests">
+
+ <application/>
+
+</manifest>
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
index ba2959f7f965..2f9f9bbecbdf 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityServiceConnectionTest.java
@@ -23,21 +23,25 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.accessibilityservice.AccessibilityServiceInfo;
+import android.accessibilityservice.GestureDescription;
import android.accessibilityservice.IAccessibilityServiceClient;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.view.Display;
import com.android.server.wm.WindowManagerInternal;
@@ -50,6 +54,7 @@ import org.mockito.MockitoAnnotations;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
+import java.util.List;
/**
@@ -73,6 +78,9 @@ public class AccessibilityServiceConnectionTest {
@Mock GlobalActionPerformer mMockGlobalActionPerformer;
@Mock KeyEventDispatcher mMockKeyEventDispatcher;
@Mock MagnificationController mMockMagnificationController;
+ @Mock IBinder mMockIBinder;
+ @Mock IAccessibilityServiceClient mMockServiceClient;
+ @Mock MotionEventInjector mMockMotionEventInjector;
MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
@@ -82,15 +90,22 @@ public class AccessibilityServiceConnectionTest {
when(mMockSystemSupport.getKeyEventDispatcher()).thenReturn(mMockKeyEventDispatcher);
when(mMockSystemSupport.getMagnificationController())
.thenReturn(mMockMagnificationController);
+ when(mMockSystemSupport.getMotionEventInjectorForDisplayLocked(
+ Display.DEFAULT_DISPLAY)).thenReturn(mMockMotionEventInjector);
when(mMockServiceInfo.getResolveInfo()).thenReturn(mMockResolveInfo);
mMockResolveInfo.serviceInfo = mock(ServiceInfo.class);
mMockResolveInfo.serviceInfo.applicationInfo = mock(ApplicationInfo.class);
+ when(mMockIBinder.queryLocalInterface(any())).thenReturn(mMockServiceClient);
+ when(mMockWindowManagerInternal.isTouchableDisplay(Display.DEFAULT_DISPLAY)).thenReturn(
+ true);
+
mConnection = new AccessibilityServiceConnection(mMockUserState, mMockContext,
COMPONENT_NAME, mMockServiceInfo, SERVICE_ID, mHandler, new Object(),
mMockSecurityPolicy, mMockSystemSupport, mMockWindowManagerInternal,
mMockGlobalActionPerformer, mMockA11yWindowManager);
+ when(mMockSecurityPolicy.canPerformGestures(mConnection)).thenReturn(true);
}
@After
@@ -115,25 +130,23 @@ public class AccessibilityServiceConnectionTest {
@Test
public void bindConnectUnbind_linksAndUnlinksToServiceDeath() throws RemoteException {
- IBinder mockBinder = mock(IBinder.class);
setServiceBinding(COMPONENT_NAME);
mConnection.bindLocked();
- mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
- verify(mockBinder).linkToDeath(eq(mConnection), anyInt());
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
+ verify(mMockIBinder).linkToDeath(eq(mConnection), anyInt());
mConnection.unbindLocked();
- verify(mockBinder).unlinkToDeath(eq(mConnection), anyInt());
+ verify(mMockIBinder).unlinkToDeath(eq(mConnection), anyInt());
}
@Test
public void connectedServiceCrashedAndRestarted_crashReportedInServiceInfo() {
- IBinder mockBinder = mock(IBinder.class);
setServiceBinding(COMPONENT_NAME);
mConnection.bindLocked();
- mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
assertFalse(mConnection.getServiceInfo().crashed);
mConnection.binderDied();
assertTrue(mConnection.getServiceInfo().crashed);
- mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
mHandler.sendAllMessages();
assertFalse(mConnection.getServiceInfo().crashed);
}
@@ -145,10 +158,9 @@ public class AccessibilityServiceConnectionTest {
@Test
public void binderDied_keysGetFlushed() {
- IBinder mockBinder = mock(IBinder.class);
setServiceBinding(COMPONENT_NAME);
mConnection.bindLocked();
- mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
mConnection.binderDied();
assertTrue(mConnection.getServiceInfo().crashed);
verify(mMockKeyEventDispatcher).flush(mConnection);
@@ -157,17 +169,63 @@ public class AccessibilityServiceConnectionTest {
@Test
public void connectedService_notInEnabledServiceList_doNotInitClient()
throws RemoteException {
- IBinder mockBinder = mock(IBinder.class);
- IAccessibilityServiceClient mockClient = mock(IAccessibilityServiceClient.class);
- when(mockBinder.queryLocalInterface(any())).thenReturn(mockClient);
when(mMockUserState.getEnabledServicesLocked())
.thenReturn(Collections.emptySet());
setServiceBinding(COMPONENT_NAME);
mConnection.bindLocked();
- mConnection.onServiceConnected(COMPONENT_NAME, mockBinder);
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
mHandler.sendAllMessages();
verify(mMockSystemSupport, times(2)).onClientChangeLocked(false);
- verify(mockClient, times(0)).init(any(), anyInt(), any());
+ verify(mMockServiceClient, times(0)).init(any(), anyInt(), any());
+ }
+
+ @Test
+ public void sendGesture_touchableDisplay_injectEvents()
+ throws RemoteException {
+ setServiceBinding(COMPONENT_NAME);
+ mConnection.bindLocked();
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
+
+ ParceledListSlice parceledListSlice = mock(ParceledListSlice.class);
+ List<GestureDescription.GestureStep> gestureSteps = mock(List.class);
+ when(parceledListSlice.getList()).thenReturn(gestureSteps);
+ mConnection.dispatchGesture(0, parceledListSlice, Display.DEFAULT_DISPLAY);
+
+ verify(mMockMotionEventInjector).injectEvents(gestureSteps, mMockServiceClient, 0);
+ }
+
+ @Test
+ public void sendGesture_untouchableDisplay_performGestureResultFailed()
+ throws RemoteException {
+ when(mMockWindowManagerInternal.isTouchableDisplay(Display.DEFAULT_DISPLAY)).thenReturn(
+ false);
+ setServiceBinding(COMPONENT_NAME);
+ mConnection.bindLocked();
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
+
+ ParceledListSlice parceledListSlice = mock(ParceledListSlice.class);
+ List<GestureDescription.GestureStep> gestureSteps = mock(List.class);
+ when(parceledListSlice.getList()).thenReturn(gestureSteps);
+ mConnection.dispatchGesture(0, parceledListSlice, Display.DEFAULT_DISPLAY);
+
+ verify(mMockMotionEventInjector, never()).injectEvents(gestureSteps, mMockServiceClient, 0);
+ verify(mMockServiceClient).onPerformGestureResult(0, false);
}
+
+ @Test
+ public void sendGesture_invalidDisplay_performGestureResultFailed()
+ throws RemoteException {
+ setServiceBinding(COMPONENT_NAME);
+ mConnection.bindLocked();
+ mConnection.onServiceConnected(COMPONENT_NAME, mMockIBinder);
+
+ ParceledListSlice parceledListSlice = mock(ParceledListSlice.class);
+ List<GestureDescription.GestureStep> gestureSteps = mock(List.class);
+ when(parceledListSlice.getList()).thenReturn(gestureSteps);
+ mConnection.dispatchGesture(0, parceledListSlice, Display.INVALID_DISPLAY);
+
+ verify(mMockServiceClient).onPerformGestureResult(0, false);
+ }
+
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
new file mode 100644
index 000000000000..470d4fa92833
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.content.pm.PackageParser;
+
+import com.android.internal.util.ArrayUtils;
+
+class PackageBuilder {
+ final PackageParser.Package mPkg;
+
+ PackageBuilder(String packageName) {
+ mPkg = new PackageParser.Package(packageName);
+ }
+
+ PackageBuilder setApplicationInfoCodePath(String codePath) {
+ mPkg.applicationInfo.setCodePath(codePath);
+ return this;
+ }
+
+ PackageBuilder setApplicationInfoResourcePath(String resourcePath) {
+ mPkg.applicationInfo.setResourcePath(resourcePath);
+ return this;
+ }
+
+ PackageBuilder setCodePath(String codePath) {
+ mPkg.codePath = codePath;
+ return this;
+ }
+
+ PackageBuilder setBaseCodePath(String baseCodePath) {
+ mPkg.baseCodePath = baseCodePath;
+ return this;
+ }
+
+ PackageBuilder addUsesStaticLibrary(String name, long version) {
+ mPkg.usesStaticLibraries = ArrayUtils.add(mPkg.usesStaticLibraries, name);
+ mPkg.usesStaticLibrariesVersions =
+ ArrayUtils.appendLong(mPkg.usesStaticLibrariesVersions, version);
+ return this;
+ }
+
+ PackageBuilder setApplicationInfoNativeLibraryRootDir(String dir) {
+ mPkg.applicationInfo.nativeLibraryRootDir = dir;
+ return this;
+ }
+
+ PackageBuilder setStaticSharedLib(String staticSharedLibName, long staticSharedLibVersion) {
+ mPkg.staticSharedLibVersion = staticSharedLibVersion;
+ mPkg.staticSharedLibName = staticSharedLibName;
+ return this;
+ }
+
+ PackageBuilder setManifestPackageName(String manifestPackageName) {
+ mPkg.manifestPackageName = manifestPackageName;
+ return this;
+ }
+
+ PackageBuilder setVersionCodeMajor(int versionCodeMajor) {
+ mPkg.mVersionCodeMajor = versionCodeMajor;
+ return this;
+ }
+
+ PackageBuilder setVersionCode(int versionCode) {
+ mPkg.mVersionCode = versionCode;
+ return this;
+ }
+
+ PackageBuilder addSplitCodePath(String splitCodePath) {
+ mPkg.splitCodePaths =
+ ArrayUtils.appendElement(String.class, mPkg.splitCodePaths, splitCodePath);
+ return this;
+ }
+
+ PackageBuilder setApplicationInfoVolumeUuid(String volumeUuid) {
+ mPkg.applicationInfo.volumeUuid = volumeUuid;
+ return this;
+ }
+
+ PackageBuilder addLibraryName(String libraryName) {
+ mPkg.libraryNames = ArrayUtils.add(mPkg.libraryNames, libraryName);
+ return this;
+ }
+
+ PackageBuilder setRealPackageName(String realPackageName) {
+ mPkg.mRealPackage = realPackageName;
+ return this;
+ }
+
+ PackageBuilder setCpuAbiOVerride(String cpuAbiOverride) {
+ mPkg.cpuAbiOverride = cpuAbiOverride;
+ return this;
+ }
+
+ PackageBuilder addPermissionRequest(String permissionName) {
+ mPkg.requestedPermissions.add(permissionName);
+ return this;
+ }
+
+ PackageParser.Package build() {
+ return mPkg;
+ }
+
+ public PackageBuilder addApplicationInfoFlag(int flag) {
+ mPkg.applicationInfo.flags |= flag;
+ return this;
+ }
+}
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 13a8eb1d7fad..e33d8ca66ed0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -22,6 +22,7 @@ import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
@@ -557,6 +558,9 @@ public class PackageParserTest {
pkg.mRequiredForAllUsers = true;
pkg.visibleToInstantApps = true;
pkg.use32bitAbi = true;
+ pkg.mForceQueryable = true;
+ pkg.mQueriesPackages = new ArrayList<>(Arrays.asList("foo27"));
+ pkg.mQueriesIntents = new ArrayList<>(Arrays.asList(new Intent("foo28")));
}
private static void assertAllFieldsExist(PackageParser.Package pkg) throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
new file mode 100644
index 000000000000..b42cfd8be4a6
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.content.pm.PackageUserState;
+import android.util.SparseArray;
+
+import java.io.File;
+import java.util.List;
+
+class PackageSettingBuilder {
+ private String mName;
+ private String mRealName;
+ private String mCodePath;
+ private String mResourcePath;
+ private String mLegacyNativeLibraryPathString;
+ private String mPrimaryCpuAbiString;
+ private String mSecondaryCpuAbiString;
+ private String mCpuAbiOverrideString;
+ private long mPVersionCode;
+ private int mPkgFlags;
+ private int mPrivateFlags;
+ private String mParentPackageName;
+ private List<String> mChildPackageNames;
+ private int mSharedUserId;
+ private String[] mUsesStaticLibraries;
+ private long[] mUsesStaticLibrariesVersions;
+ private String mVolumeUuid;
+ private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
+
+ public PackageSettingBuilder setName(String name) {
+ this.mName = name;
+ return this;
+ }
+
+ public PackageSettingBuilder setRealName(String realName) {
+ this.mRealName = realName;
+ return this;
+ }
+
+ public PackageSettingBuilder setCodePath(String codePath) {
+ this.mCodePath = codePath;
+ return this;
+ }
+
+ public PackageSettingBuilder setResourcePath(String resourcePath) {
+ this.mResourcePath = resourcePath;
+ return this;
+ }
+
+ public PackageSettingBuilder setLegacyNativeLibraryPathString(
+ String legacyNativeLibraryPathString) {
+ this.mLegacyNativeLibraryPathString = legacyNativeLibraryPathString;
+ return this;
+ }
+
+ public PackageSettingBuilder setPrimaryCpuAbiString(String primaryCpuAbiString) {
+ this.mPrimaryCpuAbiString = primaryCpuAbiString;
+ return this;
+ }
+
+ public PackageSettingBuilder setSecondaryCpuAbiString(String secondaryCpuAbiString) {
+ this.mSecondaryCpuAbiString = secondaryCpuAbiString;
+ return this;
+ }
+
+ public PackageSettingBuilder setCpuAbiOverrideString(String cpuAbiOverrideString) {
+ this.mCpuAbiOverrideString = cpuAbiOverrideString;
+ return this;
+ }
+
+ public PackageSettingBuilder setPVersionCode(long pVersionCode) {
+ this.mPVersionCode = pVersionCode;
+ return this;
+ }
+
+ public PackageSettingBuilder setPkgFlags(int pkgFlags) {
+ this.mPkgFlags = pkgFlags;
+ return this;
+ }
+
+ public PackageSettingBuilder setPrivateFlags(int privateFlags) {
+ this.mPrivateFlags = privateFlags;
+ return this;
+ }
+
+ public PackageSettingBuilder setParentPackageName(String parentPackageName) {
+ this.mParentPackageName = parentPackageName;
+ return this;
+ }
+
+ public PackageSettingBuilder setChildPackageNames(List<String> childPackageNames) {
+ this.mChildPackageNames = childPackageNames;
+ return this;
+ }
+
+ public PackageSettingBuilder setSharedUserId(int sharedUserId) {
+ this.mSharedUserId = sharedUserId;
+ return this;
+ }
+
+ public PackageSettingBuilder setUsesStaticLibraries(String[] usesStaticLibraries) {
+ this.mUsesStaticLibraries = usesStaticLibraries;
+ return this;
+ }
+
+ public PackageSettingBuilder setUsesStaticLibrariesVersions(
+ long[] usesStaticLibrariesVersions) {
+ this.mUsesStaticLibrariesVersions = usesStaticLibrariesVersions;
+ return this;
+ }
+
+ public PackageSettingBuilder setVolumeUuid(String volumeUuid) {
+ this.mVolumeUuid = volumeUuid;
+ return this;
+ }
+
+ public PackageSettingBuilder setInstantAppUserState(int userId, boolean isInstant) {
+ if (mUserStates.indexOfKey(userId) < 0) {
+ mUserStates.put(userId, new PackageUserState());
+ }
+ mUserStates.get(userId).instantApp = isInstant;
+ return this;
+ }
+
+ public PackageSetting build() {
+ final PackageSetting packageSetting = new PackageSetting(mName, mRealName,
+ new File(mCodePath), new File(mResourcePath),
+ mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, mSecondaryCpuAbiString,
+ mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mParentPackageName,
+ mChildPackageNames, mSharedUserId, mUsesStaticLibraries,
+ mUsesStaticLibrariesVersions);
+ packageSetting.volumeUuid = this.mVolumeUuid;
+ for (int i = 0; i < mUserStates.size(); i++) {
+ packageSetting.setUserState(mUserStates.keyAt(i), mUserStates.valueAt(i));
+ }
+ return packageSetting;
+
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
new file mode 100644
index 000000000000..34a3f860496a
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.content.pm.PackageParser;
+import android.os.UserHandle;
+
+class ScanRequestBuilder {
+ private final PackageParser.Package mPkg;
+ private PackageParser.Package mOldPkg;
+ private SharedUserSetting mSharedUserSetting;
+ private PackageSetting mPkgSetting;
+ private PackageSetting mDisabledPkgSetting;
+ private PackageSetting mOriginalPkgSetting;
+ private String mRealPkgName;
+ private int mParseFlags;
+ private int mScanFlags;
+ private UserHandle mUser;
+ private boolean mIsPlatformPackage;
+
+ ScanRequestBuilder(PackageParser.Package pkg) {
+ this.mPkg = pkg;
+ }
+
+ public ScanRequestBuilder setOldPkg(PackageParser.Package oldPkg) {
+ this.mOldPkg = oldPkg;
+ return this;
+ }
+
+ public ScanRequestBuilder setSharedUserSetting(SharedUserSetting sharedUserSetting) {
+ this.mSharedUserSetting = sharedUserSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setPkgSetting(PackageSetting pkgSetting) {
+ this.mPkgSetting = pkgSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setDisabledPkgSetting(PackageSetting disabledPkgSetting) {
+ this.mDisabledPkgSetting = disabledPkgSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setOriginalPkgSetting(PackageSetting originalPkgSetting) {
+ this.mOriginalPkgSetting = originalPkgSetting;
+ return this;
+ }
+
+ public ScanRequestBuilder setRealPkgName(String realPkgName) {
+ this.mRealPkgName = realPkgName;
+ return this;
+ }
+
+ public ScanRequestBuilder setParseFlags(int parseFlags) {
+ this.mParseFlags = parseFlags;
+ return this;
+ }
+
+ public ScanRequestBuilder addParseFlag(int parseFlag) {
+ this.mParseFlags |= parseFlag;
+ return this;
+ }
+
+ public ScanRequestBuilder setScanFlags(int scanFlags) {
+ this.mScanFlags = scanFlags;
+ return this;
+ }
+
+ public ScanRequestBuilder addScanFlag(int scanFlag) {
+ this.mScanFlags |= scanFlag;
+ return this;
+ }
+
+ public ScanRequestBuilder setUser(UserHandle user) {
+ this.mUser = user;
+ return this;
+ }
+
+ public ScanRequestBuilder setIsPlatformPackage(boolean isPlatformPackage) {
+ this.mIsPlatformPackage = isPlatformPackage;
+ return this;
+ }
+
+ PackageManagerService.ScanRequest build() {
+ return new PackageManagerService.ScanRequest(
+ mPkg, mSharedUserSetting, mOldPkg, mPkgSetting, mDisabledPkgSetting,
+ mOriginalPkgSetting, mRealPkgName, mParseFlags, mScanFlags, mIsPlatformPackage,
+ mUser);
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
new file mode 100644
index 000000000000..cc70ef89c75f
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import static android.content.pm.SharedLibraryInfo.TYPE_DYNAMIC;
+import static android.content.pm.SharedLibraryInfo.TYPE_STATIC;
+import static android.content.pm.SharedLibraryInfo.VERSION_UNDEFINED;
+
+import static com.android.server.pm.PackageManagerService.SCAN_AS_FULL_APP;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
+import static com.android.server.pm.PackageManagerService.SCAN_FIRST_BOOT_OR_UPGRADE;
+import static com.android.server.pm.PackageManagerService.SCAN_NEW_INSTALL;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.empty;
+import static org.hamcrest.Matchers.hasItems;
+import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.collection.IsArrayContainingInOrder.arrayContaining;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.assertNotSame;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.Manifest;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageParser;
+import android.content.pm.SharedLibraryInfo;
+import android.os.Environment;
+import android.os.UserHandle;
+import android.os.UserManagerInternal;
+import android.platform.test.annotations.Presubmit;
+
+import org.hamcrest.BaseMatcher;
+import org.hamcrest.Description;
+import org.hamcrest.Matcher;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.io.File;
+
+@RunWith(MockitoJUnitRunner.class)
+@Presubmit
+public class ScanTests {
+
+ private static final String DUMMY_PACKAGE_NAME = "some.app.to.test";
+
+ @Mock
+ PackageAbiHelper mMockPackageAbiHelper;
+ @Mock
+ UserManagerInternal mMockUserManager;
+
+ @Before
+ public void setupDefaultUser() {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+ }
+
+ @Test
+ public void newInstallSimpleAllNominal() throws Exception {
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
+ .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+ assertThat(scanResult.existingSettingCopied, is(false));
+ verify(mMockPackageAbiHelper, never()).derivePackageAbi(any(PackageParser.Package.class),
+ anyString() /*abioverride*/, anyBoolean() /*extractNativeLibs*/);
+ verify(mMockPackageAbiHelper).setNativeLibraryPaths(
+ scanResult.pkgSetting.pkg, PackageManagerService.sAppLib32InstallDir);
+ }
+
+ @Test
+ public void newInstallForAllUsers() throws Exception {
+ final int[] userIds = {0, 10, 11};
+ when(mMockUserManager.getUserIds()).thenReturn(userIds);
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setRealPkgName(null)
+ .addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
+ .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+ .build();
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ for (int uid : userIds) {
+ assertThat(scanResult.pkgSetting.readUserState(uid).installed, is(true));
+ }
+ }
+
+ @Test
+ public void installRealPackageName() throws Exception {
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setRealPkgName("com.package.real")
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.pkgSetting.realName, is("com.package.real"));
+
+ final PackageManagerService.ScanRequest scanRequestNoRealPkg =
+ createBasicScanRequestBuilder(
+ createBasicPackage(DUMMY_PACKAGE_NAME)
+ .setRealPackageName("com.package.real").build())
+ .build();
+
+ final PackageManagerService.ScanResult scanResultNoReal = executeScan(scanRequestNoRealPkg);
+ assertThat(scanResultNoReal.pkgSetting.realName, nullValue());
+ }
+
+ @Test
+ public void updateSimpleNominal() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting pkgSetting = createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setPrimaryCpuAbiString("primaryCpuAbi")
+ .setSecondaryCpuAbiString("secondaryCpuAbi")
+ .build();
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
+ .setPkgSetting(pkgSetting)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.existingSettingCopied, is(true));
+
+ // ensure we don't overwrite the existing pkgSetting, in case something post-scan fails
+ assertNotSame(pkgSetting, scanResult.pkgSetting);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+
+ assertThat(scanResult.pkgSetting.primaryCpuAbiString, is("primaryCpuAbi"));
+ assertThat(scanResult.pkgSetting.secondaryCpuAbiString, is("secondaryCpuAbi"));
+ assertThat(scanResult.pkgSetting.cpuAbiOverrideString, nullValue());
+
+ verify(mMockPackageAbiHelper, never()).derivePackageAbi(any(PackageParser.Package.class),
+ anyString() /*abioverride*/, anyBoolean() /*extractNativeLibs*/);
+ verify(mMockPackageAbiHelper).setNativeLibraryPaths(
+ scanResult.pkgSetting.pkg, PackageManagerService.sAppLib32InstallDir);
+ }
+
+ @Test
+ public void updateInstantSimpleNominal() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setInstantAppUserState(0, true)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/);
+ }
+
+ @Test
+ public void installStaticSharedLibrary() throws Exception {
+ final PackageParser.Package pkg = createBasicPackage("static.lib.pkg.123")
+ .setStaticSharedLib("static.lib", 123L)
+ .setManifestPackageName("static.lib.pkg")
+ .setVersionCodeMajor(1)
+ .setVersionCode(234)
+ .setBaseCodePath("/some/path.apk")
+ .addSplitCodePath("/some/other/path.apk")
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder(
+ pkg).setUser(UserHandle.of(0)).build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.staticSharedLibraryInfo.getPackageName(), is("static.lib.pkg.123"));
+ assertThat(scanResult.staticSharedLibraryInfo.getName(), is("static.lib"));
+ assertThat(scanResult.staticSharedLibraryInfo.getLongVersion(), is(123L));
+ assertThat(scanResult.staticSharedLibraryInfo.getType(), is(TYPE_STATIC));
+ assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getPackageName(),
+ is("static.lib.pkg"));
+ assertThat(scanResult.staticSharedLibraryInfo.getDeclaringPackage().getLongVersionCode(),
+ is(pkg.getLongVersionCode()));
+ assertThat(scanResult.staticSharedLibraryInfo.getAllCodePaths(),
+ hasItems("/some/path.apk", "/some/other/path.apk"));
+ assertThat(scanResult.staticSharedLibraryInfo.getDependencies(), nullValue());
+ assertThat(scanResult.staticSharedLibraryInfo.getDependentPackages(), empty());
+ }
+
+ @Test
+ public void installDynamicLibraries() throws Exception {
+ final PackageParser.Package pkg = createBasicPackage("dynamic.lib.pkg")
+ .setManifestPackageName("dynamic.lib.pkg")
+ .addLibraryName("liba")
+ .addLibraryName("libb")
+ .setVersionCodeMajor(1)
+ .setVersionCode(234)
+ .setBaseCodePath("/some/path.apk")
+ .addSplitCodePath("/some/other/path.apk")
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ new ScanRequestBuilder(pkg).setUser(UserHandle.of(0)).build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ final SharedLibraryInfo dynamicLib0 = scanResult.dynamicSharedLibraryInfos.get(0);
+ assertThat(dynamicLib0.getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib0.getName(), is("liba"));
+ assertThat(dynamicLib0.getLongVersion(), is((long) VERSION_UNDEFINED));
+ assertThat(dynamicLib0.getType(), is(TYPE_DYNAMIC));
+ assertThat(dynamicLib0.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib0.getDeclaringPackage().getLongVersionCode(),
+ is(pkg.getLongVersionCode()));
+ assertThat(dynamicLib0.getAllCodePaths(),
+ hasItems("/some/path.apk", "/some/other/path.apk"));
+ assertThat(dynamicLib0.getDependencies(), nullValue());
+ assertThat(dynamicLib0.getDependentPackages(), empty());
+
+ final SharedLibraryInfo dynamicLib1 = scanResult.dynamicSharedLibraryInfos.get(1);
+ assertThat(dynamicLib1.getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib1.getName(), is("libb"));
+ assertThat(dynamicLib1.getLongVersion(), is((long) VERSION_UNDEFINED));
+ assertThat(dynamicLib1.getType(), is(TYPE_DYNAMIC));
+ assertThat(dynamicLib1.getDeclaringPackage().getPackageName(), is("dynamic.lib.pkg"));
+ assertThat(dynamicLib1.getDeclaringPackage().getLongVersionCode(),
+ is(pkg.getLongVersionCode()));
+ assertThat(dynamicLib1.getAllCodePaths(),
+ hasItems("/some/path.apk", "/some/other/path.apk"));
+ assertThat(dynamicLib1.getDependencies(), nullValue());
+ assertThat(dynamicLib1.getDependentPackages(), empty());
+ }
+
+ @Test
+ public void volumeUuidChangesOnUpdate() throws Exception {
+ final PackageSetting pkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setVolumeUuid("someUuid")
+ .build();
+
+ final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .setApplicationInfoVolumeUuid("someNewUuid")
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(
+ new ScanRequestBuilder(basicPackage).setPkgSetting(pkgSetting).build());
+
+ assertThat(scanResult.pkgSetting.volumeUuid, is("someNewUuid"));
+ }
+
+ @Test
+ public void scanFirstBoot_derivesAbis() throws Exception {
+ final PackageSetting pkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME).build();
+
+ final PackageParser.Package basicPackage =
+ createBasicPackage(DUMMY_PACKAGE_NAME)
+ .setCpuAbiOVerride("testOverride")
+ .build();
+
+
+ executeScan(new ScanRequestBuilder(basicPackage)
+ .setPkgSetting(pkgSetting)
+ .addScanFlag(SCAN_FIRST_BOOT_OR_UPGRADE)
+ .build());
+
+ verify(mMockPackageAbiHelper).derivePackageAbi(basicPackage, "testOverride", true);
+ }
+
+ @Test
+ public void scanWithOriginalPkgSetting_packageNameChanges() throws Exception {
+ final PackageSetting originalPkgSetting =
+ createBasicPackageSettingBuilder("original.package").build();
+
+ final PackageParser.Package basicPackage =
+ createBasicPackage(DUMMY_PACKAGE_NAME)
+ .build();
+
+
+ final PackageManagerService.ScanResult result =
+ executeScan(new ScanRequestBuilder(basicPackage)
+ .setOriginalPkgSetting(originalPkgSetting)
+ .build());
+
+ assertThat(result.request.pkg.packageName, is("original.package"));
+ }
+
+ @Test
+ public void updateInstant_changeToFull() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setInstantAppUserState(0, true)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .addScanFlag(SCAN_AS_FULL_APP)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, false /*isInstant*/);
+ }
+
+ @Test
+ public void updateFull_changeToInstant() throws Exception {
+ when(mMockUserManager.getUserIds()).thenReturn(new int[]{0});
+
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setInstantAppUserState(0, false)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .addScanFlag(SCAN_AS_INSTANT_APP)
+ .build();
+
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertBasicPackageScanResult(scanResult, DUMMY_PACKAGE_NAME, true /*isInstant*/);
+ }
+
+ @Test
+ public void updateSystemApp_applicationInfoFlagSet() throws Exception {
+ final PackageSetting existingPkgSetting =
+ createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME)
+ .setPkgFlags(ApplicationInfo.FLAG_SYSTEM)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ .setPkgSetting(existingPkgSetting)
+ .setDisabledPkgSetting(existingPkgSetting)
+ .addScanFlag(SCAN_NEW_INSTALL)
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.request.pkg.applicationInfo.flags,
+ hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP));
+ }
+
+ @Test
+ public void factoryTestFlagSet() throws Exception {
+ final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .addPermissionRequest(Manifest.permission.FACTORY_TEST)
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = PackageManagerService.scanPackageOnlyLI(
+ createBasicScanRequestBuilder(basicPackage).build(),
+ new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper),
+ true /*isUnderFactoryTest*/,
+ System.currentTimeMillis());
+
+ assertThat(scanResult.request.pkg.applicationInfo.flags,
+ hasFlag(ApplicationInfo.FLAG_FACTORY_TEST));
+ }
+
+ @Test
+ public void scanSystemApp_isOrphanedTrue() throws Exception {
+ final PackageParser.Package pkg = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .addApplicationInfoFlag(ApplicationInfo.FLAG_SYSTEM)
+ .build();
+
+ final PackageManagerService.ScanRequest scanRequest =
+ createBasicScanRequestBuilder(pkg)
+ .build();
+
+ final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
+
+ assertThat(scanResult.pkgSetting.isOrphaned, is(true));
+ }
+
+ private static Matcher<Integer> hasFlag(final int flag) {
+ return new BaseMatcher<Integer>() {
+ @Override public void describeTo(Description description) {
+ description.appendText("flags ");
+ }
+
+ @Override public boolean matches(Object item) {
+ return ((int) item & flag) != 0;
+ }
+
+ @Override
+ public void describeMismatch(Object item, Description mismatchDescription) {
+ mismatchDescription
+ .appendValue(item)
+ .appendText(" does not contain flag ")
+ .appendValue(flag);
+ }
+ };
+ }
+
+ private PackageManagerService.ScanResult executeScan(
+ PackageManagerService.ScanRequest scanRequest) throws PackageManagerException {
+ return PackageManagerService.scanPackageOnlyLI(
+ scanRequest,
+ new PackageManagerService.Injector(mMockUserManager, mMockPackageAbiHelper),
+ false /*isUnderFactoryTest*/,
+ System.currentTimeMillis());
+ }
+
+ private static String createResourcePath(String packageName) {
+ return "/data/app/" + packageName + "-randompath/base.apk";
+ }
+
+ private static String createCodePath(String packageName) {
+ return "/data/app/" + packageName + "-randompath";
+ }
+
+ private static PackageSettingBuilder createBasicPackageSettingBuilder(String packageName) {
+ return new PackageSettingBuilder()
+ .setName(packageName)
+ .setCodePath(createCodePath(packageName))
+ .setResourcePath(createResourcePath(packageName));
+ }
+
+ private static ScanRequestBuilder createBasicScanRequestBuilder(PackageParser.Package pkg) {
+ return new ScanRequestBuilder(pkg)
+ .setUser(UserHandle.of(0));
+ }
+
+
+ private static PackageBuilder createBasicPackage(String packageName) {
+ return new PackageBuilder(packageName)
+ .setCodePath("/data/tmp/randompath")
+ .setApplicationInfoCodePath(createCodePath(packageName))
+ .setApplicationInfoResourcePath(createResourcePath(packageName))
+ .setApplicationInfoVolumeUuid("volumeUuid")
+ .setBaseCodePath("/data/tmp/randompath/base.apk")
+ .addUsesStaticLibrary("some.static.library", 234L)
+ .addUsesStaticLibrary("some.other.static.library", 456L)
+ .setApplicationInfoNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib")
+ .setVersionCodeMajor(1)
+ .setVersionCode(2345);
+ }
+
+ private static void assertBasicPackageScanResult(
+ PackageManagerService.ScanResult scanResult, String packageName, boolean isInstant) {
+ assertThat(scanResult.success, is(true));
+
+ final PackageSetting pkgSetting = scanResult.pkgSetting;
+ assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting);
+
+ final ApplicationInfo applicationInfo = pkgSetting.pkg.applicationInfo;
+ verifyBasicApplicationInfo(scanResult, applicationInfo);
+
+ }
+
+ private static void assertBasicPackageSetting(PackageManagerService.ScanResult scanResult,
+ String packageName, boolean isInstant, PackageSetting pkgSetting) {
+ assertThat(pkgSetting.pkg.packageName, is(packageName));
+ assertThat(pkgSetting.getInstantApp(0), is(isInstant));
+ assertThat(pkgSetting.usesStaticLibraries,
+ arrayContaining("some.static.library", "some.other.static.library"));
+ assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L}));
+ assertThat(pkgSetting.pkg, is(scanResult.request.pkg));
+ assertThat(pkgSetting.pkg.mExtras, is(pkgSetting));
+ assertThat(pkgSetting.legacyNativeLibraryPathString,
+ is("/data/tmp/randompath/base.apk:/lib"));
+ assertThat(pkgSetting.codePath, is(new File(createCodePath(packageName))));
+ assertThat(pkgSetting.resourcePath, is(new File(createResourcePath(packageName))));
+ assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345)));
+ }
+
+ private static void verifyBasicApplicationInfo(PackageManagerService.ScanResult scanResult,
+ ApplicationInfo applicationInfo) {
+ assertThat(applicationInfo.processName, is(scanResult.request.pkg.packageName));
+
+ final int uid = applicationInfo.uid;
+ assertThat(UserHandle.getUserId(uid), is(UserHandle.USER_SYSTEM));
+
+ final String calculatedCredentialId = Environment.getDataUserCePackageDirectory(
+ applicationInfo.volumeUuid, UserHandle.USER_SYSTEM,
+ scanResult.request.pkg.packageName).getAbsolutePath();
+ assertThat(applicationInfo.credentialProtectedDataDir, is(calculatedCredentialId));
+ assertThat(applicationInfo.dataDir, is(applicationInfo.credentialProtectedDataDir));
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index ef11a437fcb1..7b252cbfc0b0 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -31,6 +31,9 @@ import static com.android.dx.mockito.inline.extended.ExtendedMockito.mock;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.when;
+import static com.android.server.wm.ActivityRecord.FINISH_RESULT_CANCELLED;
+import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REMOVED;
+import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REQUESTED;
import static com.android.server.wm.ActivityStack.ActivityState.INITIALIZING;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
@@ -681,6 +684,73 @@ public class ActivityRecordTests extends ActivityTestsBase {
assertEquals(persistentSavedState, mActivity.getPersistentSavedState());
}
+ /**
+ * Verify that activity finish request is not performed if activity is finishing or is in
+ * incorrect state.
+ */
+ @Test
+ public void testFinishActivityLocked_cancelled() {
+ // Mark activity as finishing
+ mActivity.finishing = true;
+ assertEquals("Duplicate finish request must be ignored", FINISH_RESULT_CANCELLED,
+ mActivity.finishActivityLocked(0 /* resultCode */, null /* resultData */, "test",
+ false /* oomAdj */));
+ assertTrue(mActivity.finishing);
+ assertTrue(mActivity.isInStackLocked());
+
+ // Remove activity from task
+ mActivity.finishing = false;
+ mActivity.setTask(null);
+ assertEquals("Activity outside of task/stack cannot be finished", FINISH_RESULT_CANCELLED,
+ mActivity.finishActivityLocked(0 /* resultCode */, null /* resultData */, "test",
+ false /* oomAdj */));
+ assertFalse(mActivity.finishing);
+ }
+
+ /**
+ * Verify that activity finish request is requested, but not executed immediately if activity is
+ * not ready yet.
+ */
+ @Test
+ public void testFinishActivityLocked_requested() {
+ mActivity.finishing = false;
+ assertEquals("Currently resumed activity be paused removal", FINISH_RESULT_REQUESTED,
+ mActivity.finishActivityLocked(0 /* resultCode */, null /* resultData */, "test",
+ false /* oomAdj */));
+ assertTrue(mActivity.finishing);
+ assertTrue(mActivity.isInStackLocked());
+
+ // First request to finish activity must schedule a "destroy" request to the client.
+ // Activity must be removed from history after the client reports back or after timeout.
+ mActivity.finishing = false;
+ mActivity.setState(STOPPED, "test");
+ assertEquals("Activity outside of task/stack cannot be finished", FINISH_RESULT_REQUESTED,
+ mActivity.finishActivityLocked(0 /* resultCode */, null /* resultData */, "test",
+ false /* oomAdj */));
+ assertTrue(mActivity.finishing);
+ assertTrue(mActivity.isInStackLocked());
+ }
+
+ /**
+ * Verify that activity finish request removes activity immediately if it's ready.
+ */
+ @Test
+ public void testFinishActivityLocked_removed() {
+ // Prepare the activity record to be ready for immediate removal. It should be invisible and
+ // have no process. Otherwise, request to finish it will send a message to client first.
+ mActivity.setState(STOPPED, "test");
+ mActivity.visible = false;
+ mActivity.nowVisible = false;
+ // Set process to 'null' to allow immediate removal, but don't call mActivity.setProcess() -
+ // this will cause NPE when updating task's process.
+ mActivity.app = null;
+ assertEquals("Activity outside of task/stack cannot be finished", FINISH_RESULT_REMOVED,
+ mActivity.finishActivityLocked(0 /* resultCode */, null /* resultData */, "test",
+ false /* oomAdj */));
+ assertTrue(mActivity.finishing);
+ assertFalse(mActivity.isInStackLocked());
+ }
+
/** Setup {@link #mActivity} as a size-compat-mode-able activity without fixed orientation. */
private void prepareFixedAspectRatioUnresizableActivity() {
setupDisplayContentForCompatDisplayInsets();
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
index 26cd63c62cc1..cd292b2494ff 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationControllerTest.java
@@ -25,6 +25,7 @@ import static android.view.WindowManager.TRANSIT_ACTIVITY_CLOSE;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.atLeast;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verify;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.verifyNoMoreInteractions;
@@ -35,10 +36,12 @@ import static com.android.server.wm.RecentsAnimationController.REORDER_MOVE_TO_O
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.eq;
import android.os.Binder;
@@ -79,6 +82,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
// Hold the lock to protect the stubbing from being accessed by other threads.
spyOn(mWm.mRoot);
doNothing().when(mWm.mRoot).performSurfacePlacement(anyBoolean());
+ doReturn(mDisplayContent).when(mWm.mRoot).getDisplayContent(anyInt());
}
when(mMockRunner.asBinder()).thenReturn(new Binder());
mController = new RecentsAnimationController(mWm, mMockRunner, mAnimationCallbacks,
@@ -135,7 +139,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
hiddenAppWindow.setHidden(true);
mDisplayContent.getConfiguration().windowConfiguration.setRotation(
mDisplayContent.getRotation());
- mController.initialize(mDisplayContent, ACTIVITY_TYPE_HOME, new SparseBooleanArray());
+ mController.initialize(ACTIVITY_TYPE_HOME, new SparseBooleanArray());
// Ensure that we are animating the target activity as well
assertTrue(mController.isAnimatingTask(homeAppWindow.getTask()));
@@ -144,7 +148,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
}
@Test
- public void testCancelAnimationWithScreenShot() throws Exception {
+ public void testDeferCancelAnimation() throws Exception {
mWm.setRecentsAnimationController(mController);
final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
@@ -156,8 +160,31 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
mController.addAnimation(appWindow.getTask(), false /* isRecentTaskInvisible */);
assertTrue(mController.isAnimatingTask(appWindow.getTask()));
- mController.setCancelWithDeferredScreenshotLocked(true);
- mController.cancelAnimationWithScreenShot();
+ mController.setDeferredCancel(true /* deferred */, false /* screenshot */);
+ mController.cancelAnimationWithScreenshot(false /* screenshot */);
+ verify(mMockRunner).onAnimationCanceled(false /* deferredWithScreenshot */);
+ assertNull(mController.mRecentScreenshotAnimator);
+
+ // Simulate the app transition finishing
+ mController.mAppTransitionListener.onAppTransitionStartingLocked(0, 0, 0, 0);
+ verify(mAnimationCallbacks).onAnimationFinished(REORDER_KEEP_IN_PLACE, true, false);
+ }
+
+ @Test
+ public void testDeferCancelAnimationWithScreenShot() throws Exception {
+ mWm.setRecentsAnimationController(mController);
+ final AppWindowToken appWindow = createAppWindowToken(mDisplayContent,
+ WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD);
+ final WindowState win1 = createWindow(null, TYPE_BASE_APPLICATION, appWindow, "win1");
+ appWindow.addWindow(win1);
+ assertEquals(appWindow.getTask().getTopVisibleAppToken(), appWindow);
+ assertEquals(appWindow.findMainWindow(), win1);
+
+ mController.addAnimation(appWindow.getTask(), false /* isRecentTaskInvisible */);
+ assertTrue(mController.isAnimatingTask(appWindow.getTask()));
+
+ mController.setDeferredCancel(true /* deferred */, true /* screenshot */);
+ mController.cancelAnimationWithScreenshot(true /* screenshot */);
verify(mMockRunner).onAnimationCanceled(true /* deferredWithScreenshot */);
assertNotNull(mController.mRecentScreenshotAnimator);
assertTrue(mController.mRecentScreenshotAnimator.isAnimating());
@@ -185,7 +212,7 @@ public class RecentsAnimationControllerTest extends WindowTestsBase {
// Assume appWindow transition should animate when no
// IRecentsAnimationController#setCancelWithDeferredScreenshot called.
- assertFalse(mController.shouldCancelWithDeferredScreenshot());
+ assertFalse(mController.shouldDeferCancelWithScreenshot());
assertTrue(appWindow.shouldAnimate(TRANSIT_ACTIVITY_CLOSE));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 9630b7d46e3c..0e119e3cc375 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -274,12 +274,13 @@ public class RecentsAnimationTest extends ActivityTestsBase {
// Assume recents animation already started, set a state that cancel recents animation
// with screenshot.
- doReturn(true).when(mRecentsAnimationController).shouldCancelWithDeferredScreenshot();
+ doReturn(true).when(mRecentsAnimationController).shouldDeferCancelUntilNextTransition();
+ doReturn(true).when(mRecentsAnimationController).shouldDeferCancelWithScreenshot();
// Start another fullscreen activity.
fullscreenStack2.moveToFront("Activity start");
- // Ensure that the recents animation was canceled by cancelOnNextTransitionStart().
- verify(mRecentsAnimationController, times(1)).cancelOnNextTransitionStart();
+ // Ensure that the recents animation was canceled by setCancelOnNextTransitionStart().
+ verify(mRecentsAnimationController, times(1)).setCancelOnNextTransitionStart();
}
@Test
@@ -315,7 +316,7 @@ public class RecentsAnimationTest extends ActivityTestsBase {
// Ensure that the recents animation was NOT canceled
verify(mService.mWindowManager, times(0)).cancelRecentsAnimationSynchronously(
eq(REORDER_KEEP_IN_PLACE), any());
- verify(mRecentsAnimationController, times(0)).cancelOnNextTransitionStart();
+ verify(mRecentsAnimationController, times(0)).setCancelOnNextTransitionStart();
}
@Test
diff --git a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
index 94352b21db87..99337565e128 100644
--- a/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
+++ b/services/voiceinteraction/java/com/android/server/soundtrigger/SoundTriggerHelper.java
@@ -104,8 +104,8 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
// This is an indirect indication of the microphone being open in some other application.
private boolean mServiceDisabled = false;
- // Whether we have ANY recognition (keyphrase or generic) running.
- private boolean mRecognitionRunning = false;
+ // Whether ANY recognition (keyphrase or generic) has been requested.
+ private boolean mRecognitionRequested = false;
private PowerSaveModeListener mPowerSaveModeListener;
@@ -252,11 +252,6 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
}
- // Initialize power save, call active state monitoring logic.
- if (!mRecognitionRunning) {
- initializeTelephonyAndPowerStateListeners();
- }
-
// If the existing SoundModel is different (for the same UUID for Generic and same
// keyphrase ID for voice), ensure that it is unloaded and stopped before proceeding.
// This works for both keyphrase and generic models. This logic also ensures that a
@@ -326,8 +321,16 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
modelData.setRecognitionConfig(recognitionConfig);
modelData.setSoundModel(soundModel);
- return startRecognitionLocked(modelData,
+ int status = startRecognitionLocked(modelData,
false /* Don't notify for synchronous calls */);
+
+ // Initialize power save, call active state monitoring logic.
+ if (status == STATUS_OK && !mRecognitionRequested) {
+ initializeTelephonyAndPowerStateListeners();
+ mRecognitionRequested = true;
+ }
+
+ return status;
}
}
@@ -450,7 +453,7 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
modelData.clearCallback();
modelData.setRecognitionConfig(null);
- if (!computeRecognitionRunningLocked()) {
+ if (!computeRecognitionRequestedLocked()) {
internalClearGlobalStateLocked();
}
@@ -1196,20 +1199,20 @@ public class SoundTriggerHelper implements SoundTrigger.StatusListener {
}
// Computes whether we have any recognition running at all (voice or generic). Sets
- // the mRecognitionRunning variable with the result.
- private boolean computeRecognitionRunningLocked() {
+ // the mRecognitionRequested variable with the result.
+ private boolean computeRecognitionRequestedLocked() {
if (mModuleProperties == null || mModule == null) {
- mRecognitionRunning = false;
- return mRecognitionRunning;
+ mRecognitionRequested = false;
+ return mRecognitionRequested;
}
for (ModelData modelData : mModelDataMap.values()) {
- if (modelData.isModelStarted()) {
- mRecognitionRunning = true;
- return mRecognitionRunning;
+ if (modelData.isRequested()) {
+ mRecognitionRequested = true;
+ return mRecognitionRequested;
}
}
- mRecognitionRunning = false;
- return mRecognitionRunning;
+ mRecognitionRequested = false;
+ return mRecognitionRequested;
}
// This class encapsulates the callbacks, state, handles and any other information that
diff --git a/startop/apps/test/Android.bp b/startop/apps/test/Android.bp
index 7a1678ac9a5a..a4906d7b4cd3 100644
--- a/startop/apps/test/Android.bp
+++ b/startop/apps/test/Android.bp
@@ -23,4 +23,5 @@ android_app {
"src/FrameLayoutInflationActivity.java",
"src/TextViewInflationActivity.java",
],
+ platform_apis: true,
}
diff --git a/startop/scripts/iorap/compiler.py b/startop/scripts/iorap/compiler.py
index 1e15736b13a1..a335b30da8a5 100755
--- a/startop/scripts/iorap/compiler.py
+++ b/startop/scripts/iorap/compiler.py
@@ -27,16 +27,23 @@ import optparse
import os
import re
import sys
-from typing import Iterable, Optional
+import tempfile
+from pathlib import Path
+from typing import Iterable, Optional, List
from generated.TraceFile_pb2 import *
from lib.inode2filename import Inode2Filename
parent_dir_name = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-sys.path.append(parent_dir_name + "/trace_analyzer")
-from lib.trace2db import Trace2Db, MmFilemapAddToPageCache, RawFtraceEntry
+sys.path.append(parent_dir_name)
+from trace_analyzer.lib.trace2db import Trace2Db, MmFilemapAddToPageCache, \
+ RawFtraceEntry
+import lib.cmd_utils as cmd_utils
_PAGE_SIZE = 4096 # adb shell getconf PAGESIZE ## size of a memory page in bytes.
+ANDROID_BUILD_TOP = Path(parent_dir_name).parents[3]
+TRACECONV_BIN = ANDROID_BUILD_TOP.joinpath(
+ 'external/perfetto/tools/traceconv')
class PageRun:
"""
@@ -190,12 +197,62 @@ def query_add_to_page_cache(trace2db: Trace2Db, trace_duration: Optional[int]):
RawFtraceEntry.timestamp <= end_time).order_by(
MmFilemapAddToPageCache.id).all()
+def transform_perfetto_trace_to_systrace(path_to_perfetto_trace: str,
+ path_to_tmp_systrace: str) -> None:
+ """ Transforms the systrace file from perfetto trace. """
+ cmd_utils.run_command_nofail([str(TRACECONV_BIN),
+ 'systrace',
+ path_to_perfetto_trace,
+ path_to_tmp_systrace])
+
+
+def run(sql_db_path:str,
+ trace_file:str,
+ trace_duration:Optional[int],
+ output_file:str,
+ inode_table:str,
+ filter:List[str]) -> int:
+ trace2db = Trace2Db(sql_db_path)
+ # Speed optimization: Skip any entries that aren't mm_filemap_add_to_pagecache.
+ trace2db.set_raw_ftrace_entry_filter(\
+ lambda entry: entry['function'] == 'mm_filemap_add_to_page_cache')
+ # TODO: parse multiple trace files here.
+ parse_count = trace2db.parse_file_into_db(trace_file)
+
+ mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db,
+ trace_duration)
+ print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows)))
+
+ page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows)
+ print("DONE. Converted %d entries" %(len(page_runs)))
+
+ # TODO: flags to select optimizations.
+ optimized_page_runs = optimize_page_runs(page_runs)
+ print("DONE. Optimized down to %d entries" %(len(optimized_page_runs)))
+
+ print("Build protobuf...")
+ trace_file = build_protobuf(optimized_page_runs, inode_table, filter)
+
+ print("Write protobuf to file...")
+ output_file = open(output_file, 'wb')
+ output_file.write(trace_file.SerializeToString())
+ output_file.close()
+
+ print("DONE")
+
+ # TODO: Silent running mode [no output except on error] for build runs.
+
+ return 0
+
def main(argv):
parser = optparse.OptionParser(usage="Usage: %prog [options]", description="Compile systrace file into TraceFile.pb")
parser.add_option('-i', dest='inode_data_file', metavar='FILE',
help='Read cached inode data from a file saved earlier with pagecache.py -d')
parser.add_option('-t', dest='trace_file', metavar='FILE',
help='Path to systrace file (trace.html) that will be parsed')
+ parser.add_option('--perfetto-trace', dest='perfetto_trace_file',
+ metavar='FILE',
+ help='Path to perfetto trace that will be parsed')
parser.add_option('--db', dest='sql_db', metavar='FILE',
help='Path to intermediate sqlite3 database [default: in-memory].')
@@ -217,54 +274,42 @@ def main(argv):
# TODO: OptionParser should have some flags to make these mandatory.
if not options.inode_data_file:
parser.error("-i is required")
- if not options.trace_file:
- parser.error("-t is required")
+ if not options.trace_file and not options.perfetto_trace_file:
+ parser.error("one of -t or --perfetto-trace is required")
+ if options.trace_file and options.perfetto_trace_file:
+ parser.error("please enter either -t or --perfetto-trace, not both")
if not options.output_file:
parser.error("-o is required")
if options.launch_lock:
print("INFO: Launch lock flag (-l) enabled; filtering all events not inside launch_lock.")
-
inode_table = Inode2Filename.new_from_filename(options.inode_data_file)
- trace_file = open(options.trace_file)
-
sql_db_path = ":memory:"
if options.sql_db:
sql_db_path = options.sql_db
- trace2db = Trace2Db(sql_db_path)
- # Speed optimization: Skip any entries that aren't mm_filemap_add_to_pagecache.
- trace2db.set_raw_ftrace_entry_filter(\
- lambda entry: entry['function'] == 'mm_filemap_add_to_page_cache')
- # TODO: parse multiple trace files here.
- parse_count = trace2db.parse_file_into_db(options.trace_file)
-
- mm_filemap_add_to_page_cache_rows = query_add_to_page_cache(trace2db,
- options.trace_duration)
- print("DONE. Parsed %d entries into sql db." %(len(mm_filemap_add_to_page_cache_rows)))
-
- page_runs = page_cache_entries_to_runs(mm_filemap_add_to_page_cache_rows)
- print("DONE. Converted %d entries" %(len(page_runs)))
-
- # TODO: flags to select optimizations.
- optimized_page_runs = optimize_page_runs(page_runs)
- print("DONE. Optimized down to %d entries" %(len(optimized_page_runs)))
-
- print("Build protobuf...")
- trace_file = build_protobuf(optimized_page_runs, inode_table, options.filter)
-
- print("Write protobuf to file...")
- output_file = open(options.output_file, 'wb')
- output_file.write(trace_file.SerializeToString())
- output_file.close()
-
- print("DONE")
-
- # TODO: Silent running mode [no output except on error] for build runs.
-
- return 0
+ # if the input is systrace
+ if options.trace_file:
+ return run(sql_db_path,
+ options.trace_file,
+ options.trace_duration,
+ options.output_file,
+ inode_table,
+ options.filter)
+
+ # if the input is perfetto trace
+ # TODO python 3.7 switch to using nullcontext
+ with tempfile.NamedTemporaryFile() as trace_file:
+ transform_perfetto_trace_to_systrace(options.perfetto_trace_file,
+ trace_file.name)
+ return run(sql_db_path,
+ options.trace_file,
+ options.trace_duration,
+ options.output_file,
+ inode_table,
+ options.filter)
if __name__ == '__main__':
print(sys.argv)
diff --git a/startop/scripts/iorap/compiler_test.py b/startop/scripts/iorap/compiler_test.py
index fcb7269ed8d2..b5d28b03a8d5 100644
--- a/startop/scripts/iorap/compiler_test.py
+++ b/startop/scripts/iorap/compiler_test.py
@@ -36,6 +36,8 @@ DIR = os.path.abspath(os.path.dirname(__file__))
TEXTCACHE = os.path.join(DIR, 'test_fixtures/compiler/common_textcache')
SYSTRACE = os.path.join(DIR, 'test_fixtures/compiler/common_systrace')
ARGV = [os.path.join(DIR, 'compiler.py'), '-i', TEXTCACHE, '-t', SYSTRACE]
+PERFETTO_TRACE = os.path.join(DIR,
+ 'test_fixtures/compiler/common_perfetto_trace.pb')
def assert_compile_result(output, expected, *extra_argv):
argv = ARGV + ['-o', output] + [args for args in extra_argv]
@@ -45,6 +47,18 @@ def assert_compile_result(output, expected, *extra_argv):
with open(output, 'rb') as f1, open(expected, 'rb') as f2:
assert f1.read() == f2.read()
+### Unit tests - testing compiler code directly
+def test_transform_perfetto_trace_to_systrace(tmpdir):
+ expected = os.path.join(DIR,
+ 'test_fixtures/compiler/test_result_systrace')
+ output = tmpdir.mkdir('compiler').join('tmp_systrace')
+
+ compiler.transform_perfetto_trace_to_systrace(PERFETTO_TRACE, str(output))
+
+ with open(output, 'rb') as f1, open(expected, 'rb') as f2:
+ assert f1.read() == f2.read()
+
+### Functional tests - calls 'compiler.py --args...'
def test_compiler_main(tmpdir):
output = tmpdir.mkdir('compiler').join('output')
diff --git a/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb b/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb
new file mode 100644
index 000000000000..a47ad3d5d9ec
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/common_perfetto_trace.pb
Binary files differ
diff --git a/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace b/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace
new file mode 100644
index 000000000000..f731e73ba9b2
--- /dev/null
+++ b/startop/scripts/iorap/test_fixtures/compiler/test_result_systrace
@@ -0,0 +1,748 @@
+TRACE:
+# tracer: nop
+#
+# entries-in-buffer/entries-written: 30624/30624 #P:4
+#
+# _-----=> irqs-off
+# / _----=> need-resched
+# | / _---=> hardirq/softirq
+# || / _--=> preempt-depth
+# ||| / delay
+# TASK-PID TGID CPU# |||| TIMESTAMP FUNCTION
+# | | | | |||| | |
+ <unknown>-27388 (-----) [004] .... 1920260.530929: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1461937 ofs=9535488
+ <unknown>-27388 (-----) [005] .... 1920260.532161: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1344589 ofs=9474048
+ <unknown>-27388 (-----) [005] .... 1920260.532183: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1153671 ofs=9478144
+ <unknown>-27388 (-----) [005] .... 1920260.532184: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1219563 ofs=9482240
+ <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1083162 ofs=9486336
+ <unknown>-27388 (-----) [005] .... 1920260.532185: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1147318 ofs=9490432
+ <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1333594 ofs=9494528
+ <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1375715 ofs=9498624
+ <unknown>-27388 (-----) [005] .... 1920260.532186: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1184831 ofs=9502720
+ <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1241653 ofs=9506816
+ <unknown>-27388 (-----) [005] .... 1920260.532187: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1134975 ofs=9510912
+ <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1145772 ofs=9515008
+ <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1090457 ofs=9519104
+ <unknown>-27388 (-----) [005] .... 1920260.532190: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1137942 ofs=9523200
+ <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1130123 ofs=9527296
+ <unknown>-27388 (-----) [005] .... 1920260.532191: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1208783 ofs=9531392
+ <unknown>-27388 (-----) [005] .... 1920260.532192: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1294989 ofs=9539584
+ <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1163979 ofs=9543680
+ <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1350628 ofs=9547776
+ <unknown>-27388 (-----) [005] .... 1920260.532206: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1386717 ofs=9551872
+ <unknown>-27388 (-----) [005] .... 1920260.532207: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1316148 ofs=9555968
+ <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1316419 ofs=9560064
+ <unknown>-27388 (-----) [005] .... 1920260.532208: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1149076 ofs=9564160
+ <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1372772 ofs=9568256
+ <unknown>-27388 (-----) [005] .... 1920260.532209: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1116389 ofs=9572352
+ <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1325458 ofs=9576448
+ <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1195423 ofs=9580544
+ <unknown>-27388 (-----) [005] .... 1920260.532211: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1250964 ofs=9584640
+ <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1196027 ofs=9588736
+ <unknown>-27388 (-----) [005] .... 1920260.532212: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1354059 ofs=9592832
+ <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1264649 ofs=9596928
+ <unknown>-27388 (-----) [005] .... 1920260.532213: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1245285 ofs=9601024
+ <unknown>-27388 (-----) [005] .... 1920260.535119: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1411552 ofs=44244992
+ <unknown>-27388 (-----) [005] .... 1920260.535129: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1483081 ofs=433524736
+ <unknown>-27388 (-----) [004] .... 1920260.536144: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1276173 ofs=438185984
+ <unknown>-27388 (-----) [004] .... 1920260.536462: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1174575 ofs=44249088
+ <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1126294 ofs=44253184
+ <unknown>-27388 (-----) [004] .... 1920260.536464: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1248232 ofs=44257280
+ <unknown>-27388 (-----) [004] .... 1920260.537065: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1332993 ofs=44240896
+ <unknown>-27388 (-----) [006] .... 1920260.537646: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1153343 ofs=44400640
+ <unknown>-27388 (-----) [005] .... 1920260.538777: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1358397 ofs=44474368
+ <unknown>-12683 (-----) [006] .... 1920260.560094: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1426577 ofs=0
+ <unknown>-12683 (-----) [006] .... 1920260.560105: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117587 ofs=1171456
+ <unknown>-12683 (-----) [006] .... 1920260.561199: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099987 ofs=4096
+ <unknown>-12683 (-----) [006] .... 1920260.561411: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099910 ofs=16384
+ <unknown>-12683 (-----) [006] .... 1920260.561598: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099905 ofs=20480
+ <unknown>-12683 (-----) [006] .... 1920260.561758: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099883 ofs=32768
+ <unknown>-12683 (-----) [006] .... 1920260.562088: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099809 ofs=36864
+ <unknown>-12683 (-----) [006] .... 1920260.562325: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099803 ofs=98304
+ <unknown>-12683 (-----) [006] .... 1920260.562516: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099795 ofs=102400
+ <unknown>-12683 (-----) [006] .... 1920260.563094: mm_filemap_add_to_page_cache: dev 0:64768 ino 1523 page=0000000000000000 pfn=1107649 ofs=12288
+ <unknown>-12683 (-----) [006] .... 1920260.563105: mm_filemap_add_to_page_cache: dev 0:64768 ino 1523 page=0000000000000000 pfn=1269029 ofs=16384
+ <unknown>-12683 (-----) [006] .... 1920260.563785: mm_filemap_add_to_page_cache: dev 0:64768 ino 1242 page=0000000000000000 pfn=1451096 ofs=8192
+ <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 1242 page=0000000000000000 pfn=1301480 ofs=12288
+ <unknown>-12683 (-----) [006] .... 1920260.563790: mm_filemap_add_to_page_cache: dev 0:64768 ino 1242 page=0000000000000000 pfn=1314353 ofs=16384
+ <unknown>-12683 (-----) [006] .... 1920260.563791: mm_filemap_add_to_page_cache: dev 0:64768 ino 1242 page=0000000000000000 pfn=1216744 ofs=24576
+ <unknown>-12683 (-----) [006] .... 1920260.564309: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099787 ofs=49152
+ <unknown>-12683 (-----) [006] .... 1920260.564514: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1099778 ofs=53248
+ <unknown>-12683 (-----) [005] .... 1920260.564756: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1148849 ofs=114688
+ <unknown>-12683 (-----) [005] .... 1920260.564973: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1164731 ofs=118784
+ <unknown>-12683 (-----) [005] .... 1920260.565000: mm_filemap_add_to_page_cache: dev 0:2053 ino 26 page=0000000000000000 pfn=1170255 ofs=0
+ <unknown>-12683 (-----) [005] .... 1920260.565003: mm_filemap_add_to_page_cache: dev 0:2053 ino 26 page=0000000000000000 pfn=1181043 ofs=4096
+ <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 26 page=0000000000000000 pfn=1296004 ofs=8192
+ <unknown>-12683 (-----) [005] .... 1920260.565004: mm_filemap_add_to_page_cache: dev 0:2053 ino 26 page=0000000000000000 pfn=1102004 ofs=12288
+ <unknown>-12683 (-----) [005] .... 1920260.565626: mm_filemap_add_to_page_cache: dev 0:3 ino 0 page=0000000000000000 pfn=1351232 ofs=470597632
+ <unknown>-12683 (-----) [005] .... 1920260.565982: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1391336 ofs=40210432
+ <unknown>-12683 (-----) [005] .... 1920260.565985: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267536 ofs=12668928
+ <unknown>-27388 (-----) [007] .... 1920260.566082: mm_filemap_add_to_page_cache: dev 0:64768 ino 1416 page=0000000000000000 pfn=1256752 ofs=43921408
+ <unknown>-12683 (-----) [005] .... 1920260.566516: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1110966 ofs=176226304
+ <unknown>-12683 (-----) [005] .... 1920260.566519: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1060586 ofs=12967936
+ <unknown>-12683 (-----) [004] .... 1920260.567773: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1117234 ofs=421888
+ <unknown>-12683 (-----) [005] .... 1920260.568604: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1210571 ofs=430080
+ <unknown>-12683 (-----) [005] .... 1920260.568887: mm_filemap_add_to_page_cache: dev 0:64771 ino 105 page=0000000000000000 pfn=1055640 ofs=0
+ <unknown>-12683 (-----) [005] .... 1920260.568908: mm_filemap_add_to_page_cache: dev 0:64771 ino 73 page=0000000000000000 pfn=1142694 ofs=0
+ <unknown>-12683 (-----) [005] .... 1920260.568910: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1060788 ofs=299008
+ <unknown>-12683 (-----) [005] .... 1920260.569418: mm_filemap_add_to_page_cache: dev 0:64771 ino 73 page=0000000000000000 pfn=1085046 ofs=4096
+ <unknown>-12683 (-----) [005] .... 1920260.569640: mm_filemap_add_to_page_cache: dev 0:64771 ino 73 page=0000000000000000 pfn=1057135 ofs=8192
+ <unknown>-12683 (-----) [005] .... 1920260.569833: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1058976 ofs=19406848
+ <unknown>-12683 (-----) [005] .... 1920260.569835: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1477947 ofs=10526720
+ <unknown>-12683 (-----) [005] .... 1920260.572285: mm_filemap_add_to_page_cache: dev 0:64768 ino 1565 page=0000000000000000 pfn=1237492 ofs=299008
+ <unknown>-12683 (-----) [005] .... 1920260.572297: mm_filemap_add_to_page_cache: dev 0:64768 ino 1565 page=0000000000000000 pfn=1264914 ofs=339968
+ <unknown>-12683 (-----) [005] .... 1920260.572314: mm_filemap_add_to_page_cache: dev 0:64768 ino 1565 page=0000000000000000 pfn=1434748 ofs=348160
+ <unknown>-12683 (-----) [005] .... 1920260.572316: mm_filemap_add_to_page_cache: dev 0:64768 ino 1565 page=0000000000000000 pfn=1372959 ofs=352256
+ <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 1565 page=0000000000000000 pfn=1258955 ofs=356352
+ <unknown>-12683 (-----) [005] .... 1920260.572317: mm_filemap_add_to_page_cache: dev 0:64768 ino 1565 page=0000000000000000 pfn=1113420 ofs=360448
+ <unknown>-12683 (-----) [005] .... 1920260.572318: mm_filemap_add_to_page_cache: dev 0:64768 ino 1565 page=0000000000000000 pfn=1137083 ofs=364544
+ <unknown>-12683 (-----) [004] .... 1920260.575490: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1379679 ofs=65536
+ <unknown>-12683 (-----) [006] .... 1920260.576194: mm_filemap_add_to_page_cache: dev 0:64771 ino 286 page=0000000000000000 pfn=1323898 ofs=69632
+ <unknown>-12683 (-----) [006] .... 1920260.576248: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323895 ofs=262623232
+ <unknown>-12683 (-----) [006] .... 1920260.576251: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323861 ofs=13156352
+ <unknown>-12683 (-----) [005] .... 1920260.576810: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1477585 ofs=262590464
+ <unknown>-12683 (-----) [004] .... 1920260.577197: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1267617 ofs=25206784
+ <unknown>-12683 (-----) [004] .... 1920260.577200: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1267618 ofs=12636160
+ <unknown>-12683 (-----) [005] .... 1920260.577725: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1056225 ofs=228618240
+ <unknown>-12683 (-----) [005] .... 1920260.577727: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1164942 ofs=13082624
+ <unknown>-12683 (-----) [007] .... 1920260.578411: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1372616 ofs=0
+ <unknown>-12683 (-----) [007] .... 1920260.578422: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1307468 ofs=4096
+ <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1120117 ofs=8192
+ <unknown>-12683 (-----) [007] .... 1920260.578428: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1217989 ofs=12288
+ <unknown>-12683 (-----) [007] .... 1920260.578650: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1475011 ofs=5419008
+ <unknown>-12683 (-----) [007] .... 1920260.578653: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1066084 ofs=236453888
+ <unknown>-12683 (-----) [007] .... 1920260.578654: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1100271 ofs=13099008
+ <unknown>-12683 (-----) [004] .... 1920260.579004: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1485156 ofs=5423104
+ <unknown>-12683 (-----) [004] .... 1920260.579005: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1124212 ofs=5427200
+ <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1195377 ofs=5431296
+ <unknown>-12683 (-----) [004] .... 1920260.579006: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1265888 ofs=5435392
+ <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1170194 ofs=5439488
+ <unknown>-12683 (-----) [004] .... 1920260.579007: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1403742 ofs=5443584
+ <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1123826 ofs=5447680
+ <unknown>-12683 (-----) [004] .... 1920260.579008: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1255034 ofs=5451776
+ <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1190447 ofs=5455872
+ <unknown>-12683 (-----) [004] .... 1920260.579011: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1286864 ofs=5459968
+ <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1428535 ofs=5464064
+ <unknown>-12683 (-----) [004] .... 1920260.579012: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1184092 ofs=5468160
+ <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1411906 ofs=5472256
+ <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1342349 ofs=5476352
+ <unknown>-12683 (-----) [004] .... 1920260.579013: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1188185 ofs=5480448
+ <unknown>-12683 (-----) [004] .... 1920260.579014: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1158702 ofs=5484544
+ <unknown>-12683 (-----) [005] .... 1920260.579430: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1299421 ofs=5230592
+ <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1317097 ofs=5234688
+ <unknown>-12683 (-----) [005] .... 1920260.579435: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1441714 ofs=5238784
+ <unknown>-12683 (-----) [005] .... 1920260.579438: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1081974 ofs=5242880
+ <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1128684 ofs=5246976
+ <unknown>-12683 (-----) [005] .... 1920260.579439: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1447381 ofs=5251072
+ <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1466410 ofs=5255168
+ <unknown>-12683 (-----) [005] .... 1920260.579440: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1259909 ofs=5259264
+ <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1125784 ofs=5263360
+ <unknown>-12683 (-----) [005] .... 1920260.579441: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1270592 ofs=5267456
+ <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1246070 ofs=5271552
+ <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1472544 ofs=5275648
+ <unknown>-12683 (-----) [005] .... 1920260.579442: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1113357 ofs=5279744
+ <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1202021 ofs=5283840
+ <unknown>-12683 (-----) [005] .... 1920260.579443: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1078639 ofs=5287936
+ <unknown>-12683 (-----) [005] .... 1920260.579449: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1176171 ofs=5292032
+ <unknown>-12683 (-----) [005] .... 1920260.579450: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1089516 ofs=5296128
+ <unknown>-12683 (-----) [005] .... 1920260.579451: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1400065 ofs=5300224
+ <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1300489 ofs=5304320
+ <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1452081 ofs=5308416
+ <unknown>-12683 (-----) [005] .... 1920260.579452: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1161862 ofs=5312512
+ <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1161871 ofs=5316608
+ <unknown>-12683 (-----) [005] .... 1920260.579453: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1263798 ofs=5320704
+ <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1126887 ofs=5324800
+ <unknown>-12683 (-----) [005] .... 1920260.579454: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1375498 ofs=5328896
+ <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1328067 ofs=5332992
+ <unknown>-12683 (-----) [005] .... 1920260.579455: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1420691 ofs=5337088
+ <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1298707 ofs=5341184
+ <unknown>-12683 (-----) [005] .... 1920260.579456: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1078670 ofs=5345280
+ <unknown>-12683 (-----) [005] .... 1920260.579457: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1430498 ofs=5349376
+ <unknown>-12683 (-----) [005] .... 1920260.579458: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1338720 ofs=5353472
+ <unknown>-12683 (-----) [005] .... 1920260.579476: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1452611 ofs=5357568
+ <unknown>-12683 (-----) [006] .... 1920260.580451: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1241967 ofs=0
+ <unknown>-12683 (-----) [006] .... 1920260.580454: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1116541 ofs=4096
+ <unknown>-12683 (-----) [006] .... 1920260.580461: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1145049 ofs=8192
+ <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1277255 ofs=12288
+ <unknown>-12683 (-----) [006] .... 1920260.580462: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1098037 ofs=16384
+ <unknown>-12683 (-----) [006] .... 1920260.580463: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1135986 ofs=20480
+ <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1154455 ofs=24576
+ <unknown>-12683 (-----) [006] .... 1920260.580464: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1221822 ofs=28672
+ <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1078684 ofs=32768
+ <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1158876 ofs=36864
+ <unknown>-12683 (-----) [006] .... 1920260.580465: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1289644 ofs=40960
+ <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1289386 ofs=45056
+ <unknown>-12683 (-----) [006] .... 1920260.580466: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1131002 ofs=49152
+ <unknown>-12683 (-----) [006] .... 1920260.580467: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1464335 ofs=53248
+ <unknown>-12683 (-----) [006] .... 1920260.580468: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1135789 ofs=57344
+ <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1240897 ofs=61440
+ <unknown>-12683 (-----) [006] .... 1920260.580469: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1241770 ofs=65536
+ <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1421959 ofs=69632
+ <unknown>-12683 (-----) [006] .... 1920260.580470: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1230007 ofs=73728
+ <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1109271 ofs=77824
+ <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1159974 ofs=81920
+ <unknown>-12683 (-----) [006] .... 1920260.580471: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1154528 ofs=86016
+ <unknown>-12683 (-----) [006] .... 1920260.580472: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1315790 ofs=90112
+ <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1185583 ofs=94208
+ <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1253153 ofs=98304
+ <unknown>-12683 (-----) [006] .... 1920260.580473: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103982 ofs=102400
+ <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1284589 ofs=106496
+ <unknown>-12683 (-----) [006] .... 1920260.580474: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1169601 ofs=110592
+ <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1206248 ofs=114688
+ <unknown>-12683 (-----) [006] .... 1920260.580476: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1261161 ofs=118784
+ <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1305841 ofs=122880
+ <unknown>-12683 (-----) [006] .... 1920260.580477: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1468293 ofs=126976
+ <unknown>-12683 (-----) [004] .... 1920260.580646: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1318816 ofs=16384
+ <unknown>-12683 (-----) [004] .... 1920260.580649: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1472922 ofs=20480
+ <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1473229 ofs=24576
+ <unknown>-12683 (-----) [004] .... 1920260.580650: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1524262 ofs=28672
+ <unknown>-12683 (-----) [004] .... 1920260.580656: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1205714 ofs=32768
+ <unknown>-12683 (-----) [004] .... 1920260.580657: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1310560 ofs=36864
+ <unknown>-12683 (-----) [004] .... 1920260.580658: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1295070 ofs=40960
+ <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1404093 ofs=45056
+ <unknown>-12683 (-----) [004] .... 1920260.580659: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1435814 ofs=49152
+ <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1435442 ofs=53248
+ <unknown>-12683 (-----) [004] .... 1920260.580660: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1096077 ofs=57344
+ <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1483793 ofs=61440
+ <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1231298 ofs=65536
+ <unknown>-12683 (-----) [004] .... 1920260.580661: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1215648 ofs=69632
+ <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1327326 ofs=73728
+ <unknown>-12683 (-----) [004] .... 1920260.580662: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1108894 ofs=77824
+ <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1327545 ofs=81920
+ <unknown>-12683 (-----) [004] .... 1920260.580663: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1328804 ofs=86016
+ <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1300171 ofs=90112
+ <unknown>-12683 (-----) [004] .... 1920260.580664: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1353250 ofs=94208
+ <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1333681 ofs=98304
+ <unknown>-12683 (-----) [004] .... 1920260.580668: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1144969 ofs=102400
+ <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1450962 ofs=106496
+ <unknown>-12683 (-----) [004] .... 1920260.580669: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1255701 ofs=110592
+ <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1294782 ofs=114688
+ <unknown>-12683 (-----) [004] .... 1920260.580670: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1226912 ofs=118784
+ <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1294579 ofs=122880
+ <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1246960 ofs=126976
+ <unknown>-12683 (-----) [004] .... 1920260.580671: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1199086 ofs=131072
+ <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1449590 ofs=135168
+ <unknown>-12683 (-----) [004] .... 1920260.580672: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1276363 ofs=139264
+ <unknown>-12683 (-----) [004] .... 1920260.580675: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1389998 ofs=143360
+ <unknown>-12683 (-----) [004] .... 1920260.580739: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1423031 ofs=1249280
+ <unknown>-12683 (-----) [004] .... 1920260.580741: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1171032 ofs=1253376
+ <unknown>-12683 (-----) [004] .... 1920260.580742: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1320946 ofs=1257472
+ <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1314696 ofs=1261568
+ <unknown>-12683 (-----) [004] .... 1920260.580743: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1414864 ofs=1265664
+ <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1334933 ofs=1269760
+ <unknown>-12683 (-----) [004] .... 1920260.580744: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1242845 ofs=1273856
+ <unknown>-12683 (-----) [004] .... 1920260.580747: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1289488 ofs=1277952
+ <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1335445 ofs=1282048
+ <unknown>-12683 (-----) [004] .... 1920260.580748: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1289663 ofs=1286144
+ <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1080462 ofs=1290240
+ <unknown>-12683 (-----) [004] .... 1920260.580749: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1286303 ofs=1294336
+ <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1353531 ofs=1298432
+ <unknown>-12683 (-----) [004] .... 1920260.580750: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1280701 ofs=1302528
+ <unknown>-12683 (-----) [004] .... 1920260.580751: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1107730 ofs=1306624
+ <unknown>-12683 (-----) [004] .... 1920260.580752: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1242729 ofs=1310720
+ <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1078336 ofs=1314816
+ <unknown>-12683 (-----) [004] .... 1920260.580753: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1372425 ofs=1318912
+ <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1248813 ofs=1323008
+ <unknown>-12683 (-----) [004] .... 1920260.580754: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1201155 ofs=1327104
+ <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1250103 ofs=1331200
+ <unknown>-12683 (-----) [004] .... 1920260.580755: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1359710 ofs=1335296
+ <unknown>-12683 (-----) [004] .... 1920260.580756: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1272462 ofs=1339392
+ <unknown>-12683 (-----) [004] .... 1920260.580758: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1097035 ofs=1343488
+ <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1233124 ofs=1347584
+ <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1455812 ofs=1351680
+ <unknown>-12683 (-----) [004] .... 1920260.580759: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1355689 ofs=1355776
+ <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1263593 ofs=1359872
+ <unknown>-12683 (-----) [004] .... 1920260.580760: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1230789 ofs=1363968
+ <unknown>-12683 (-----) [004] .... 1920260.580761: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1143766 ofs=1368064
+ <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1269666 ofs=1372160
+ <unknown>-12683 (-----) [004] .... 1920260.580762: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1353022 ofs=1376256
+ <unknown>-12683 (-----) [004] .... 1920260.581613: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1355509 ofs=258048
+ <unknown>-12683 (-----) [004] .... 1920260.581615: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1178902 ofs=262144
+ <unknown>-12683 (-----) [004] .... 1920260.581616: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1193649 ofs=266240
+ <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1225497 ofs=270336
+ <unknown>-12683 (-----) [004] .... 1920260.581618: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1228259 ofs=274432
+ <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1309674 ofs=278528
+ <unknown>-12683 (-----) [004] .... 1920260.581635: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1239390 ofs=282624
+ <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1468083 ofs=286720
+ <unknown>-12683 (-----) [004] .... 1920260.581636: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1292751 ofs=290816
+ <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1318066 ofs=294912
+ <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1489314 ofs=299008
+ <unknown>-12683 (-----) [004] .... 1920260.581637: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1169867 ofs=303104
+ <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1314256 ofs=307200
+ <unknown>-12683 (-----) [004] .... 1920260.581639: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1310230 ofs=311296
+ <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1356180 ofs=315392
+ <unknown>-12683 (-----) [004] .... 1920260.581640: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1419179 ofs=319488
+ <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1307265 ofs=323584
+ <unknown>-12683 (-----) [004] .... 1920260.581641: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1218590 ofs=327680
+ <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1447586 ofs=331776
+ <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1209382 ofs=335872
+ <unknown>-12683 (-----) [004] .... 1920260.581642: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1072148 ofs=339968
+ <unknown>-12683 (-----) [004] .... 1920260.581645: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1227195 ofs=344064
+ <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1246369 ofs=348160
+ <unknown>-12683 (-----) [004] .... 1920260.581646: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1193845 ofs=352256
+ <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1137553 ofs=356352
+ <unknown>-12683 (-----) [004] .... 1920260.581647: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1475215 ofs=360448
+ <unknown>-12683 (-----) [004] .... 1920260.581648: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1258935 ofs=364544
+ <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1448788 ofs=368640
+ <unknown>-12683 (-----) [004] .... 1920260.581649: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1447611 ofs=372736
+ <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1290842 ofs=376832
+ <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1447826 ofs=380928
+ <unknown>-12683 (-----) [004] .... 1920260.581650: mm_filemap_add_to_page_cache: dev 0:64771 ino 55815 page=0000000000000000 pfn=1181016 ofs=385024
+ <unknown>-12683 (-----) [005] .... 1920260.582230: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1216810 ofs=1662976
+ <unknown>-12683 (-----) [005] .... 1920260.582234: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1175966 ofs=1667072
+ <unknown>-12683 (-----) [005] .... 1920260.582235: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1449798 ofs=1671168
+ <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1273480 ofs=1675264
+ <unknown>-12683 (-----) [005] .... 1920260.582236: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1152779 ofs=1679360
+ <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1272810 ofs=1683456
+ <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1248634 ofs=1687552
+ <unknown>-12683 (-----) [005] .... 1920260.582237: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1203376 ofs=1691648
+ <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1138880 ofs=1695744
+ <unknown>-12683 (-----) [005] .... 1920260.582238: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1344591 ofs=1699840
+ <unknown>-12683 (-----) [005] .... 1920260.582239: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1416060 ofs=1703936
+ <unknown>-12683 (-----) [005] .... 1920260.582246: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1128676 ofs=1708032
+ <unknown>-12683 (-----) [005] .... 1920260.582247: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1301921 ofs=1712128
+ <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1384569 ofs=1716224
+ <unknown>-12683 (-----) [005] .... 1920260.582248: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1249106 ofs=1720320
+ <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1206596 ofs=1724416
+ <unknown>-12683 (-----) [005] .... 1920260.582249: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1429831 ofs=1728512
+ <unknown>-12683 (-----) [005] .... 1920260.582252: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1107796 ofs=1732608
+ <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1098336 ofs=1736704
+ <unknown>-12683 (-----) [005] .... 1920260.582255: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1230286 ofs=1740800
+ <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1100370 ofs=1744896
+ <unknown>-12683 (-----) [005] .... 1920260.582256: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1241930 ofs=1748992
+ <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1366807 ofs=1753088
+ <unknown>-12683 (-----) [005] .... 1920260.582257: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1136252 ofs=1757184
+ <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1274291 ofs=1761280
+ <unknown>-12683 (-----) [005] .... 1920260.582258: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1254775 ofs=1765376
+ <unknown>-12683 (-----) [005] .... 1920260.582259: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1194679 ofs=1769472
+ <unknown>-12683 (-----) [005] .... 1920260.582262: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1177090 ofs=1773568
+ <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1343925 ofs=1777664
+ <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1159217 ofs=1781760
+ <unknown>-12683 (-----) [005] .... 1920260.582263: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1435471 ofs=1785856
+ <unknown>-12683 (-----) [005] .... 1920260.582264: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1435529 ofs=1789952
+ <unknown>-12683 (-----) [004] .... 1920260.582524: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1181910 ofs=0
+ <unknown>-12683 (-----) [004] .... 1920260.582528: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1212021 ofs=4096
+ <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1162778 ofs=8192
+ <unknown>-12683 (-----) [004] .... 1920260.582529: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1107700 ofs=12288
+ <unknown>-12683 (-----) [004] .... 1920260.583553: mm_filemap_add_to_page_cache: dev 0:64771 ino 57137 page=0000000000000000 pfn=1093394 ofs=3399680
+ <unknown>-12683 (-----) [004] .... 1920260.583984: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1121431 ofs=242503680
+ <unknown>-12683 (-----) [004] .... 1920260.583986: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1168551 ofs=13115392
+ <unknown>-12683 (-----) [004] .... 1920260.584304: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1347409 ofs=0
+ <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1428681 ofs=4096
+ <unknown>-12683 (-----) [004] .... 1920260.584307: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1259106 ofs=8192
+ <unknown>-12683 (-----) [004] .... 1920260.584308: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1343229 ofs=12288
+ <unknown>-12694 (-----) [005] .... 1920260.584622: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1098733 ofs=1531904
+ <unknown>-12696 (-----) [006] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1331319 ofs=1536000
+ <unknown>-12694 (-----) [005] .... 1920260.584626: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1278537 ofs=1540096
+ <unknown>-12696 (-----) [006] .... 1920260.584631: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1492534 ofs=1544192
+ <unknown>-12694 (-----) [005] .... 1920260.584636: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1460878 ofs=1548288
+ <unknown>-12694 (-----) [005] .... 1920260.584640: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1092973 ofs=1552384
+ <unknown>-12694 (-----) [005] .... 1920260.584641: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1103200 ofs=1556480
+ <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1257426 ofs=1560576
+ <unknown>-12694 (-----) [005] .... 1920260.584642: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1219424 ofs=1564672
+ <unknown>-12683 (-----) [004] .... 1920260.584660: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1279352 ofs=1568768
+ <unknown>-12696 (-----) [006] .... 1920260.584662: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1260572 ofs=1572864
+ <unknown>-12683 (-----) [004] .... 1920260.584663: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1225809 ofs=1576960
+ <unknown>-12696 (-----) [006] .... 1920260.584665: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1350766 ofs=1585152
+ <unknown>-12697 (-----) [007] .... 1920260.584666: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1107173 ofs=1581056
+ <unknown>-12683 (-----) [004] .... 1920260.584668: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1305885 ofs=1589248
+ <unknown>-12694 (-----) [005] .... 1920260.584669: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1293385 ofs=1593344
+ <unknown>-12696 (-----) [006] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1173841 ofs=1597440
+ <unknown>-12697 (-----) [007] .... 1920260.584670: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1080021 ofs=1601536
+ <unknown>-12683 (-----) [004] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1147419 ofs=1605632
+ <unknown>-12696 (-----) [006] .... 1920260.584673: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1252762 ofs=1609728
+ <unknown>-12694 (-----) [005] .... 1920260.584674: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1323916 ofs=1613824
+ <unknown>-12683 (-----) [004] .... 1920260.584675: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1155631 ofs=1617920
+ <unknown>-12696 (-----) [006] .... 1920260.584676: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1449815 ofs=1622016
+ <unknown>-12694 (-----) [005] .... 1920260.584678: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1227069 ofs=1626112
+ <unknown>-12696 (-----) [006] .... 1920260.584680: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1317692 ofs=1630208
+ <unknown>-12694 (-----) [005] .... 1920260.584681: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1492244 ofs=1634304
+ <unknown>-12683 (-----) [004] .... 1920260.584682: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1241876 ofs=1638400
+ <unknown>-12697 (-----) [007] .... 1920260.585446: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1402958 ofs=167936
+ <unknown>-12697 (-----) [007] .... 1920260.585449: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1133263 ofs=172032
+ <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1295502 ofs=176128
+ <unknown>-12697 (-----) [007] .... 1920260.585450: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1249495 ofs=180224
+ <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1237999 ofs=184320
+ <unknown>-12697 (-----) [007] .... 1920260.585451: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1280965 ofs=188416
+ <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1208361 ofs=192512
+ <unknown>-12697 (-----) [007] .... 1920260.585454: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1308840 ofs=196608
+ <unknown>-12695 (-----) [004] .... 1920260.585455: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1138875 ofs=569344
+ <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1314886 ofs=573440
+ <unknown>-12697 (-----) [007] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1242734 ofs=200704
+ <unknown>-12695 (-----) [004] .... 1920260.585458: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1447386 ofs=577536
+ <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1241302 ofs=204800
+ <unknown>-12695 (-----) [004] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1328663 ofs=581632
+ <unknown>-12697 (-----) [007] .... 1920260.585459: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1476101 ofs=208896
+ <unknown>-12695 (-----) [004] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1209461 ofs=585728
+ <unknown>-12697 (-----) [007] .... 1920260.585460: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1080147 ofs=212992
+ <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1128509 ofs=217088
+ <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1371915 ofs=221184
+ <unknown>-12697 (-----) [007] .... 1920260.585461: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1264015 ofs=225280
+ <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1211695 ofs=229376
+ <unknown>-12697 (-----) [007] .... 1920260.585462: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1150386 ofs=233472
+ <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1135747 ofs=237568
+ <unknown>-12697 (-----) [007] .... 1920260.585463: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1128230 ofs=241664
+ <unknown>-12697 (-----) [007] .... 1920260.585464: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1155451 ofs=245760
+ <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1246841 ofs=249856
+ <unknown>-12697 (-----) [007] .... 1920260.585465: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1462971 ofs=253952
+ <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1131333 ofs=258048
+ <unknown>-12697 (-----) [007] .... 1920260.585466: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1289407 ofs=262144
+ <unknown>-12695 (-----) [004] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1134730 ofs=589824
+ <unknown>-12697 (-----) [007] .... 1920260.585467: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1289873 ofs=266240
+ <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1448734 ofs=270336
+ <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1129776 ofs=593920
+ <unknown>-12697 (-----) [007] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1524090 ofs=274432
+ <unknown>-12695 (-----) [004] .... 1920260.585468: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1399725 ofs=598016
+ <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1524081 ofs=278528
+ <unknown>-12695 (-----) [004] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1276535 ofs=602112
+ <unknown>-12697 (-----) [007] .... 1920260.585469: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1524060 ofs=282624
+ <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1449847 ofs=606208
+ <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1158944 ofs=286720
+ <unknown>-12695 (-----) [004] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1384536 ofs=610304
+ <unknown>-12697 (-----) [007] .... 1920260.585470: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1116785 ofs=290816
+ <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1308118 ofs=614400
+ <unknown>-12697 (-----) [007] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1448669 ofs=294912
+ <unknown>-12695 (-----) [004] .... 1920260.585471: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1227050 ofs=618496
+ <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1289324 ofs=622592
+ <unknown>-12695 (-----) [004] .... 1920260.585473: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1187869 ofs=626688
+ <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1400523 ofs=630784
+ <unknown>-12695 (-----) [004] .... 1920260.585474: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1344176 ofs=634880
+ <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1092871 ofs=638976
+ <unknown>-12695 (-----) [004] .... 1920260.585475: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1092021 ofs=643072
+ <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1198169 ofs=647168
+ <unknown>-12695 (-----) [004] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1371540 ofs=651264
+ <unknown>-12683 (-----) [005] .... 1920260.585476: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1195003 ofs=348160
+ <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1228787 ofs=655360
+ <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1236123 ofs=659456
+ <unknown>-12695 (-----) [004] .... 1920260.585477: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1137213 ofs=663552
+ <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1294618 ofs=667648
+ <unknown>-12695 (-----) [004] .... 1920260.585478: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1241048 ofs=671744
+ <unknown>-12695 (-----) [004] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1228779 ofs=675840
+ <unknown>-12683 (-----) [005] .... 1920260.585479: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1199292 ofs=352256
+ <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1200861 ofs=356352
+ <unknown>-12695 (-----) [004] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1309572 ofs=679936
+ <unknown>-12683 (-----) [005] .... 1920260.585480: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1215770 ofs=360448
+ <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1409002 ofs=684032
+ <unknown>-12683 (-----) [005] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1151883 ofs=364544
+ <unknown>-12695 (-----) [004] .... 1920260.585481: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1103729 ofs=688128
+ <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1468126 ofs=368640
+ <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1162720 ofs=692224
+ <unknown>-12683 (-----) [005] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1251672 ofs=372736
+ <unknown>-12695 (-----) [004] .... 1920260.585482: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1199221 ofs=696320
+ <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1283325 ofs=376832
+ <unknown>-12683 (-----) [005] .... 1920260.585483: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1190489 ofs=380928
+ <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1489117 ofs=385024
+ <unknown>-12683 (-----) [005] .... 1920260.585484: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1273899 ofs=389120
+ <unknown>-12683 (-----) [005] .... 1920260.585485: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1274459 ofs=393216
+ <unknown>-12683 (-----) [005] .... 1920260.585486: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1316649 ofs=397312
+ <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1375678 ofs=401408
+ <unknown>-12683 (-----) [005] .... 1920260.585491: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1483317 ofs=405504
+ <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1240286 ofs=409600
+ <unknown>-12683 (-----) [005] .... 1920260.585492: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1131345 ofs=413696
+ <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1200483 ofs=417792
+ <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1384693 ofs=421888
+ <unknown>-12683 (-----) [005] .... 1920260.585493: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1161385 ofs=425984
+ <unknown>-12683 (-----) [005] .... 1920260.585494: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1452025 ofs=430080
+ <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1253654 ofs=434176
+ <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1116697 ofs=438272
+ <unknown>-12683 (-----) [005] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1432645 ofs=442368
+ <unknown>-12694 (-----) [006] .... 1920260.585495: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1337397 ofs=16384
+ <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1304229 ofs=446464
+ <unknown>-12683 (-----) [005] .... 1920260.585496: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1419147 ofs=450560
+ <unknown>-12683 (-----) [005] .... 1920260.585498: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1349246 ofs=454656
+ <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1128519 ofs=458752
+ <unknown>-12683 (-----) [005] .... 1920260.585499: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1125168 ofs=462848
+ <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1081031 ofs=20480
+ <unknown>-12694 (-----) [006] .... 1920260.585509: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1293022 ofs=24576
+ <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1113007 ofs=28672
+ <unknown>-12694 (-----) [006] .... 1920260.585510: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1339312 ofs=32768
+ <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1412311 ofs=36864
+ <unknown>-12694 (-----) [006] .... 1920260.585511: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1260960 ofs=40960
+ <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1189529 ofs=45056
+ <unknown>-12694 (-----) [006] .... 1920260.585512: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1412184 ofs=49152
+ <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1481227 ofs=53248
+ <unknown>-12694 (-----) [006] .... 1920260.585513: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1455940 ofs=57344
+ <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1299132 ofs=61440
+ <unknown>-12694 (-----) [006] .... 1920260.585514: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1337375 ofs=65536
+ <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1328742 ofs=69632
+ <unknown>-12694 (-----) [006] .... 1920260.585529: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1315646 ofs=73728
+ <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1225475 ofs=77824
+ <unknown>-12694 (-----) [006] .... 1920260.585531: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1146097 ofs=81920
+ <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1318775 ofs=86016
+ <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1448391 ofs=90112
+ <unknown>-12694 (-----) [006] .... 1920260.585532: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1441412 ofs=94208
+ <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1138111 ofs=98304
+ <unknown>-12694 (-----) [006] .... 1920260.585533: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1143223 ofs=102400
+ <unknown>-12683 (-----) [005] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1079876 ofs=466944
+ <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1447637 ofs=106496
+ <unknown>-12694 (-----) [006] .... 1920260.585534: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1220585 ofs=110592
+ <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1449051 ofs=114688
+ <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1313180 ofs=118784
+ <unknown>-12694 (-----) [006] .... 1920260.585535: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1313166 ofs=122880
+ <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1313154 ofs=126976
+ <unknown>-12683 (-----) [005] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1218394 ofs=471040
+ <unknown>-12694 (-----) [006] .... 1920260.585536: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1144047 ofs=131072
+ <unknown>-12683 (-----) [005] .... 1920260.585537: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1218579 ofs=475136
+ <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1241332 ofs=135168
+ <unknown>-12694 (-----) [006] .... 1920260.585543: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1097199 ofs=139264
+ <unknown>-12694 (-----) [006] .... 1920260.585545: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1214197 ofs=143360
+ <unknown>-12694 (-----) [006] .... 1920260.585645: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1197633 ofs=147456
+ <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1311536 ofs=151552
+ <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1322952 ofs=155648
+ <unknown>-12694 (-----) [006] .... 1920260.585647: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1346974 ofs=159744
+ <unknown>-12694 (-----) [006] .... 1920260.585648: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1257232 ofs=163840
+ <unknown>-12695 (-----) [004] .... 1920260.586355: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1204484 ofs=700416
+ <unknown>-12695 (-----) [004] .... 1920260.586357: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1326426 ofs=704512
+ <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1151808 ofs=708608
+ <unknown>-12695 (-----) [004] .... 1920260.586358: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1209422 ofs=712704
+ <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1408387 ofs=716800
+ <unknown>-12695 (-----) [004] .... 1920260.586359: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1197336 ofs=720896
+ <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1205652 ofs=724992
+ <unknown>-12695 (-----) [004] .... 1920260.586363: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1133421 ofs=729088
+ <unknown>-12695 (-----) [004] .... 1920260.586364: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1092173 ofs=733184
+ <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1124430 ofs=737280
+ <unknown>-12695 (-----) [004] .... 1920260.586365: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1143926 ofs=741376
+ <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1090109 ofs=745472
+ <unknown>-12695 (-----) [004] .... 1920260.586366: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1102012 ofs=749568
+ <unknown>-12695 (-----) [004] .... 1920260.586367: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1154930 ofs=753664
+ <unknown>-12695 (-----) [004] .... 1920260.586368: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1132993 ofs=757760
+ <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1430780 ofs=761856
+ <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1197452 ofs=765952
+ <unknown>-12695 (-----) [004] .... 1920260.586369: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1075111 ofs=770048
+ <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1275616 ofs=774144
+ <unknown>-12695 (-----) [004] .... 1920260.586370: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1444981 ofs=778240
+ <unknown>-12695 (-----) [004] .... 1920260.586371: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1452592 ofs=782336
+ <unknown>-12695 (-----) [004] .... 1920260.586374: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1102857 ofs=786432
+ <unknown>-12695 (-----) [004] .... 1920260.586376: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1406969 ofs=790528
+ <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1522553 ofs=794624
+ <unknown>-12695 (-----) [004] .... 1920260.586378: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1260771 ofs=798720
+ <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1474649 ofs=802816
+ <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1268708 ofs=806912
+ <unknown>-12695 (-----) [004] .... 1920260.586379: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1346144 ofs=811008
+ <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1081167 ofs=815104
+ <unknown>-12695 (-----) [004] .... 1920260.586380: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1137677 ofs=819200
+ <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1161175 ofs=823296
+ <unknown>-12695 (-----) [004] .... 1920260.586381: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1461331 ofs=827392
+ <unknown>-12695 (-----) [004] .... 1920260.586492: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1347219 ofs=831488
+ <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1290004 ofs=835584
+ <unknown>-12695 (-----) [004] .... 1920260.586494: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1299174 ofs=839680
+ <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1317595 ofs=843776
+ <unknown>-12695 (-----) [004] .... 1920260.586496: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1484924 ofs=847872
+ <unknown>-12695 (-----) [004] .... 1920260.586497: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1169920 ofs=851968
+ <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1359189 ofs=856064
+ <unknown>-12695 (-----) [004] .... 1920260.586501: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1307842 ofs=860160
+ <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1237858 ofs=864256
+ <unknown>-12695 (-----) [004] .... 1920260.586502: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1189461 ofs=868352
+ <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1223232 ofs=872448
+ <unknown>-12695 (-----) [004] .... 1920260.586503: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1104076 ofs=876544
+ <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1079223 ofs=880640
+ <unknown>-12695 (-----) [004] .... 1920260.586504: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1092537 ofs=884736
+ <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1353960 ofs=888832
+ <unknown>-12695 (-----) [004] .... 1920260.586505: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1346330 ofs=892928
+ <unknown>-12695 (-----) [004] .... 1920260.586506: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1345764 ofs=897024
+ <unknown>-12695 (-----) [004] .... 1920260.586507: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1363913 ofs=901120
+ <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1319570 ofs=905216
+ <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1367024 ofs=909312
+ <unknown>-12695 (-----) [004] .... 1920260.586508: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1333808 ofs=913408
+ <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1158627 ofs=917504
+ <unknown>-12695 (-----) [004] .... 1920260.586509: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1300368 ofs=921600
+ <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1245363 ofs=925696
+ <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1345609 ofs=929792
+ <unknown>-12695 (-----) [004] .... 1920260.586510: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1393826 ofs=933888
+ <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1200552 ofs=937984
+ <unknown>-12695 (-----) [004] .... 1920260.586511: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1170885 ofs=942080
+ <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1536209 ofs=946176
+ <unknown>-12695 (-----) [004] .... 1920260.586512: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1189630 ofs=950272
+ <unknown>-12695 (-----) [004] .... 1920260.586513: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1121010 ofs=954368
+ <unknown>-12695 (-----) [004] .... 1920260.586514: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1324474 ofs=958464
+ <unknown>-12697 (-----) [007] .... 1920260.586578: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1129628 ofs=299008
+ <unknown>-12697 (-----) [007] .... 1920260.586579: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1307120 ofs=303104
+ <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1347284 ofs=307200
+ <unknown>-12697 (-----) [007] .... 1920260.586580: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1312996 ofs=311296
+ <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1170623 ofs=315392
+ <unknown>-12697 (-----) [007] .... 1920260.586581: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1359281 ofs=319488
+ <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1180021 ofs=323584
+ <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1195728 ofs=327680
+ <unknown>-12697 (-----) [007] .... 1920260.586582: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1163642 ofs=331776
+ <unknown>-12697 (-----) [007] .... 1920260.586587: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1152538 ofs=335872
+ <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1345922 ofs=339968
+ <unknown>-12697 (-----) [007] .... 1920260.586589: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1343604 ofs=344064
+ <unknown>-12697 (-----) [007] .... 1920260.586721: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1399371 ofs=479232
+ <unknown>-12697 (-----) [007] .... 1920260.586723: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1106549 ofs=483328
+ <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1331546 ofs=487424
+ <unknown>-12697 (-----) [007] .... 1920260.586724: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1299299 ofs=491520
+ <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1288883 ofs=495616
+ <unknown>-12697 (-----) [007] .... 1920260.586725: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1399049 ofs=499712
+ <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1146931 ofs=503808
+ <unknown>-12697 (-----) [007] .... 1920260.586726: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1296592 ofs=507904
+ <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1468397 ofs=512000
+ <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1215698 ofs=516096
+ <unknown>-12697 (-----) [007] .... 1920260.586727: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1177341 ofs=520192
+ <unknown>-12697 (-----) [007] .... 1920260.586731: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1189162 ofs=524288
+ <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1435997 ofs=528384
+ <unknown>-12697 (-----) [007] .... 1920260.586732: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1209896 ofs=532480
+ <unknown>-12697 (-----) [007] .... 1920260.586733: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1255888 ofs=536576
+ <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1234200 ofs=540672
+ <unknown>-12697 (-----) [007] .... 1920260.586734: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1422854 ofs=544768
+ <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1435794 ofs=548864
+ <unknown>-12697 (-----) [007] .... 1920260.586735: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1236279 ofs=552960
+ <unknown>-12697 (-----) [007] .... 1920260.586736: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1485732 ofs=557056
+ <unknown>-12683 (-----) [005] .... 1920260.586743: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1417198 ofs=561152
+ <unknown>-12683 (-----) [005] .... 1920260.586746: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1469450 ofs=565248
+ <unknown>-12696 (-----) [004] .... 1920260.587465: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1489023 ofs=1040384
+ <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1449498 ofs=1044480
+ <unknown>-12696 (-----) [004] .... 1920260.587469: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1447737 ofs=1048576
+ <unknown>-12696 (-----) [004] .... 1920260.587470: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1124530 ofs=1052672
+ <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1246743 ofs=1056768
+ <unknown>-12696 (-----) [004] .... 1920260.587476: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1441927 ofs=1060864
+ <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1280581 ofs=1064960
+ <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1289438 ofs=1069056
+ <unknown>-12696 (-----) [004] .... 1920260.587477: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1464236 ofs=1073152
+ <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1125808 ofs=1077248
+ <unknown>-12696 (-----) [004] .... 1920260.587478: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1329385 ofs=1081344
+ <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1314093 ofs=1085440
+ <unknown>-12696 (-----) [004] .... 1920260.587480: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1201837 ofs=1089536
+ <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1327734 ofs=1093632
+ <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1406568 ofs=1097728
+ <unknown>-12696 (-----) [004] .... 1920260.587481: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1331873 ofs=1101824
+ <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1331898 ofs=1105920
+ <unknown>-12696 (-----) [004] .... 1920260.587482: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1331917 ofs=1110016
+ <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1332091 ofs=1114112
+ <unknown>-12696 (-----) [004] .... 1920260.587483: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1108186 ofs=1118208
+ <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1182631 ofs=1122304
+ <unknown>-12696 (-----) [004] .... 1920260.587486: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1085941 ofs=1126400
+ <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1433982 ofs=1130496
+ <unknown>-12696 (-----) [004] .... 1920260.587487: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1387028 ofs=1134592
+ <unknown>-12696 (-----) [004] .... 1920260.587488: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1353117 ofs=1138688
+ <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1352364 ofs=1142784
+ <unknown>-12696 (-----) [004] .... 1920260.587489: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1144513 ofs=1146880
+ <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1403984 ofs=1150976
+ <unknown>-12696 (-----) [004] .... 1920260.587490: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1278970 ofs=1155072
+ <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1326743 ofs=1159168
+ <unknown>-12696 (-----) [004] .... 1920260.587491: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1221809 ofs=1163264
+ <unknown>-12696 (-----) [004] .... 1920260.587492: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1268668 ofs=1167360
+ <unknown>-12695 (-----) [005] .... 1920260.587502: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1074544 ofs=962560
+ <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1074294 ofs=966656
+ <unknown>-12695 (-----) [005] .... 1920260.587506: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1075097 ofs=970752
+ <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1162407 ofs=974848
+ <unknown>-12695 (-----) [005] .... 1920260.587507: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1141370 ofs=978944
+ <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1306487 ofs=983040
+ <unknown>-12695 (-----) [005] .... 1920260.587508: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1306434 ofs=987136
+ <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1306347 ofs=991232
+ <unknown>-12695 (-----) [005] .... 1920260.587514: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1306247 ofs=995328
+ <unknown>-12695 (-----) [005] .... 1920260.587515: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1306195 ofs=999424
+ <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1306039 ofs=1003520
+ <unknown>-12695 (-----) [005] .... 1920260.587516: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1305983 ofs=1007616
+ <unknown>-12694 (-----) [006] .... 1920260.587701: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1216391 ofs=1171456
+ <unknown>-12694 (-----) [006] .... 1920260.587705: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1262462 ofs=1175552
+ <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1358114 ofs=1179648
+ <unknown>-12694 (-----) [006] .... 1920260.587706: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1357898 ofs=1183744
+ <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1237003 ofs=1187840
+ <unknown>-12694 (-----) [006] .... 1920260.587707: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1126319 ofs=1191936
+ <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1415489 ofs=1196032
+ <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1279558 ofs=1200128
+ <unknown>-12694 (-----) [006] .... 1920260.587708: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1434022 ofs=1204224
+ <unknown>-12694 (-----) [006] .... 1920260.587709: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1220130 ofs=1208320
+ <unknown>-12694 (-----) [006] .... 1920260.587710: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1163037 ofs=1212416
+ <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1404501 ofs=1216512
+ <unknown>-12694 (-----) [006] .... 1920260.587711: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1406287 ofs=1220608
+ <unknown>-12697 (-----) [007] .... 1920260.588132: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1355143 ofs=1376256
+ <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1213923 ofs=1380352
+ <unknown>-12697 (-----) [007] .... 1920260.588136: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1243190 ofs=1384448
+ <unknown>-12697 (-----) [007] .... 1920260.588143: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1300698 ofs=1388544
+ <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1482568 ofs=1392640
+ <unknown>-12697 (-----) [007] .... 1920260.588144: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1461789 ofs=1396736
+ <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1242314 ofs=1400832
+ <unknown>-12697 (-----) [007] .... 1920260.588145: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1471996 ofs=1404928
+ <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1242742 ofs=1409024
+ <unknown>-12697 (-----) [007] .... 1920260.588146: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1242579 ofs=1413120
+ <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1242553 ofs=1417216
+ <unknown>-12697 (-----) [007] .... 1920260.588148: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1457332 ofs=1421312
+ <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1315431 ofs=1425408
+ <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1080653 ofs=1429504
+ <unknown>-12697 (-----) [007] .... 1920260.588149: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1324174 ofs=1433600
+ <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1324142 ofs=1437696
+ <unknown>-12697 (-----) [007] .... 1920260.588150: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1157760 ofs=1441792
+ <unknown>-12697 (-----) [007] .... 1920260.588151: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1075059 ofs=1445888
+ <unknown>-12683 (-----) [006] .... 1920260.589785: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1279192 ofs=1486848
+ <unknown>-12683 (-----) [006] .... 1920260.589790: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1278527 ofs=1490944
+ <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1091778 ofs=1495040
+ <unknown>-12683 (-----) [006] .... 1920260.589791: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1339447 ofs=1499136
+ <unknown>-12683 (-----) [006] .... 1920260.589792: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1254007 ofs=1503232
+ <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1115173 ofs=1507328
+ <unknown>-12683 (-----) [006] .... 1920260.589793: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1393985 ofs=1511424
+ <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1369123 ofs=1515520
+ <unknown>-12683 (-----) [006] .... 1920260.589794: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1314257 ofs=1519616
+ <unknown>-12683 (-----) [006] .... 1920260.589802: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1404487 ofs=1523712
+ <unknown>-12683 (-----) [006] .... 1920260.589803: mm_filemap_add_to_page_cache: dev 0:64771 ino 59205 page=0000000000000000 pfn=1354554 ofs=1527808
+ <unknown>-12683 (-----) [006] .... 1920260.594312: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1141445 ofs=9801728
+ <unknown>-12683 (-----) [006] .... 1920260.594322: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323774 ofs=231460864
+ <unknown>-12683 (-----) [006] .... 1920260.594326: mm_filemap_add_to_page_cache: dev 0:64771 ino 2 page=0000000000000000 pfn=1323772 ofs=10993664
+ <unknown>-12683 (-----) [006] .... 1920260.595212: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1481305 ofs=9805824
+ <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1481306 ofs=9809920
+ <unknown>-12683 (-----) [006] .... 1920260.595214: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1481316 ofs=9814016
+ <unknown>-12683 (-----) [006] .... 1920260.595215: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1481340 ofs=9818112
+ <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1394587 ofs=9822208
+ <unknown>-12683 (-----) [006] .... 1920260.595216: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103455 ofs=9826304
+ <unknown>-12683 (-----) [006] .... 1920260.595217: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103271 ofs=9830400
+ <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103168 ofs=9834496
+ <unknown>-12683 (-----) [006] .... 1920260.595218: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103145 ofs=9838592
+ <unknown>-12683 (-----) [006] .... 1920260.595219: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103115 ofs=9842688
+ <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103057 ofs=9846784
+ <unknown>-12683 (-----) [006] .... 1920260.595222: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1331958 ofs=9850880
+ <unknown>-12683 (-----) [006] .... 1920260.595227: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1356305 ofs=9854976
+ <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103708 ofs=9859072
+ <unknown>-12683 (-----) [006] .... 1920260.595228: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1099286 ofs=9863168
+ <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1435190 ofs=9867264
+ <unknown>-12683 (-----) [006] .... 1920260.595229: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1395504 ofs=9871360
+ <unknown>-12683 (-----) [006] .... 1920260.595230: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1352916 ofs=9875456
+ <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1255529 ofs=9879552
+ <unknown>-12683 (-----) [006] .... 1920260.595231: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1336145 ofs=9883648
+ <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1334143 ofs=9887744
+ <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1328548 ofs=9891840
+ <unknown>-12683 (-----) [006] .... 1920260.595232: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1222215 ofs=9895936
+ <unknown>-12683 (-----) [006] .... 1920260.595233: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1461056 ofs=9900032
+ <unknown>-12683 (-----) [006] .... 1920260.595234: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1228276 ofs=9904128
+ <unknown>-12683 (-----) [006] .... 1920260.595235: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1151188 ofs=9908224
+ <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1443605 ofs=9912320
+ <unknown>-12683 (-----) [006] .... 1920260.595236: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1146821 ofs=9916416
+ <unknown>-12683 (-----) [006] .... 1920260.595237: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103669 ofs=9920512
+ <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103744 ofs=9924608
+ <unknown>-12683 (-----) [006] .... 1920260.595238: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1103868 ofs=9928704
+ <unknown>-12683 (-----) [006] .... 1920260.595789: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1465942 ofs=15855616
+ <unknown>-12683 (-----) [006] .... 1920260.595792: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323712 ofs=261189632
+ <unknown>-12683 (-----) [006] .... 1920260.595998: mm_filemap_add_to_page_cache: dev 0:64771 ino 1 page=0000000000000000 pfn=1323701 ofs=262094848
+ <unknown>-12683 (-----) [006] .... 1920260.596191: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1222287 ofs=15859712
+ <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1213146 ofs=15863808
+ <unknown>-12683 (-----) [006] .... 1920260.596192: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1310396 ofs=15867904
+ <unknown>-12683 (-----) [006] .... 1920260.596193: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1310177 ofs=15872000
+ <unknown>-12683 (-----) [006] .... 1920260.596194: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1187914 ofs=15876096
+ <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1322409 ofs=15880192
+ <unknown>-12683 (-----) [006] .... 1920260.596195: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1282484 ofs=15884288
+ <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1097245 ofs=15888384
+ <unknown>-12683 (-----) [006] .... 1920260.596200: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1416816 ofs=15892480
+ <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1257125 ofs=15896576
+ <unknown>-12683 (-----) [006] .... 1920260.596201: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1403527 ofs=15900672
+ <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1218006 ofs=15904768
+ <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1153893 ofs=15908864
+ <unknown>-12683 (-----) [006] .... 1920260.596202: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1328023 ofs=15912960
+ <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1465412 ofs=15917056
+ <unknown>-12683 (-----) [006] .... 1920260.596203: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1092448 ofs=15921152
+ <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1239220 ofs=15925248
+ <unknown>-12683 (-----) [006] .... 1920260.596204: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1276491 ofs=15929344
+ <unknown>-12683 (-----) [006] .... 1920260.596205: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1262240 ofs=15933440
+ <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1323793 ofs=15937536
+ <unknown>-12683 (-----) [006] .... 1920260.596206: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1074937 ofs=15941632
+ <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1311157 ofs=15945728
+ <unknown>-12683 (-----) [006] .... 1920260.596207: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1308442 ofs=15949824
+ <unknown>-12683 (-----) [006] .... 1920260.596210: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1467709 ofs=15953920
+ <unknown>-12683 (-----) [006] .... 1920260.596211: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1394299 ofs=15958016
+ <unknown>-12683 (-----) [004] .... 1920260.612586: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1316156 ofs=344064
+ <unknown>-12683 (-----) [004] .... 1920260.612591: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1406323 ofs=348160
+ <unknown>-12683 (-----) [004] .... 1920260.612601: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1216972 ofs=352256
+ <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1271924 ofs=356352
+ <unknown>-12683 (-----) [004] .... 1920260.612605: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1369225 ofs=360448
+ <unknown>-12683 (-----) [004] .... 1920260.612608: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1318474 ofs=364544
+ <unknown>-12683 (-----) [004] .... 1920260.612609: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1227283 ofs=368640
+ <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1364376 ofs=372736
+ <unknown>-12683 (-----) [004] .... 1920260.612613: mm_filemap_add_to_page_cache: dev 0:64771 ino 6154 page=0000000000000000 pfn=1073400 ofs=376832
diff --git a/startop/scripts/lib/cmd_utils.py b/startop/scripts/lib/cmd_utils.py
index bc5ca3140d3d..6071f145fe1d 100644
--- a/startop/scripts/lib/cmd_utils.py
+++ b/startop/scripts/lib/cmd_utils.py
@@ -26,6 +26,18 @@ import lib.print_utils as print_utils
TIMEOUT = 50
SIMULATE = False
+def run_command_nofail(cmd: List[str], **kwargs) -> None:
+ """Runs cmd list with default timeout.
+
+ Throws exception if the execution fails.
+ """
+ my_kwargs = {"timeout": TIMEOUT, "shell": False, "simulate": False}
+ my_kwargs.update(kwargs)
+ passed, out = execute_arbitrary_command(cmd, **my_kwargs)
+ if not passed:
+ raise RuntimeError(
+ "Failed to execute %s (kwargs=%s), output=%s" % (cmd, kwargs, out))
+
def run_adb_shell_command(cmd: str) -> Tuple[bool, str]:
"""Runs command using adb shell.
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 91bea5ff479b..4016c5c6c6f3 100755
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -3029,6 +3029,23 @@ public class CarrierConfigManager {
"is_opportunistic_subscription_bool";
/**
+ * Configs used by the IMS stack.
+ */
+ public static final class Ims {
+ /** Prefix of all Ims.KEY_* constants. */
+ public static final String KEY_PREFIX = "ims.";
+
+ //TODO: Add configs related to IMS.
+
+ private Ims() {}
+
+ private static PersistableBundle getDefaults() {
+ PersistableBundle defaults = new PersistableBundle();
+ return defaults;
+ }
+ }
+
+ /**
* A list of 4 GSM RSSI thresholds above which a signal level is considered POOR,
* MODERATE, GOOD, or EXCELLENT, to be used in SignalStrength reporting.
*
@@ -3463,6 +3480,7 @@ public class CarrierConfigManager {
-89, /* SIGNAL_STRENGTH_GREAT */
});
sDefaults.putBoolean(KEY_SUPPORT_WPS_OVER_IMS_BOOL, true);
+ sDefaults.putAll(Ims.getDefaults());
}
/**
@@ -3659,4 +3677,75 @@ public class CarrierConfigManager {
return ICarrierConfigLoader.Stub
.asInterface(ServiceManager.getService(Context.CARRIER_CONFIG_SERVICE));
}
+
+ /**
+ * Gets the configuration values for a component using its prefix.
+ *
+ * <p>Requires Permission:
+ * {@link android.Manifest.permission#READ_PHONE_STATE READ_PHONE_STATE}
+ *
+ * @param prefix prefix of the component.
+ * @param subId the subscription ID, normally obtained from {@link SubscriptionManager}.
+ *
+ * @see #getConfigForSubId
+ */
+ @Nullable
+ public PersistableBundle getConfigByComponentForSubId(String prefix, int subId) {
+ PersistableBundle configs = getConfigForSubId(subId);
+
+ if (configs == null) {
+ return null;
+ }
+
+ PersistableBundle ret = new PersistableBundle();
+ for (String configKey : configs.keySet()) {
+ if (configKey.startsWith(prefix)) {
+ addConfig(configKey, configs.get(configKey), ret);
+ }
+ }
+
+ return ret;
+ }
+
+ private void addConfig(String key, Object value, PersistableBundle configs) {
+ if (value instanceof String) {
+ configs.putString(key, (String) value);
+ }
+
+ if (value instanceof String[]) {
+ configs.putStringArray(key, (String[]) value);
+ }
+
+ if (value instanceof Integer) {
+ configs.putInt(key, (Integer) value);
+ }
+
+ if (value instanceof Long) {
+ configs.putLong(key, (Long) value);
+ }
+
+ if (value instanceof Double) {
+ configs.putDouble(key, (Double) value);
+ }
+
+ if (value instanceof Boolean) {
+ configs.putBoolean(key, (Boolean) value);
+ }
+
+ if (value instanceof int[]) {
+ configs.putIntArray(key, (int[]) value);
+ }
+
+ if (value instanceof double[]) {
+ configs.putDoubleArray(key, (double[]) value);
+ }
+
+ if (value instanceof boolean[]) {
+ configs.putBooleanArray(key, (boolean[]) value);
+ }
+
+ if (value instanceof long[]) {
+ configs.putLongArray(key, (long[]) value);
+ }
+ }
}
diff --git a/telephony/java/android/telephony/ims/ImsException.java b/telephony/java/android/telephony/ims/ImsException.java
index 8c686f704967..8e1324b3be0b 100644
--- a/telephony/java/android/telephony/ims/ImsException.java
+++ b/telephony/java/android/telephony/ims/ImsException.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.content.pm.PackageManager;
+import android.telephony.SubscriptionManager;
import android.text.TextUtils;
import java.lang.annotation.Retention;
@@ -55,12 +56,23 @@ public final class ImsException extends Exception {
*/
public static final int CODE_ERROR_UNSUPPORTED_OPERATION = 2;
+ /**
+ * The subscription ID associated with this operation is invalid or not active.
+ * <p>
+ * This is a configuration error and there should be no retry. The subscription used for this
+ * operation is either invalid or has become inactive. The active subscriptions can be queried
+ * with {@link SubscriptionManager#getActiveSubscriptionInfoList()}.
+ * @hide
+ */
+ public static final int CODE_ERROR_INVALID_SUBSCRIPTION = 3;
+
/**@hide*/
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "CODE_ERROR_", value = {
CODE_ERROR_UNSPECIFIED,
CODE_ERROR_SERVICE_UNAVAILABLE,
- CODE_ERROR_UNSUPPORTED_OPERATION
+ CODE_ERROR_UNSUPPORTED_OPERATION,
+ CODE_ERROR_INVALID_SUBSCRIPTION
})
public @interface ImsErrorCode {}
diff --git a/telephony/java/android/telephony/ims/ImsMmTelManager.java b/telephony/java/android/telephony/ims/ImsMmTelManager.java
index be5872387d7b..a1a7fcc5dd51 100644
--- a/telephony/java/android/telephony/ims/ImsMmTelManager.java
+++ b/telephony/java/android/telephony/ims/ImsMmTelManager.java
@@ -31,6 +31,7 @@ import android.net.Uri;
import android.os.Binder;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.ServiceSpecificException;
import android.telephony.AccessNetworkConstants;
import android.telephony.SubscriptionManager;
import android.telephony.ims.aidl.IImsCapabilityCallback;
@@ -375,6 +376,13 @@ public class ImsMmTelManager {
c.setExecutor(executor);
try {
getITelephony().registerImsRegistrationCallback(mSubId, c.getBinder());
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException | IllegalStateException e) {
throw new ImsException(e.getMessage(), ImsException.CODE_ERROR_SERVICE_UNAVAILABLE);
}
@@ -390,8 +398,6 @@ public class ImsMmTelManager {
* @param c The {@link RegistrationCallback} to be removed.
* @see SubscriptionManager.OnSubscriptionsChangedListener
* @see #registerImsRegistrationCallback(Executor, RegistrationCallback)
- * @throws IllegalArgumentException if the subscription ID associated with this callback is
- * invalid.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void unregisterImsRegistrationCallback(@NonNull RegistrationCallback c) {
@@ -445,6 +451,13 @@ public class ImsMmTelManager {
c.setExecutor(executor);
try {
getITelephony().registerMmTelCapabilityCallback(mSubId, c.getBinder());
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
} catch (IllegalStateException e) {
@@ -460,8 +473,6 @@ public class ImsMmTelManager {
* inactive subscription, it will result in a no-op.
* @param c The MmTel {@link CapabilityCallback} to be removed.
* @see #registerMmTelCapabilityCallback(Executor, CapabilityCallback)
- * @throws IllegalArgumentException if the subscription ID associated with this callback is
- * invalid.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public void unregisterMmTelCapabilityCallback(@NonNull CapabilityCallback c) {
@@ -482,12 +493,9 @@ public class ImsMmTelManager {
* be enabled as long as the carrier has provisioned these services for the specified
* subscription. Other IMS services (SMS/UT) are not affected by this user setting and depend on
* carrier requirements.
- *
- * Modifying this value may also trigger an IMS registration or deregistration, depending on
- * whether or not the new value is enabled or disabled.
- *
+ * <p>
* Note: If the carrier configuration for advanced calling is not editable or hidden, this
- * method will do nothing and will instead always use the default value.
+ * method will always return the default value.
*
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_PROVISIONING_REQUIRED_BOOL
* @see android.telephony.CarrierConfigManager#KEY_EDITABLE_ENHANCED_4G_LTE_BOOL
@@ -495,12 +503,21 @@ public class ImsMmTelManager {
* @see android.telephony.CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
* @see #setAdvancedCallingSettingEnabled(boolean)
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user's setting for advanced calling is enabled, false otherwise.
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isAdvancedCallingSettingEnabled() {
try {
return getITelephony().isAdvancedCallingSettingEnabled(mSubId);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -526,12 +543,20 @@ public class ImsMmTelManager {
* @see android.telephony.CarrierConfigManager#KEY_ENHANCED_4G_LTE_ON_BY_DEFAULT_BOOL
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_AVAILABLE_BOOL
* @see #isAdvancedCallingSettingEnabled()
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setAdvancedCallingSettingEnabled(boolean isEnabled) {
try {
getITelephony().setAdvancedCallingSettingEnabled(mSubId, isEnabled);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -597,6 +622,9 @@ public class ImsMmTelManager {
/**
* The user's setting for whether or not they have enabled the "Video Calling" setting.
+ *
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user’s “Video Calling†setting is currently enabled.
* @see #setVtSettingEnabled(boolean)
*/
@@ -604,6 +632,13 @@ public class ImsMmTelManager {
public boolean isVtSettingEnabled() {
try {
return getITelephony().isVtSettingEnabled(mSubId);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -611,13 +646,22 @@ public class ImsMmTelManager {
/**
* Change the user's setting for Video Telephony and enable the Video Telephony capability.
+ *
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see #isVtSettingEnabled()
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVtSettingEnabled(boolean isEnabled) {
try {
getITelephony().setVtSettingEnabled(mSubId, isEnabled);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -625,12 +669,22 @@ public class ImsMmTelManager {
/**
* @return true if the user's setting for Voice over WiFi is enabled and false if it is not.
+ *
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see #setVoWiFiSettingEnabled(boolean)
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public boolean isVoWiFiSettingEnabled() {
try {
return getITelephony().isVoWiFiSettingEnabled(mSubId);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -638,6 +692,9 @@ public class ImsMmTelManager {
/**
* Sets the user's setting for whether or not Voice over WiFi is enabled.
+ *
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @param isEnabled true if the user's setting for Voice over WiFi is enabled, false otherwise=
* @see #isVoWiFiSettingEnabled()
*/
@@ -645,13 +702,23 @@ public class ImsMmTelManager {
public void setVoWiFiSettingEnabled(boolean isEnabled) {
try {
getITelephony().setVoWiFiSettingEnabled(mSubId, isEnabled);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
/**
+ * Returns the user's voice over WiFi roaming setting associated with the current subscription.
+ *
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @return true if the user's setting for Voice over WiFi while roaming is enabled, false
* if disabled.
* @see #setVoWiFiRoamingSettingEnabled(boolean)
@@ -660,6 +727,13 @@ public class ImsMmTelManager {
public boolean isVoWiFiRoamingSettingEnabled() {
try {
return getITelephony().isVoWiFiRoamingSettingEnabled(mSubId);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -667,15 +741,24 @@ public class ImsMmTelManager {
/**
* Change the user's setting for Voice over WiFi while roaming.
+ *
* @param isEnabled true if the user's setting for Voice over WiFi while roaming is enabled,
* false otherwise.
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see #isVoWiFiRoamingSettingEnabled()
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiRoamingSettingEnabled(boolean isEnabled) {
try {
getITelephony().setVoWiFiRoamingSettingEnabled(mSubId, isEnabled);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -691,19 +774,31 @@ public class ImsMmTelManager {
* - {@link #WIFI_MODE_WIFI_ONLY}
* - {@link #WIFI_MODE_CELLULAR_PREFERRED}
* - {@link #WIFI_MODE_WIFI_PREFERRED}
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see #setVoWiFiSettingEnabled(boolean)
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiNonPersistent(boolean isCapable, int mode) {
try {
getITelephony().setVoWiFiNonPersistent(mSubId, isCapable, mode);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
}
/**
+ * Returns the user's voice over WiFi Roaming mode setting associated with the device.
+ *
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @return The Voice over WiFi Mode preference set by the user, which can be one of the
* following:
* - {@link #WIFI_MODE_WIFI_ONLY}
@@ -715,6 +810,13 @@ public class ImsMmTelManager {
public @WiFiCallingMode int getVoWiFiModeSetting() {
try {
return getITelephony().getVoWiFiModeSetting(mSubId);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -727,13 +829,21 @@ public class ImsMmTelManager {
* - {@link #WIFI_MODE_WIFI_ONLY}
* - {@link #WIFI_MODE_CELLULAR_PREFERRED}
* - {@link #WIFI_MODE_WIFI_PREFERRED}
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see #getVoWiFiModeSetting()
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiModeSetting(@WiFiCallingMode int mode) {
try {
getITelephony().setVoWiFiModeSetting(mSubId, mode);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -748,12 +858,21 @@ public class ImsMmTelManager {
* - {@link #WIFI_MODE_WIFI_ONLY}
* - {@link #WIFI_MODE_CELLULAR_PREFERRED}
* - {@link #WIFI_MODE_WIFI_PREFERRED}
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see #setVoWiFiRoamingSettingEnabled(boolean)
*/
@RequiresPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE)
public @WiFiCallingMode int getVoWiFiRoamingModeSetting() {
try {
return getITelephony().getVoWiFiRoamingModeSetting(mSubId);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -768,13 +887,21 @@ public class ImsMmTelManager {
* - {@link #WIFI_MODE_WIFI_ONLY}
* - {@link #WIFI_MODE_CELLULAR_PREFERRED}
* - {@link #WIFI_MODE_WIFI_PREFERRED}
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see #getVoWiFiRoamingModeSetting()
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setVoWiFiRoamingModeSetting(@WiFiCallingMode int mode) {
try {
getITelephony().setVoWiFiRoamingModeSetting(mSubId, mode);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -787,13 +914,21 @@ public class ImsMmTelManager {
* {@link android.provider.Settings.Secure#RTT_CALLING_MODE}, which is the global user setting
* for RTT. That value is enabled/disabled separately by the user through the Accessibility
* settings.
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @param isEnabled if true RTT should be enabled during calls made on this subscription.
*/
@RequiresPermission(Manifest.permission.MODIFY_PHONE_STATE)
public void setRttCapabilitySetting(boolean isEnabled) {
try {
getITelephony().setRttCapabilitySetting(mSubId, isEnabled);
- return;
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
@@ -801,6 +936,9 @@ public class ImsMmTelManager {
/**
* @return true if TTY over VoLTE is supported
+ *
+ * @throws IllegalArgumentException if the subscription associated with this operation is not
+ * active (SIM is not inserted, ESIM inactive) or invalid.
* @see android.telecom.TelecomManager#getCurrentTtyMode
* @see android.telephony.CarrierConfigManager#KEY_CARRIER_VOLTE_TTY_SUPPORTED_BOOL
*/
@@ -808,6 +946,13 @@ public class ImsMmTelManager {
boolean isTtyOverVolteEnabled() {
try {
return getITelephony().isTtyOverVolteEnabled(mSubId);
+ } catch (ServiceSpecificException e) {
+ if (e.errorCode == ImsException.CODE_ERROR_INVALID_SUBSCRIPTION) {
+ // Rethrow as runtime error to keep API compatible.
+ throw new IllegalArgumentException(e.getMessage());
+ } else {
+ throw new RuntimeException(e.getMessage());
+ }
} catch (RemoteException e) {
throw e.rethrowAsRuntimeException();
}
diff --git a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
index 4433c1c03c1f..53e459697958 100644
--- a/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
+++ b/telephony/java/android/telephony/ims/aidl/IImsConfig.aidl
@@ -17,6 +17,8 @@
package android.telephony.ims.aidl;
+import android.os.PersistableBundle;
+
import android.telephony.ims.aidl.IImsConfigCallback;
import com.android.ims.ImsConfigListener;
@@ -37,4 +39,5 @@ interface IImsConfig {
int setConfigInt(int item, int value);
// Return result code defined in ImsConfig#OperationStatusConstants
int setConfigString(int item, String value);
+ void updateImsCarrierConfigs(in PersistableBundle bundle);
}
diff --git a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
index 321bfff40652..91b0a43844c9 100644
--- a/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
+++ b/telephony/java/android/telephony/ims/stub/ImsConfigImplBase.java
@@ -19,6 +19,7 @@ package android.telephony.ims.stub;
import android.annotation.IntDef;
import android.annotation.SystemApi;
import android.content.Context;
+import android.os.PersistableBundle;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.telephony.ims.aidl.IImsConfig;
@@ -182,6 +183,11 @@ public class ImsConfigImplBase {
return retVal;
}
+ @Override
+ public void updateImsCarrierConfigs(PersistableBundle bundle) throws RemoteException {
+ getImsConfigImpl().updateImsCarrierConfigs(bundle);
+ }
+
private ImsConfigImplBase getImsConfigImpl() throws RemoteException {
ImsConfigImplBase ref = mImsConfigImplBaseWeakReference.get();
if (ref == null) {
@@ -387,4 +393,11 @@ public class ImsConfigImplBase {
// Base Implementation - To be overridden.
return null;
}
+
+ /**
+ * @hide
+ */
+ public void updateImsCarrierConfigs(PersistableBundle bundle) {
+ // Base Implementation - Should be overridden
+ }
}
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 11150dd8e882..b725920ba014 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -386,6 +386,9 @@ bool ManifestFixer::BuildRules(xml::XmlActionExecutor* executor,
manifest_action["package-verifier"];
manifest_action["meta-data"] = meta_data_action;
manifest_action["uses-split"].Action(RequiredNameIsJavaPackage);
+ manifest_action["queries"]["package"].Action(RequiredNameIsJavaPackage);
+ manifest_action["queries"]["intent"] = intent_filter_action;
+ // TODO: more complicated component name tag
manifest_action["key-sets"]["key-set"]["public-key"];
manifest_action["key-sets"]["upgrade-key-set"];
diff --git a/tools/preload2/Android.bp b/tools/preload2/Android.bp
deleted file mode 100644
index 5809421da3e8..000000000000
--- a/tools/preload2/Android.bp
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright (C) 2015 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-java_library_host {
- name: "preload2",
-
- srcs: ["src/**/*.java"],
-
- // To connect to devices (and take hprof dumps).
- static_libs: [
- "ddmlib-prebuilt",
- "tools-common-prebuilt",
-
- // To process hprof dumps.
- "perflib-prebuilt",
-
- "trove-prebuilt",
- "guavalib",
-
- // For JDWP access we use the framework in the JDWP tests from Apache Harmony, for
- // convenience (and to not depend on internal JDK APIs).
- "apache-harmony-jdwp-tests",
- "junit",
- ],
-
- // Copy to build artifacts
- dist: {
- targets: [
- "dist_files",
- ],
- },
-}
-
-// Copy the preload-tool shell script to the host's bin directory.
-sh_binary_host {
- name: "preload-tool",
- src: "preload-tool",
- required: ["preload2"],
-}
diff --git a/tools/preload2/preload-tool b/tools/preload2/preload-tool
deleted file mode 100644
index 322b62fda071..000000000000
--- a/tools/preload2/preload-tool
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (C) 2015 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-# This script is used on the host only. It uses a common subset
-# shell dialect that should work well. It is partially derived
-# from art/tools/art.
-
-function follow_links() {
- if [ z"$BASH_SOURCE" != z ]; then
- file="$BASH_SOURCE"
- else
- file="$0"
- fi
- while [ -h "$file" ]; do
- # On Mac OS, readlink -f doesn't work.
- file="$(readlink "$file")"
- done
- echo "$file"
-}
-
-
-PROG_NAME="$(follow_links)"
-PROG_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
-ANDROID_ROOT=$PROG_DIR/..
-
-java -cp $ANDROID_ROOT/framework/preload2.jar com.android.preload.Main $@
diff --git a/tools/preload2/src/com/android/preload/ClientUtils.java b/tools/preload2/src/com/android/preload/ClientUtils.java
deleted file mode 100644
index 71ef025d6587..000000000000
--- a/tools/preload2/src/com/android/preload/ClientUtils.java
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload;
-
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-
-/**
- * Helper class for common communication with a Client (the ddms name for a running application).
- *
- * Instances take a default timeout parameter that's applied to all functions without explicit
- * timeout. Timeouts are in milliseconds.
- */
-public class ClientUtils {
-
- private int defaultTimeout;
-
- public ClientUtils() {
- this(10000);
- }
-
- public ClientUtils(int defaultTimeout) {
- this.defaultTimeout = defaultTimeout;
- }
-
- /**
- * Shortcut for findClient with default timeout.
- */
- public Client findClient(IDevice device, String processName, int processPid) {
- return findClient(device, processName, processPid, defaultTimeout);
- }
-
- /**
- * Find the client with the given process name or process id. The name takes precedence over
- * the process id (if valid). Stop looking after the given timeout.
- *
- * @param device The device to communicate with.
- * @param processName The name of the process. May be null.
- * @param processPid The pid of the process. Values less than or equal to zero are ignored.
- * @param timeout The amount of milliseconds to wait, at most.
- * @return The client, if found. Otherwise null.
- */
- public Client findClient(IDevice device, String processName, int processPid, int timeout) {
- WaitForClient wfc = new WaitForClient(device, processName, processPid, timeout);
- return wfc.get();
- }
-
- /**
- * Shortcut for findAllClients with default timeout.
- */
- public Client[] findAllClients(IDevice device) {
- return findAllClients(device, defaultTimeout);
- }
-
- /**
- * Retrieve all clients known to the given device. Wait at most the given timeout.
- *
- * @param device The device to investigate.
- * @param timeout The amount of milliseconds to wait, at most.
- * @return An array of clients running on the given device. May be null depending on the
- * device implementation.
- */
- public Client[] findAllClients(IDevice device, int timeout) {
- if (device.hasClients()) {
- return device.getClients();
- }
- WaitForClients wfc = new WaitForClients(device, timeout);
- return wfc.get();
- }
-
- private static class WaitForClient implements IClientChangeListener {
-
- private IDevice device;
- private String processName;
- private int processPid;
- private long timeout;
- private Client result;
-
- public WaitForClient(IDevice device, String processName, int processPid, long timeout) {
- this.device = device;
- this.processName = processName;
- this.processPid = processPid;
- this.timeout = timeout;
- this.result = null;
- }
-
- public Client get() {
- synchronized (this) {
- AndroidDebugBridge.addClientChangeListener(this);
-
- // Maybe it's already there.
- if (result == null) {
- result = searchForClient(device);
- }
-
- if (result == null) {
- try {
- wait(timeout);
- } catch (InterruptedException e) {
- // Note: doesn't guard for spurious wakeup.
- }
- }
- }
-
- AndroidDebugBridge.removeClientChangeListener(this);
- return result;
- }
-
- private Client searchForClient(IDevice device) {
- if (processName != null) {
- Client tmp = device.getClient(processName);
- if (tmp != null) {
- return tmp;
- }
- }
- if (processPid > 0) {
- String name = device.getClientName(processPid);
- if (name != null && !name.isEmpty()) {
- Client tmp = device.getClient(name);
- if (tmp != null) {
- return tmp;
- }
- }
- }
- if (processPid > 0) {
- // Try manual search.
- for (Client cl : device.getClients()) {
- if (cl.getClientData().getPid() == processPid
- && cl.getClientData().getClientDescription() != null) {
- return cl;
- }
- }
- }
- return null;
- }
-
- private boolean isTargetClient(Client c) {
- if (processPid > 0 && c.getClientData().getPid() == processPid) {
- return true;
- }
- if (processName != null
- && processName.equals(c.getClientData().getClientDescription())) {
- return true;
- }
- return false;
- }
-
- @Override
- public void clientChanged(Client arg0, int arg1) {
- synchronized (this) {
- if ((arg1 & Client.CHANGE_INFO) != 0 && (arg0.getDevice() == device)) {
- if (isTargetClient(arg0)) {
- result = arg0;
- notifyAll();
- }
- }
- }
- }
- }
-
- private static class WaitForClients implements IClientChangeListener {
-
- private IDevice device;
- private long timeout;
-
- public WaitForClients(IDevice device, long timeout) {
- this.device = device;
- this.timeout = timeout;
- }
-
- public Client[] get() {
- synchronized (this) {
- AndroidDebugBridge.addClientChangeListener(this);
-
- if (device.hasClients()) {
- return device.getClients();
- }
-
- try {
- wait(timeout); // Note: doesn't guard for spurious wakeup.
- } catch (InterruptedException exc) {
- }
-
- // We will be woken up when the first client data arrives. Sleep a little longer
- // to give (hopefully all of) the rest of the clients a chance to become available.
- // Note: a loop with timeout is brittle as well and complicated, just accept this
- // for now.
- try {
- Thread.sleep(500);
- } catch (InterruptedException exc) {
- }
- }
-
- AndroidDebugBridge.removeClientChangeListener(this);
-
- return device.getClients();
- }
-
- @Override
- public void clientChanged(Client arg0, int arg1) {
- synchronized (this) {
- if ((arg1 & Client.CHANGE_INFO) != 0 && (arg0.getDevice() == device)) {
- notifyAll();
- }
- }
- }
- }
-}
diff --git a/tools/preload2/src/com/android/preload/DeviceUtils.java b/tools/preload2/src/com/android/preload/DeviceUtils.java
deleted file mode 100644
index 18cab7bee12d..000000000000
--- a/tools/preload2/src/com/android/preload/DeviceUtils.java
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload;
-
-import com.android.ddmlib.AdbCommandRejectedException;
-import com.android.ddmlib.AndroidDebugBridge;
-import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
-import com.android.preload.classdataretrieval.hprof.Hprof;
-import com.android.ddmlib.DdmPreferences;
-import com.android.ddmlib.IDevice;
-import com.android.ddmlib.IShellOutputReceiver;
-import com.android.ddmlib.SyncException;
-import com.android.ddmlib.TimeoutException;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.Date;
-import java.util.concurrent.Future;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Helper class for some device routines.
- */
-public class DeviceUtils {
-
- // Locations
- private static final String PRELOADED_CLASSES_FILE = "/etc/preloaded-classes";
- // Shell commands
- private static final String CREATE_EMPTY_PRELOADED_CMD = "touch " + PRELOADED_CLASSES_FILE;
- private static final String DELETE_CACHE_CMD = "rm /data/dalvik-cache/*/*boot.art";
- private static final String DELETE_PRELOADED_CMD = "rm " + PRELOADED_CLASSES_FILE;
- private static final String READ_PRELOADED_CMD = "cat " + PRELOADED_CLASSES_FILE;
- private static final String START_SHELL_CMD = "start";
- private static final String STOP_SHELL_CMD = "stop";
- private static final String REMOUNT_SYSTEM_CMD = "mount -o rw,remount /system";
- private static final String UNSET_BOOTCOMPLETE_CMD = "setprop dev.bootcomplete \"0\"";
-
- public static void init(int debugPort) {
- DdmPreferences.setSelectedDebugPort(debugPort);
-
- Hprof.init();
-
- AndroidDebugBridge.init(true);
-
- AndroidDebugBridge.createBridge();
- }
-
- /**
- * Run a command in the shell on the device.
- */
- public static void doShell(IDevice device, String cmdline, long timeout, TimeUnit unit) {
- doShell(device, cmdline, new NullShellOutputReceiver(), timeout, unit);
- }
-
- /**
- * Run a command in the shell on the device. Collects and returns the console output.
- */
- public static String doShellReturnString(IDevice device, String cmdline, long timeout,
- TimeUnit unit) {
- CollectStringShellOutputReceiver rec = new CollectStringShellOutputReceiver();
- doShell(device, cmdline, rec, timeout, unit);
- return rec.toString();
- }
-
- /**
- * Run a command in the shell on the device, directing all output to the given receiver.
- */
- public static void doShell(IDevice device, String cmdline, IShellOutputReceiver receiver,
- long timeout, TimeUnit unit) {
- try {
- device.executeShellCommand(cmdline, receiver, timeout, unit);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- /**
- * Run am start on the device.
- */
- public static void doAMStart(IDevice device, String name, String activity) {
- doShell(device, "am start -n " + name + " /." + activity, 30, TimeUnit.SECONDS);
- }
-
- /**
- * Find the device with the given serial. Give up after the given timeout (in milliseconds).
- */
- public static IDevice findDevice(String serial, int timeout) {
- WaitForDevice wfd = new WaitForDevice(serial, timeout);
- return wfd.get();
- }
-
- /**
- * Get all devices ddms knows about. Wait at most for the given timeout.
- */
- public static IDevice[] findDevices(int timeout) {
- WaitForDevice wfd = new WaitForDevice(null, timeout);
- wfd.get();
- return AndroidDebugBridge.getBridge().getDevices();
- }
-
- /**
- * Return the build type of the given device. This is the value of the "ro.build.type"
- * system property.
- */
- public static String getBuildType(IDevice device) {
- try {
- Future<String> buildType = device.getSystemProperty("ro.build.type");
- return buildType.get(500, TimeUnit.MILLISECONDS);
- } catch (Exception e) {
- }
- return null;
- }
-
- /**
- * Check whether the given device has a pre-optimized boot image. More precisely, checks
- * whether /system/framework/ * /boot.art exists.
- */
- public static boolean hasPrebuiltBootImage(IDevice device) {
- String ret =
- doShellReturnString(device, "ls /system/framework/*/boot.art", 500, TimeUnit.MILLISECONDS);
-
- return !ret.contains("No such file or directory");
- }
-
- /**
- * Write over the preloaded-classes file with an empty or existing file and regenerate the boot
- * image as necessary.
- *
- * @param device
- * @param pcFile
- * @param bootTimeout
- * @throws AdbCommandRejectedException
- * @throws IOException
- * @throws TimeoutException
- * @throws SyncException
- * @return true if successfully overwritten, false otherwise
- */
- public static boolean overwritePreloaded(IDevice device, File pcFile, long bootTimeout)
- throws AdbCommandRejectedException, IOException, TimeoutException, SyncException {
- boolean writeEmpty = (pcFile == null);
- if (writeEmpty) {
- // Check if the preloaded-classes file is already empty.
- String oldContent =
- doShellReturnString(device, READ_PRELOADED_CMD, 1, TimeUnit.SECONDS);
- if (oldContent.trim().equals("")) {
- System.out.println("Preloaded-classes already empty.");
- return true;
- }
- }
-
- // Stop the system server etc.
- doShell(device, STOP_SHELL_CMD, 1, TimeUnit.SECONDS);
- // Remount the read-only system partition
- doShell(device, REMOUNT_SYSTEM_CMD, 1, TimeUnit.SECONDS);
- // Delete the preloaded-classes file
- doShell(device, DELETE_PRELOADED_CMD, 1, TimeUnit.SECONDS);
- // Delete the dalvik cache files
- doShell(device, DELETE_CACHE_CMD, 1, TimeUnit.SECONDS);
- if (writeEmpty) {
- // Write an empty preloaded-classes file
- doShell(device, CREATE_EMPTY_PRELOADED_CMD, 500, TimeUnit.MILLISECONDS);
- } else {
- // Push the new preloaded-classes file
- device.pushFile(pcFile.getAbsolutePath(), PRELOADED_CLASSES_FILE);
- }
- // Manually reset the boot complete flag
- doShell(device, UNSET_BOOTCOMPLETE_CMD, 1, TimeUnit.SECONDS);
- // Restart system server on the device
- doShell(device, START_SHELL_CMD, 1, TimeUnit.SECONDS);
- // Wait for the boot complete flag and return the outcome.
- return waitForBootComplete(device, bootTimeout);
- }
-
- private static boolean waitForBootComplete(IDevice device, long timeout) {
- // Do a loop checking each second whether bootcomplete. Wait for at most the given
- // threshold.
- Date startDate = new Date();
- for (;;) {
- try {
- Thread.sleep(1000);
- } catch (InterruptedException e) {
- // Ignore spurious wakeup.
- }
- // Check whether bootcomplete.
- String ret =
- doShellReturnString(device, "getprop dev.bootcomplete", 500, TimeUnit.MILLISECONDS);
- if (ret.trim().equals("1")) {
- break;
- }
- System.out.println("Still not booted: " + ret);
-
- // Check whether we timed out. This is a simplistic check that doesn't take into account
- // things like switches in time.
- Date endDate = new Date();
- long seconds =
- TimeUnit.SECONDS.convert(endDate.getTime() - startDate.getTime(), TimeUnit.MILLISECONDS);
- if (seconds > timeout) {
- return false;
- }
- }
-
- return true;
- }
-
- /**
- * Enable method-tracing on device. The system should be restarted after this.
- */
- public static void enableTracing(IDevice device) {
- // Disable selinux.
- doShell(device, "setenforce 0", 100, TimeUnit.MILLISECONDS);
-
- // Make the profile directory world-writable.
- doShell(device, "chmod 777 /data/dalvik-cache/profiles", 100, TimeUnit.MILLISECONDS);
-
- // Enable streaming method tracing with a small 1K buffer.
- doShell(device, "setprop dalvik.vm.method-trace true", 100, TimeUnit.MILLISECONDS);
- doShell(device, "setprop dalvik.vm.method-trace-file "
- + "/data/dalvik-cache/profiles/zygote.trace.bin", 100, TimeUnit.MILLISECONDS);
- doShell(device, "setprop dalvik.vm.method-trace-file-siz 1024", 100, TimeUnit.MILLISECONDS);
- doShell(device, "setprop dalvik.vm.method-trace-stream true", 100, TimeUnit.MILLISECONDS);
- }
-
- private static class NullShellOutputReceiver implements IShellOutputReceiver {
- @Override
- public boolean isCancelled() {
- return false;
- }
-
- @Override
- public void flush() {}
-
- @Override
- public void addOutput(byte[] arg0, int arg1, int arg2) {}
- }
-
- private static class CollectStringShellOutputReceiver implements IShellOutputReceiver {
-
- private StringBuilder builder = new StringBuilder();
-
- @Override
- public String toString() {
- String ret = builder.toString();
- // Strip trailing newlines. They are especially ugly because adb uses DOS line endings.
- while (ret.endsWith("\r") || ret.endsWith("\n")) {
- ret = ret.substring(0, ret.length() - 1);
- }
- return ret;
- }
-
- @Override
- public void addOutput(byte[] arg0, int arg1, int arg2) {
- builder.append(new String(arg0, arg1, arg2));
- }
-
- @Override
- public void flush() {}
-
- @Override
- public boolean isCancelled() {
- return false;
- }
- }
-
- private static class WaitForDevice {
-
- private String serial;
- private long timeout;
- private IDevice device;
-
- public WaitForDevice(String serial, long timeout) {
- this.serial = serial;
- this.timeout = timeout;
- device = null;
- }
-
- public IDevice get() {
- if (device == null) {
- WaitForDeviceListener wfdl = new WaitForDeviceListener(serial);
- synchronized (wfdl) {
- AndroidDebugBridge.addDeviceChangeListener(wfdl);
-
- // Check whether we already know about this device.
- IDevice[] devices = AndroidDebugBridge.getBridge().getDevices();
- if (serial != null) {
- for (IDevice d : devices) {
- if (serial.equals(d.getSerialNumber())) {
- // Only accept if there are clients already. Else wait for the callback informing
- // us that we now have clients.
- if (d.hasClients()) {
- device = d;
- }
-
- break;
- }
- }
- } else {
- if (devices.length > 0) {
- device = devices[0];
- }
- }
-
- if (device == null) {
- try {
- wfdl.wait(timeout);
- } catch (InterruptedException e) {
- // Ignore spurious wakeups.
- }
- device = wfdl.getDevice();
- }
-
- AndroidDebugBridge.removeDeviceChangeListener(wfdl);
- }
- }
-
- if (device != null) {
- // Wait for clients.
- WaitForClientsListener wfcl = new WaitForClientsListener(device);
- synchronized (wfcl) {
- AndroidDebugBridge.addDeviceChangeListener(wfcl);
-
- if (!device.hasClients()) {
- try {
- wfcl.wait(timeout);
- } catch (InterruptedException e) {
- // Ignore spurious wakeups.
- }
- }
-
- AndroidDebugBridge.removeDeviceChangeListener(wfcl);
- }
- }
-
- return device;
- }
-
- private static class WaitForDeviceListener implements IDeviceChangeListener {
-
- private String serial;
- private IDevice device;
-
- public WaitForDeviceListener(String serial) {
- this.serial = serial;
- }
-
- public IDevice getDevice() {
- return device;
- }
-
- @Override
- public void deviceChanged(IDevice arg0, int arg1) {
- // We may get a device changed instead of connected. Handle like a connection.
- deviceConnected(arg0);
- }
-
- @Override
- public void deviceConnected(IDevice arg0) {
- if (device != null) {
- // Ignore updates.
- return;
- }
-
- if (serial == null || serial.equals(arg0.getSerialNumber())) {
- device = arg0;
- synchronized (this) {
- notifyAll();
- }
- }
- }
-
- @Override
- public void deviceDisconnected(IDevice arg0) {
- // Ignore disconnects.
- }
-
- }
-
- private static class WaitForClientsListener implements IDeviceChangeListener {
-
- private IDevice myDevice;
-
- public WaitForClientsListener(IDevice myDevice) {
- this.myDevice = myDevice;
- }
-
- @Override
- public void deviceChanged(IDevice arg0, int arg1) {
- if (arg0 == myDevice && (arg1 & IDevice.CHANGE_CLIENT_LIST) != 0) {
- // Got a client list, done here.
- synchronized (this) {
- notifyAll();
- }
- }
- }
-
- @Override
- public void deviceConnected(IDevice arg0) {
- }
-
- @Override
- public void deviceDisconnected(IDevice arg0) {
- }
-
- }
- }
-
-}
diff --git a/tools/preload2/src/com/android/preload/DumpData.java b/tools/preload2/src/com/android/preload/DumpData.java
deleted file mode 100644
index d99722416a1d..000000000000
--- a/tools/preload2/src/com/android/preload/DumpData.java
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload;
-
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Holds the collected data for a process.
- */
-public class DumpData {
- /**
- * Name of the package (=application).
- */
- String packageName;
-
- /**
- * A map of class name to a string for the classloader. This may be a toString equivalent,
- * or just a unique ID.
- */
- Map<String, String> dumpData;
-
- /**
- * The Date when this data was captured. Mostly for display purposes.
- */
- Date date;
-
- /**
- * A cached value for the number of boot classpath classes (classloader value in dumpData is
- * null).
- */
- int bcpClasses;
-
- public DumpData(String packageName, Map<String, String> dumpData, Date date) {
- this.packageName = packageName;
- this.dumpData = dumpData;
- this.date = date;
-
- countBootClassPath();
- }
-
- public String getPackageName() {
- return packageName;
- }
-
- public Date getDate() {
- return date;
- }
-
- public Map<String, String> getDumpData() {
- return dumpData;
- }
-
- public void countBootClassPath() {
- bcpClasses = 0;
- for (Map.Entry<String, String> e : dumpData.entrySet()) {
- if (e.getValue() == null) {
- bcpClasses++;
- }
- }
- }
-
- // Return an inverted mapping.
- public Map<String, Set<String>> invertData() {
- Map<String, Set<String>> ret = new HashMap<>();
- for (Map.Entry<String, String> e : dumpData.entrySet()) {
- if (!ret.containsKey(e.getValue())) {
- ret.put(e.getValue(), new HashSet<String>());
- }
- ret.get(e.getValue()).add(e.getKey());
- }
- return ret;
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/DumpDataIO.java b/tools/preload2/src/com/android/preload/DumpDataIO.java
deleted file mode 100644
index 28625c5531e4..000000000000
--- a/tools/preload2/src/com/android/preload/DumpDataIO.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.InputSource;
-import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
-import org.xml.sax.helpers.DefaultHandler;
-
-import java.io.File;
-import java.io.FileReader;
-import java.text.DateFormat;
-import java.util.Collection;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.Map;
-
-import javax.xml.parsers.SAXParser;
-import javax.xml.parsers.SAXParserFactory;
-
-/**
- * Helper class for serialization and deserialization of a collection of DumpData objects to XML.
- */
-public class DumpDataIO {
-
- /**
- * Serialize the given collection to an XML document. Returns the produced string.
- */
- public static String serialize(Collection<DumpData> data) {
- // We'll do this by hand, constructing a DOM or similar is too complicated for our simple
- // use case.
-
- StringBuilder sb = new StringBuilder();
- sb.append("<preloaded-classes-data>\n");
-
- for (DumpData d : data) {
- serialize(d, sb);
- }
-
- sb.append("</preloaded-classes-data>\n");
- return sb.toString();
- }
-
- private static void serialize(DumpData d, StringBuilder sb) {
- sb.append("<data package=\"" + d.packageName + "\" date=\"" +
- DateFormat.getDateTimeInstance().format(d.date) +"\">\n");
-
- for (Map.Entry<String, String> e : d.dumpData.entrySet()) {
- sb.append("<class name=\"" + e.getKey() + "\" classloader=\"" + e.getValue() + "\"/>\n");
- }
-
- sb.append("</data>\n");
- }
-
- /**
- * Load a collection of DumpData objects from the given file.
- */
- public static Collection<DumpData> deserialize(File f) throws Exception {
- // Use SAX parsing. Our format is very simple. Don't do any schema validation or such.
-
- SAXParserFactory spf = SAXParserFactory.newInstance();
- spf.setNamespaceAware(false);
- SAXParser saxParser = spf.newSAXParser();
-
- XMLReader xmlReader = saxParser.getXMLReader();
- DumpDataContentHandler ddch = new DumpDataContentHandler();
- xmlReader.setContentHandler(ddch);
- xmlReader.parse(new InputSource(new FileReader(f)));
-
- return ddch.data;
- }
-
- private static class DumpDataContentHandler extends DefaultHandler {
- Collection<DumpData> data = new LinkedList<DumpData>();
- DumpData openData = null;
-
- @Override
- public void startElement(String uri, String localName, String qName, Attributes attributes)
- throws SAXException {
- if (qName.equals("data")) {
- if (openData != null) {
- throw new IllegalStateException();
- }
- String pkg = attributes.getValue("package");
- String dateString = attributes.getValue("date");
-
- if (pkg == null || dateString == null) {
- throw new IllegalArgumentException();
- }
-
- try {
- Date date = DateFormat.getDateTimeInstance().parse(dateString);
- openData = new DumpData(pkg, new HashMap<String, String>(), date);
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- } else if (qName.equals("class")) {
- if (openData == null) {
- throw new IllegalStateException();
- }
- String className = attributes.getValue("name");
- String classLoader = attributes.getValue("classloader");
-
- if (className == null || classLoader == null) {
- throw new IllegalArgumentException();
- }
-
- openData.dumpData.put(className, classLoader.equals("null") ? null : classLoader);
- }
- }
-
- @Override
- public void endElement(String uri, String localName, String qName) throws SAXException {
- if (qName.equals("data")) {
- if (openData == null) {
- throw new IllegalStateException();
- }
- openData.countBootClassPath();
-
- data.add(openData);
- openData = null;
- }
- }
- }
-}
diff --git a/tools/preload2/src/com/android/preload/DumpTableModel.java b/tools/preload2/src/com/android/preload/DumpTableModel.java
deleted file mode 100644
index d97cbf0df5e5..000000000000
--- a/tools/preload2/src/com/android/preload/DumpTableModel.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.swing.table.AbstractTableModel;
-
-/**
- * A table model for collected DumpData. This is both the internal storage as well as the model
- * for display.
- */
-public class DumpTableModel extends AbstractTableModel {
-
- private List<DumpData> data = new ArrayList<DumpData>();
-
- public void addData(DumpData d) {
- data.add(d);
- fireTableRowsInserted(data.size() - 1, data.size() - 1);
- }
-
- public void clear() {
- int size = data.size();
- if (size > 0) {
- data.clear();
- fireTableRowsDeleted(0, size - 1);
- }
- }
-
- public List<DumpData> getData() {
- return data;
- }
-
- @Override
- public int getRowCount() {
- return data.size();
- }
-
- @Override
- public int getColumnCount() {
- return 4;
- }
-
- @Override
- public String getColumnName(int column) {
- switch (column) {
- case 0:
- return "Package";
- case 1:
- return "Date";
- case 2:
- return "# All Classes";
- case 3:
- return "# Boot Classpath Classes";
-
- default:
- throw new IndexOutOfBoundsException(String.valueOf(column));
- }
- }
-
- @Override
- public Object getValueAt(int rowIndex, int columnIndex) {
- DumpData d = data.get(rowIndex);
- switch (columnIndex) {
- case 0:
- return d.packageName;
- case 1:
- return d.date;
- case 2:
- return d.dumpData.size();
- case 3:
- return d.bcpClasses;
-
- default:
- throw new IndexOutOfBoundsException(String.valueOf(columnIndex));
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/Main.java b/tools/preload2/src/com/android/preload/Main.java
deleted file mode 100644
index 2265e9557c4b..000000000000
--- a/tools/preload2/src/com/android/preload/Main.java
+++ /dev/null
@@ -1,341 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.preload.actions.ClearTableAction;
-import com.android.preload.actions.ComputeThresholdAction;
-import com.android.preload.actions.ComputeThresholdXAction;
-import com.android.preload.actions.DeviceSpecific;
-import com.android.preload.actions.ExportAction;
-import com.android.preload.actions.ImportAction;
-import com.android.preload.actions.ReloadListAction;
-import com.android.preload.actions.RunMonkeyAction;
-import com.android.preload.actions.ScanAllPackagesAction;
-import com.android.preload.actions.ScanPackageAction;
-import com.android.preload.actions.ShowDataAction;
-import com.android.preload.actions.WritePreloadedClassesAction;
-import com.android.preload.classdataretrieval.ClassDataRetriever;
-import com.android.preload.classdataretrieval.hprof.Hprof;
-import com.android.preload.classdataretrieval.jdwp.JDWPClassDataRetriever;
-import com.android.preload.ui.IUI;
-import com.android.preload.ui.SequenceUI;
-import com.android.preload.ui.SwingUI;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.NoSuchElementException;
-
-import javax.swing.Action;
-import javax.swing.DefaultListModel;
-
-public class Main {
-
- /**
- * Enable tracing mode. This is a work-in-progress to derive compiled-methods data, so it is
- * off for now.
- */
- public final static boolean ENABLE_TRACING = false;
-
- /**
- * Ten-second timeout.
- */
- public final static int DEFAULT_TIMEOUT_MILLIS = 10 * 1000;
-
- /**
- * Hprof timeout. Two minutes.
- */
- public final static int HPROF_TIMEOUT_MILLIS = 120 * 1000;
-
- private IDevice device;
- private static ClientUtils clientUtils;
-
- private DumpTableModel dataTableModel;
- private DefaultListModel<Client> clientListModel;
-
- private IUI ui;
-
- // Actions that need to be updated once a device is selected.
- private Collection<DeviceSpecific> deviceSpecificActions;
-
- // Current main instance.
- private static Main top;
- private static boolean useJdwpClassDataRetriever = false;
-
- public final static String CLASS_PRELOAD_BLACKLIST = "android.app.AlarmManager$" + "|"
- + "android.app.SearchManager$" + "|" + "android.os.FileObserver$" + "|"
- + "com.android.server.PackageManagerService\\$AppDirObserver$" + "|" +
-
-
- // Threads
- "android.os.AsyncTask$" + "|" + "android.pim.ContactsAsyncHelper$" + "|"
- + "android.webkit.WebViewClassic\\$1$" + "|" + "java.lang.ProcessManager$" + "|"
- + "(.*\\$NoPreloadHolder$)";
-
- public final static String SCAN_ALL_CMD = "scan-all";
- public final static String SCAN_PACKAGE_CMD = "scan";
- public final static String COMPUTE_FILE_CMD = "comp";
- public final static String EXPORT_CMD = "export";
- public final static String IMPORT_CMD = "import";
- public final static String WRITE_CMD = "write";
-
- /**
- * @param args
- */
- public static void main(String[] args) {
- Main m;
- if (args.length > 0 && args[0].equals("--seq")) {
- m = createSequencedMain(args);
- } else {
- m = new Main(new SwingUI());
- }
-
- top = m;
- m.startUp();
- }
-
- public Main(IUI ui) {
- this.ui = ui;
-
- clientListModel = new DefaultListModel<Client>();
- dataTableModel = new DumpTableModel();
-
- clientUtils = new ClientUtils(DEFAULT_TIMEOUT_MILLIS); // Client utils with 10s timeout.
-
- List<Action> actions = new ArrayList<Action>();
- actions.add(new ReloadListAction(clientUtils, null, clientListModel));
- actions.add(new ClearTableAction(dataTableModel));
- actions.add(new RunMonkeyAction(null, dataTableModel));
- actions.add(new ScanPackageAction(clientUtils, null, dataTableModel));
- actions.add(new ScanAllPackagesAction(clientUtils, null, dataTableModel));
- actions.add(new ComputeThresholdAction("Compute preloaded-classes", dataTableModel, 2,
- CLASS_PRELOAD_BLACKLIST));
- actions.add(new ComputeThresholdAction("Compute compiled-classes", dataTableModel, 1,
- null));
- actions.add(new ComputeThresholdXAction("Compute(X)", dataTableModel,
- CLASS_PRELOAD_BLACKLIST));
- actions.add(new WritePreloadedClassesAction(clientUtils, null, dataTableModel));
- actions.add(new ShowDataAction(dataTableModel));
- actions.add(new ImportAction(dataTableModel));
- actions.add(new ExportAction(dataTableModel));
-
- deviceSpecificActions = new ArrayList<DeviceSpecific>();
- for (Action a : actions) {
- if (a instanceof DeviceSpecific) {
- deviceSpecificActions.add((DeviceSpecific)a);
- }
- }
-
- ui.prepare(clientListModel, dataTableModel, actions);
- }
-
- /**
- * @param args
- * @return
- */
- private static Main createSequencedMain(String[] args) {
- SequenceUI ui = new SequenceUI();
- Main main = new Main(ui);
-
- Iterator<String> it = Arrays.asList(args).iterator();
- it.next(); // --seq
- // Setup
- ui.choice("#" + it.next()); // Device.
- ui.confirmNo(); // Prepare: no.
- // Actions
- try {
- while (it.hasNext()) {
- String op = it.next();
- // Operation: Scan a single package
- if (SCAN_PACKAGE_CMD.equals(op)) {
- System.out.println("Scanning package.");
- ui.action(ScanPackageAction.class);
- ui.client(it.next());
- // Operation: Scan all packages
- } else if (SCAN_ALL_CMD.equals(op)) {
- System.out.println("Scanning all packages.");
- ui.action(ScanAllPackagesAction.class);
- // Operation: Export the output to a file
- } else if (EXPORT_CMD.equals(op)) {
- System.out.println("Exporting data.");
- ui.action(ExportAction.class);
- ui.output(new File(it.next()));
- // Operation: Import the input from a file or directory
- } else if (IMPORT_CMD.equals(op)) {
- System.out.println("Importing data.");
- File file = new File(it.next());
- if (!file.exists()) {
- throw new RuntimeException(
- String.format("File does not exist, %s.", file.getAbsolutePath()));
- } else if (file.isFile()) {
- ui.action(ImportAction.class);
- ui.input(file);
- } else if (file.isDirectory()) {
- for (File content : file.listFiles()) {
- ui.action(ImportAction.class);
- ui.input(content);
- }
- }
- // Operation: Compute preloaded classes with specific threshold
- } else if (COMPUTE_FILE_CMD.equals(op)) {
- System.out.println("Compute preloaded classes.");
- ui.action(ComputeThresholdXAction.class);
- ui.input(it.next());
- ui.confirmYes();
- ui.output(new File(it.next()));
- // Operation: Write preloaded classes from a specific file
- } else if (WRITE_CMD.equals(op)) {
- System.out.println("Writing preloaded classes.");
- ui.action(WritePreloadedClassesAction.class);
- ui.input(new File(it.next()));
- }
- }
- } catch (NoSuchElementException e) {
- System.out.println("Failed to parse action sequence correctly.");
- throw e;
- }
-
- return main;
- }
-
- public static IUI getUI() {
- return top.ui;
- }
-
- public static ClassDataRetriever getClassDataRetriever() {
- if (useJdwpClassDataRetriever) {
- return new JDWPClassDataRetriever();
- } else {
- return new Hprof(HPROF_TIMEOUT_MILLIS);
- }
- }
-
- public IDevice getDevice() {
- return device;
- }
-
- public void setDevice(IDevice device) {
- this.device = device;
- for (DeviceSpecific ds : deviceSpecificActions) {
- ds.setDevice(device);
- }
- }
-
- public DefaultListModel<Client> getClientListModel() {
- return clientListModel;
- }
-
- static class DeviceWrapper {
- IDevice device;
-
- public DeviceWrapper(IDevice d) {
- device = d;
- }
-
- @Override
- public String toString() {
- return device.getName() + " (#" + device.getSerialNumber() + ")";
- }
- }
-
- private void startUp() {
- getUI().showWaitDialog();
- initDevice();
-
- // Load clients.
- new ReloadListAction(clientUtils, getDevice(), clientListModel).run();
-
- getUI().hideWaitDialog();
- getUI().ready();
- }
-
- private void initDevice() {
- DeviceUtils.init(DEFAULT_TIMEOUT_MILLIS);
-
- IDevice devices[] = DeviceUtils.findDevices(DEFAULT_TIMEOUT_MILLIS);
- if (devices == null || devices.length == 0) {
- throw new RuntimeException("Could not find any devices...");
- }
-
- getUI().hideWaitDialog();
-
- DeviceWrapper deviceWrappers[] = new DeviceWrapper[devices.length];
- for (int i = 0; i < devices.length; i++) {
- deviceWrappers[i] = new DeviceWrapper(devices[i]);
- }
-
- DeviceWrapper ret = Main.getUI().showChoiceDialog("Choose a device", "Choose device",
- deviceWrappers);
- if (ret != null) {
- setDevice(ret.device);
- } else {
- System.exit(0);
- }
-
- boolean prepare = Main.getUI().showConfirmDialog("Prepare device?",
- "Do you want to prepare the device? This is highly recommended.");
- if (prepare) {
- String buildType = DeviceUtils.getBuildType(device);
- if (buildType == null || (!buildType.equals("userdebug") && !buildType.equals("eng"))) {
- Main.getUI().showMessageDialog("Need a userdebug or eng build! (Found " + buildType
- + ")");
- return;
- }
- if (DeviceUtils.hasPrebuiltBootImage(device)) {
- Main.getUI().showMessageDialog("Cannot prepare a device with pre-optimized boot "
- + "image!");
- return;
- }
-
- if (ENABLE_TRACING) {
- DeviceUtils.enableTracing(device);
- }
-
- Main.getUI().showMessageDialog("The device will reboot. This will potentially take a "
- + "long time. Please be patient.");
- boolean success = false;
- try {
- success = DeviceUtils.overwritePreloaded(device, null, 15 * 60);
- } catch (Exception e) {
- System.err.println(e);
- } finally {
- if (!success) {
- Main.getUI().showMessageDialog(
- "Removing preloaded-classes failed unexpectedly!");
- }
- }
- }
- }
-
- public static Map<String, String> findAndGetClassData(IDevice device, String packageName)
- throws Exception {
- Client client = clientUtils.findClient(device, packageName, -1);
- if (client == null) {
- throw new RuntimeException("Could not find client...");
- }
- System.out.println("Found client: " + client);
-
- return getClassDataRetriever().getClassData(client);
- }
-
-}
diff --git a/tools/preload2/src/com/android/preload/actions/AbstractThreadedAction.java b/tools/preload2/src/com/android/preload/actions/AbstractThreadedAction.java
deleted file mode 100644
index 5787d8507230..000000000000
--- a/tools/preload2/src/com/android/preload/actions/AbstractThreadedAction.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.preload.Main;
-import java.awt.event.ActionEvent;
-
-import javax.swing.AbstractAction;
-
-public abstract class AbstractThreadedAction extends AbstractAction implements Runnable {
-
- protected AbstractThreadedAction(String title) {
- super(title);
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if (Main.getUI().isSingleThreaded()) {
- run();
- } else {
- new Thread(this).start();
- }
- }
-
-}
diff --git a/tools/preload2/src/com/android/preload/actions/AbstractThreadedDeviceSpecificAction.java b/tools/preload2/src/com/android/preload/actions/AbstractThreadedDeviceSpecificAction.java
deleted file mode 100644
index 7906417b7a8d..000000000000
--- a/tools/preload2/src/com/android/preload/actions/AbstractThreadedDeviceSpecificAction.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.ddmlib.IDevice;
-
-import java.awt.event.ActionEvent;
-
-public abstract class AbstractThreadedDeviceSpecificAction extends AbstractThreadedAction
- implements DeviceSpecific {
-
- protected IDevice device;
-
- protected AbstractThreadedDeviceSpecificAction(String title, IDevice device) {
- super(title);
- this.device = device;
- }
-
- @Override
- public void setDevice(IDevice device) {
- this.device = device;
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if (device == null) {
- return;
- }
- super.actionPerformed(e);
- }
-}
diff --git a/tools/preload2/src/com/android/preload/actions/ClearTableAction.java b/tools/preload2/src/com/android/preload/actions/ClearTableAction.java
deleted file mode 100644
index c0e4795b6d90..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ClearTableAction.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.preload.DumpTableModel;
-
-import java.awt.event.ActionEvent;
-
-import javax.swing.AbstractAction;
-
-public class ClearTableAction extends AbstractAction {
- private final DumpTableModel dataTableModel;
-
- public ClearTableAction(DumpTableModel dataTableModel) {
- super("Clear");
- this.dataTableModel = dataTableModel;
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- dataTableModel.clear();
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/ComputeThresholdAction.java b/tools/preload2/src/com/android/preload/actions/ComputeThresholdAction.java
deleted file mode 100644
index 3a7f7f74d755..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ComputeThresholdAction.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.preload.DumpData;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-import java.awt.event.ActionEvent;
-import java.io.File;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import java.util.regex.Pattern;
-
-import javax.swing.AbstractAction;
-
-/**
- * Compute an intersection of classes from the given data. A class is in the intersection if it
- * appears in at least the number of threshold given packages. An optional blacklist can be
- * used to filter classes from the intersection.
- */
-public class ComputeThresholdAction extends AbstractThreadedAction {
- protected int threshold;
- private Pattern blacklist;
- private DumpTableModel dataTableModel;
-
- /**
- * Create an action with the given parameters. The blacklist is a regular expression
- * that filters classes.
- */
- public ComputeThresholdAction(String name, DumpTableModel dataTableModel, int threshold,
- String blacklist) {
- super(name);
- this.dataTableModel = dataTableModel;
- this.threshold = threshold;
- if (blacklist != null) {
- this.blacklist = Pattern.compile(blacklist);
- }
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- List<DumpData> data = dataTableModel.getData();
- if (data.size() == 0) {
- Main.getUI().showMessageDialog("No data available, please scan packages or run "
- + "monkeys.");
- return;
- }
- if (data.size() == 1) {
- Main.getUI().showMessageDialog("Cannot compute list from only one data set, please "
- + "scan packages or run monkeys.");
- return;
- }
-
- super.actionPerformed(e);
- }
-
- @Override
- public void run() {
- Main.getUI().showWaitDialog();
-
- Map<String, Set<String>> uses = new HashMap<String, Set<String>>();
- for (DumpData d : dataTableModel.getData()) {
- Main.getUI().updateWaitDialog("Merging " + d.getPackageName());
- updateClassUse(d.getPackageName(), uses, getBootClassPathClasses(d.getDumpData()));
- }
-
- Main.getUI().updateWaitDialog("Computing thresholded set");
- Set<String> result = fromThreshold(uses, blacklist, threshold);
- Main.getUI().hideWaitDialog();
-
- boolean ret = Main.getUI().showConfirmDialog("Computed a set with " + result.size()
- + " classes, would you like to save to disk?", "Save?");
- if (ret) {
- File f = Main.getUI().showSaveDialog();
- if (f != null) {
- saveSet(result, f);
- }
- }
- }
-
- private Set<String> fromThreshold(Map<String, Set<String>> classUses, Pattern blacklist,
- int threshold) {
- TreeSet<String> ret = new TreeSet<>(); // TreeSet so it's nicely ordered by name.
-
- for (Map.Entry<String, Set<String>> e : classUses.entrySet()) {
- if (e.getValue().size() >= threshold) {
- if (blacklist == null || !blacklist.matcher(e.getKey()).matches()) {
- ret.add(e.getKey());
- }
- }
- }
-
- return ret;
- }
-
- private static void updateClassUse(String pkg, Map<String, Set<String>> classUses,
- Set<String> classes) {
- for (String className : classes) {
- Set<String> old = classUses.get(className);
- if (old == null) {
- classUses.put(className, new HashSet<String>());
- }
- classUses.get(className).add(pkg);
- }
- }
-
- private static Set<String> getBootClassPathClasses(Map<String, String> source) {
- Set<String> ret = new HashSet<>();
- for (Map.Entry<String, String> e : source.entrySet()) {
- if (e.getValue() == null) {
- ret.add(e.getKey());
- }
- }
- return ret;
- }
-
- private static void saveSet(Set<String> result, File f) {
- try {
- PrintWriter out = new PrintWriter(f);
- for (String s : result) {
- out.println(s);
- }
- out.close();
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/ComputeThresholdXAction.java b/tools/preload2/src/com/android/preload/actions/ComputeThresholdXAction.java
deleted file mode 100644
index 3ec0a4c18db1..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ComputeThresholdXAction.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-public class ComputeThresholdXAction extends ComputeThresholdAction {
-
- public ComputeThresholdXAction(String name, DumpTableModel dataTableModel,
- String blacklist) {
- super(name, dataTableModel, 1, blacklist);
- }
-
- @Override
- public void run() {
- String value = Main.getUI().showInputDialog("Threshold?");
-
- if (value != null) {
- try {
- threshold = Integer.parseInt(value);
- super.run();
- } catch (Exception exc) {
- }
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/DeviceSpecific.java b/tools/preload2/src/com/android/preload/actions/DeviceSpecific.java
deleted file mode 100644
index 35a8f26a99fe..000000000000
--- a/tools/preload2/src/com/android/preload/actions/DeviceSpecific.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.ddmlib.IDevice;
-
-/**
- * Marks an action as being device-specific. The user must set the device through the specified
- * method if the device selection changes.
- *
- * Implementors must tolerate a null device (for example, with a no-op). This includes calling
- * any methods before setDevice has been called.
- */
-public interface DeviceSpecific {
-
- /**
- * Set the device that should be used. Note that there is no restriction on calling other
- * methods of the implementor before a setDevice call. Neither is device guaranteed to be
- * non-null.
- *
- * @param device The device to use going forward.
- */
- public void setDevice(IDevice device);
-}
diff --git a/tools/preload2/src/com/android/preload/actions/ExportAction.java b/tools/preload2/src/com/android/preload/actions/ExportAction.java
deleted file mode 100644
index 848a56826788..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ExportAction.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.preload.DumpDataIO;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-import java.awt.event.ActionEvent;
-import java.io.File;
-import java.io.PrintWriter;
-
-public class ExportAction extends AbstractThreadedAction {
- private File lastSaveFile;
- private DumpTableModel dataTableModel;
-
- public ExportAction(DumpTableModel dataTableModel) {
- super("Export data");
- this.dataTableModel = dataTableModel;
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- lastSaveFile = Main.getUI().showSaveDialog();
- if (lastSaveFile != null) {
- super.actionPerformed(e);
- }
- }
-
- @Override
- public void run() {
- Main.getUI().showWaitDialog();
-
- String serialized = DumpDataIO.serialize(dataTableModel.getData());
-
- if (serialized != null) {
- try {
- PrintWriter out = new PrintWriter(lastSaveFile);
- out.println(serialized);
- out.close();
-
- Main.getUI().hideWaitDialog();
- } catch (Exception e) {
- Main.getUI().hideWaitDialog();
- Main.getUI().showMessageDialog("Failed writing: " + e.getMessage());
- }
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/ImportAction.java b/tools/preload2/src/com/android/preload/actions/ImportAction.java
deleted file mode 100644
index bfeeb836fd45..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ImportAction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.preload.DumpData;
-import com.android.preload.DumpDataIO;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-import java.awt.event.ActionEvent;
-import java.io.File;
-import java.util.Collection;
-
-import javax.swing.AbstractAction;
-
-public class ImportAction extends AbstractThreadedAction {
- private File[] lastOpenFiles;
- private DumpTableModel dataTableModel;
-
- public ImportAction(DumpTableModel dataTableModel) {
- super("Import data");
- this.dataTableModel = dataTableModel;
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- lastOpenFiles = Main.getUI().showOpenDialog(true);
- if (lastOpenFiles != null) {
- super.actionPerformed(e);
- }
- }
-
- @Override
- public void run() {
- Main.getUI().showWaitDialog();
-
- try {
- for (File f : lastOpenFiles) {
- try {
- Collection<DumpData> data = DumpDataIO.deserialize(f);
-
- for (DumpData d : data) {
- dataTableModel.addData(d);
- }
- } catch (Exception e) {
- Main.getUI().showMessageDialog("Failed reading: " + e.getMessage());
- }
- }
- } finally {
- Main.getUI().hideWaitDialog();
- }
-
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/ReloadListAction.java b/tools/preload2/src/com/android/preload/actions/ReloadListAction.java
deleted file mode 100644
index 29f055700dfa..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ReloadListAction.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.preload.ClientUtils;
-
-import java.util.Arrays;
-import java.util.Comparator;
-
-import javax.swing.DefaultListModel;
-
-public class ReloadListAction extends AbstractThreadedDeviceSpecificAction {
-
- private ClientUtils clientUtils;
- private final DefaultListModel<Client> clientListModel;
-
- public ReloadListAction(ClientUtils utils, IDevice device,
- DefaultListModel<Client> clientListModel) {
- super("Reload", device);
- this.clientUtils = utils;
- this.clientListModel = clientListModel;
- }
-
- @Override
- public void run() {
- Client[] clients = clientUtils.findAllClients(device);
- if (clients != null) {
- Arrays.sort(clients, new ClientComparator());
- }
- clientListModel.removeAllElements();
- for (Client c : clients) {
- clientListModel.addElement(c);
- }
- }
-
- private static class ClientComparator implements Comparator<Client> {
-
- @Override
- public int compare(Client o1, Client o2) {
- String s1 = o1.getClientData().getClientDescription();
- String s2 = o2.getClientData().getClientDescription();
-
- if (s1 == null || s2 == null) {
- // Not good, didn't get all data?
- return (s1 == null) ? -1 : 1;
- }
-
- return s1.compareTo(s2);
- }
-
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/RunMonkeyAction.java b/tools/preload2/src/com/android/preload/actions/RunMonkeyAction.java
deleted file mode 100644
index 29464fc7abdf..000000000000
--- a/tools/preload2/src/com/android/preload/actions/RunMonkeyAction.java
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.ddmlib.IDevice;
-import com.android.preload.DeviceUtils;
-import com.android.preload.DumpData;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-import java.awt.event.ActionEvent;
-import java.util.Date;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-
-import javax.swing.AbstractAction;
-
-public class RunMonkeyAction extends AbstractAction implements DeviceSpecific {
-
- private final static String DEFAULT_MONKEY_PACKAGES =
- "com.android.calendar,com.android.gallery3d";
-
- private IDevice device;
- private DumpTableModel dataTableModel;
-
- public RunMonkeyAction(IDevice device, DumpTableModel dataTableModel) {
- super("Run monkey");
- this.device = device;
- this.dataTableModel = dataTableModel;
- }
-
- @Override
- public void setDevice(IDevice device) {
- this.device = device;
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- String packages = Main.getUI().showInputDialog("Please enter packages name to run with"
- + " the monkey, or leave empty for default.");
- if (packages == null) {
- return;
- }
- if (packages.isEmpty()) {
- packages = DEFAULT_MONKEY_PACKAGES;
- }
- Runnable r = new RunMonkeyRunnable(packages);
- if (Main.getUI().isSingleThreaded()) {
- r.run();
- } else {
- new Thread(r).start();
- }
- }
-
- private class RunMonkeyRunnable implements Runnable {
-
- private String packages;
- private final static int ITERATIONS = 1000;
-
- public RunMonkeyRunnable(String packages) {
- this.packages = packages;
- }
-
- @Override
- public void run() {
- Main.getUI().showWaitDialog();
-
- try {
- String pkgs[] = packages.split(",");
-
- for (String pkg : pkgs) {
- Main.getUI().updateWaitDialog("Running monkey on " + pkg);
-
- try {
- // Stop running app.
- forceStop(pkg);
-
- // Little bit of breather here.
- try {
- Thread.sleep(1000);
- } catch (Exception e) {
- }
-
- DeviceUtils.doShell(device, "monkey -p " + pkg + " " + ITERATIONS, 1,
- TimeUnit.MINUTES);
-
- Main.getUI().updateWaitDialog("Retrieving heap data for " + pkg);
- Map<String, String> data = Main.findAndGetClassData(device, pkg);
- DumpData dumpData = new DumpData(pkg, data, new Date());
- dataTableModel.addData(dumpData);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // Stop running app.
- forceStop(pkg);
- }
- }
- } finally {
- Main.getUI().hideWaitDialog();
- }
- }
-
- private void forceStop(String packageName) {
- // Stop running app.
- DeviceUtils.doShell(device, "force-stop " + packageName, 5, TimeUnit.SECONDS);
- DeviceUtils.doShell(device, "kill " + packageName, 5, TimeUnit.SECONDS);
- DeviceUtils.doShell(device, "kill `pid " + packageName + "`", 5, TimeUnit.SECONDS);
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/ScanAllPackagesAction.java b/tools/preload2/src/com/android/preload/actions/ScanAllPackagesAction.java
deleted file mode 100644
index d74b8a3f6cfb..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ScanAllPackagesAction.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.preload.ClientUtils;
-import com.android.preload.DumpData;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-import java.util.Date;
-import java.util.Map;
-
-public class ScanAllPackagesAction extends AbstractThreadedDeviceSpecificAction {
-
- private ClientUtils clientUtils;
- private DumpTableModel dataTableModel;
-
- public ScanAllPackagesAction(ClientUtils utils, IDevice device, DumpTableModel dataTableModel) {
- super("Scan all packages", device);
- this.clientUtils = utils;
- this.dataTableModel = dataTableModel;
- }
-
- @Override
- public void run() {
- Main.getUI().showWaitDialog();
-
- try {
- Client[] clients = clientUtils.findAllClients(device);
- for (Client c : clients) {
- String pkg = c.getClientData().getClientDescription();
- Main.getUI().showWaitDialog();
- Main.getUI().updateWaitDialog("Retrieving heap data for " + pkg);
-
- try {
- Map<String, String> data = Main.getClassDataRetriever().getClassData(c);
- DumpData dumpData = new DumpData(pkg, data, new Date());
- dataTableModel.addData(dumpData);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- } finally {
- Main.getUI().hideWaitDialog();
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/ScanPackageAction.java b/tools/preload2/src/com/android/preload/actions/ScanPackageAction.java
deleted file mode 100644
index 98492bd951bf..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ScanPackageAction.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.preload.ClientUtils;
-import com.android.preload.DumpData;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-import java.util.Date;
-import java.util.Map;
-
-public class ScanPackageAction extends AbstractThreadedDeviceSpecificAction {
-
- private ClientUtils clientUtils;
- private DumpTableModel dataTableModel;
-
- public ScanPackageAction(ClientUtils utils, IDevice device, DumpTableModel dataTableModel) {
- super("Scan package", device);
- this.clientUtils = utils;
- this.dataTableModel = dataTableModel;
- }
-
- @Override
- public void run() {
- Main.getUI().showWaitDialog();
-
- try {
- Client client = Main.getUI().getSelectedClient();
- if (client != null) {
- work(client);
- } else {
- Client[] clients = clientUtils.findAllClients(device);
- if (clients.length > 0) {
- ClientWrapper[] clientWrappers = new ClientWrapper[clients.length];
- for (int i = 0; i < clientWrappers.length; i++) {
- clientWrappers[i] = new ClientWrapper(clients[i]);
- }
- Main.getUI().hideWaitDialog();
-
- ClientWrapper ret = Main.getUI().showChoiceDialog("Choose a package to scan",
- "Choose package",
- clientWrappers);
- if (ret != null) {
- work(ret.client);
- }
- }
- }
- } finally {
- Main.getUI().hideWaitDialog();
- }
- }
-
- private void work(Client c) {
- String pkg = c.getClientData().getClientDescription();
- Main.getUI().showWaitDialog();
- Main.getUI().updateWaitDialog("Retrieving heap data for " + pkg);
-
- try {
- Map<String, String> data = Main.findAndGetClassData(device, pkg);
- DumpData dumpData = new DumpData(pkg, data, new Date());
- dataTableModel.addData(dumpData);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
-
- private static class ClientWrapper {
- private Client client;
-
- public ClientWrapper(Client c) {
- client = c;
- }
-
- @Override
- public String toString() {
- return client.getClientData().getClientDescription() + " (pid "
- + client.getClientData().getPid() + ")";
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/ShowDataAction.java b/tools/preload2/src/com/android/preload/actions/ShowDataAction.java
deleted file mode 100644
index 2bb175f60772..000000000000
--- a/tools/preload2/src/com/android/preload/actions/ShowDataAction.java
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.preload.DumpData;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-import java.awt.BorderLayout;
-import java.awt.event.ActionEvent;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.swing.AbstractAction;
-import javax.swing.JFrame;
-import javax.swing.JScrollPane;
-import javax.swing.JTextArea;
-
-public class ShowDataAction extends AbstractAction {
- private DumpTableModel dataTableModel;
-
- public ShowDataAction(DumpTableModel dataTableModel) {
- super("Show data");
- this.dataTableModel = dataTableModel;
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- // TODO(agampe): Auto-generated method stub
- int selRow = Main.getUI().getSelectedDataTableRow();
- if (selRow != -1) {
- DumpData data = dataTableModel.getData().get(selRow);
- Map<String, Set<String>> inv = data.invertData();
-
- StringBuilder builder = new StringBuilder();
-
- // First bootclasspath.
- add(builder, "Boot classpath:", inv.get(null));
-
- // Now everything else.
- for (String k : inv.keySet()) {
- if (k != null) {
- builder.append("==================\n\n");
- add(builder, k, inv.get(k));
- }
- }
-
- JFrame newFrame = new JFrame(data.getPackageName() + " " + data.getDate());
- newFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
- newFrame.getContentPane().add(new JScrollPane(new JTextArea(builder.toString())),
- BorderLayout.CENTER);
- newFrame.setSize(800, 600);
- newFrame.setLocationRelativeTo(null);
- newFrame.setVisible(true);
- }
- }
-
- private void add(StringBuilder builder, String head, Set<String> set) {
- builder.append(head);
- builder.append('\n');
- addSet(builder, set);
- builder.append('\n');
- }
-
- private void addSet(StringBuilder builder, Set<String> set) {
- if (set == null) {
- builder.append(" NONE\n");
- return;
- }
- List<String> sorted = new ArrayList<>(set);
- Collections.sort(sorted);
- for (String s : sorted) {
- builder.append(s);
- builder.append('\n');
- }
- }
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/actions/WritePreloadedClassesAction.java b/tools/preload2/src/com/android/preload/actions/WritePreloadedClassesAction.java
deleted file mode 100644
index 9b97f1168df9..000000000000
--- a/tools/preload2/src/com/android/preload/actions/WritePreloadedClassesAction.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.actions;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.IDevice;
-import com.android.preload.ClientUtils;
-import com.android.preload.DeviceUtils;
-import com.android.preload.DumpData;
-import com.android.preload.DumpTableModel;
-import com.android.preload.Main;
-
-import java.awt.event.ActionEvent;
-import java.io.File;
-import java.util.Date;
-import java.util.Map;
-
-public class WritePreloadedClassesAction extends AbstractThreadedDeviceSpecificAction {
- private File preloadedClassFile;
-
- public WritePreloadedClassesAction(ClientUtils utils, IDevice device, DumpTableModel dataTableModel) {
- super("Write preloaded classes action", device);
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- File[] files = Main.getUI().showOpenDialog(true);
- if (files != null && files.length > 0) {
- preloadedClassFile = files[0];
- super.actionPerformed(e);
- }
- }
-
- @Override
- public void run() {
- Main.getUI().showWaitDialog();
- try {
- // Write the new file with a 5-minute timeout
- DeviceUtils.overwritePreloaded(device, preloadedClassFile, 5 * 60);
- } catch (Exception e) {
- System.err.println(e);
- } finally {
- Main.getUI().hideWaitDialog();
- }
- }
-}
diff --git a/tools/preload2/src/com/android/preload/classdataretrieval/ClassDataRetriever.java b/tools/preload2/src/com/android/preload/classdataretrieval/ClassDataRetriever.java
deleted file mode 100644
index f04360fc1942..000000000000
--- a/tools/preload2/src/com/android/preload/classdataretrieval/ClassDataRetriever.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.classdataretrieval;
-
-import com.android.ddmlib.Client;
-
-import java.util.Map;
-
-/**
- * Retrieve a class-to-classloader map for loaded classes from the client.
- */
-public interface ClassDataRetriever {
-
- public Map<String, String> getClassData(Client client);
-}
diff --git a/tools/preload2/src/com/android/preload/classdataretrieval/hprof/GeneralHprofDumpHandler.java b/tools/preload2/src/com/android/preload/classdataretrieval/hprof/GeneralHprofDumpHandler.java
deleted file mode 100644
index 8d797ee00128..000000000000
--- a/tools/preload2/src/com/android/preload/classdataretrieval/hprof/GeneralHprofDumpHandler.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.classdataretrieval.hprof;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData.IHprofDumpHandler;
-
-import java.util.ArrayList;
-import java.util.List;
-
-public class GeneralHprofDumpHandler implements IHprofDumpHandler {
-
- private List<IHprofDumpHandler> handlers = new ArrayList<>();
-
- public void addHandler(IHprofDumpHandler h) {
- synchronized (handlers) {
- handlers.add(h);
- }
- }
-
- public void removeHandler(IHprofDumpHandler h) {
- synchronized (handlers) {
- handlers.remove(h);
- }
- }
-
- private List<IHprofDumpHandler> getIterationList() {
- synchronized (handlers) {
- return new ArrayList<>(handlers);
- }
- }
-
- @Override
- public void onEndFailure(Client arg0, String arg1) {
- List<IHprofDumpHandler> iterList = getIterationList();
- for (IHprofDumpHandler h : iterList) {
- h.onEndFailure(arg0, arg1);
- }
- }
-
- @Override
- public void onSuccess(String arg0, Client arg1) {
- List<IHprofDumpHandler> iterList = getIterationList();
- for (IHprofDumpHandler h : iterList) {
- h.onSuccess(arg0, arg1);
- }
- }
-
- @Override
- public void onSuccess(byte[] arg0, Client arg1) {
- List<IHprofDumpHandler> iterList = getIterationList();
- for (IHprofDumpHandler h : iterList) {
- h.onSuccess(arg0, arg1);
- }
- }
- } \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/classdataretrieval/hprof/Hprof.java b/tools/preload2/src/com/android/preload/classdataretrieval/hprof/Hprof.java
deleted file mode 100644
index 84ec8b7d0fdd..000000000000
--- a/tools/preload2/src/com/android/preload/classdataretrieval/hprof/Hprof.java
+++ /dev/null
@@ -1,228 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.classdataretrieval.hprof;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import com.android.ddmlib.ClientData.IHprofDumpHandler;
-import com.android.preload.classdataretrieval.ClassDataRetriever;
-import com.android.preload.ui.NullProgressMonitor;
-import com.android.tools.perflib.captures.MemoryMappedFileBuffer;
-import com.android.tools.perflib.heap.ClassObj;
-import com.android.tools.perflib.heap.Queries;
-import com.android.tools.perflib.heap.Snapshot;
-
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class Hprof implements ClassDataRetriever {
-
- private static GeneralHprofDumpHandler hprofHandler;
-
- public static void init() {
- synchronized(Hprof.class) {
- if (hprofHandler == null) {
- ClientData.setHprofDumpHandler(hprofHandler = new GeneralHprofDumpHandler());
- }
- }
- }
-
- public static File doHprof(Client client, int timeout) {
- GetHprof gh = new GetHprof(client, timeout);
- return gh.get();
- }
-
- /**
- * Return a map of class names to class-loader names derived from the hprof dump.
- *
- * @param hprofLocalFile
- */
- public static Map<String, String> analyzeHprof(File hprofLocalFile) throws Exception {
- Snapshot snapshot = Snapshot.createSnapshot(new MemoryMappedFileBuffer(hprofLocalFile));
-
- Map<String, Set<ClassObj>> classes = Queries.classes(snapshot, null);
- Map<String, String> retValue = new HashMap<String, String>();
- for (Map.Entry<String, Set<ClassObj>> e : classes.entrySet()) {
- for (ClassObj c : e.getValue()) {
- String cl = c.getClassLoader() == null ? null : c.getClassLoader().toString();
- String cName = c.getClassName();
- int aDepth = 0;
- while (cName.endsWith("[]")) {
- cName = cName.substring(0, cName.length()-2);
- aDepth++;
- }
- String newName = transformPrimitiveClass(cName);
- if (aDepth > 0) {
- // Need to use kind-a descriptor syntax. If it was transformed, it is primitive.
- if (newName.equals(cName)) {
- newName = "L" + newName + ";";
- }
- for (int i = 0; i < aDepth; i++) {
- newName = "[" + newName;
- }
- }
- retValue.put(newName, cl);
- }
- }
-
- // Free up memory.
- snapshot.dispose();
-
- return retValue;
- }
-
- private static Map<String, String> primitiveMapping;
-
- static {
- primitiveMapping = new HashMap<>();
- primitiveMapping.put("boolean", "Z");
- primitiveMapping.put("byte", "B");
- primitiveMapping.put("char", "C");
- primitiveMapping.put("double", "D");
- primitiveMapping.put("float", "F");
- primitiveMapping.put("int", "I");
- primitiveMapping.put("long", "J");
- primitiveMapping.put("short", "S");
- primitiveMapping.put("void", "V");
- }
-
- private static String transformPrimitiveClass(String name) {
- String rep = primitiveMapping.get(name);
- if (rep != null) {
- return rep;
- }
- return name;
- }
-
- private static class GetHprof implements IHprofDumpHandler {
-
- private File target;
- private long timeout;
- private Client client;
-
- public GetHprof(Client client, long timeout) {
- this.client = client;
- this.timeout = timeout;
- }
-
- public File get() {
- synchronized (this) {
- hprofHandler.addHandler(this);
- client.dumpHprof();
- if (target == null) {
- try {
- wait(timeout);
- } catch (Exception e) {
- System.out.println(e);
- }
- }
- }
-
- hprofHandler.removeHandler(this);
- return target;
- }
-
- private void wakeUp() {
- synchronized (this) {
- notifyAll();
- }
- }
-
- @Override
- public void onEndFailure(Client arg0, String arg1) {
- System.out.println("GetHprof.onEndFailure");
- if (client == arg0) {
- wakeUp();
- }
- }
-
- private static File createTargetFile() {
- try {
- return File.createTempFile("ddms", ".hprof");
- } catch (Exception e) {
- throw new RuntimeException(e);
- }
- }
-
- @Override
- public void onSuccess(String arg0, Client arg1) {
- System.out.println("GetHprof.onSuccess");
- if (client == arg1) {
- try {
- target = createTargetFile();
- arg1.getDevice().getSyncService().pullFile(arg0,
- target.getAbsoluteFile().toString(), new NullProgressMonitor());
- } catch (Exception e) {
- if (target != null) {
- target.delete();
- }
- e.printStackTrace();
- target = null;
- }
- wakeUp();
- }
- }
-
- @Override
- public void onSuccess(byte[] arg0, Client arg1) {
- System.out.println("GetHprof.onSuccess");
- if (client == arg1) {
- try {
- target = createTargetFile();
- BufferedOutputStream out =
- new BufferedOutputStream(new FileOutputStream(target));
- out.write(arg0);
- out.close();
- } catch (Exception e) {
- if (target != null) {
- target.delete();
- }
- e.printStackTrace();
- target = null;
- }
- wakeUp();
- }
- }
- }
-
- private int timeout;
-
- public Hprof(int timeout) {
- this.timeout = timeout;
- }
-
- @Override
- public Map<String, String> getClassData(Client client) {
- File hprofLocalFile = Hprof.doHprof(client, timeout);
- if (hprofLocalFile == null) {
- throw new RuntimeException("Failed getting dump...");
- }
- System.out.println("Dump file is " + hprofLocalFile);
-
- try {
- return analyzeHprof(hprofLocalFile);
- } catch (Exception e) {
- throw new RuntimeException(e);
- } finally {
- hprofLocalFile.delete();
- }
- }
-}
diff --git a/tools/preload2/src/com/android/preload/classdataretrieval/jdwp/JDWPClassDataRetriever.java b/tools/preload2/src/com/android/preload/classdataretrieval/jdwp/JDWPClassDataRetriever.java
deleted file mode 100644
index dbd4c89b27cf..000000000000
--- a/tools/preload2/src/com/android/preload/classdataretrieval/jdwp/JDWPClassDataRetriever.java
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.classdataretrieval.jdwp;
-
-import com.android.ddmlib.Client;
-import com.android.preload.classdataretrieval.ClassDataRetriever;
-
-import org.apache.harmony.jpda.tests.framework.jdwp.CommandPacket;
-import org.apache.harmony.jpda.tests.framework.jdwp.JDWPCommands;
-import org.apache.harmony.jpda.tests.framework.jdwp.JDWPConstants;
-import org.apache.harmony.jpda.tests.framework.jdwp.ReplyPacket;
-import org.apache.harmony.jpda.tests.jdwp.share.JDWPTestCase;
-import org.apache.harmony.jpda.tests.jdwp.share.JDWPUnitDebuggeeWrapper;
-import org.apache.harmony.jpda.tests.share.JPDALogWriter;
-import org.apache.harmony.jpda.tests.share.JPDATestOptions;
-
-import java.util.HashMap;
-import java.util.Map;
-
-public class JDWPClassDataRetriever extends JDWPTestCase implements ClassDataRetriever {
-
- private final Client client;
-
- public JDWPClassDataRetriever() {
- this(null);
- }
-
- public JDWPClassDataRetriever(Client client) {
- this.client = client;
- }
-
-
- @Override
- protected String getDebuggeeClassName() {
- return "<unset>";
- }
-
- @Override
- public Map<String, String> getClassData(Client client) {
- return new JDWPClassDataRetriever(client).retrieve();
- }
-
- private Map<String, String> retrieve() {
- if (client == null) {
- throw new IllegalStateException();
- }
-
- settings = createTestOptions("localhost:" + String.valueOf(client.getDebuggerListenPort()));
- settings.setDebuggeeSuspend("n");
-
- logWriter = new JPDALogWriter(System.out, "", false);
-
- try {
- internalSetUp();
-
- return retrieveImpl();
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- } finally {
- internalTearDown();
- }
- }
-
- private Map<String, String> retrieveImpl() {
- try {
- // Suspend the app.
- {
- CommandPacket packet = new CommandPacket(
- JDWPCommands.VirtualMachineCommandSet.CommandSetID,
- JDWPCommands.VirtualMachineCommandSet.SuspendCommand);
- ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
- if (reply.getErrorCode() != JDWPConstants.Error.NONE) {
- return null;
- }
- }
-
- // List all classes.
- CommandPacket packet = new CommandPacket(
- JDWPCommands.VirtualMachineCommandSet.CommandSetID,
- JDWPCommands.VirtualMachineCommandSet.AllClassesCommand);
- ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
-
- if (reply.getErrorCode() != JDWPConstants.Error.NONE) {
- return null;
- }
-
- int classCount = reply.getNextValueAsInt();
- System.out.println("Runtime reported " + classCount + " classes.");
-
- Map<Long, String> classes = new HashMap<Long, String>();
- Map<Long, String> arrayClasses = new HashMap<Long, String>();
-
- for (int i = 0; i < classCount; i++) {
- byte refTypeTag = reply.getNextValueAsByte();
- long typeID = reply.getNextValueAsReferenceTypeID();
- String signature = reply.getNextValueAsString();
- /* int status = */ reply.getNextValueAsInt();
-
- switch (refTypeTag) {
- case JDWPConstants.TypeTag.CLASS:
- case JDWPConstants.TypeTag.INTERFACE:
- classes.put(typeID, signature);
- break;
-
- case JDWPConstants.TypeTag.ARRAY:
- arrayClasses.put(typeID, signature);
- break;
- }
- }
-
- Map<String, String> result = new HashMap<String, String>();
-
- // Parse all classes.
- for (Map.Entry<Long, String> entry : classes.entrySet()) {
- long typeID = entry.getKey();
- String signature = entry.getValue();
-
- if (!checkClass(typeID, signature, result)) {
- System.err.println("Issue investigating " + signature);
- }
- }
-
- // For arrays, look at the leaf component type.
- for (Map.Entry<Long, String> entry : arrayClasses.entrySet()) {
- long typeID = entry.getKey();
- String signature = entry.getValue();
-
- if (!checkArrayClass(typeID, signature, result)) {
- System.err.println("Issue investigating " + signature);
- }
- }
-
- return result;
- } finally {
- // Resume the app.
- {
- CommandPacket packet = new CommandPacket(
- JDWPCommands.VirtualMachineCommandSet.CommandSetID,
- JDWPCommands.VirtualMachineCommandSet.ResumeCommand);
- /* ReplyPacket reply = */ debuggeeWrapper.vmMirror.performCommand(packet);
- }
- }
- }
-
- private boolean checkClass(long typeID, String signature, Map<String, String> result) {
- CommandPacket packet = new CommandPacket(
- JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
- JDWPCommands.ReferenceTypeCommandSet.ClassLoaderCommand);
- packet.setNextValueAsReferenceTypeID(typeID);
- ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
- if (reply.getErrorCode() != JDWPConstants.Error.NONE) {
- return false;
- }
-
- long classLoaderID = reply.getNextValueAsObjectID();
-
- // TODO: Investigate the classloader to have a better string?
- String classLoaderString = (classLoaderID == 0) ? null : String.valueOf(classLoaderID);
-
- result.put(getClassName(signature), classLoaderString);
-
- return true;
- }
-
- private boolean checkArrayClass(long typeID, String signature, Map<String, String> result) {
- // Classloaders of array classes are the same as the component class'.
- CommandPacket packet = new CommandPacket(
- JDWPCommands.ReferenceTypeCommandSet.CommandSetID,
- JDWPCommands.ReferenceTypeCommandSet.ClassLoaderCommand);
- packet.setNextValueAsReferenceTypeID(typeID);
- ReplyPacket reply = debuggeeWrapper.vmMirror.performCommand(packet);
- if (reply.getErrorCode() != JDWPConstants.Error.NONE) {
- return false;
- }
-
- long classLoaderID = reply.getNextValueAsObjectID();
-
- // TODO: Investigate the classloader to have a better string?
- String classLoaderString = (classLoaderID == 0) ? null : String.valueOf(classLoaderID);
-
- // For array classes, we *need* the signature directly.
- result.put(signature, classLoaderString);
-
- return true;
- }
-
- private static String getClassName(String signature) {
- String withoutLAndSemicolon = signature.substring(1, signature.length() - 1);
- return withoutLAndSemicolon.replace('/', '.');
- }
-
-
- private static JPDATestOptions createTestOptions(String address) {
- JPDATestOptions options = new JPDATestOptions();
- options.setAttachConnectorKind();
- options.setTimeout(1000);
- options.setWaitingTime(1000);
- options.setTransportAddress(address);
- return options;
- }
-
- @Override
- protected JDWPUnitDebuggeeWrapper createDebuggeeWrapper() {
- return new PreloadDebugeeWrapper(settings, logWriter);
- }
-}
diff --git a/tools/preload2/src/com/android/preload/classdataretrieval/jdwp/PreloadDebugeeWrapper.java b/tools/preload2/src/com/android/preload/classdataretrieval/jdwp/PreloadDebugeeWrapper.java
deleted file mode 100644
index b9df6d0aeb93..000000000000
--- a/tools/preload2/src/com/android/preload/classdataretrieval/jdwp/PreloadDebugeeWrapper.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.classdataretrieval.jdwp;
-
-import org.apache.harmony.jpda.tests.framework.LogWriter;
-import org.apache.harmony.jpda.tests.jdwp.share.JDWPManualDebuggeeWrapper;
-import org.apache.harmony.jpda.tests.share.JPDATestOptions;
-
-import java.io.IOException;
-
-public class PreloadDebugeeWrapper extends JDWPManualDebuggeeWrapper {
-
- public PreloadDebugeeWrapper(JPDATestOptions options, LogWriter writer) {
- super(options, writer);
- }
-
- @Override
- protected Process launchProcess(String cmdLine) throws IOException {
- return null;
- }
-
- @Override
- protected void WaitForProcessExit(Process process) {
- }
-
-}
diff --git a/tools/preload2/src/com/android/preload/ui/IUI.java b/tools/preload2/src/com/android/preload/ui/IUI.java
deleted file mode 100644
index 9371463e9a79..000000000000
--- a/tools/preload2/src/com/android/preload/ui/IUI.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.android.preload.ui;
-
-import com.android.ddmlib.Client;
-import java.io.File;
-import java.util.List;
-import javax.swing.Action;
-import javax.swing.ListModel;
-import javax.swing.table.TableModel;
-
-/**
- * UI abstraction for the tool. This allows a graphical mode, command line mode,
- * or silent mode.
- */
-public interface IUI {
-
- void prepare(ListModel<Client> clientListModel, TableModel dataTableModel,
- List<Action> actions);
-
- void ready();
-
- boolean isSingleThreaded();
-
- Client getSelectedClient();
-
- int getSelectedDataTableRow();
-
- void showWaitDialog();
-
- void updateWaitDialog(String s);
-
- void hideWaitDialog();
-
- void showMessageDialog(String s);
-
- boolean showConfirmDialog(String title, String message);
-
- String showInputDialog(String message);
-
- <T> T showChoiceDialog(String title, String message, T[] choices);
-
- File showSaveDialog();
-
- File[] showOpenDialog(boolean multi);
-
-}
diff --git a/tools/preload2/src/com/android/preload/ui/NullProgressMonitor.java b/tools/preload2/src/com/android/preload/ui/NullProgressMonitor.java
deleted file mode 100644
index f45aad06ac6b..000000000000
--- a/tools/preload2/src/com/android/preload/ui/NullProgressMonitor.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.ui;
-
-import com.android.ddmlib.SyncService.ISyncProgressMonitor;
-
-public class NullProgressMonitor implements ISyncProgressMonitor {
-
- @Override
- public void advance(int arg0) {}
-
- @Override
- public boolean isCanceled() {
- return false;
- }
-
- @Override
- public void start(int arg0) {}
-
- @Override
- public void startSubTask(String arg0) {}
-
- @Override
- public void stop() {}
-} \ No newline at end of file
diff --git a/tools/preload2/src/com/android/preload/ui/SequenceUI.java b/tools/preload2/src/com/android/preload/ui/SequenceUI.java
deleted file mode 100644
index dc6a4f389b10..000000000000
--- a/tools/preload2/src/com/android/preload/ui/SequenceUI.java
+++ /dev/null
@@ -1,222 +0,0 @@
-package com.android.preload.ui;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-import java.io.File;
-import java.util.LinkedList;
-import java.util.List;
-import javax.swing.Action;
-import javax.swing.ListModel;
-import javax.swing.table.TableModel;
-
-public class SequenceUI implements IUI {
-
- private ListModel<Client> clientListModel;
- @SuppressWarnings("unused")
- private TableModel dataTableModel;
- private List<Action> actions;
-
- private List<Object> sequence = new LinkedList<>();
-
- public SequenceUI() {
- }
-
- @Override
- public boolean isSingleThreaded() {
- return true;
- }
-
- @Override
- public void prepare(ListModel<Client> clientListModel, TableModel dataTableModel,
- List<Action> actions) {
- this.clientListModel = clientListModel;
- this.dataTableModel = dataTableModel;
- this.actions = actions;
- }
-
- public SequenceUI action(Action a) {
- sequence.add(a);
- return this;
- }
-
- public SequenceUI action(Class<? extends Action> actionClass) {
- for (Action a : actions) {
- if (actionClass.equals(a.getClass())) {
- sequence.add(a);
- return this;
- }
- }
- throw new IllegalArgumentException("No action of class " + actionClass + " found.");
- }
-
- public SequenceUI confirmYes() {
- sequence.add(Boolean.TRUE);
- return this;
- }
-
- public SequenceUI confirmNo() {
- sequence.add(Boolean.FALSE);
- return this;
- }
-
- public SequenceUI input(String input) {
- sequence.add(input);
- return this;
- }
-
- public SequenceUI input(File... f) {
- sequence.add(f);
- return this;
- }
-
- public SequenceUI output(File f) {
- sequence.add(f);
- return this;
- }
-
- public SequenceUI tableRow(int i) {
- sequence.add(i);
- return this;
- }
-
- private class ClientSelector {
- private String pkg;
-
- public ClientSelector(String pkg) {
- this.pkg = pkg;
- }
-
- public Client getClient() {
- for (int i = 0; i < clientListModel.getSize(); i++) {
- ClientData cd = clientListModel.getElementAt(i).getClientData();
- if (cd != null) {
- String s = cd.getClientDescription();
- if (pkg.equals(s)) {
- return clientListModel.getElementAt(i);
- }
- }
- }
- throw new RuntimeException("Didn't find client " + pkg);
- }
- }
-
- public SequenceUI client(String pkg) {
- sequence.add(new ClientSelector(pkg));
- return this;
- }
-
- public SequenceUI choice(String pattern) {
- sequence.add(pattern);
- return this;
- }
-
- @Override
- public void ready() {
- // Run the actions.
- // No iterator or foreach loop as the sequence will be emptied while running.
- try {
- while (!sequence.isEmpty()) {
- Object next = sequence.remove(0);
- if (next instanceof Action) {
- ((Action)next).actionPerformed(null);
- } else {
- throw new IllegalStateException("Didn't expect a non-action: " + next);
- }
- }
- } catch (Exception e) {
- e.printStackTrace(System.out);
- }
-
- // Now shut down.
- System.exit(0);
- }
-
- @Override
- public Client getSelectedClient() {
- Object next = sequence.remove(0);
- if (next instanceof ClientSelector) {
- return ((ClientSelector)next).getClient();
- }
- throw new IllegalStateException("Unexpected: " + next);
- }
-
- @Override
- public int getSelectedDataTableRow() {
- Object next = sequence.remove(0);
- if (next instanceof Integer) {
- return ((Integer)next).intValue();
- }
- throw new IllegalStateException("Unexpected: " + next);
- }
-
- @Override
- public void showWaitDialog() {
- }
-
- @Override
- public void updateWaitDialog(String s) {
- System.out.println(s);
- }
-
- @Override
- public void hideWaitDialog() {
- }
-
- @Override
- public void showMessageDialog(String s) {
- System.out.println(s);
- }
-
- @Override
- public boolean showConfirmDialog(String title, String message) {
- Object next = sequence.remove(0);
- if (next instanceof Boolean) {
- return ((Boolean)next).booleanValue();
- }
- throw new IllegalStateException("Unexpected: " + next);
- }
-
- @Override
- public String showInputDialog(String message) {
- Object next = sequence.remove(0);
- if (next instanceof String) {
- return (String)next;
- }
- throw new IllegalStateException("Unexpected: " + next);
- }
-
- @Override
- public <T> T showChoiceDialog(String title, String message, T[] choices) {
- Object next = sequence.remove(0);
- if (next instanceof String) {
- String s = (String)next;
- for (T t : choices) {
- if (t.toString().contains(s)) {
- return t;
- }
- }
- return null;
- }
- throw new IllegalStateException("Unexpected: " + next);
- }
-
- @Override
- public File showSaveDialog() {
- Object next = sequence.remove(0);
- if (next instanceof File) {
- System.out.println(next);
- return (File)next;
- }
- throw new IllegalStateException("Unexpected: " + next);
- }
-
- @Override
- public File[] showOpenDialog(boolean multi) {
- Object next = sequence.remove(0);
- if (next instanceof File[]) {
- return (File[])next;
- }
- throw new IllegalStateException("Unexpected: " + next);
- }
-
-}
diff --git a/tools/preload2/src/com/android/preload/ui/SwingUI.java b/tools/preload2/src/com/android/preload/ui/SwingUI.java
deleted file mode 100644
index cab3744ad74c..000000000000
--- a/tools/preload2/src/com/android/preload/ui/SwingUI.java
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * Copyright (C) 2015 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.preload.ui;
-
-import com.android.ddmlib.Client;
-import com.android.ddmlib.ClientData;
-
-import java.awt.BorderLayout;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.io.File;
-import java.util.List;
-
-import javax.swing.Action;
-import javax.swing.DefaultListCellRenderer;
-import javax.swing.JDialog;
-import javax.swing.JFileChooser;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JOptionPane;
-import javax.swing.JProgressBar;
-import javax.swing.JScrollPane;
-import javax.swing.JTable;
-import javax.swing.JToolBar;
-import javax.swing.ListModel;
-import javax.swing.SwingUtilities;
-import javax.swing.table.TableModel;
-
-public class SwingUI extends JFrame implements IUI {
-
- private JList<Client> clientList;
- private JTable dataTable;
-
- // Shared file chooser, means the directory is retained.
- private JFileChooser jfc;
-
- public SwingUI() {
- super("Preloaded-classes computation");
- }
-
- @Override
- public boolean isSingleThreaded() {
- return false;
- }
-
- @Override
- public void prepare(ListModel<Client> clientListModel, TableModel dataTableModel,
- List<Action> actions) {
- getContentPane().add(new JScrollPane(clientList = new JList<Client>(clientListModel)),
- BorderLayout.WEST);
- clientList.setCellRenderer(new ClientListCellRenderer());
- // clientList.addListSelectionListener(listener);
-
- dataTable = new JTable(dataTableModel);
- getContentPane().add(new JScrollPane(dataTable), BorderLayout.CENTER);
-
- JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL);
- for (Action a : actions) {
- if (a == null) {
- toolbar.addSeparator();
- } else {
- toolbar.add(a);
- }
- }
- getContentPane().add(toolbar, BorderLayout.PAGE_START);
-
- setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- setBounds(100, 100, 800, 600);
-
- setVisible(true);
- }
-
- @Override
- public void ready() {
- }
-
- @Override
- public Client getSelectedClient() {
- return clientList.getSelectedValue();
- }
-
- @Override
- public int getSelectedDataTableRow() {
- return dataTable.getSelectedRow();
- }
-
- private JDialog currentWaitDialog = null;
-
- @Override
- public void showWaitDialog() {
- if (currentWaitDialog == null) {
- currentWaitDialog = new JDialog(this, "Please wait...", true);
- currentWaitDialog.getContentPane().add(new JLabel("Please be patient."),
- BorderLayout.CENTER);
- JProgressBar progress = new JProgressBar(JProgressBar.HORIZONTAL);
- progress.setIndeterminate(true);
- currentWaitDialog.getContentPane().add(progress, BorderLayout.SOUTH);
- currentWaitDialog.setSize(200, 100);
- currentWaitDialog.setLocationRelativeTo(null);
- showWaitDialogLater();
- }
- }
-
- private void showWaitDialogLater() {
- SwingUtilities.invokeLater(new Runnable() {
- @Override
- public void run() {
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(true); // This is blocking.
- }
- }
- });
- }
-
- @Override
- public void updateWaitDialog(String s) {
- if (currentWaitDialog != null) {
- ((JLabel) currentWaitDialog.getContentPane().getComponent(0)).setText(s);
- Dimension prefSize = currentWaitDialog.getPreferredSize();
- Dimension curSize = currentWaitDialog.getSize();
- if (prefSize.width > curSize.width || prefSize.height > curSize.height) {
- currentWaitDialog.setSize(Math.max(prefSize.width, curSize.width),
- Math.max(prefSize.height, curSize.height));
- currentWaitDialog.invalidate();
- }
- }
- }
-
- @Override
- public void hideWaitDialog() {
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(false);
- currentWaitDialog = null;
- }
- }
-
- @Override
- public void showMessageDialog(String s) {
- // Hide the wait dialog...
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(false);
- }
-
- try {
- JOptionPane.showMessageDialog(this, s);
- } finally {
- // And reshow it afterwards...
- if (currentWaitDialog != null) {
- showWaitDialogLater();
- }
- }
- }
-
- @Override
- public boolean showConfirmDialog(String title, String message) {
- // Hide the wait dialog...
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(false);
- }
-
- try {
- return JOptionPane.showConfirmDialog(this, title, message, JOptionPane.YES_NO_OPTION)
- == JOptionPane.YES_OPTION;
- } finally {
- // And reshow it afterwards...
- if (currentWaitDialog != null) {
- showWaitDialogLater();
- }
- }
- }
-
- @Override
- public String showInputDialog(String message) {
- // Hide the wait dialog...
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(false);
- }
-
- try {
- return JOptionPane.showInputDialog(message);
- } finally {
- // And reshow it afterwards...
- if (currentWaitDialog != null) {
- showWaitDialogLater();
- }
- }
- }
-
- @Override
- @SuppressWarnings("unchecked")
- public <T> T showChoiceDialog(String title, String message, T[] choices) {
- // Hide the wait dialog...
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(false);
- }
-
- try{
- return (T)JOptionPane.showInputDialog(this,
- title,
- message,
- JOptionPane.QUESTION_MESSAGE,
- null,
- choices,
- choices[0]);
- } finally {
- // And reshow it afterwards...
- if (currentWaitDialog != null) {
- showWaitDialogLater();
- }
- }
- }
-
- @Override
- public File showSaveDialog() {
- // Hide the wait dialog...
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(false);
- }
-
- try{
- if (jfc == null) {
- jfc = new JFileChooser();
- }
-
- int ret = jfc.showSaveDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION) {
- return jfc.getSelectedFile();
- } else {
- return null;
- }
- } finally {
- // And reshow it afterwards...
- if (currentWaitDialog != null) {
- showWaitDialogLater();
- }
- }
- }
-
- @Override
- public File[] showOpenDialog(boolean multi) {
- // Hide the wait dialog...
- if (currentWaitDialog != null) {
- currentWaitDialog.setVisible(false);
- }
-
- try{
- if (jfc == null) {
- jfc = new JFileChooser();
- }
-
- jfc.setMultiSelectionEnabled(multi);
- int ret = jfc.showOpenDialog(this);
- if (ret == JFileChooser.APPROVE_OPTION) {
- return jfc.getSelectedFiles();
- } else {
- return null;
- }
- } finally {
- // And reshow it afterwards...
- if (currentWaitDialog != null) {
- showWaitDialogLater();
- }
- }
- }
-
- private class ClientListCellRenderer extends DefaultListCellRenderer {
-
- @Override
- public Component getListCellRendererComponent(JList<?> list, Object value, int index,
- boolean isSelected, boolean cellHasFocus) {
- ClientData cd = ((Client) value).getClientData();
- String s = cd.getClientDescription() + " (pid " + cd.getPid() + ")";
- return super.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus);
- }
- }
-}