summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apct-tests/perftests/core/Android.mk6
-rw-r--r--apct-tests/perftests/core/AndroidManifest.xml7
-rw-r--r--apct-tests/perftests/core/apps/overlay/Android.bp188
-rw-r--r--apct-tests/perftests/core/apps/overlay/AndroidManifest.xml21
-rw-r--r--apct-tests/perftests/core/apps/overlay/res/values/values.xml19
-rw-r--r--apct-tests/perftests/core/apps/overlay/res_large/values/values.xml274
-rw-r--r--apct-tests/perftests/core/apps/reources_manager/Android.bp34
-rw-r--r--apct-tests/perftests/core/apps/reources_manager/AndroidManifest.xml20
-rw-r--r--apct-tests/perftests/core/res/color/color_state_list.xml25
-rw-r--r--apct-tests/perftests/core/res/values/overlayable.xml280
-rw-r--r--apct-tests/perftests/core/res/values/strings.xml32
-rw-r--r--apct-tests/perftests/core/res/values/values.xml368
-rw-r--r--apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java234
-rw-r--r--apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java139
-rw-r--r--apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java165
-rw-r--r--apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java71
-rw-r--r--apct-tests/perftests/utils/src/android/perftests/utils/TestPackageInstaller.java145
-rw-r--r--apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java2
-rw-r--r--apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java112
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java (renamed from services/usage/java/com/android/server/usage/AppIdleHistory.java)0
-rw-r--r--apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java (renamed from services/usage/java/com/android/server/usage/AppStandbyController.java)148
-rw-r--r--api/current.txt4
-rw-r--r--api/system-current.txt10
-rw-r--r--api/test-current.txt5
-rw-r--r--cmds/locksettings/TEST_MAPPING2
-rw-r--r--cmds/statsd/src/main.cpp2
-rw-r--r--cmds/statsd/tests/StatsLogProcessor_test.cpp307
-rw-r--r--core/java/android/accessibilityservice/AccessibilityService.java30
-rw-r--r--core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl2
-rw-r--r--core/java/android/app/ResourcesManager.java20
-rw-r--r--core/java/android/app/SystemServiceRegistry.java4
-rw-r--r--core/java/android/app/UiAutomation.java32
-rw-r--r--core/java/android/app/role/IRoleManager.aidl6
-rw-r--r--core/java/android/app/usage/AppStandbyInfo.java4
-rw-r--r--core/java/android/content/Context.java2
-rw-r--r--core/java/android/content/PermissionChecker.java319
-rw-r--r--core/java/android/content/om/IOverlayManager.aidl6
-rw-r--r--core/java/android/content/om/OverlayManager.java25
-rw-r--r--core/java/android/content/pm/UserInfo.java2
-rw-r--r--core/java/android/content/res/ApkAssets.java2
-rw-r--r--core/java/android/content/res/StringBlock.java2
-rw-r--r--core/java/android/hardware/location/ContextHubClientCallback.java13
-rw-r--r--core/java/android/provider/Settings.java10
-rw-r--r--core/java/android/service/autofill/AutofillFieldClassificationService.java7
-rw-r--r--core/java/android/speech/RecognitionService.java24
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java35
-rw-r--r--core/java/android/view/accessibility/AccessibilityWindowInfo.aidl1
-rw-r--r--core/java/android/view/accessibility/AccessibilityWindowInfo.java48
-rw-r--r--core/java/android/webkit/MimeTypeMap.java2
-rw-r--r--core/java/android/widget/TextView.java6
-rw-r--r--core/java/com/android/internal/compat/IPlatformCompat.aidl40
-rw-r--r--core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java7
-rw-r--r--core/java/com/android/internal/os/RuntimeInit.java6
-rw-r--r--core/java/com/android/internal/util/MimeIconUtils.java2
-rw-r--r--core/java/com/android/internal/util/function/DecConsumer.java (renamed from services/core/java/com/android/server/integrity/engine/RuleEvaluation.java)15
-rw-r--r--core/java/com/android/internal/util/function/DecFunction.java28
-rw-r--r--core/java/com/android/internal/util/function/DecPredicate.java28
-rw-r--r--core/java/com/android/internal/util/function/UndecConsumer.java28
-rw-r--r--core/java/com/android/internal/util/function/UndecFunction.java28
-rw-r--r--core/java/com/android/internal/util/function/UndecPredicate.java28
-rwxr-xr-xcore/java/com/android/internal/util/function/pooled/OmniFunction.java87
-rwxr-xr-xcore/java/com/android/internal/util/function/pooled/PooledLambda.java304
-rwxr-xr-xcore/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java74
-rw-r--r--core/jni/android_os_Debug.cpp3
-rw-r--r--core/jni/android_util_Process.cpp18
-rw-r--r--core/res/AndroidManifest.xml12
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/strings.xml10
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/bugreports/Android.bp1
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java4
-rw-r--r--data/etc/hiddenapi-package-whitelist.xml4
-rw-r--r--data/etc/privapp-permissions-platform.xml1
-rw-r--r--location/java/android/location/LocationManager.java126
-rw-r--r--media/java/android/media/IMediaRouterService.aidl3
-rw-r--r--media/java/android/media/MediaFile.java2
-rw-r--r--media/java/android/media/MediaRouter.java29
-rw-r--r--media/java/android/media/MediaRouter2.java4
-rw-r--r--media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java2
-rw-r--r--media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java67
-rw-r--r--mime/java/android/content/type/DefaultMimeMapFactory.java2
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java8
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java6
-rw-r--r--packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java162
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java5
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java6
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java1
-rw-r--r--packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java1
-rw-r--r--packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java3
-rw-r--r--packages/SystemUI/README.md6
-rw-r--r--packages/SystemUI/res/values/config.xml2
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java4
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java7
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/DependencyBinder.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/DependencyProvider.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemBars.java88
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIBinder.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotificationData.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java15
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java306
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java20
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java7
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt69
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java9
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java6
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java11
-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/StatusBarTest.java316
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java111
-rw-r--r--services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java18
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java3
-rw-r--r--services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java20
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java4
-rw-r--r--services/core/java/com/android/server/am/TEST_MAPPING1
-rw-r--r--services/core/java/com/android/server/am/UserController.java2
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java28
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java43
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java29
-rw-r--r--services/core/java/com/android/server/hdmi/OneTouchPlayAction.java2
-rw-r--r--services/core/java/com/android/server/integrity/TEST_MAPPING18
-rw-r--r--services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java55
-rw-r--r--services/core/java/com/android/server/integrity/engine/RuleLoader.java61
-rw-r--r--services/core/java/com/android/server/integrity/model/AppInstallMetadata.java (renamed from services/core/java/com/android/server/integrity/engine/AppInstallMetadata.java)4
-rw-r--r--services/core/java/com/android/server/integrity/model/Rule.java160
-rw-r--r--services/core/java/com/android/server/locksettings/LockSettingsService.java114
-rw-r--r--services/core/java/com/android/server/locksettings/TEST_MAPPING2
-rw-r--r--services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java156
-rw-r--r--services/core/java/com/android/server/media/MediaRouterService.java13
-rwxr-xr-x[-rw-r--r--]services/core/java/com/android/server/notification/NotificationManagerService.java56
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerService.java19
-rw-r--r--services/core/java/com/android/server/om/OverlayManagerServiceImpl.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerService.java4
-rw-r--r--services/core/java/com/android/server/role/RoleManagerService.java35
-rw-r--r--services/core/java/com/android/server/rollback/RollbackStore.java23
-rw-r--r--services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java12
-rw-r--r--services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java11
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java13
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java212
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java66
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java6
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java21
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java318
-rwxr-xr-x[-rw-r--r--]services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java8
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java10
-rw-r--r--telephony/java/android/telephony/CellBroadcastService.java112
-rw-r--r--telephony/java/android/telephony/ICellBroadcastService.aidl32
-rw-r--r--telephony/java/android/telephony/IFinancialSmsCallback.aidl34
-rw-r--r--telephony/java/android/telephony/PhoneStateListener.java2
-rw-r--r--telephony/java/android/telephony/SmsManager.java19
-rw-r--r--telephony/java/com/android/internal/telephony/ISms.aidl12
-rw-r--r--telephony/java/com/android/internal/telephony/ISmsImplBase.java7
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java11
-rw-r--r--telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java34
-rwxr-xr-xtests/Codegen/runTest.sh1
-rw-r--r--tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java362
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleDataClass.java6
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java34
-rw-r--r--tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java75
-rw-r--r--tools/codegen/src/com/android/codegen/Generators.kt9
-rw-r--r--tools/codegen/src/com/android/codegen/SharedConstants.kt2
183 files changed, 6531 insertions, 1508 deletions
diff --git a/apct-tests/perftests/core/Android.mk b/apct-tests/perftests/core/Android.mk
index 3f87a1c8b598..968478c3f338 100644
--- a/apct-tests/perftests/core/Android.mk
+++ b/apct-tests/perftests/core/Android.mk
@@ -9,8 +9,11 @@ LOCAL_SRC_FILES := \
src/android/os/ISomeService.aidl
LOCAL_STATIC_JAVA_LIBRARIES := \
+ androidx.appcompat_appcompat \
androidx.test.rules \
androidx.annotation_annotation \
+ apct-perftests-overlay-apps \
+ apct-perftests-resources-manager-apps \
apct-perftests-utils \
guava
@@ -25,5 +28,6 @@ LOCAL_JNI_SHARED_LIBRARIES := libperftestscore_jni
LOCAL_ASSET_DIR := $(TOP)/external/google-fonts/dancing-script
LOCAL_COMPATIBILITY_SUITE += device-tests
+LOCAL_CERTIFICATE := platform
-include $(BUILD_PACKAGE)
+include $(BUILD_PACKAGE) \ No newline at end of file
diff --git a/apct-tests/perftests/core/AndroidManifest.xml b/apct-tests/perftests/core/AndroidManifest.xml
index a564a4d27fb3..525975d36772 100644
--- a/apct-tests/perftests/core/AndroidManifest.xml
+++ b/apct-tests/perftests/core/AndroidManifest.xml
@@ -5,8 +5,11 @@
<permission android:name="com.android.perftests.core.TestPermission" />
<uses-permission android:name="com.android.perftests.core.TestPermission" />
- <uses-permission
- android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.CHANGE_OVERLAY_PACKAGES" />
+ <uses-permission android:name="android.permission.DELETE_PACKAGES" />
+ <uses-permission android:name="android.permission.GET_ACCOUNTS" />
+ <uses-permission android:name="android.permission.INSTALL_PACKAGES"/>
+ <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS" />
<application>
<uses-library android:name="android.test.runner" />
diff --git a/apct-tests/perftests/core/apps/overlay/Android.bp b/apct-tests/perftests/core/apps/overlay/Android.bp
new file mode 100644
index 000000000000..7bee30ee9cb4
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/Android.bp
@@ -0,0 +1,188 @@
+// 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.
+
+android_test_helper_app {
+ name: "Overlay0",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay0",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay1",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay1",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay2",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay2",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay3",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay3",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay4",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay4",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay5",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay5",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay6",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay6",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay7",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay7",
+ ]
+}
+android_test_helper_app {
+ name: "Overlay8",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay8",
+ ]
+}
+
+android_test_helper_app {
+ name: "Overlay9",
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay9",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay0",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large0",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay1",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large1",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay2",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large2",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay3",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large3",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay4",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large4",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay5",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large5",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay6",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large6",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay7",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large7",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay8",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large8",
+ ]
+}
+
+android_test_helper_app {
+ name: "LargeOverlay9",
+ resource_dirs : [ "res_large" ],
+ aaptflags: [
+ "--rename-manifest-package com.android.perftests.overlay.large9",
+ ]
+}
+
+java_library {
+ name: "apct-perftests-overlay-apps",
+ java_resources: [
+ ":Overlay0",
+ ":Overlay1",
+ ":Overlay2",
+ ":Overlay3",
+ ":Overlay4",
+ ":Overlay5",
+ ":Overlay6",
+ ":Overlay7",
+ ":Overlay8",
+ ":Overlay9",
+ ":LargeOverlay0",
+ ":LargeOverlay1",
+ ":LargeOverlay2",
+ ":LargeOverlay3",
+ ":LargeOverlay4",
+ ":LargeOverlay5",
+ ":LargeOverlay6",
+ ":LargeOverlay7",
+ ":LargeOverlay8",
+ ":LargeOverlay9",
+ ],
+} \ No newline at end of file
diff --git a/apct-tests/perftests/core/apps/overlay/AndroidManifest.xml b/apct-tests/perftests/core/apps/overlay/AndroidManifest.xml
new file mode 100644
index 000000000000..52f5a89bc9e4
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?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"
+ package="com.android.perftests.overlay">
+ <application android:hasCode="false" />
+ <uses-sdk android:targetSdkVersion="29" />
+ <overlay android:targetPackage="com.android.perftests.core" android:targetName="TestResources"/>
+</manifest> \ No newline at end of file
diff --git a/apct-tests/perftests/core/apps/overlay/res/values/values.xml b/apct-tests/perftests/core/apps/overlay/res/values/values.xml
new file mode 100644
index 000000000000..a1a8d83eb193
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/res/values/values.xml
@@ -0,0 +1,19 @@
+<?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.
+-->
+
+<resources>
+ <string name="short_text">B</string>
+</resources>
diff --git a/apct-tests/perftests/core/apps/overlay/res_large/values/values.xml b/apct-tests/perftests/core/apps/overlay/res_large/values/values.xml
new file mode 100644
index 000000000000..e74144648e32
--- /dev/null
+++ b/apct-tests/perftests/core/apps/overlay/res_large/values/values.xml
@@ -0,0 +1,274 @@
+<?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.
+-->
+
+<resources>
+ <string name="short_text000">B</string>
+ <string name="short_text001">B</string>
+ <string name="short_text002">B</string>
+ <string name="short_text003">B</string>
+ <string name="short_text004">B</string>
+ <string name="short_text005">B</string>
+ <string name="short_text006">B</string>
+ <string name="short_text007">B</string>
+ <string name="short_text008">B</string>
+ <string name="short_text009">B</string>
+ <string name="short_text010">B</string>
+ <string name="short_text011">B</string>
+ <string name="short_text012">B</string>
+ <string name="short_text013">B</string>
+ <string name="short_text014">B</string>
+ <string name="short_text015">B</string>
+ <string name="short_text016">B</string>
+ <string name="short_text017">B</string>
+ <string name="short_text018">B</string>
+ <string name="short_text019">B</string>
+ <string name="short_text020">B</string>
+ <string name="short_text021">B</string>
+ <string name="short_text022">B</string>
+ <string name="short_text023">B</string>
+ <string name="short_text024">B</string>
+ <string name="short_text025">B</string>
+ <string name="short_text026">B</string>
+ <string name="short_text027">B</string>
+ <string name="short_text028">B</string>
+ <string name="short_text029">B</string>
+ <string name="short_text030">B</string>
+ <string name="short_text031">B</string>
+ <string name="short_text032">B</string>
+ <string name="short_text033">B</string>
+ <string name="short_text034">B</string>
+ <string name="short_text035">B</string>
+ <string name="short_text036">B</string>
+ <string name="short_text037">B</string>
+ <string name="short_text038">B</string>
+ <string name="short_text039">B</string>
+ <string name="short_text040">B</string>
+ <string name="short_text041">B</string>
+ <string name="short_text042">B</string>
+ <string name="short_text043">B</string>
+ <string name="short_text044">B</string>
+ <string name="short_text045">B</string>
+ <string name="short_text046">B</string>
+ <string name="short_text047">B</string>
+ <string name="short_text048">B</string>
+ <string name="short_text049">B</string>
+ <string name="short_text050">B</string>
+ <string name="short_text051">B</string>
+ <string name="short_text052">B</string>
+ <string name="short_text053">B</string>
+ <string name="short_text054">B</string>
+ <string name="short_text055">B</string>
+ <string name="short_text056">B</string>
+ <string name="short_text057">B</string>
+ <string name="short_text058">B</string>
+ <string name="short_text059">B</string>
+ <string name="short_text060">B</string>
+ <string name="short_text061">B</string>
+ <string name="short_text062">B</string>
+ <string name="short_text063">B</string>
+ <string name="short_text064">B</string>
+ <string name="short_text065">B</string>
+ <string name="short_text066">B</string>
+ <string name="short_text067">B</string>
+ <string name="short_text068">B</string>
+ <string name="short_text069">B</string>
+ <string name="short_text070">B</string>
+ <string name="short_text071">B</string>
+ <string name="short_text072">B</string>
+ <string name="short_text073">B</string>
+ <string name="short_text074">B</string>
+ <string name="short_text075">B</string>
+ <string name="short_text076">B</string>
+ <string name="short_text077">B</string>
+ <string name="short_text078">B</string>
+ <string name="short_text079">B</string>
+ <string name="short_text080">B</string>
+ <string name="short_text081">B</string>
+ <string name="short_text082">B</string>
+ <string name="short_text083">B</string>
+ <string name="short_text084">B</string>
+ <string name="short_text085">B</string>
+ <string name="short_text086">B</string>
+ <string name="short_text087">B</string>
+ <string name="short_text088">B</string>
+ <string name="short_text089">B</string>
+ <string name="short_text090">B</string>
+ <string name="short_text091">B</string>
+ <string name="short_text092">B</string>
+ <string name="short_text093">B</string>
+ <string name="short_text094">B</string>
+ <string name="short_text095">B</string>
+ <string name="short_text096">B</string>
+ <string name="short_text097">B</string>
+ <string name="short_text098">B</string>
+ <string name="short_text099">B</string>
+ <string name="short_text100">B</string>
+ <string name="short_text101">B</string>
+ <string name="short_text102">B</string>
+ <string name="short_text103">B</string>
+ <string name="short_text104">B</string>
+ <string name="short_text105">B</string>
+ <string name="short_text106">B</string>
+ <string name="short_text107">B</string>
+ <string name="short_text108">B</string>
+ <string name="short_text109">B</string>
+ <string name="short_text110">B</string>
+ <string name="short_text111">B</string>
+ <string name="short_text112">B</string>
+ <string name="short_text113">B</string>
+ <string name="short_text114">B</string>
+ <string name="short_text115">B</string>
+ <string name="short_text116">B</string>
+ <string name="short_text117">B</string>
+ <string name="short_text118">B</string>
+ <string name="short_text119">B</string>
+ <string name="short_text120">B</string>
+ <string name="short_text121">B</string>
+ <string name="short_text122">B</string>
+ <string name="short_text123">B</string>
+ <string name="short_text124">B</string>
+ <string name="short_text125">B</string>
+ <string name="short_text126">B</string>
+ <string name="short_text127">B</string>
+ <string name="short_text128">B</string>
+ <string name="short_text129">B</string>
+ <string name="short_text130">B</string>
+ <string name="short_text131">B</string>
+ <string name="short_text132">B</string>
+ <string name="short_text133">B</string>
+ <string name="short_text134">B</string>
+ <string name="short_text135">B</string>
+ <string name="short_text136">B</string>
+ <string name="short_text137">B</string>
+ <string name="short_text138">B</string>
+ <string name="short_text139">B</string>
+ <string name="short_text140">B</string>
+ <string name="short_text141">B</string>
+ <string name="short_text142">B</string>
+ <string name="short_text143">B</string>
+ <string name="short_text144">B</string>
+ <string name="short_text145">B</string>
+ <string name="short_text146">B</string>
+ <string name="short_text147">B</string>
+ <string name="short_text148">B</string>
+ <string name="short_text149">B</string>
+ <string name="short_text150">B</string>
+ <string name="short_text151">B</string>
+ <string name="short_text152">B</string>
+ <string name="short_text153">B</string>
+ <string name="short_text154">B</string>
+ <string name="short_text155">B</string>
+ <string name="short_text156">B</string>
+ <string name="short_text157">B</string>
+ <string name="short_text158">B</string>
+ <string name="short_text159">B</string>
+ <string name="short_text160">B</string>
+ <string name="short_text161">B</string>
+ <string name="short_text162">B</string>
+ <string name="short_text163">B</string>
+ <string name="short_text164">B</string>
+ <string name="short_text165">B</string>
+ <string name="short_text166">B</string>
+ <string name="short_text167">B</string>
+ <string name="short_text168">B</string>
+ <string name="short_text169">B</string>
+ <string name="short_text170">B</string>
+ <string name="short_text171">B</string>
+ <string name="short_text172">B</string>
+ <string name="short_text173">B</string>
+ <string name="short_text174">B</string>
+ <string name="short_text175">B</string>
+ <string name="short_text176">B</string>
+ <string name="short_text177">B</string>
+ <string name="short_text178">B</string>
+ <string name="short_text179">B</string>
+ <string name="short_text180">B</string>
+ <string name="short_text181">B</string>
+ <string name="short_text182">B</string>
+ <string name="short_text183">B</string>
+ <string name="short_text184">B</string>
+ <string name="short_text185">B</string>
+ <string name="short_text186">B</string>
+ <string name="short_text187">B</string>
+ <string name="short_text188">B</string>
+ <string name="short_text189">B</string>
+ <string name="short_text190">B</string>
+ <string name="short_text191">B</string>
+ <string name="short_text192">B</string>
+ <string name="short_text193">B</string>
+ <string name="short_text194">B</string>
+ <string name="short_text195">B</string>
+ <string name="short_text196">B</string>
+ <string name="short_text197">B</string>
+ <string name="short_text198">B</string>
+ <string name="short_text199">B</string>
+ <string name="short_text200">B</string>
+ <string name="short_text201">B</string>
+ <string name="short_text202">B</string>
+ <string name="short_text203">B</string>
+ <string name="short_text204">B</string>
+ <string name="short_text205">B</string>
+ <string name="short_text206">B</string>
+ <string name="short_text207">B</string>
+ <string name="short_text208">B</string>
+ <string name="short_text209">B</string>
+ <string name="short_text210">B</string>
+ <string name="short_text211">B</string>
+ <string name="short_text212">B</string>
+ <string name="short_text213">B</string>
+ <string name="short_text214">B</string>
+ <string name="short_text215">B</string>
+ <string name="short_text216">B</string>
+ <string name="short_text217">B</string>
+ <string name="short_text218">B</string>
+ <string name="short_text219">B</string>
+ <string name="short_text220">B</string>
+ <string name="short_text221">B</string>
+ <string name="short_text222">B</string>
+ <string name="short_text223">B</string>
+ <string name="short_text224">B</string>
+ <string name="short_text225">B</string>
+ <string name="short_text226">B</string>
+ <string name="short_text227">B</string>
+ <string name="short_text228">B</string>
+ <string name="short_text229">B</string>
+ <string name="short_text230">B</string>
+ <string name="short_text231">B</string>
+ <string name="short_text232">B</string>
+ <string name="short_text233">B</string>
+ <string name="short_text234">B</string>
+ <string name="short_text235">B</string>
+ <string name="short_text236">B</string>
+ <string name="short_text237">B</string>
+ <string name="short_text238">B</string>
+ <string name="short_text239">B</string>
+ <string name="short_text240">B</string>
+ <string name="short_text241">B</string>
+ <string name="short_text242">B</string>
+ <string name="short_text243">B</string>
+ <string name="short_text244">B</string>
+ <string name="short_text245">B</string>
+ <string name="short_text246">B</string>
+ <string name="short_text247">B</string>
+ <string name="short_text248">B</string>
+ <string name="short_text249">B</string>
+ <string name="short_text250">B</string>
+ <string name="short_text251">B</string>
+ <string name="short_text252">B</string>
+ <string name="short_text253">B</string>
+ <string name="short_text254">B</string>
+ <string name="short_text255">B</string>
+</resources>
diff --git a/apct-tests/perftests/core/apps/reources_manager/Android.bp b/apct-tests/perftests/core/apps/reources_manager/Android.bp
new file mode 100644
index 000000000000..451613236140
--- /dev/null
+++ b/apct-tests/perftests/core/apps/reources_manager/Android.bp
@@ -0,0 +1,34 @@
+// 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.
+
+android_test_helper_app {
+ name: "LargeResourcesCompressed",
+ static_libs: [ "androidx.appcompat_appcompat" ],
+}
+
+genrule {
+ name: "LargeResourcesUncompressed",
+ srcs: [ ":LargeResourcesCompressed" ],
+ out: ["LargeResourcesUncompressed.apk"],
+ cmd: "cp $(in) $(out) && unzip -o $(out) resources.arsc"
+ + " && zip $(out) resources.arsc"
+}
+
+java_library {
+ name: "apct-perftests-resources-manager-apps",
+ java_resources: [
+ ":LargeResourcesCompressed",
+ ":LargeResourcesUncompressed",
+ ],
+} \ No newline at end of file
diff --git a/apct-tests/perftests/core/apps/reources_manager/AndroidManifest.xml b/apct-tests/perftests/core/apps/reources_manager/AndroidManifest.xml
new file mode 100644
index 000000000000..adb4e406c608
--- /dev/null
+++ b/apct-tests/perftests/core/apps/reources_manager/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?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"
+ package="fake.android">
+ <application android:hasCode="false" />
+ <uses-sdk android:targetSdkVersion="29" />
+</manifest> \ No newline at end of file
diff --git a/apct-tests/perftests/core/res/color/color_state_list.xml b/apct-tests/perftests/core/res/color/color_state_list.xml
new file mode 100644
index 000000000000..142e47ae2738
--- /dev/null
+++ b/apct-tests/perftests/core/res/color/color_state_list.xml
@@ -0,0 +1,25 @@
+<?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.
+-->
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_focused="true"
+ android:color="#000000" />
+ <item android:state_pressed="true"
+ android:state_enabled="false"
+ android:color="#212121" />
+ <item android:state_enabled="false"
+ android:color="#414141" />
+ <item android:color="#616161" />
+</selector> \ No newline at end of file
diff --git a/apct-tests/perftests/core/res/values/overlayable.xml b/apct-tests/perftests/core/res/values/overlayable.xml
new file mode 100644
index 000000000000..70cedd7b0b75
--- /dev/null
+++ b/apct-tests/perftests/core/res/values/overlayable.xml
@@ -0,0 +1,280 @@
+<?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
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <overlayable name="TestResources">
+ <policy type="public">
+ <item type="string" name="short_text" />
+ <item type="string" name="short_text000" />
+ <item type="string" name="short_text001" />
+ <item type="string" name="short_text002" />
+ <item type="string" name="short_text003" />
+ <item type="string" name="short_text004" />
+ <item type="string" name="short_text005" />
+ <item type="string" name="short_text006" />
+ <item type="string" name="short_text007" />
+ <item type="string" name="short_text008" />
+ <item type="string" name="short_text009" />
+ <item type="string" name="short_text010" />
+ <item type="string" name="short_text011" />
+ <item type="string" name="short_text012" />
+ <item type="string" name="short_text013" />
+ <item type="string" name="short_text014" />
+ <item type="string" name="short_text015" />
+ <item type="string" name="short_text016" />
+ <item type="string" name="short_text017" />
+ <item type="string" name="short_text018" />
+ <item type="string" name="short_text019" />
+ <item type="string" name="short_text020" />
+ <item type="string" name="short_text021" />
+ <item type="string" name="short_text022" />
+ <item type="string" name="short_text023" />
+ <item type="string" name="short_text024" />
+ <item type="string" name="short_text025" />
+ <item type="string" name="short_text026" />
+ <item type="string" name="short_text027" />
+ <item type="string" name="short_text028" />
+ <item type="string" name="short_text029" />
+ <item type="string" name="short_text030" />
+ <item type="string" name="short_text031" />
+ <item type="string" name="short_text032" />
+ <item type="string" name="short_text033" />
+ <item type="string" name="short_text034" />
+ <item type="string" name="short_text035" />
+ <item type="string" name="short_text036" />
+ <item type="string" name="short_text037" />
+ <item type="string" name="short_text038" />
+ <item type="string" name="short_text039" />
+ <item type="string" name="short_text040" />
+ <item type="string" name="short_text041" />
+ <item type="string" name="short_text042" />
+ <item type="string" name="short_text043" />
+ <item type="string" name="short_text044" />
+ <item type="string" name="short_text045" />
+ <item type="string" name="short_text046" />
+ <item type="string" name="short_text047" />
+ <item type="string" name="short_text048" />
+ <item type="string" name="short_text049" />
+ <item type="string" name="short_text050" />
+ <item type="string" name="short_text051" />
+ <item type="string" name="short_text052" />
+ <item type="string" name="short_text053" />
+ <item type="string" name="short_text054" />
+ <item type="string" name="short_text055" />
+ <item type="string" name="short_text056" />
+ <item type="string" name="short_text057" />
+ <item type="string" name="short_text058" />
+ <item type="string" name="short_text059" />
+ <item type="string" name="short_text060" />
+ <item type="string" name="short_text061" />
+ <item type="string" name="short_text062" />
+ <item type="string" name="short_text063" />
+ <item type="string" name="short_text064" />
+ <item type="string" name="short_text065" />
+ <item type="string" name="short_text066" />
+ <item type="string" name="short_text067" />
+ <item type="string" name="short_text068" />
+ <item type="string" name="short_text069" />
+ <item type="string" name="short_text070" />
+ <item type="string" name="short_text071" />
+ <item type="string" name="short_text072" />
+ <item type="string" name="short_text073" />
+ <item type="string" name="short_text074" />
+ <item type="string" name="short_text075" />
+ <item type="string" name="short_text076" />
+ <item type="string" name="short_text077" />
+ <item type="string" name="short_text078" />
+ <item type="string" name="short_text079" />
+ <item type="string" name="short_text080" />
+ <item type="string" name="short_text081" />
+ <item type="string" name="short_text082" />
+ <item type="string" name="short_text083" />
+ <item type="string" name="short_text084" />
+ <item type="string" name="short_text085" />
+ <item type="string" name="short_text086" />
+ <item type="string" name="short_text087" />
+ <item type="string" name="short_text088" />
+ <item type="string" name="short_text089" />
+ <item type="string" name="short_text090" />
+ <item type="string" name="short_text091" />
+ <item type="string" name="short_text092" />
+ <item type="string" name="short_text093" />
+ <item type="string" name="short_text094" />
+ <item type="string" name="short_text095" />
+ <item type="string" name="short_text096" />
+ <item type="string" name="short_text097" />
+ <item type="string" name="short_text098" />
+ <item type="string" name="short_text099" />
+ <item type="string" name="short_text100" />
+ <item type="string" name="short_text101" />
+ <item type="string" name="short_text102" />
+ <item type="string" name="short_text103" />
+ <item type="string" name="short_text104" />
+ <item type="string" name="short_text105" />
+ <item type="string" name="short_text106" />
+ <item type="string" name="short_text107" />
+ <item type="string" name="short_text108" />
+ <item type="string" name="short_text109" />
+ <item type="string" name="short_text110" />
+ <item type="string" name="short_text111" />
+ <item type="string" name="short_text112" />
+ <item type="string" name="short_text113" />
+ <item type="string" name="short_text114" />
+ <item type="string" name="short_text115" />
+ <item type="string" name="short_text116" />
+ <item type="string" name="short_text117" />
+ <item type="string" name="short_text118" />
+ <item type="string" name="short_text119" />
+ <item type="string" name="short_text120" />
+ <item type="string" name="short_text121" />
+ <item type="string" name="short_text122" />
+ <item type="string" name="short_text123" />
+ <item type="string" name="short_text124" />
+ <item type="string" name="short_text125" />
+ <item type="string" name="short_text126" />
+ <item type="string" name="short_text127" />
+ <item type="string" name="short_text128" />
+ <item type="string" name="short_text129" />
+ <item type="string" name="short_text130" />
+ <item type="string" name="short_text131" />
+ <item type="string" name="short_text132" />
+ <item type="string" name="short_text133" />
+ <item type="string" name="short_text134" />
+ <item type="string" name="short_text135" />
+ <item type="string" name="short_text136" />
+ <item type="string" name="short_text137" />
+ <item type="string" name="short_text138" />
+ <item type="string" name="short_text139" />
+ <item type="string" name="short_text140" />
+ <item type="string" name="short_text141" />
+ <item type="string" name="short_text142" />
+ <item type="string" name="short_text143" />
+ <item type="string" name="short_text144" />
+ <item type="string" name="short_text145" />
+ <item type="string" name="short_text146" />
+ <item type="string" name="short_text147" />
+ <item type="string" name="short_text148" />
+ <item type="string" name="short_text149" />
+ <item type="string" name="short_text150" />
+ <item type="string" name="short_text151" />
+ <item type="string" name="short_text152" />
+ <item type="string" name="short_text153" />
+ <item type="string" name="short_text154" />
+ <item type="string" name="short_text155" />
+ <item type="string" name="short_text156" />
+ <item type="string" name="short_text157" />
+ <item type="string" name="short_text158" />
+ <item type="string" name="short_text159" />
+ <item type="string" name="short_text160" />
+ <item type="string" name="short_text161" />
+ <item type="string" name="short_text162" />
+ <item type="string" name="short_text163" />
+ <item type="string" name="short_text164" />
+ <item type="string" name="short_text165" />
+ <item type="string" name="short_text166" />
+ <item type="string" name="short_text167" />
+ <item type="string" name="short_text168" />
+ <item type="string" name="short_text169" />
+ <item type="string" name="short_text170" />
+ <item type="string" name="short_text171" />
+ <item type="string" name="short_text172" />
+ <item type="string" name="short_text173" />
+ <item type="string" name="short_text174" />
+ <item type="string" name="short_text175" />
+ <item type="string" name="short_text176" />
+ <item type="string" name="short_text177" />
+ <item type="string" name="short_text178" />
+ <item type="string" name="short_text179" />
+ <item type="string" name="short_text180" />
+ <item type="string" name="short_text181" />
+ <item type="string" name="short_text182" />
+ <item type="string" name="short_text183" />
+ <item type="string" name="short_text184" />
+ <item type="string" name="short_text185" />
+ <item type="string" name="short_text186" />
+ <item type="string" name="short_text187" />
+ <item type="string" name="short_text188" />
+ <item type="string" name="short_text189" />
+ <item type="string" name="short_text190" />
+ <item type="string" name="short_text191" />
+ <item type="string" name="short_text192" />
+ <item type="string" name="short_text193" />
+ <item type="string" name="short_text194" />
+ <item type="string" name="short_text195" />
+ <item type="string" name="short_text196" />
+ <item type="string" name="short_text197" />
+ <item type="string" name="short_text198" />
+ <item type="string" name="short_text199" />
+ <item type="string" name="short_text200" />
+ <item type="string" name="short_text201" />
+ <item type="string" name="short_text202" />
+ <item type="string" name="short_text203" />
+ <item type="string" name="short_text204" />
+ <item type="string" name="short_text205" />
+ <item type="string" name="short_text206" />
+ <item type="string" name="short_text207" />
+ <item type="string" name="short_text208" />
+ <item type="string" name="short_text209" />
+ <item type="string" name="short_text210" />
+ <item type="string" name="short_text211" />
+ <item type="string" name="short_text212" />
+ <item type="string" name="short_text213" />
+ <item type="string" name="short_text214" />
+ <item type="string" name="short_text215" />
+ <item type="string" name="short_text216" />
+ <item type="string" name="short_text217" />
+ <item type="string" name="short_text218" />
+ <item type="string" name="short_text219" />
+ <item type="string" name="short_text220" />
+ <item type="string" name="short_text221" />
+ <item type="string" name="short_text222" />
+ <item type="string" name="short_text223" />
+ <item type="string" name="short_text224" />
+ <item type="string" name="short_text225" />
+ <item type="string" name="short_text226" />
+ <item type="string" name="short_text227" />
+ <item type="string" name="short_text228" />
+ <item type="string" name="short_text229" />
+ <item type="string" name="short_text230" />
+ <item type="string" name="short_text231" />
+ <item type="string" name="short_text232" />
+ <item type="string" name="short_text233" />
+ <item type="string" name="short_text234" />
+ <item type="string" name="short_text235" />
+ <item type="string" name="short_text236" />
+ <item type="string" name="short_text237" />
+ <item type="string" name="short_text238" />
+ <item type="string" name="short_text239" />
+ <item type="string" name="short_text240" />
+ <item type="string" name="short_text241" />
+ <item type="string" name="short_text242" />
+ <item type="string" name="short_text243" />
+ <item type="string" name="short_text244" />
+ <item type="string" name="short_text245" />
+ <item type="string" name="short_text246" />
+ <item type="string" name="short_text247" />
+ <item type="string" name="short_text248" />
+ <item type="string" name="short_text249" />
+ <item type="string" name="short_text250" />
+ <item type="string" name="short_text251" />
+ <item type="string" name="short_text252" />
+ <item type="string" name="short_text253" />
+ <item type="string" name="short_text254" />
+ <item type="string" name="short_text255" />
+ </policy>
+ </overlayable>
+</resources>
diff --git a/apct-tests/perftests/core/res/values/strings.xml b/apct-tests/perftests/core/res/values/strings.xml
deleted file mode 100644
index 7ab325f79dc7..000000000000
--- a/apct-tests/perftests/core/res/values/strings.xml
+++ /dev/null
@@ -1,32 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ 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
- -->
-
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="long_text">text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text typo text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text text text text text
- text text text text text text text text text text text text </string>
- <string name="short_text">text text</string>
-</resources>
diff --git a/apct-tests/perftests/core/res/values/values.xml b/apct-tests/perftests/core/res/values/values.xml
new file mode 100644
index 000000000000..aad42ba04e11
--- /dev/null
+++ b/apct-tests/perftests/core/res/values/values.xml
@@ -0,0 +1,368 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ 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
+ -->
+
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <string name="long_text">text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text typo text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text text text text text
+ text text text text text text text text text text text text </string>
+
+ <plurals name="plurals_text">
+ <item quantity="one">1 text</item>
+ <item quantity="other"><xliff:g id="count" example="3">%d</xliff:g> texts</item>
+ </plurals>
+
+ <string-array name="strings">
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ <item>Run</item>
+ <item>the</item>
+ <item>performance</item>
+ <item>tests!</item>
+ </string-array>
+
+ <integer-array name="ints">
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ <item>0</item>
+ <item>1</item>
+ <item>2</item>
+ <item>3</item>
+ </integer-array>
+
+ <color name="white">#ffffff</color>
+
+ <integer name="forty_two">42</integer>
+
+ <string name="short_text">text text</string>
+ <string name="short_text000">B</string>
+ <string name="short_text001">B</string>
+ <string name="short_text002">B</string>
+ <string name="short_text003">B</string>
+ <string name="short_text004">B</string>
+ <string name="short_text005">B</string>
+ <string name="short_text006">B</string>
+ <string name="short_text007">B</string>
+ <string name="short_text008">B</string>
+ <string name="short_text009">B</string>
+ <string name="short_text010">B</string>
+ <string name="short_text011">B</string>
+ <string name="short_text012">B</string>
+ <string name="short_text013">B</string>
+ <string name="short_text014">B</string>
+ <string name="short_text015">B</string>
+ <string name="short_text016">B</string>
+ <string name="short_text017">B</string>
+ <string name="short_text018">B</string>
+ <string name="short_text019">B</string>
+ <string name="short_text020">B</string>
+ <string name="short_text021">B</string>
+ <string name="short_text022">B</string>
+ <string name="short_text023">B</string>
+ <string name="short_text024">B</string>
+ <string name="short_text025">B</string>
+ <string name="short_text026">B</string>
+ <string name="short_text027">B</string>
+ <string name="short_text028">B</string>
+ <string name="short_text029">B</string>
+ <string name="short_text030">B</string>
+ <string name="short_text031">B</string>
+ <string name="short_text032">B</string>
+ <string name="short_text033">B</string>
+ <string name="short_text034">B</string>
+ <string name="short_text035">B</string>
+ <string name="short_text036">B</string>
+ <string name="short_text037">B</string>
+ <string name="short_text038">B</string>
+ <string name="short_text039">B</string>
+ <string name="short_text040">B</string>
+ <string name="short_text041">B</string>
+ <string name="short_text042">B</string>
+ <string name="short_text043">B</string>
+ <string name="short_text044">B</string>
+ <string name="short_text045">B</string>
+ <string name="short_text046">B</string>
+ <string name="short_text047">B</string>
+ <string name="short_text048">B</string>
+ <string name="short_text049">B</string>
+ <string name="short_text050">B</string>
+ <string name="short_text051">B</string>
+ <string name="short_text052">B</string>
+ <string name="short_text053">B</string>
+ <string name="short_text054">B</string>
+ <string name="short_text055">B</string>
+ <string name="short_text056">B</string>
+ <string name="short_text057">B</string>
+ <string name="short_text058">B</string>
+ <string name="short_text059">B</string>
+ <string name="short_text060">B</string>
+ <string name="short_text061">B</string>
+ <string name="short_text062">B</string>
+ <string name="short_text063">B</string>
+ <string name="short_text064">B</string>
+ <string name="short_text065">B</string>
+ <string name="short_text066">B</string>
+ <string name="short_text067">B</string>
+ <string name="short_text068">B</string>
+ <string name="short_text069">B</string>
+ <string name="short_text070">B</string>
+ <string name="short_text071">B</string>
+ <string name="short_text072">B</string>
+ <string name="short_text073">B</string>
+ <string name="short_text074">B</string>
+ <string name="short_text075">B</string>
+ <string name="short_text076">B</string>
+ <string name="short_text077">B</string>
+ <string name="short_text078">B</string>
+ <string name="short_text079">B</string>
+ <string name="short_text080">B</string>
+ <string name="short_text081">B</string>
+ <string name="short_text082">B</string>
+ <string name="short_text083">B</string>
+ <string name="short_text084">B</string>
+ <string name="short_text085">B</string>
+ <string name="short_text086">B</string>
+ <string name="short_text087">B</string>
+ <string name="short_text088">B</string>
+ <string name="short_text089">B</string>
+ <string name="short_text090">B</string>
+ <string name="short_text091">B</string>
+ <string name="short_text092">B</string>
+ <string name="short_text093">B</string>
+ <string name="short_text094">B</string>
+ <string name="short_text095">B</string>
+ <string name="short_text096">B</string>
+ <string name="short_text097">B</string>
+ <string name="short_text098">B</string>
+ <string name="short_text099">B</string>
+ <string name="short_text100">B</string>
+ <string name="short_text101">B</string>
+ <string name="short_text102">B</string>
+ <string name="short_text103">B</string>
+ <string name="short_text104">B</string>
+ <string name="short_text105">B</string>
+ <string name="short_text106">B</string>
+ <string name="short_text107">B</string>
+ <string name="short_text108">B</string>
+ <string name="short_text109">B</string>
+ <string name="short_text110">B</string>
+ <string name="short_text111">B</string>
+ <string name="short_text112">B</string>
+ <string name="short_text113">B</string>
+ <string name="short_text114">B</string>
+ <string name="short_text115">B</string>
+ <string name="short_text116">B</string>
+ <string name="short_text117">B</string>
+ <string name="short_text118">B</string>
+ <string name="short_text119">B</string>
+ <string name="short_text120">B</string>
+ <string name="short_text121">B</string>
+ <string name="short_text122">B</string>
+ <string name="short_text123">B</string>
+ <string name="short_text124">B</string>
+ <string name="short_text125">B</string>
+ <string name="short_text126">B</string>
+ <string name="short_text127">B</string>
+ <string name="short_text128">B</string>
+ <string name="short_text129">B</string>
+ <string name="short_text130">B</string>
+ <string name="short_text131">B</string>
+ <string name="short_text132">B</string>
+ <string name="short_text133">B</string>
+ <string name="short_text134">B</string>
+ <string name="short_text135">B</string>
+ <string name="short_text136">B</string>
+ <string name="short_text137">B</string>
+ <string name="short_text138">B</string>
+ <string name="short_text139">B</string>
+ <string name="short_text140">B</string>
+ <string name="short_text141">B</string>
+ <string name="short_text142">B</string>
+ <string name="short_text143">B</string>
+ <string name="short_text144">B</string>
+ <string name="short_text145">B</string>
+ <string name="short_text146">B</string>
+ <string name="short_text147">B</string>
+ <string name="short_text148">B</string>
+ <string name="short_text149">B</string>
+ <string name="short_text150">B</string>
+ <string name="short_text151">B</string>
+ <string name="short_text152">B</string>
+ <string name="short_text153">B</string>
+ <string name="short_text154">B</string>
+ <string name="short_text155">B</string>
+ <string name="short_text156">B</string>
+ <string name="short_text157">B</string>
+ <string name="short_text158">B</string>
+ <string name="short_text159">B</string>
+ <string name="short_text160">B</string>
+ <string name="short_text161">B</string>
+ <string name="short_text162">B</string>
+ <string name="short_text163">B</string>
+ <string name="short_text164">B</string>
+ <string name="short_text165">B</string>
+ <string name="short_text166">B</string>
+ <string name="short_text167">B</string>
+ <string name="short_text168">B</string>
+ <string name="short_text169">B</string>
+ <string name="short_text170">B</string>
+ <string name="short_text171">B</string>
+ <string name="short_text172">B</string>
+ <string name="short_text173">B</string>
+ <string name="short_text174">B</string>
+ <string name="short_text175">B</string>
+ <string name="short_text176">B</string>
+ <string name="short_text177">B</string>
+ <string name="short_text178">B</string>
+ <string name="short_text179">B</string>
+ <string name="short_text180">B</string>
+ <string name="short_text181">B</string>
+ <string name="short_text182">B</string>
+ <string name="short_text183">B</string>
+ <string name="short_text184">B</string>
+ <string name="short_text185">B</string>
+ <string name="short_text186">B</string>
+ <string name="short_text187">B</string>
+ <string name="short_text188">B</string>
+ <string name="short_text189">B</string>
+ <string name="short_text190">B</string>
+ <string name="short_text191">B</string>
+ <string name="short_text192">B</string>
+ <string name="short_text193">B</string>
+ <string name="short_text194">B</string>
+ <string name="short_text195">B</string>
+ <string name="short_text196">B</string>
+ <string name="short_text197">B</string>
+ <string name="short_text198">B</string>
+ <string name="short_text199">B</string>
+ <string name="short_text200">B</string>
+ <string name="short_text201">B</string>
+ <string name="short_text202">B</string>
+ <string name="short_text203">B</string>
+ <string name="short_text204">B</string>
+ <string name="short_text205">B</string>
+ <string name="short_text206">B</string>
+ <string name="short_text207">B</string>
+ <string name="short_text208">B</string>
+ <string name="short_text209">B</string>
+ <string name="short_text210">B</string>
+ <string name="short_text211">B</string>
+ <string name="short_text212">B</string>
+ <string name="short_text213">B</string>
+ <string name="short_text214">B</string>
+ <string name="short_text215">B</string>
+ <string name="short_text216">B</string>
+ <string name="short_text217">B</string>
+ <string name="short_text218">B</string>
+ <string name="short_text219">B</string>
+ <string name="short_text220">B</string>
+ <string name="short_text221">B</string>
+ <string name="short_text222">B</string>
+ <string name="short_text223">B</string>
+ <string name="short_text224">B</string>
+ <string name="short_text225">B</string>
+ <string name="short_text226">B</string>
+ <string name="short_text227">B</string>
+ <string name="short_text228">B</string>
+ <string name="short_text229">B</string>
+ <string name="short_text230">B</string>
+ <string name="short_text231">B</string>
+ <string name="short_text232">B</string>
+ <string name="short_text233">B</string>
+ <string name="short_text234">B</string>
+ <string name="short_text235">B</string>
+ <string name="short_text236">B</string>
+ <string name="short_text237">B</string>
+ <string name="short_text238">B</string>
+ <string name="short_text239">B</string>
+ <string name="short_text240">B</string>
+ <string name="short_text241">B</string>
+ <string name="short_text242">B</string>
+ <string name="short_text243">B</string>
+ <string name="short_text244">B</string>
+ <string name="short_text245">B</string>
+ <string name="short_text246">B</string>
+ <string name="short_text247">B</string>
+ <string name="short_text248">B</string>
+ <string name="short_text249">B</string>
+ <string name="short_text250">B</string>
+ <string name="short_text251">B</string>
+ <string name="short_text252">B</string>
+ <string name="short_text253">B</string>
+ <string name="short_text254">B</string>
+ <string name="short_text255">B</string>
+</resources>
diff --git a/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java b/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java
new file mode 100644
index 000000000000..fcb13a8d51f1
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/app/OverlayManagerPerfTest.java
@@ -0,0 +1,234 @@
+/*
+ * 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.app;
+
+import static org.junit.Assert.assertTrue;
+
+import android.content.Context;
+import android.content.om.OverlayManager;
+import android.os.UserHandle;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.perftests.utils.TestPackageInstaller;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
+import com.android.perftests.core.R;
+
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * Benchmarks for {@link android.content.om.OverlayManager}.
+ */
+@LargeTest
+public class OverlayManagerPerfTest {
+ private static final int OVERLAY_PKG_COUNT = 10;
+ private static Context sContext;
+ private static OverlayManager sOverlayManager;
+ private static Executor sExecutor;
+ private static ArrayList<TestPackageInstaller.InstalledPackage> sSmallOverlays =
+ new ArrayList<>();
+ private static ArrayList<TestPackageInstaller.InstalledPackage> sLargeOverlays =
+ new ArrayList<>();
+
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @BeforeClass
+ public static void classSetUp() throws Exception {
+ sContext = InstrumentationRegistry.getTargetContext();
+ sOverlayManager = new OverlayManager(sContext);
+ sExecutor = (command) -> new Thread(command).start();
+
+ // Install all of the test overlays.
+ TestPackageInstaller installer = new TestPackageInstaller(sContext);
+ for (int i = 0; i < OVERLAY_PKG_COUNT; i++) {
+ sSmallOverlays.add(installer.installPackage("Overlay" + i +".apk"));
+ sLargeOverlays.add(installer.installPackage("LargeOverlay" + i +".apk"));
+ }
+ }
+
+ @AfterClass
+ public static void classTearDown() throws Exception {
+ for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
+ overlay.uninstall();
+ }
+
+ for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
+ overlay.uninstall();
+ }
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ // Disable all test overlays after each test.
+ for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), false);
+ }
+
+ for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), false);
+ }
+ }
+
+ /**
+ * Enables the overlay and waits for the APK path change sto be propagated to the context
+ * AssetManager.
+ */
+ private void assertSetEnabled(Context context, String overlayPackage, boolean eanabled)
+ throws Exception {
+ sOverlayManager.setEnabled(overlayPackage, true, UserHandle.SYSTEM);
+
+ // Wait for the overlay changes to propagate
+ FutureTask<Boolean> task = new FutureTask<>(() -> {
+ while (true) {
+ for (String path : context.getAssets().getApkPaths()) {
+ if (eanabled == path.contains(overlayPackage)) {
+ return true;
+ }
+ }
+ }
+ });
+
+ sExecutor.execute(task);
+ assertTrue("Failed to load overlay " + overlayPackage,
+ task.get(20, TimeUnit.SECONDS));
+ }
+
+ @Test
+ public void setEnabledWarmCache() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ assertSetEnabled(sContext, packageName, true);
+
+ // Disable the overlay for the next iteration of the test
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, false);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void setEnabledColdCacheSmallOverlay() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ assertSetEnabled(sContext, packageName, true);
+
+ // Disable the overlay and remove the idmap for the next iteration of the test
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, false);
+ sOverlayManager.invalidateCachesForOverlay(packageName, UserHandle.SYSTEM);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void setEnabledColdCacheLargeOverlay() throws Exception {
+ String packageName = sLargeOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ assertSetEnabled(sContext, packageName, true);
+
+ // Disable the overlay and remove the idmap for the next iteration of the test
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, false);
+ sOverlayManager.invalidateCachesForOverlay(packageName, UserHandle.SYSTEM);
+ state.resumeTiming();
+ }
+ }
+
+ @Test
+ public void setEnabledDisable() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ assertSetEnabled(sContext, packageName, true);
+ state.resumeTiming();
+
+ assertSetEnabled(sContext, packageName, false);
+ }
+ }
+
+ @Test
+ public void getStringOneSmallOverlay() throws Exception {
+ String packageName = sSmallOverlays.get(0).getPackageName();
+ assertSetEnabled(sContext, packageName, true);
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sContext.getString(R.string.short_text);
+ }
+
+ assertSetEnabled(sContext, packageName, false);
+ }
+
+ @Test
+ public void getStringOneLargeOverlay() throws Exception {
+ String packageName = sLargeOverlays.get(0).getPackageName();
+ assertSetEnabled(sContext, packageName, true);
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int resId = R.string.short_text000; resId < R.string.short_text255; resId++) {
+ sContext.getString(resId);
+ }
+ }
+
+ assertSetEnabled(sContext, packageName, false);
+ }
+
+ @Test
+ public void getStringTenOverlays() throws Exception {
+ // Enable all test overlays
+ for (TestPackageInstaller.InstalledPackage overlay : sSmallOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), true);
+ }
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ sContext.getString(R.string.short_text);
+ }
+ }
+
+ @Test
+ public void getStringLargeTenOverlays() throws Exception {
+ // Enable all test overlays
+ for (TestPackageInstaller.InstalledPackage overlay : sLargeOverlays) {
+ assertSetEnabled(sContext, overlay.getPackageName(), true);
+ }
+
+ BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ for (int resId = R.string.short_text000; resId < R.string.short_text255; resId++) {
+ sContext.getString(resId);
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
new file mode 100644
index 000000000000..2955d2ca7d0e
--- /dev/null
+++ b/apct-tests/perftests/core/src/android/app/ResourcesManagerPerfTest.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package android.app;
+
+import android.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.perftests.utils.BenchmarkState;
+import android.perftests.utils.PerfStatusReporter;
+import android.view.Display;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.LargeTest;
+
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Benchmarks for {@link android.app.ResourcesManager}.
+ */
+@LargeTest
+public class ResourcesManagerPerfTest {
+ private static Context sContext;
+ private static File sResourcesCompressed;
+ private static File sResourcesUncompressed;
+
+ @Rule
+ public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+
+ @BeforeClass
+ public static void setUp() throws Exception {
+ sContext = InstrumentationRegistry.getTargetContext();
+ sResourcesCompressed = copyApkToTemp("LargeResourcesCompressed.apk",
+ "LargeResourcesCompressed.apk");
+ sResourcesUncompressed = copyApkToTemp("LargeResourcesUncompressed.apk",
+ "LargeResourcesUncompressed.apk");
+ }
+
+ @AfterClass
+ public static void tearDown() {
+ Assert.assertTrue(sResourcesCompressed.delete());
+ Assert.assertTrue(sResourcesUncompressed.delete());
+ }
+
+ private static File copyApkToTemp(String inputFileName, String fileName) throws Exception {
+ File file = File.createTempFile(fileName, null, sContext.getCacheDir());
+ try (OutputStream tempOutputStream = new FileOutputStream(file);
+ InputStream is = sContext.getResources().getAssets().openNonAsset(inputFileName)) {
+ byte[] buffer = new byte[4096];
+ int n;
+ while ((n = is.read(buffer)) >= 0) {
+ tempOutputStream.write(buffer, 0, n);
+ }
+ tempOutputStream.flush();
+ }
+ return file;
+ }
+
+ private void getResourcesForPath(String path) {
+ ResourcesManager.getInstance().getResources(null, path, null, null, null,
+ Display.DEFAULT_DISPLAY, null, sContext.getResources().getCompatibilityInfo(),
+ null);
+ }
+
+ @Test
+ public void getResourcesCached() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ getResourcesForPath(sResourcesCompressed.getPath());
+ while (state.keepRunning()) {
+ getResourcesForPath(sResourcesCompressed.getPath());
+ }
+ }
+
+ @Test
+ public void getResourcesCompressedUncached() {
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ resourcesManager.invalidatePath(sResourcesCompressed.getPath());
+ state.resumeTiming();
+
+ getResourcesForPath(sResourcesCompressed.getPath());
+ }
+ }
+
+ @Test
+ public void getResourcesUncompressedUncached() {
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ state.pauseTiming();
+ resourcesManager.invalidatePath(sResourcesUncompressed.getPath());
+ state.resumeTiming();
+
+ getResourcesForPath(sResourcesUncompressed.getPath());
+ }
+ }
+
+ @Test
+ public void applyConfigurationToResourcesLocked() {
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ Configuration c = new Configuration(resourcesManager.getConfiguration());
+ c.uiMode = Configuration.UI_MODE_TYPE_WATCH;
+
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ resourcesManager.applyConfigurationToResources(c, null);
+
+ // Alternate configurations to ensure the set configuration is different each iteration
+ if (c.uiMode == Configuration.UI_MODE_TYPE_WATCH) {
+ c.uiMode = Configuration.UI_MODE_TYPE_TELEVISION;
+ } else {
+ c.uiMode = Configuration.UI_MODE_TYPE_WATCH;
+ }
+ }
+ }
+}
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java
index c3e43ee07453..72162448a2e0 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesPerfTest.java
@@ -18,15 +18,18 @@ package android.app;
import static org.junit.Assert.fail;
-import android.content.res.AssetManager;
+import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
+import android.util.TypedValue;
+import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
-import org.junit.After;
+import com.android.perftests.core.R;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -43,36 +46,123 @@ public class ResourcesPerfTest {
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
- private AssetManager mAsset;
private Resources mRes;
- private int mTextId;
- private int mColorId;
- private int mIntegerId;
- private int mLayoutId;
-
@Before
public void setUp() {
- mAsset = new AssetManager();
- mAsset.addAssetPath("/system/framework/framework-res.apk");
- mRes = new Resources(mAsset, null, null);
+ Context context = InstrumentationRegistry.getTargetContext();
+ mRes = context.getResources();
+ }
+
+ @Test
+ public void getValue() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(R.integer.forty_two, value, false /* resolve_refs */);
+ }
+ }
- mTextId = mRes.getIdentifier("cancel", "string", "android");
- mColorId = mRes.getIdentifier("transparent", "color", "android");
- mIntegerId = mRes.getIdentifier("config_shortAnimTime", "integer", "android");
- mLayoutId = mRes.getIdentifier("two_line_list_item", "layout", "android");
+ @Test
+ public void getFrameworkValue() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(com.android.internal.R.integer.autofill_max_visible_datasets, value,
+ false /* resolve_refs */);
+ }
+ }
+
+ @Test
+ public void getValueString() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(R.string.long_text, value, false /* resolve_refs */);
+ }
+ }
+
+ @Test
+ public void getFrameworkStringValue() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(com.android.internal.R.string.cancel, value, false /* resolve_refs */);
+ }
}
- @After
- public void tearDown() {
- mAsset.close();
+ @Test
+ public void getValueManyConfigurations() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ TypedValue value = new TypedValue();
+ while (state.keepRunning()) {
+ mRes.getValue(com.android.internal.R.string.mmcc_illegal_me, value,
+ false /* resolve_refs */);
+ }
}
@Test
public void getText() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- mRes.getText(mTextId);
+ mRes.getText(R.string.long_text);
+ }
+ }
+
+
+ @Test
+ public void getFont() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getFont(R.font.samplefont);
+ }
+ }
+
+ @Test
+ public void getString() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getString(R.string.long_text);
+ }
+ }
+
+ @Test
+ public void getQuantityString() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getQuantityString(R.plurals.plurals_text, 5);
+ }
+ }
+
+ @Test
+ public void getQuantityText() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getQuantityText(R.plurals.plurals_text, 5);
+ }
+ }
+
+ @Test
+ public void getTextArray() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getTextArray(R.array.strings);
+ }
+ }
+
+ @Test
+ public void getStringArray() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getStringArray(R.array.strings);
+ }
+ }
+
+ @Test
+ public void getIntegerArray() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getIntArray(R.array.ints);
}
}
@@ -80,15 +170,23 @@ public class ResourcesPerfTest {
public void getColor() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- mRes.getColor(mColorId, null);
+ mRes.getColor(R.color.white, null);
}
}
@Test
- public void getInteger() {
+ public void getColorStateList() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- mRes.getInteger(mIntegerId);
+ mRes.getColorStateList(R.color.color_state_list, null);
+ }
+ }
+
+ @Test
+ public void getVectorDrawable() {
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ mRes.getDrawable(R.drawable.vector_drawable01, null);
}
}
@@ -96,13 +194,32 @@ public class ResourcesPerfTest {
public void getLayoutAndTravese() {
final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
while (state.keepRunning()) {
- try (XmlResourceParser parser = mRes.getLayout(mLayoutId)) {
+ try (XmlResourceParser parser = mRes.getLayout(R.layout.test_relative_layout)) {
+ while (parser.next() != XmlPullParser.END_DOCUMENT) {
+ // Walk the entire tree
+ }
+ } catch (IOException | XmlPullParserException exception) {
+ fail("Parsing of the layout failed. Something is really broken");
+ }
+ }
+ }
+
+ @Test
+ public void getLayoutAndTraverseInvalidateCaches() {
+ mRes.flushLayoutCache();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ try (XmlResourceParser parser = mRes.getLayout(R.layout.test_relative_layout)) {
while (parser.next() != XmlPullParser.END_DOCUMENT) {
// Walk the entire tree
}
} catch (IOException | XmlPullParserException exception) {
fail("Parsing of the layout failed. Something is really broken");
}
+
+ state.pauseTiming();
+ mRes.flushLayoutCache();
+ state.resumeTiming();
}
}
-}
+} \ No newline at end of file
diff --git a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
index 1b07572fd3f8..6123e69b584e 100644
--- a/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
+++ b/apct-tests/perftests/core/src/android/app/ResourcesThemePerfTest.java
@@ -16,13 +16,19 @@
package android.app;
import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.Configuration;
import android.content.res.Resources;
+import android.os.UserHandle;
import android.perftests.utils.BenchmarkState;
import android.perftests.utils.PerfStatusReporter;
+import android.view.Display;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.LargeTest;
+import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -35,13 +41,69 @@ public class ResourcesThemePerfTest {
@Rule
public PerfStatusReporter mPerfStatusReporter = new PerfStatusReporter();
+ private Context mContext;
+ private int mThemeResId;
private Resources.Theme mTheme;
@Before
- public void setUp() {
- Context context = InstrumentationRegistry.getTargetContext();
- mTheme = context.getTheme();
+ public void setUp() throws Exception {
+ mContext = InstrumentationRegistry.getTargetContext();
+ mThemeResId = com.android.perftests.core.R.style.Base_V7_Theme_AppCompat;
+ mTheme = mContext.getResources().newTheme();
+ mTheme.applyStyle(mThemeResId, true /* force */);
+ }
+
+ @Test
+ public void applyStyle() {
+ Resources.Theme destTheme = mContext.getResources().newTheme();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.applyStyle(mThemeResId, true /* force */);
+ }
+ }
+ @Test
+ public void rebase() {
+ Resources.Theme destTheme = mContext.getResources().newTheme();
+ destTheme.applyStyle(mThemeResId, true /* force */);
+ destTheme.applyStyle(android.R.style.Theme_Material, true /* force */);
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.rebase();
+ }
+ }
+
+ @Test
+ public void setToSameAssetManager() {
+ Resources.Theme destTheme = mContext.getResources().newTheme();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.setTo(mTheme);
+ }
+ }
+
+ @Test
+ public void setToDifferentAssetManager() throws Exception {
+ // Create a new Resources object with the same asset paths but a different AssetManager
+ PackageManager packageManager = mContext.getApplicationContext().getPackageManager();
+ ApplicationInfo ai = packageManager.getApplicationInfo(mContext.getPackageName(),
+ UserHandle.myUserId());
+
+ ResourcesManager resourcesManager = ResourcesManager.getInstance();
+ Configuration c = resourcesManager.getConfiguration();
+ c.orientation = (c.orientation == Configuration.ORIENTATION_PORTRAIT)
+ ? Configuration.ORIENTATION_LANDSCAPE : Configuration.ORIENTATION_PORTRAIT;
+
+ Resources destResources = resourcesManager.getResources(null, ai.sourceDir,
+ ai.splitSourceDirs, ai.resourceDirs, ai.sharedLibraryFiles, Display.DEFAULT_DISPLAY,
+ c, mContext.getResources().getCompatibilityInfo(), null);
+ Assert.assertNotEquals(destResources.getAssets(), mContext.getAssets());
+
+ Resources.Theme destTheme = destResources.newTheme();
+ final BenchmarkState state = mPerfStatusReporter.getBenchmarkState();
+ while (state.keepRunning()) {
+ destTheme.setTo(mTheme);
+ }
}
@Test
@@ -51,5 +113,4 @@ public class ResourcesThemePerfTest {
mTheme.obtainStyledAttributes(android.R.style.Theme_Material, android.R.styleable.View);
}
}
-
-}
+} \ No newline at end of file
diff --git a/apct-tests/perftests/utils/src/android/perftests/utils/TestPackageInstaller.java b/apct-tests/perftests/utils/src/android/perftests/utils/TestPackageInstaller.java
new file mode 100644
index 000000000000..a433d801acaf
--- /dev/null
+++ b/apct-tests/perftests/utils/src/android/perftests/utils/TestPackageInstaller.java
@@ -0,0 +1,145 @@
+/*
+ * 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.perftests.utils;
+
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.IntentSender;
+import android.content.pm.PackageInstaller;
+import android.content.res.Resources;
+import android.util.Log;
+
+import org.junit.Assert;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * Installs packages included within the assets directory.
+ */
+public class TestPackageInstaller {
+ private static final String LOG_TAG = "TestPackageInstaller";
+ private static final String BROADCAST_ACTION =
+ "com.android.perftests.core.ACTION_INSTALL_COMMIT";
+
+ private final Context mContext;
+ public TestPackageInstaller(Context context) {
+ mContext = context;
+ }
+
+
+
+ /**
+ * Installs an APK located at the specified path in the assets directory.
+ **/
+ public InstalledPackage installPackage(String resourceName) throws IOException,
+ InterruptedException {
+ Log.d(LOG_TAG, "Installing resource APK '" + resourceName + "'");
+ LocalBroadcastReceiver intentSender = new LocalBroadcastReceiver(mContext);
+
+ // Initialize the package install session.
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
+ PackageInstaller.SessionParams.MODE_FULL_INSTALL);
+ params.setInstallAsInstantApp(false);
+ int sessionId = packageInstaller.createSession(params);
+ PackageInstaller.Session session = packageInstaller.openSession(sessionId);
+
+ // Copy the apk to the install session.
+ try (OutputStream os = session.openWrite("TestPackageInstaller", 0, -1);
+ InputStream is = mContext.getResources().getAssets().openNonAsset(resourceName)) {
+ if (is == null) {
+ throw new IOException("Resource " + resourceName + " not found");
+ }
+ byte[] buffer = new byte[4096];
+ int n;
+ while ((n = is.read(buffer)) >= 0) {
+ os.write(buffer, 0, n);
+ }
+ }
+
+ session.commit(intentSender.getIntentSender(sessionId));
+ session.close();
+
+ // Retrieve the results of the installation.
+ Intent intent = intentSender.getIntentSenderResult();
+ int status = intent.getIntExtra(PackageInstaller.EXTRA_STATUS,
+ PackageInstaller.STATUS_FAILURE);
+ Assert.assertEquals(PackageInstaller.STATUS_SUCCESS, status);
+ String packageName = intent.getStringExtra(PackageInstaller.EXTRA_PACKAGE_NAME);
+ return new InstalledPackage(sessionId, packageName);
+ }
+
+ public class InstalledPackage {
+ private int mSessionId;
+ private String mPackageName;
+
+ private InstalledPackage(int sessionId, String packageName) {
+ mSessionId = sessionId;
+ mPackageName = packageName;
+ }
+
+ public String getPackageName() {
+ return mPackageName;
+ }
+
+ public void uninstall() throws Exception {
+ Log.d(LOG_TAG, "Uninstalling package '" + mPackageName + "'");
+ LocalBroadcastReceiver intentSender = new LocalBroadcastReceiver(mContext);
+ PackageInstaller packageInstaller = mContext.getPackageManager().getPackageInstaller();
+ packageInstaller.uninstall(mPackageName, intentSender.getIntentSender(mSessionId));
+ int status = intentSender.getIntentSenderResult()
+ .getIntExtra(PackageInstaller.EXTRA_STATUS, PackageInstaller.STATUS_FAILURE);
+ Assert.assertEquals(PackageInstaller.STATUS_SUCCESS, status);
+ }
+ }
+
+ private class LocalBroadcastReceiver extends BroadcastReceiver {
+ private final BlockingQueue<Intent> mIntentSenderResults = new LinkedBlockingQueue<>();
+ private final Context mContext;
+
+ private LocalBroadcastReceiver(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ mIntentSenderResults.add(intent);
+ }
+
+ IntentSender getIntentSender(int sessionId) {
+ String action = BROADCAST_ACTION + "." + sessionId;
+ IntentFilter filter = new IntentFilter(action);
+ mContext.registerReceiver(this, filter);
+
+ Intent intent = new Intent(action);
+ PendingIntent pending = PendingIntent.getBroadcast(mContext, sessionId, intent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ return pending.getIntentSender();
+ }
+
+ Intent getIntentSenderResult() throws InterruptedException {
+ return mIntentSenderResults.take();
+ }
+ }
+}
diff --git a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
index a807eb1d3311..5b1405628b49 100644
--- a/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
+++ b/apex/jobscheduler/framework/java/android/app/DeviceIdleFrameworkInitializer.java
@@ -36,7 +36,7 @@ public class DeviceIdleFrameworkInitializer {
SystemServiceRegistry.registerCachedService(
Context.DEVICE_IDLE_CONTROLLER, DeviceIdleManager.class,
(context, b) -> new DeviceIdleManager(
- context.getOuterContext(), IDeviceIdleController.Stub.asInterface(b)));
+ context, IDeviceIdleController.Stub.asInterface(b)));
PowerManager.setIsIgnoringBatteryOptimizationsCallback((packageName) -> {
// No need for synchronization on sIDeviceIdleController; worst case
// we just initialize it twice.
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
new file mode 100644
index 000000000000..3cfb08082ff7
--- /dev/null
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -0,0 +1,112 @@
+package com.android.server.usage;
+
+import android.app.usage.AppStandbyInfo;
+import android.app.usage.UsageEvents;
+import android.app.usage.UsageStatsManager.StandbyBuckets;
+import android.app.usage.UsageStatsManagerInternal.AppIdleStateChangeListener;
+import android.content.Context;
+import android.os.Looper;
+
+import com.android.internal.util.IndentingPrintWriter;
+
+import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.List;
+import java.util.Set;
+
+public interface AppStandbyInternal {
+ /**
+ * TODO AppStandbyController should probably be a binder service, and then we shouldn't need
+ * this method.
+ */
+ static AppStandbyInternal newAppStandbyController(ClassLoader loader, Context context,
+ Looper looper) {
+ try {
+ final Class<?> clazz = Class.forName("com.android.server.usage.AppStandbyController",
+ true, loader);
+ final Constructor<?> ctor = clazz.getConstructor(Context.class, Looper.class);
+ return (AppStandbyInternal) ctor.newInstance(context, looper);
+ } catch (NoSuchMethodException | InstantiationException
+ | IllegalAccessException | InvocationTargetException | ClassNotFoundException e) {
+ throw new RuntimeException("Unable to instantiate AppStandbyController!", e);
+ }
+ }
+
+ void onBootPhase(int phase);
+
+ boolean isParoledOrCharging();
+
+ void postCheckIdleStates(int userId);
+
+ /**
+ * We send a different message to check idle states once, otherwise we would end up
+ * scheduling a series of repeating checkIdleStates each time we fired off one.
+ */
+ void postOneTimeCheckIdleStates();
+
+ void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId);
+
+ void setLastJobRunTime(String packageName, int userId, long elapsedRealtime);
+
+ long getTimeSinceLastJobRun(String packageName, int userId);
+
+ void onUserRemoved(int userId);
+
+ void addListener(AppIdleStateChangeListener listener);
+
+ void removeListener(AppIdleStateChangeListener listener);
+
+ int getAppId(String packageName);
+
+ boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime,
+ boolean shouldObfuscateInstantApps);
+
+ /**
+ * Checks if an app has been idle for a while and filters out apps that are excluded.
+ * It returns false if the current system state allows all apps to be considered active.
+ * This happens if the device is plugged in or temporarily allowed to make exceptions.
+ * Called by interface impls.
+ */
+ boolean isAppIdleFiltered(String packageName, int appId, int userId,
+ long elapsedRealtime);
+
+ int[] getIdleUidsForUser(int userId);
+
+ void setAppIdleAsync(String packageName, boolean idle, int userId);
+
+ @StandbyBuckets
+ int getAppStandbyBucket(String packageName, int userId,
+ long elapsedRealtime, boolean shouldObfuscateInstantApps);
+
+ List<AppStandbyInfo> getAppStandbyBuckets(int userId);
+
+ void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
+ int reason, long elapsedRealtime, boolean resetTimeout);
+
+ void addActiveDeviceAdmin(String adminPkg, int userId);
+
+ void setActiveAdminApps(Set<String> adminPkgs, int userId);
+
+ void onAdminDataAvailable();
+
+ void clearCarrierPrivilegedApps();
+
+ void flushToDisk(int userId);
+
+ void flushDurationsToDisk();
+
+ void initializeDefaultsForSystemApps(int userId);
+
+ void postReportContentProviderUsage(String name, String packageName, int userId);
+
+ void postReportSyncScheduled(String packageName, int userId, boolean exempted);
+
+ void postReportExemptedSyncStart(String packageName, int userId);
+
+ void dumpUser(IndentingPrintWriter idpw, int userId, String pkg);
+
+ void dumpState(String[] args, PrintWriter pw);
+
+ boolean isAppIdleEnabled();
+}
diff --git a/services/usage/java/com/android/server/usage/AppIdleHistory.java b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
index 1e4861a89694..1e4861a89694 100644
--- a/services/usage/java/com/android/server/usage/AppIdleHistory.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppIdleHistory.java
diff --git a/services/usage/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index 75e8fb5a34fe..df5d6aeb8ee5 100644
--- a/services/usage/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -120,9 +120,9 @@ import java.util.concurrent.CountDownLatch;
* Manages the standby state of an app, listening to various events.
*
* Unit test:
- atest ${ANDROID_BUILD_TOP}/frameworks/base/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+ atest com.android.server.usage.AppStandbyControllerTests
*/
-public class AppStandbyController {
+public class AppStandbyController implements AppStandbyInternal {
private static final String TAG = "AppStandbyController";
static final boolean DEBUG = false;
@@ -247,7 +247,7 @@ public class AppStandbyController {
/** The length of time phone must be charging before considered stable enough to run jobs */
long mStableChargingThresholdMillis;
- volatile boolean mAppIdleEnabled;
+ private volatile boolean mAppIdleEnabled;
boolean mAppIdleTempParoled;
boolean mCharging;
boolean mChargingStable;
@@ -320,7 +320,7 @@ public class AppStandbyController {
}
}
- AppStandbyController(Context context, Looper looper) {
+ public AppStandbyController(Context context, Looper looper) {
this(new Injector(context, looper));
}
@@ -351,6 +351,7 @@ public class AppStandbyController {
null, mHandler);
}
+ @VisibleForTesting
void setAppIdleEnabled(boolean enabled) {
synchronized (mAppIdleLock) {
if (mAppIdleEnabled != enabled) {
@@ -363,6 +364,12 @@ public class AppStandbyController {
}
}
+ @Override
+ public boolean isAppIdleEnabled() {
+ return mAppIdleEnabled;
+ }
+
+ @Override
public void onBootPhase(int phase) {
mInjector.onBootPhase(phase);
if (phase == PHASE_SYSTEM_SERVICES_READY) {
@@ -400,7 +407,7 @@ public class AppStandbyController {
}
}
- void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
+ private void reportContentProviderUsage(String authority, String providerPkgName, int userId) {
if (!mAppIdleEnabled) return;
// Get sync adapters for the authority
@@ -432,7 +439,7 @@ public class AppStandbyController {
}
}
- void reportExemptedSyncScheduled(String packageName, int userId) {
+ private void reportExemptedSyncScheduled(String packageName, int userId) {
if (!mAppIdleEnabled) return;
final int bucketToPromote;
@@ -463,7 +470,7 @@ public class AppStandbyController {
}
}
- void reportUnexemptedSyncScheduled(String packageName, int userId) {
+ private void reportUnexemptedSyncScheduled(String packageName, int userId) {
if (!mAppIdleEnabled) return;
final long elapsedRealtime = mInjector.elapsedRealtime();
@@ -482,7 +489,7 @@ public class AppStandbyController {
}
}
- void reportExemptedSyncStart(String packageName, int userId) {
+ private void reportExemptedSyncStart(String packageName, int userId) {
if (!mAppIdleEnabled) return;
final long elapsedRealtime = mInjector.elapsedRealtime();
@@ -497,6 +504,7 @@ public class AppStandbyController {
}
}
+ @VisibleForTesting
void setChargingState(boolean charging) {
synchronized (mAppIdleLock) {
if (mCharging != charging) {
@@ -517,7 +525,7 @@ public class AppStandbyController {
}
}
- void updateChargingStableState() {
+ private void updateChargingStableState() {
synchronized (mAppIdleLock) {
if (mChargingStable != mCharging) {
if (DEBUG) Slog.d(TAG, "Setting mChargingStable to " + mCharging);
@@ -527,8 +535,7 @@ public class AppStandbyController {
}
}
- /** Paroled here means temporary pardon from being inactive */
- void setAppIdleParoled(boolean paroled) {
+ private void setAppIdleParoled(boolean paroled) {
synchronized (mAppIdleLock) {
final long now = mInjector.currentTimeMillis();
if (mAppIdleTempParoled != paroled) {
@@ -545,7 +552,8 @@ public class AppStandbyController {
}
}
- boolean isParoledOrCharging() {
+ @Override
+ public boolean isParoledOrCharging() {
if (!mAppIdleEnabled) return true;
synchronized (mAppIdleLock) {
// Only consider stable charging when determining charge state.
@@ -583,15 +591,13 @@ public class AppStandbyController {
mHandler.sendEmptyMessage(MSG_PAROLE_STATE_CHANGED);
}
- void postCheckIdleStates(int userId) {
+ @Override
+ public void postCheckIdleStates(int userId) {
mHandler.sendMessage(mHandler.obtainMessage(MSG_CHECK_IDLE_STATES, userId, 0));
}
- /**
- * We send a different message to check idle states once, otherwise we would end up
- * scheduling a series of repeating checkIdleStates each time we fired off one.
- */
- void postOneTimeCheckIdleStates() {
+ @Override
+ public void postOneTimeCheckIdleStates() {
if (mInjector.getBootPhase() < PHASE_SYSTEM_SERVICES_READY) {
// Not booted yet; wait for it!
mPendingOneTimeCheckIdleStates = true;
@@ -601,10 +607,7 @@ public class AppStandbyController {
}
}
- /**
- * Check all running users' or specified user's apps to see if they enter an idle state.
- * @return Returns whether checking should continue periodically.
- */
+ @VisibleForTesting
boolean checkIdleStates(int checkUserId) {
if (!mAppIdleEnabled) {
return false;
@@ -776,19 +779,15 @@ public class AppStandbyController {
* @return the bucket for the app, based on time since last used
*/
@GuardedBy("mAppIdleLock")
- @StandbyBuckets int getBucketForLocked(String packageName, int userId,
+ @StandbyBuckets
+ private int getBucketForLocked(String packageName, int userId,
long elapsedRealtime) {
int bucketIndex = mAppIdleHistory.getThresholdIndex(packageName, userId,
elapsedRealtime, mAppStandbyScreenThresholds, mAppStandbyElapsedThresholds);
return THRESHOLD_BUCKETS[bucketIndex];
}
- /**
- * Check if it's been a while since last parole and let idle apps do some work.
- * If network is not available, delay parole until it is available up until the end of the
- * parole window. Force the parole to be set if end of the parole window is reached.
- */
- void checkParoleTimeout() {
+ private void checkParoleTimeout() {
boolean setParoled = false;
boolean waitForNetwork = false;
NetworkInfo activeNetwork = mConnectivityManager.getActiveNetworkInfo();
@@ -845,7 +844,7 @@ public class AppStandbyController {
}
}
- void onDeviceIdleModeChanged() {
+ private void onDeviceIdleModeChanged() {
final boolean deviceIdle = mPowerManager.isDeviceIdleMode();
if (DEBUG) Slog.i(TAG, "DeviceIdleMode changed to " + deviceIdle);
boolean paroled = false;
@@ -869,7 +868,8 @@ public class AppStandbyController {
setAppIdleParoled(paroled);
}
- void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) {
+ @Override
+ public void reportEvent(UsageEvents.Event event, long elapsedRealtime, int userId) {
if (!mAppIdleEnabled) return;
synchronized (mAppIdleLock) {
// TODO: Ideally this should call isAppIdleFiltered() to avoid calling back
@@ -950,14 +950,7 @@ public class AppStandbyController {
}
}
- /**
- * Forces the app's beginIdleTime and lastUsedTime to reflect idle or active. If idle,
- * then it rolls back the beginIdleTime and lastUsedTime to a point in time that's behind
- * the threshold for idle.
- *
- * This method is always called from the handler thread, so not much synchronization is
- * required.
- */
+ @VisibleForTesting
void forceIdleState(String packageName, int userId, boolean idle) {
if (!mAppIdleEnabled) return;
@@ -983,12 +976,14 @@ public class AppStandbyController {
}
}
+ @Override
public void setLastJobRunTime(String packageName, int userId, long elapsedRealtime) {
synchronized (mAppIdleLock) {
mAppIdleHistory.setLastJobRunTime(packageName, userId, elapsedRealtime);
}
}
+ @Override
public long getTimeSinceLastJobRun(String packageName, int userId) {
final long elapsedRealtime = mInjector.elapsedRealtime();
synchronized (mAppIdleLock) {
@@ -996,6 +991,7 @@ public class AppStandbyController {
}
}
+ @Override
public void onUserRemoved(int userId) {
synchronized (mAppIdleLock) {
mAppIdleHistory.onUserRemoved(userId);
@@ -1011,7 +1007,8 @@ public class AppStandbyController {
}
}
- void addListener(AppIdleStateChangeListener listener) {
+ @Override
+ public void addListener(AppIdleStateChangeListener listener) {
synchronized (mPackageAccessListeners) {
if (!mPackageAccessListeners.contains(listener)) {
mPackageAccessListeners.add(listener);
@@ -1019,13 +1016,15 @@ public class AppStandbyController {
}
}
- void removeListener(AppIdleStateChangeListener listener) {
+ @Override
+ public void removeListener(AppIdleStateChangeListener listener) {
synchronized (mPackageAccessListeners) {
mPackageAccessListeners.remove(listener);
}
}
- int getAppId(String packageName) {
+ @Override
+ public int getAppId(String packageName) {
try {
ApplicationInfo ai = mPackageManager.getApplicationInfo(packageName,
PackageManager.MATCH_ANY_USER
@@ -1036,7 +1035,8 @@ public class AppStandbyController {
}
}
- boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime,
+ @Override
+ public boolean isAppIdleFilteredOrParoled(String packageName, int userId, long elapsedRealtime,
boolean shouldObfuscateInstantApps) {
if (isParoledOrCharging()) {
return false;
@@ -1048,8 +1048,7 @@ public class AppStandbyController {
return isAppIdleFiltered(packageName, getAppId(packageName), userId, elapsedRealtime);
}
- /** Returns true if this app should be whitelisted for some reason, to never go into standby */
- boolean isAppSpecial(String packageName, int appId, int userId) {
+ private boolean isAppSpecial(String packageName, int appId, int userId) {
if (packageName == null) return false;
// If not enabled at all, of course nobody is ever idle.
if (!mAppIdleEnabled) {
@@ -1102,13 +1101,8 @@ public class AppStandbyController {
return false;
}
- /**
- * Checks if an app has been idle for a while and filters out apps that are excluded.
- * It returns false if the current system state allows all apps to be considered active.
- * This happens if the device is plugged in or temporarily allowed to make exceptions.
- * Called by interface impls.
- */
- boolean isAppIdleFiltered(String packageName, int appId, int userId,
+ @Override
+ public boolean isAppIdleFiltered(String packageName, int appId, int userId,
long elapsedRealtime) {
if (isAppSpecial(packageName, appId, userId)) {
return false;
@@ -1117,7 +1111,8 @@ public class AppStandbyController {
}
}
- int[] getIdleUidsForUser(int userId) {
+ @Override
+ public int[] getIdleUidsForUser(int userId) {
if (!mAppIdleEnabled) {
return new int[0];
}
@@ -1181,13 +1176,15 @@ public class AppStandbyController {
return res;
}
- void setAppIdleAsync(String packageName, boolean idle, int userId) {
+ @Override
+ public void setAppIdleAsync(String packageName, boolean idle, int userId) {
if (packageName == null || !mAppIdleEnabled) return;
mHandler.obtainMessage(MSG_FORCE_IDLE_STATE, userId, idle ? 1 : 0, packageName)
.sendToTarget();
}
+ @Override
@StandbyBuckets public int getAppStandbyBucket(String packageName, int userId,
long elapsedRealtime, boolean shouldObfuscateInstantApps) {
if (!mAppIdleEnabled || (shouldObfuscateInstantApps
@@ -1200,18 +1197,21 @@ public class AppStandbyController {
}
}
+ @Override
public List<AppStandbyInfo> getAppStandbyBuckets(int userId) {
synchronized (mAppIdleLock) {
return mAppIdleHistory.getAppStandbyBuckets(userId, mAppIdleEnabled);
}
}
+ @VisibleForTesting
void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
int reason, long elapsedRealtime) {
setAppStandbyBucket(packageName, userId, newBucket, reason, elapsedRealtime, false);
}
- void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
+ @Override
+ public void setAppStandbyBucket(String packageName, int userId, @StandbyBuckets int newBucket,
int reason, long elapsedRealtime, boolean resetTimeout) {
synchronized (mAppIdleLock) {
// If the package is not installed, don't allow the bucket to be set.
@@ -1279,6 +1279,7 @@ public class AppStandbyController {
}
}
+ @Override
public void addActiveDeviceAdmin(String adminPkg, int userId) {
synchronized (mActiveAdminApps) {
Set<String> adminPkgs = mActiveAdminApps.get(userId);
@@ -1290,6 +1291,7 @@ public class AppStandbyController {
}
}
+ @Override
public void setActiveAdminApps(Set<String> adminPkgs, int userId) {
synchronized (mActiveAdminApps) {
if (adminPkgs == null) {
@@ -1300,6 +1302,7 @@ public class AppStandbyController {
}
}
+ @Override
public void onAdminDataAvailable() {
mAdminDataAvailableLatch.countDown();
}
@@ -1314,6 +1317,7 @@ public class AppStandbyController {
}
}
+ @VisibleForTesting
Set<String> getActiveAdminAppsForTest(int userId) {
synchronized (mActiveAdminApps) {
return mActiveAdminApps.get(userId);
@@ -1342,7 +1346,8 @@ public class AppStandbyController {
}
}
- void clearCarrierPrivilegedApps() {
+ @Override
+ public void clearCarrierPrivilegedApps() {
if (DEBUG) {
Slog.i(TAG, "Clearing carrier privileged apps list");
}
@@ -1368,7 +1373,7 @@ public class AppStandbyController {
return packageName != null && packageName.equals(activeScorer);
}
- void informListeners(String packageName, int userId, int bucket, int reason,
+ private void informListeners(String packageName, int userId, int bucket, int reason,
boolean userInteraction) {
final boolean idle = bucket >= STANDBY_BUCKET_RARE;
synchronized (mPackageAccessListeners) {
@@ -1381,7 +1386,7 @@ public class AppStandbyController {
}
}
- void informParoleStateChanged() {
+ private void informParoleStateChanged() {
final boolean paroled = isParoledOrCharging();
synchronized (mPackageAccessListeners) {
for (AppIdleStateChangeListener listener : mPackageAccessListeners) {
@@ -1390,13 +1395,15 @@ public class AppStandbyController {
}
}
- void flushToDisk(int userId) {
+ @Override
+ public void flushToDisk(int userId) {
synchronized (mAppIdleLock) {
mAppIdleHistory.writeAppIdleTimes(userId);
}
}
- void flushDurationsToDisk() {
+ @Override
+ public void flushDurationsToDisk() {
// Persist elapsed and screen on time. If this fails for whatever reason, the apps will be
// considered not-idle, which is the safest outcome in such an event.
synchronized (mAppIdleLock) {
@@ -1404,10 +1411,11 @@ public class AppStandbyController {
}
}
- boolean isDisplayOn() {
+ private boolean isDisplayOn() {
return mInjector.isDefaultDisplayOn();
}
+ @VisibleForTesting
void clearAppIdleForPackage(String packageName, int userId) {
synchronized (mAppIdleLock) {
mAppIdleHistory.clearUsage(packageName, userId);
@@ -1431,7 +1439,8 @@ public class AppStandbyController {
}
}
- void initializeDefaultsForSystemApps(int userId) {
+ @Override
+ public void initializeDefaultsForSystemApps(int userId) {
if (!mSystemServicesReady) {
// Do it later, since SettingsProvider wasn't queried yet for app_standby_enabled
mPendingInitializeDefaults = true;
@@ -1461,7 +1470,8 @@ public class AppStandbyController {
}
}
- void postReportContentProviderUsage(String name, String packageName, int userId) {
+ @Override
+ public void postReportContentProviderUsage(String name, String packageName, int userId) {
SomeArgs args = SomeArgs.obtain();
args.arg1 = name;
args.arg2 = packageName;
@@ -1470,23 +1480,27 @@ public class AppStandbyController {
.sendToTarget();
}
- void postReportSyncScheduled(String packageName, int userId, boolean exempted) {
+ @Override
+ public void postReportSyncScheduled(String packageName, int userId, boolean exempted) {
mHandler.obtainMessage(MSG_REPORT_SYNC_SCHEDULED, userId, exempted ? 1 : 0, packageName)
.sendToTarget();
}
- void postReportExemptedSyncStart(String packageName, int userId) {
+ @Override
+ public void postReportExemptedSyncStart(String packageName, int userId) {
mHandler.obtainMessage(MSG_REPORT_EXEMPTED_SYNC_START, userId, 0, packageName)
.sendToTarget();
}
- void dumpUser(IndentingPrintWriter idpw, int userId, String pkg) {
+ @Override
+ public void dumpUser(IndentingPrintWriter idpw, int userId, String pkg) {
synchronized (mAppIdleLock) {
mAppIdleHistory.dump(idpw, userId, pkg);
}
}
- void dumpState(String[] args, PrintWriter pw) {
+ @Override
+ public void dumpState(String[] args, PrintWriter pw) {
synchronized (mAppIdleLock) {
pw.println("Carrier privileged apps (have=" + mHaveCarrierPrivilegedApps
+ "): " + mCarrierPrivilegedApps);
diff --git a/api/current.txt b/api/current.txt
index 3ce043c89b65..a123f2cc8ba2 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -2834,6 +2834,7 @@ package android.accessibilityservice {
method public final android.accessibilityservice.AccessibilityServiceInfo getServiceInfo();
method @NonNull public final android.accessibilityservice.AccessibilityService.SoftKeyboardController getSoftKeyboardController();
method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
+ method @NonNull public final android.util.SparseArray<java.util.List<android.view.accessibility.AccessibilityWindowInfo>> getWindowsOnAllDisplays();
method public abstract void onAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
method public final android.os.IBinder onBind(android.content.Intent);
method @Deprecated protected boolean onGesture(int);
@@ -6363,6 +6364,7 @@ package android.app {
method public android.view.WindowAnimationFrameStats getWindowAnimationFrameStats();
method public android.view.WindowContentFrameStats getWindowContentFrameStats(int);
method public java.util.List<android.view.accessibility.AccessibilityWindowInfo> getWindows();
+ method @NonNull public android.util.SparseArray<java.util.List<android.view.accessibility.AccessibilityWindowInfo>> getWindowsOnAllDisplays();
method public void grantRuntimePermission(String, String);
method public void grantRuntimePermissionAsUser(String, String, android.os.UserHandle);
method public boolean injectInputEvent(android.view.InputEvent, boolean);
@@ -57410,7 +57412,7 @@ package android.widget {
method public boolean onPrivateIMECommand(String, android.os.Bundle);
method public void onRestoreInstanceState(android.os.Parcelable);
method public android.os.Parcelable onSaveInstanceState();
- method protected void onSelectionChanged(int, int);
+ method @CallSuper protected void onSelectionChanged(int, int);
method protected void onTextChanged(CharSequence, int, int, int);
method public boolean onTextContextMenuItem(int);
method public void removeTextChangedListener(android.text.TextWatcher);
diff --git a/api/system-current.txt b/api/system-current.txt
index a4e20cc5c500..8875e7995105 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -24,6 +24,7 @@ package android {
field public static final String BACKUP = "android.permission.BACKUP";
field public static final String BIND_ATTENTION_SERVICE = "android.permission.BIND_ATTENTION_SERVICE";
field public static final String BIND_AUGMENTED_AUTOFILL_SERVICE = "android.permission.BIND_AUGMENTED_AUTOFILL_SERVICE";
+ field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE";
field @Deprecated public static final String BIND_CONNECTION_SERVICE = "android.permission.BIND_CONNECTION_SERVICE";
field public static final String BIND_CONTENT_CAPTURE_SERVICE = "android.permission.BIND_CONTENT_CAPTURE_SERVICE";
field public static final String BIND_CONTENT_SUGGESTIONS_SERVICE = "android.permission.BIND_CONTENT_SUGGESTIONS_SERVICE";
@@ -6361,6 +6362,7 @@ package android.service.autofill {
method public android.os.IBinder onBind(android.content.Intent);
method @Nullable public float[][] onCalculateScores(@NonNull java.util.List<android.view.autofill.AutofillValue>, @NonNull java.util.List<java.lang.String>, @NonNull java.util.List<java.lang.String>, @Nullable String, @Nullable android.os.Bundle, @Nullable java.util.Map, @Nullable java.util.Map);
method @Deprecated @Nullable public float[][] onGetScores(@Nullable String, @Nullable android.os.Bundle, @NonNull java.util.List<android.view.autofill.AutofillValue>, @NonNull java.util.List<java.lang.String>);
+ field public static final String REQUIRED_ALGORITHM_CREDIT_CARD = "CREDIT_CARD";
field public static final String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
field public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
@@ -7303,6 +7305,14 @@ package android.telephony {
method @NonNull public android.telephony.CarrierRestrictionRules.Builder setMultiSimPolicy(int);
}
+ public abstract class CellBroadcastService extends android.app.Service {
+ ctor public CellBroadcastService();
+ method @CallSuper public android.os.IBinder onBind(android.content.Intent);
+ method public abstract void onCdmaCellBroadcastSms(int, byte[]);
+ method public abstract void onGsmCellBroadcastSms(int, byte[]);
+ field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
+ }
+
public final class DataFailCause {
field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab
field public static final int ACCESS_BLOCK = 2087; // 0x827
diff --git a/api/test-current.txt b/api/test-current.txt
index a40cb923065f..7637b87085b8 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5,6 +5,7 @@ package android {
field public static final String ACCESS_NOTIFICATIONS = "android.permission.ACCESS_NOTIFICATIONS";
field public static final String ACTIVITY_EMBEDDING = "android.permission.ACTIVITY_EMBEDDING";
field public static final String APPROVE_INCIDENT_REPORTS = "android.permission.APPROVE_INCIDENT_REPORTS";
+ field public static final String BIND_CELL_BROADCAST_SERVICE = "android.permission.BIND_CELL_BROADCAST_SERVICE";
field public static final String BRIGHTNESS_SLIDER_USAGE = "android.permission.BRIGHTNESS_SLIDER_USAGE";
field public static final String CHANGE_APP_IDLE_STATE = "android.permission.CHANGE_APP_IDLE_STATE";
field public static final String CLEAR_APP_USER_DATA = "android.permission.CLEAR_APP_USER_DATA";
@@ -2404,7 +2405,6 @@ package android.provider {
field public static final String LOCATION_ACCESS_CHECK_DELAY_MILLIS = "location_access_check_delay_millis";
field public static final String LOCATION_ACCESS_CHECK_INTERVAL_MILLIS = "location_access_check_interval_millis";
field public static final String NOTIFICATION_BADGING = "notification_badging";
- field @Deprecated public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
field @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public static final String SYNC_PARENT_SOUNDS = "sync_parent_sounds";
field public static final String USER_SETUP_COMPLETE = "user_setup_complete";
field public static final String VOICE_INTERACTION_SERVICE = "voice_interaction_service";
@@ -2481,6 +2481,7 @@ package android.service.autofill {
public abstract class AutofillFieldClassificationService extends android.app.Service {
ctor public AutofillFieldClassificationService();
method public android.os.IBinder onBind(android.content.Intent);
+ field public static final String REQUIRED_ALGORITHM_CREDIT_CARD = "CREDIT_CARD";
field public static final String REQUIRED_ALGORITHM_EDIT_DISTANCE = "EDIT_DISTANCE";
field public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
field public static final String SERVICE_INTERFACE = "android.service.autofill.AutofillFieldClassificationService";
@@ -2900,6 +2901,8 @@ package android.telephony {
}
public class PhoneStateListener {
+ method public void onOutgoingEmergencyCall(@NonNull android.telephony.emergency.EmergencyNumber);
+ method public void onOutgoingEmergencySms(@NonNull android.telephony.emergency.EmergencyNumber);
field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_CALL_EMERGENCY_NUMBER = 268435456; // 0x10000000
field @RequiresPermission("android.permission.READ_ACTIVE_EMERGENCY_SESSION") public static final int LISTEN_OUTGOING_SMS_EMERGENCY_NUMBER = 536870912; // 0x20000000
}
diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING
index c1cba5f7f22d..56f5cc034f05 100644
--- a/cmds/locksettings/TEST_MAPPING
+++ b/cmds/locksettings/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-devicepolicy": [
{
"name": "CtsDevicePolicyManagerTestCases",
"options": [
diff --git a/cmds/statsd/src/main.cpp b/cmds/statsd/src/main.cpp
index 42132ee0daae..7d446a9a1ed6 100644
--- a/cmds/statsd/src/main.cpp
+++ b/cmds/statsd/src/main.cpp
@@ -53,6 +53,8 @@ void sigHandler(int sig) {
if (gStatsService != nullptr) {
gStatsService->Terminate();
}
+ ALOGW("statsd terminated on receiving signal %d.", sig);
+ exit(1);
}
void registerSigHandler()
diff --git a/cmds/statsd/tests/StatsLogProcessor_test.cpp b/cmds/statsd/tests/StatsLogProcessor_test.cpp
index 76ee9a6e5996..460b9e0995c8 100644
--- a/cmds/statsd/tests/StatsLogProcessor_test.cpp
+++ b/cmds/statsd/tests/StatsLogProcessor_test.cpp
@@ -1199,87 +1199,66 @@ TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActi
ConfigKey cfgKey1(uid, 12341);
long timeBase1 = 1;
- sp<StatsLogProcessor> processor =
+ sp<StatsLogProcessor> processor1 =
CreateStatsLogProcessor(timeBase1, timeBase1, config1, cfgKey1);
// Metric 1 is not active.
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_EQ(1, processor->mMetricsManagers.size());
- auto it = processor->mMetricsManagers.find(cfgKey1);
- EXPECT_TRUE(it != processor->mMetricsManagers.end());
+ EXPECT_EQ(1, processor1->mMetricsManagers.size());
+ auto it = processor1->mMetricsManagers.find(cfgKey1);
+ EXPECT_TRUE(it != processor1->mMetricsManagers.end());
auto& metricsManager1 = it->second;
EXPECT_TRUE(metricsManager1->isActive());
- auto metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer1 = *metricIt;
- EXPECT_FALSE(metricProducer1->isActive());
-
- metricIt = metricsManager1->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1->mAllMetricProducers.end());
- auto& metricProducer2 = *metricIt;
- EXPECT_TRUE(metricProducer2->isActive());
-
- int i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1->ttl_ns);
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kNotActive, activation1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1->activationType);
-
- i = 0;
- for (; i < metricsManager1->mAllAtomMatchers.size(); i++) {
- if (metricsManager1->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation2 = metricProducer1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation2->ttl_ns);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2->activationType);
+ EXPECT_EQ(metricsManager1->mAllMetricProducers.size(), 2);
+ // We assume that the index of a MetricProducer within the mAllMetricProducers
+ // array follows the order in which metrics are added to the config.
+ auto& metricProducer1_1 = metricsManager1->mAllMetricProducers[0];
+ EXPECT_EQ(metricProducer1_1->getMetricId(), metricId1);
+ EXPECT_FALSE(metricProducer1_1->isActive()); // inactive due to associated MetricActivation
+
+ auto& metricProducer1_2 = metricsManager1->mAllMetricProducers[1];
+ EXPECT_EQ(metricProducer1_2->getMetricId(), metricId2);
+ EXPECT_TRUE(metricProducer1_2->isActive());
+
+ EXPECT_EQ(metricProducer1_1->mEventActivationMap.size(), 2);
+ // The key in mEventActivationMap is the index of the associated atom matcher. We assume
+ // that matchers are indexed in the order that they are added to the config.
+ const auto& activation1_1_1 = metricProducer1_1->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation1_1_1->ttl_ns);
+ EXPECT_EQ(0, activation1_1_1->start_ns);
+ EXPECT_EQ(kNotActive, activation1_1_1->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation1_1_1->activationType);
+
+ const auto& activation1_1_2 = metricProducer1_1->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation1_1_2->ttl_ns);
+ EXPECT_EQ(0, activation1_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation1_1_2->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1_1_2->activationType);
// }}}------------------------------------------------------------------------------
// Trigger Activation 1 for Metric 1
std::vector<AttributionNodeInternal> attributions1 = {CreateAttribution(111, "App1")};
auto event = CreateAcquireWakelockEvent(attributions1, "wl1", 100 + timeBase1);
- processor->OnLogEvent(event.get());
+ processor1->OnLogEvent(event.get());
// Metric 1 is not active; Activation 1 set to kActiveOnBoot
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_FALSE(metricProducer1->isActive());
- EXPECT_EQ(0, activation1->start_ns);
- EXPECT_EQ(kActiveOnBoot, activation1->state);
- EXPECT_EQ(0, activation2->start_ns);
- EXPECT_EQ(kNotActive, activation2->state);
+ EXPECT_FALSE(metricProducer1_1->isActive());
+ EXPECT_EQ(0, activation1_1_1->start_ns);
+ EXPECT_EQ(kActiveOnBoot, activation1_1_1->state);
+ EXPECT_EQ(0, activation1_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation1_1_2->state);
- EXPECT_TRUE(metricProducer2->isActive());
+ EXPECT_TRUE(metricProducer1_2->isActive());
// }}}-----------------------------------------------------------------------------
// Simulate shutdown by saving state to disk
int64_t shutDownTime = timeBase1 + 100 * NS_PER_SEC;
- processor->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_FALSE(metricProducer1->isActive());
- int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
+ processor1->SaveActiveConfigsToDisk(shutDownTime);
+ EXPECT_FALSE(metricProducer1_1->isActive());
// Simulate device restarted state by creating new instance of StatsLogProcessor with the
// same config.
@@ -1293,55 +1272,34 @@ TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActi
EXPECT_EQ(1, processor2->mMetricsManagers.size());
it = processor2->mMetricsManagers.find(cfgKey1);
EXPECT_TRUE(it != processor2->mMetricsManagers.end());
- auto& metricsManager1001 = it->second;
- EXPECT_TRUE(metricsManager1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1001 = *metricIt;
- EXPECT_FALSE(metricProducer1001->isActive());
-
- metricIt = metricsManager1001->mAllMetricProducers.begin();
- for (; metricIt != metricsManager1001->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManager1001->mAllMetricProducers.end());
- auto& metricProducer1002 = *metricIt;
- EXPECT_TRUE(metricProducer1002->isActive());
-
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activation1001_1 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activation1001_1->ttl_ns);
- EXPECT_EQ(0, activation1001_1->start_ns);
- EXPECT_EQ(kNotActive, activation1001_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activation1001_1->activationType);
-
- i = 0;
- for (; i < metricsManager1001->mAllAtomMatchers.size(); i++) {
- if (metricsManager1001->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
+ auto& metricsManager2 = it->second;
+ EXPECT_TRUE(metricsManager2->isActive());
- const auto& activation1001_2 = metricProducer1001->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activation1001_2->ttl_ns);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation1001_2->activationType);
+ EXPECT_EQ(metricsManager2->mAllMetricProducers.size(), 2);
+ // We assume that the index of a MetricProducer within the mAllMetricProducers
+ // array follows the order in which metrics are added to the config.
+ auto& metricProducer2_1 = metricsManager2->mAllMetricProducers[0];
+ EXPECT_EQ(metricProducer2_1->getMetricId(), metricId1);
+ EXPECT_FALSE(metricProducer2_1->isActive());
+
+ auto& metricProducer2_2 = metricsManager2->mAllMetricProducers[1];
+ EXPECT_EQ(metricProducer2_2->getMetricId(), metricId2);
+ EXPECT_TRUE(metricProducer2_2->isActive());
+
+ EXPECT_EQ(metricProducer2_1->mEventActivationMap.size(), 2);
+ // The key in mEventActivationMap is the index of the associated atom matcher. We assume
+ // that matchers are indexed in the order that they are added to the config.
+ const auto& activation2_1_1 = metricProducer2_1->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation2_1_1->ttl_ns);
+ EXPECT_EQ(0, activation2_1_1->start_ns);
+ EXPECT_EQ(kNotActive, activation2_1_1->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation2_1_1->activationType);
+
+ const auto& activation2_1_2 = metricProducer2_1->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation2_1_2->ttl_ns);
+ EXPECT_EQ(0, activation2_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation2_1_2->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation2_1_2->activationType);
// }}}-----------------------------------------------------------------------------------
// Load saved state from disk.
@@ -1350,13 +1308,14 @@ TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActi
// Metric 1 active; Activation 1 is active, Activation 2 is not active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(0, activation1001_2->start_ns);
- EXPECT_EQ(kNotActive, activation1001_2->state);
+ EXPECT_TRUE(metricProducer2_1->isActive());
+ int64_t ttl1 = metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC;
+ EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
+ EXPECT_EQ(kActive, activation2_1_1->state);
+ EXPECT_EQ(0, activation2_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation2_1_2->state);
- EXPECT_TRUE(metricProducer1002->isActive());
+ EXPECT_TRUE(metricProducer2_2->isActive());
// }}}--------------------------------------------------------------------------------
// Trigger Activation 2 for Metric 1.
@@ -1369,23 +1328,23 @@ TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActi
// Metric 1 active; Activation 1 is active, Activation 2 is active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_EQ(timeBase2 + ttl1 - activation1001_1->ttl_ns, activation1001_1->start_ns);
- EXPECT_EQ(kActive, activation1001_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation1001_2->start_ns);
- EXPECT_EQ(kActive, activation1001_2->state);
+ EXPECT_TRUE(metricProducer2_1->isActive());
+ EXPECT_EQ(timeBase2 + ttl1 - activation2_1_1->ttl_ns, activation2_1_1->start_ns);
+ EXPECT_EQ(kActive, activation2_1_1->state);
+ EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation2_1_2->start_ns);
+ EXPECT_EQ(kActive, activation2_1_2->state);
- EXPECT_TRUE(metricProducer1002->isActive());
+ EXPECT_TRUE(metricProducer2_2->isActive());
// }}}---------------------------------------------------------------------------
// Simulate shutdown by saving state to disk
shutDownTime = timeBase2 + 50 * NS_PER_SEC;
processor2->SaveActiveConfigsToDisk(shutDownTime);
- EXPECT_TRUE(metricProducer1001->isActive());
- EXPECT_TRUE(metricProducer1002->isActive());
- ttl1 = timeBase2 + metric1ActivationTrigger1->ttl_seconds() * NS_PER_SEC - shutDownTime;
- int64_t ttl2 = screenOnEvent->GetElapsedTimestampNs() +
- metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC - shutDownTime;
+ EXPECT_TRUE(metricProducer2_1->isActive());
+ EXPECT_TRUE(metricProducer2_2->isActive());
+ ttl1 -= shutDownTime - timeBase2;
+ int64_t ttl2 = metric1ActivationTrigger2->ttl_seconds() * NS_PER_SEC
+ - (shutDownTime - screenOnEvent->GetElapsedTimestampNs());
// Simulate device restarted state by creating new instance of StatsLogProcessor with the
// same config.
@@ -1399,55 +1358,34 @@ TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActi
EXPECT_EQ(1, processor3->mMetricsManagers.size());
it = processor3->mMetricsManagers.find(cfgKey1);
EXPECT_TRUE(it != processor3->mMetricsManagers.end());
- auto& metricsManagerTimeBase3 = it->second;
- EXPECT_TRUE(metricsManagerTimeBase3->isActive());
-
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId1) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_1 = *metricIt;
- EXPECT_FALSE(metricProducerTimeBase3_1->isActive());
-
- metricIt = metricsManagerTimeBase3->mAllMetricProducers.begin();
- for (; metricIt != metricsManagerTimeBase3->mAllMetricProducers.end(); metricIt++) {
- if ((*metricIt)->getMetricId() == metricId2) {
- break;
- }
- }
- EXPECT_TRUE(metricIt != metricsManagerTimeBase3->mAllMetricProducers.end());
- auto& metricProducerTimeBase3_2 = *metricIt;
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
-
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger1->atom_matcher_id()) {
- break;
- }
- }
- const auto& activationTimeBase3_1 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(100 * NS_PER_SEC, activationTimeBase3_1->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
- EXPECT_EQ(ACTIVATE_ON_BOOT, activationTimeBase3_1->activationType);
-
- i = 0;
- for (; i < metricsManagerTimeBase3->mAllAtomMatchers.size(); i++) {
- if (metricsManagerTimeBase3->mAllAtomMatchers[i]->getId() ==
- metric1ActivationTrigger2->atom_matcher_id()) {
- break;
- }
- }
+ auto& metricsManager3 = it->second;
+ EXPECT_TRUE(metricsManager3->isActive());
- const auto& activationTimeBase3_2 = metricProducerTimeBase3_1->mEventActivationMap.at(i);
- EXPECT_EQ(200 * NS_PER_SEC, activationTimeBase3_2->ttl_ns);
- EXPECT_EQ(0, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kNotActive, activationTimeBase3_2->state);
- EXPECT_EQ(ACTIVATE_IMMEDIATELY, activationTimeBase3_2->activationType);
+ EXPECT_EQ(metricsManager3->mAllMetricProducers.size(), 2);
+ // We assume that the index of a MetricProducer within the mAllMetricProducers
+ // array follows the order in which metrics are added to the config.
+ auto& metricProducer3_1 = metricsManager3->mAllMetricProducers[0];
+ EXPECT_EQ(metricProducer3_1->getMetricId(), metricId1);
+ EXPECT_FALSE(metricProducer3_1->isActive());
+
+ auto& metricProducer3_2 = metricsManager3->mAllMetricProducers[1];
+ EXPECT_EQ(metricProducer3_2->getMetricId(), metricId2);
+ EXPECT_TRUE(metricProducer3_2->isActive());
+
+ EXPECT_EQ(metricProducer3_1->mEventActivationMap.size(), 2);
+ // The key in mEventActivationMap is the index of the associated atom matcher. We assume
+ // that matchers are indexed in the order that they are added to the config.
+ const auto& activation3_1_1 = metricProducer3_1->mEventActivationMap.at(0);
+ EXPECT_EQ(100 * NS_PER_SEC, activation3_1_1->ttl_ns);
+ EXPECT_EQ(0, activation3_1_1->start_ns);
+ EXPECT_EQ(kNotActive, activation3_1_1->state);
+ EXPECT_EQ(ACTIVATE_ON_BOOT, activation3_1_1->activationType);
+
+ const auto& activation3_1_2 = metricProducer3_1->mEventActivationMap.at(1);
+ EXPECT_EQ(200 * NS_PER_SEC, activation3_1_2->ttl_ns);
+ EXPECT_EQ(0, activation3_1_2->start_ns);
+ EXPECT_EQ(kNotActive, activation3_1_2->state);
+ EXPECT_EQ(ACTIVATE_IMMEDIATELY, activation3_1_2->activationType);
// }}}----------------------------------------------------------------------------------
// Load saved state from disk.
@@ -1456,13 +1394,13 @@ TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActi
// Metric 1 active: Activation 1 is active, Activation 2 is active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(timeBase3 + ttl1 - activationTimeBase3_1->ttl_ns, activationTimeBase3_1->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_1->state);
- EXPECT_EQ(timeBase3 + ttl2 - activationTimeBase3_2->ttl_ns, activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
+ EXPECT_TRUE(metricProducer3_1->isActive());
+ EXPECT_EQ(timeBase3 + ttl1 - activation3_1_1->ttl_ns, activation3_1_1->start_ns);
+ EXPECT_EQ(kActive, activation3_1_1->state);
+ EXPECT_EQ(timeBase3 + ttl2 - activation3_1_2->ttl_ns, activation3_1_2->start_ns);
+ EXPECT_EQ(kActive, activation3_1_2->state);
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
+ EXPECT_TRUE(metricProducer3_2->isActive());
// }}}-------------------------------------------------------------------------------
@@ -1473,15 +1411,16 @@ TEST(StatsLogProcessorTest, TestActivationOnBootMultipleActivationsDifferentActi
);
processor3->OnLogEvent(screenOnEvent.get());
- // Metric 1 active; Activation 1 is not active, Activation 2 is set to active
+ // Metric 1 active; Activation 1 is inactive (above screenOnEvent causes ttl1 to expire),
+ // Activation 2 is set to active
// Metric 2 is active.
// {{{---------------------------------------------------------------------------
- EXPECT_TRUE(metricProducerTimeBase3_1->isActive());
- EXPECT_EQ(kNotActive, activationTimeBase3_1->state);
- EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activationTimeBase3_2->start_ns);
- EXPECT_EQ(kActive, activationTimeBase3_2->state);
+ EXPECT_TRUE(metricProducer3_1->isActive());
+ EXPECT_EQ(kNotActive, activation3_1_1->state);
+ EXPECT_EQ(screenOnEvent->GetElapsedTimestampNs(), activation3_1_2->start_ns);
+ EXPECT_EQ(kActive, activation3_1_2->state);
- EXPECT_TRUE(metricProducerTimeBase3_2->isActive());
+ EXPECT_TRUE(metricProducer3_2->isActive());
// }}}---------------------------------------------------------------------------
}
diff --git a/core/java/android/accessibilityservice/AccessibilityService.java b/core/java/android/accessibilityservice/AccessibilityService.java
index d3c274f4bdfe..4603f08c765f 100644
--- a/core/java/android/accessibilityservice/AccessibilityService.java
+++ b/core/java/android/accessibilityservice/AccessibilityService.java
@@ -605,7 +605,7 @@ public abstract class AccessibilityService extends Service {
}
/**
- * Gets the windows on the screen. This method returns only the windows
+ * Gets the windows on the screen of the default display. This method returns only the windows
* that a sighted user can interact with, as opposed to all windows.
* For example, if there is a modal dialog shown and the user cannot touch
* anything behind it, then only the modal window will be reported
@@ -632,6 +632,34 @@ public abstract class AccessibilityService extends Service {
}
/**
+ * Gets the windows on the screen of all displays. This method returns only the windows
+ * that a sighted user can interact with, as opposed to all windows.
+ * For example, if there is a modal dialog shown and the user cannot touch
+ * anything behind it, then only the modal window will be reported
+ * (assuming it is the top one). For convenience the returned windows
+ * are ordered in a descending layer order, which is the windows that
+ * are on top are reported first. Since the user can always
+ * interact with the window that has input focus by typing, the focused
+ * window is always returned (even if covered by a modal window).
+ * <p>
+ * <strong>Note:</strong> In order to access the windows your service has
+ * to declare the capability to retrieve window content by setting the
+ * {@link android.R.styleable#AccessibilityService_canRetrieveWindowContent}
+ * property in its meta-data. For details refer to {@link #SERVICE_META_DATA}.
+ * Also the service has to opt-in to retrieve the interactive windows by
+ * setting the {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS}
+ * flag.
+ * </p>
+ *
+ * @return The windows of all displays if there are windows and the service is can retrieve
+ * them, otherwise an empty list. The key of SparseArray is display ID.
+ */
+ @NonNull
+ public final SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
+ return AccessibilityInteractionClient.getInstance().getWindowsOnAllDisplays(mConnectionId);
+ }
+
+ /**
* Gets the root node in the currently active window if this service
* can retrieve window content. The active window is the one that the user
* is currently touching or the window with input focus, if the user is not
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index 1ca07dd6ed23..4841781170e1 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -60,7 +60,7 @@ interface IAccessibilityServiceConnection {
AccessibilityWindowInfo getWindow(int windowId);
- List<AccessibilityWindowInfo> getWindows();
+ AccessibilityWindowInfo.WindowListSparseArray getWindows();
AccessibilityServiceInfo getServiceInfo();
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 40cb29fc80ab..cb9ebac728ec 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -20,6 +20,7 @@ import static android.app.ActivityThread.DEBUG_CONFIGURATION;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.annotation.UnsupportedAppUsage;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
@@ -191,6 +192,17 @@ public class ResourcesManager {
}
}
Log.i(TAG, "Invalidated " + count + " asset managers that referenced " + path);
+
+ for (int i = mCachedApkAssets.size() - 1; i >= 0; i--) {
+ final ApkKey key = mCachedApkAssets.keyAt(i);
+ if (key.path.equals(path)) {
+ WeakReference<ApkAssets> apkAssetsRef = mCachedApkAssets.remove(key);
+ if (apkAssetsRef != null && apkAssetsRef.get() != null) {
+ apkAssetsRef.get().close();
+ }
+ mCachedApkAssets.remove(key);
+ }
+ }
}
}
@@ -1000,6 +1012,14 @@ public class ResourcesManager {
}
}
+ @TestApi
+ public final boolean applyConfigurationToResources(@NonNull Configuration config,
+ @Nullable CompatibilityInfo compat) {
+ synchronized(this) {
+ return applyConfigurationToResourcesLocked(config, compat);
+ }
+ }
+
public final boolean applyConfigurationToResourcesLocked(@NonNull Configuration config,
@Nullable CompatibilityInfo compat) {
try {
diff --git a/core/java/android/app/SystemServiceRegistry.java b/core/java/android/app/SystemServiceRegistry.java
index 049933743450..e81dc1c59040 100644
--- a/core/java/android/app/SystemServiceRegistry.java
+++ b/core/java/android/app/SystemServiceRegistry.java
@@ -1343,13 +1343,13 @@ public final class SystemServiceRegistry {
* @hide
*/
public static <T> void registerCachedService(String serviceName, Class<T> serviceWrapperClass,
- BiFunction<ContextImpl, IBinder, T> serviceFetcher) {
+ BiFunction<Context, IBinder, T> serviceFetcher) {
registerService(serviceName, serviceWrapperClass,
new CachedServiceFetcher<T>() {
@Override
public T createService(ContextImpl ctx) throws ServiceNotFoundException {
IBinder b = ServiceManager.getServiceOrThrow(serviceName);
- return serviceFetcher.apply(ctx, b);
+ return serviceFetcher.apply(ctx.getOuterContext(), b);
}});
}
diff --git a/core/java/android/app/UiAutomation.java b/core/java/android/app/UiAutomation.java
index fd93450c29f0..13d566c0e04b 100644
--- a/core/java/android/app/UiAutomation.java
+++ b/core/java/android/app/UiAutomation.java
@@ -42,6 +42,7 @@ import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.Log;
+import android.util.SparseArray;
import android.view.Display;
import android.view.InputEvent;
import android.view.KeyEvent;
@@ -535,7 +536,7 @@ public final class UiAutomation {
}
/**
- * Gets the windows on the screen. This method returns only the windows
+ * Gets the windows on the screen of the default display. This method returns only the windows
* that a sighted user can interact with, as opposed to all windows.
* For example, if there is a modal dialog shown and the user cannot touch
* anything behind it, then only the modal window will be reported
@@ -562,6 +563,35 @@ public final class UiAutomation {
}
/**
+ * Gets the windows on the screen of all displays. This method returns only the windows
+ * that a sighted user can interact with, as opposed to all windows.
+ * For example, if there is a modal dialog shown and the user cannot touch
+ * anything behind it, then only the modal window will be reported
+ * (assuming it is the top one). For convenience the returned windows
+ * are ordered in a descending layer order, which is the windows that
+ * are higher in the Z-order are reported first.
+ * <p>
+ * <strong>Note:</strong> In order to access the windows you have to opt-in
+ * to retrieve the interactive windows by setting the
+ * {@link AccessibilityServiceInfo#FLAG_RETRIEVE_INTERACTIVE_WINDOWS} flag.
+ * </p>
+ *
+ * @return The windows of all displays if there are windows and the service is can retrieve
+ * them, otherwise an empty list. The key of SparseArray is display ID.
+ */
+ @NonNull
+ public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays() {
+ final int connectionId;
+ synchronized (mLock) {
+ throwIfNotConnectedLocked();
+ connectionId = mConnectionId;
+ }
+ // Calling out without a lock held.
+ return AccessibilityInteractionClient.getInstance()
+ .getWindowsOnAllDisplays(connectionId);
+ }
+
+ /**
* Gets the root {@link AccessibilityNodeInfo} in the active window.
*
* @return The root info.
diff --git a/core/java/android/app/role/IRoleManager.aidl b/core/java/android/app/role/IRoleManager.aidl
index d8cea2860aa8..6d790b381ace 100644
--- a/core/java/android/app/role/IRoleManager.aidl
+++ b/core/java/android/app/role/IRoleManager.aidl
@@ -19,7 +19,6 @@ package android.app.role;
import android.app.role.IOnRoleHoldersChangedListener;
import android.os.Bundle;
import android.os.RemoteCallback;
-import android.telephony.IFinancialSmsCallback;
/**
* @hide
@@ -55,9 +54,4 @@ interface IRoleManager {
List<String> getHeldRolesFromController(in String packageName);
String getDefaultSmsPackage(int userId);
-
- /**
- * Get filtered SMS messages for financial app.
- */
- void getSmsMessagesForFinancialApp(in String callingPkg, in Bundle params, in IFinancialSmsCallback callback);
}
diff --git a/core/java/android/app/usage/AppStandbyInfo.java b/core/java/android/app/usage/AppStandbyInfo.java
index ebdbf833b81a..c283702a6bbf 100644
--- a/core/java/android/app/usage/AppStandbyInfo.java
+++ b/core/java/android/app/usage/AppStandbyInfo.java
@@ -22,6 +22,10 @@ import android.os.Parcelable;
/**
* A pair of {package, bucket} to denote the app standby bucket for a given package.
* Used as a vehicle of data across the binder IPC.
+ *
+ * Note we're not moving this class to the jobscheduler apex, because it's consumed by
+ * UsageStatsManager, which is not updatable anyway, so making this updatable isn't really
+ * beneficial.
* @hide
*/
public final class AppStandbyInfo implements Parcelable {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 802c1a0ae6d5..08817e05e0a5 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -3301,7 +3301,7 @@ public abstract class Context {
* <dt> {@link #VIBRATOR_SERVICE} ("vibrator")
* <dd> A {@link android.os.Vibrator} for interacting with the vibrator
* hardware.
- * <dt> {@link #CONNECTIVITY_SERVICE} ("connection")
+ * <dt> {@link #CONNECTIVITY_SERVICE} ("connectivity")
* <dd> A {@link android.net.ConnectivityManager ConnectivityManager} for
* handling management of network connections.
* <dt> {@link #IPSEC_SERVICE} ("ipsec")
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index e24512ac525d..c3daad188792 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -16,8 +16,6 @@
package android.content;
-import static android.app.AppOpsManager.strOpToOp;
-
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -52,6 +50,19 @@ import java.lang.annotation.RetentionPolicy;
* permission model for which the user had disabled the "permission"
* which is achieved by disallowing the corresponding app op.
* </p>
+ * <p>
+ * This class has two types of methods and you should be careful which
+ * type to call based on whether permission protected data is being
+ * passed to the app or you are just checking whether the app holds a
+ * permission. The reason is that a permission check requires checking
+ * the runtime permission and if it is granted checking the corresponding
+ * app op as for apps not supporting the runtime mode we never revoke
+ * permissions but disable app ops. Since there are two types of app op
+ * checks, one that does not leave a record an action was performed and
+ * another the does, one needs to call the preflight flavor of the checks
+ * named xxxForPreflight only if no private data is being delivered but
+ * a permission check is what is needed and the xxxForDataDelivery where
+ * the permission check is right before private data delivery.
*
* @hide
*/
@@ -65,6 +76,9 @@ public final class PermissionChecker {
/** Permission result: The permission is denied because the app op is not allowed. */
public static final int PERMISSION_DENIED_APP_OP = PackageManager.PERMISSION_DENIED - 1;
+ /** Constant when the PID for which we check permissions is unknown. */
+ public static final int PID_UNKNOWN = -1;
+
/** @hide */
@IntDef({PERMISSION_GRANTED,
PERMISSION_DENIED,
@@ -77,63 +91,97 @@ public final class PermissionChecker {
}
/**
- * @deprecated Use {@link #checkPermission(Context, String, int, int, String, String)} instead
+ * Checks whether a given package in a UID and PID has a given permission
+ * and whether the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkPermissionForPreflight(Context, String, int, int, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method which
+ * will evaluate the permission access based on the current fg/bg state of the app and
+ * leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @param pid The process id for which to check. Use {@link #PID_UNKNOWN} if the PID
+ * is not known.
+ * @param uid The uid for which to check.
+ * @param packageName The package name for which to check. If null the
+ * the first package for the calling UID will be used.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkPermissionForPreflight(Context, String, int, int, String)
*/
- @Deprecated
@PermissionResult
- public static int checkPermission(@NonNull Context context, @NonNull String permission,
- int pid, int uid, @Nullable String packageName) {
- return checkPermission(context, permission, pid, uid, packageName, null);
+ public static int checkPermissionForDataDelivery(@NonNull Context context,
+ @NonNull String permission, int pid, int uid, @Nullable String packageName,
+ @Nullable String message) {
+ return checkPermissionCommon(context, permission, pid, uid, packageName, message,
+ true /*forDataDelivery*/);
}
/**
* Checks whether a given package in a UID and PID has a given permission
* and whether the app op that corresponds to this permission is allowed.
*
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the app's
+ * fg/gb state) and this check will not leave a trace that permission protected data
+ * was delivered. When you are about to deliver the location data to a registered
+ * listener you should use {@link #checkPermissionForDataDelivery(Context, String,
+ * int, int, String, String)} which will evaluate the permission access based on the current
+ * fg/bg state of the app and leave a record that the data was accessed.
+ *
* @param context Context for accessing resources.
* @param permission The permission to check.
* @param pid The process id for which to check.
* @param uid The uid for which to check.
* @param packageName The package name for which to check. If null the
* the first package for the calling UID will be used.
- * @param message A message describing the reason the permission was checked
- *
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
* or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkPermissionForDataDelivery(Context, String, int, int, String, String)
*/
@PermissionResult
- public static int checkPermission(@NonNull Context context, @NonNull String permission,
- int pid, int uid, @Nullable String packageName, @Nullable String message) {
- if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) {
- return PERMISSION_DENIED;
- }
-
- AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
- String op = appOpsManager.permissionToOp(permission);
- if (op == null) {
- return PERMISSION_GRANTED;
- }
-
- if (packageName == null) {
- String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
- if (packageNames == null || packageNames.length <= 0) {
- return PERMISSION_DENIED;
- }
- packageName = packageNames[0];
- }
-
- if (appOpsManager.noteProxyOpNoThrow(strOpToOp(op), packageName, uid, message)
- != AppOpsManager.MODE_ALLOWED) {
- return PERMISSION_DENIED_APP_OP;
- }
-
- return PERMISSION_GRANTED;
+ public static int checkPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission, int pid, int uid, @Nullable String packageName) {
+ return checkPermissionCommon(context, permission, pid, uid, packageName, null /*message*/,
+ false /*forDataDelivery*/);
}
/**
* Checks whether your app has a given permission and whether the app op
* that corresponds to this permission is allowed.
*
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkSelfPermissionForPreflight(Context, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method
+ * which will evaluate the permission access based on the current fg/bg state of the
+ * app and leave a record that the data was accessed.
+ *
* <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
* {@link Process#myUid()}.
*
@@ -141,74 +189,229 @@ public final class PermissionChecker {
* @param permission The permission to check.
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
* or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkSelfPermissionForPreflight(Context, String)
*/
@PermissionResult
- public static int checkSelfPermission(@NonNull Context context,
- @NonNull String permission) {
- return checkPermission(context, permission, Process.myPid(),
- Process.myUid(), context.getPackageName(), null /* self access */);
+ public static int checkSelfPermissionForDataDelivery(@NonNull Context context,
+ @NonNull String permission, @Nullable String message) {
+ return checkPermissionForDataDelivery(context, permission, Process.myPid(),
+ Process.myUid(), context.getPackageName(), message);
}
/**
- * @deprecated Use {@link #checkCallingPermission(Context, String, String, String)} instead
+ * Checks whether your app has a given permission and whether the app op
+ * that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the
+ * app's fg/gb state) and this check will not leave a trace that permission protected
+ * data was delivered. When you are about to deliver the location data to a registered
+ * listener you should use this method which will evaluate the permission access based
+ * on the current fg/bg state of the app and leave a record that the data was accessed.
+ *
+ * <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
+ * {@link Process#myUid()}.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkSelfPermissionForDataDelivery(Context, String, String)
*/
- @Deprecated
@PermissionResult
- public static int checkCallingPermission(@NonNull Context context,
- @NonNull String permission, @Nullable String packageName) {
- return checkCallingPermission(context, permission, packageName, null);
+ public static int checkSelfPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission) {
+ return checkPermissionForPreflight(context, permission, Process.myPid(),
+ Process.myUid(), context.getPackageName());
}
/**
* Checks whether the IPC you are handling has a given permission and whether
* the app op that corresponds to this permission is allowed.
*
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkCallingPermissionForPreflight(Context, String, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method which
+ * will evaluate the permission access based on the current fg/bg state of the app and
+ * leave a record that the data was accessed.
+ *
* @param context Context for accessing resources.
* @param permission The permission to check.
* @param packageName The package name making the IPC. If null the
* the first package for the calling UID will be used.
- * @param message A message describing the reason the permission was checked
- *
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
* or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkCallingPermissionForPreflight(Context, String, String)
*/
@PermissionResult
- public static int checkCallingPermission(@NonNull Context context,
+ public static int checkCallingPermissionForDataDelivery(@NonNull Context context,
@NonNull String permission, @Nullable String packageName, @Nullable String message) {
if (Binder.getCallingPid() == Process.myPid()) {
return PERMISSION_DENIED;
}
- return checkPermission(context, permission, Binder.getCallingPid(),
+ return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
Binder.getCallingUid(), packageName, message);
}
/**
- * @deprecated Use {@link #checkCallingOrSelfPermission(Context, String, String)} instead
+ * Checks whether the IPC you are handling has a given permission and whether
+ * the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the app's
+ * fg/gb state) and this check will not leave a trace that permission protected data
+ * was delivered. When you are about to deliver the location data to a registered
+ * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context,
+ * String, String)} which will evaluate the permission access based on the current fg/bg state
+ * of the app and leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @param packageName The package name making the IPC. If null the
+ * the first package for the calling UID will be used.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkCallingPermissionForDataDelivery(Context, String, String, String)
*/
- @Deprecated
@PermissionResult
- public static int checkCallingOrSelfPermission(@NonNull Context context,
- @NonNull String permission) {
- return checkCallingOrSelfPermission(context, permission, null);
+ public static int checkCallingPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission, @Nullable String packageName) {
+ if (Binder.getCallingPid() == Process.myPid()) {
+ return PERMISSION_DENIED;
+ }
+ return checkPermissionForPreflight(context, permission, Binder.getCallingPid(),
+ Binder.getCallingUid(), packageName);
}
/**
* Checks whether the IPC you are handling or your app has a given permission
* and whether the app op that corresponds to this permission is allowed.
*
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * point where you will deliver the permission protected data to clients.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use {@link #checkCallingOrSelfPermissionForPreflight(Context, String)}
+ * to determine if the app has or may have location permission (if app has only foreground
+ * location the grant state depends on the app's fg/gb state) and this check will not
+ * leave a trace that permission protected data was delivered. When you are about to
+ * deliver the location data to a registered listener you should use this method which
+ * will evaluate the permission access based on the current fg/bg state of the app and
+ * leave a record that the data was accessed.
+ *
* @param context Context for accessing resources.
* @param permission The permission to check.
- * @param message A message describing the reason the permission was checked
- *
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
* or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ * @param message A message describing the reason the permission was checked
+ *
+ * @see #checkCallingOrSelfPermissionForPreflight(Context, String)
*/
@PermissionResult
- public static int checkCallingOrSelfPermission(@NonNull Context context,
+ public static int checkCallingOrSelfPermissionForDataDelivery(@NonNull Context context,
@NonNull String permission, @Nullable String message) {
String packageName = (Binder.getCallingPid() == Process.myPid())
? context.getPackageName() : null;
- return checkPermission(context, permission, Binder.getCallingPid(),
+ return checkPermissionForDataDelivery(context, permission, Binder.getCallingPid(),
Binder.getCallingUid(), packageName, message);
}
-}
+
+ /**
+ * Checks whether the IPC you are handling or your app has a given permission
+ * and whether the app op that corresponds to this permission is allowed.
+ *
+ * <strong>NOTE:</strong> Use this method only for permission checks at the
+ * preflight point where you will not deliver the permission protected data
+ * to clients but schedule permission data delivery, apps register listeners,
+ * etc.
+ *
+ * <p>For example, if an app registers a location listener it should have the location
+ * permission but no data is actually sent to the app at the moment of registration
+ * and you should use this method to determine if the app has or may have location
+ * permission (if app has only foreground location the grant state depends on the
+ * app's fg/gb state) and this check will not leave a trace that permission protected
+ * data was delivered. When you are about to deliver the location data to a registered
+ * listener you should use {@link #checkCallingOrSelfPermissionForDataDelivery(Context,
+ * String, String)} which will evaluate the permission access based on the current fg/bg state
+ * of the app and leave a record that the data was accessed.
+ *
+ * @param context Context for accessing resources.
+ * @param permission The permission to check.
+ * @return The permission check result which is either {@link #PERMISSION_GRANTED}
+ * or {@link #PERMISSION_DENIED} or {@link #PERMISSION_DENIED_APP_OP}.
+ *
+ * @see #checkCallingOrSelfPermissionForDataDelivery(Context, String, String)
+ */
+ @PermissionResult
+ public static int checkCallingOrSelfPermissionForPreflight(@NonNull Context context,
+ @NonNull String permission) {
+ String packageName = (Binder.getCallingPid() == Process.myPid())
+ ? context.getPackageName() : null;
+ return checkPermissionForPreflight(context, permission, Binder.getCallingPid(),
+ Binder.getCallingUid(), packageName);
+ }
+
+ private static int checkPermissionCommon(@NonNull Context context, @NonNull String permission,
+ int pid, int uid, @Nullable String packageName, @Nullable String message,
+ boolean forDataDelivery) {
+ if (context.checkPermission(permission, pid, uid) == PackageManager.PERMISSION_DENIED) {
+ return PERMISSION_DENIED;
+ }
+
+ AppOpsManager appOpsManager = context.getSystemService(AppOpsManager.class);
+ String op = appOpsManager.permissionToOp(permission);
+ if (op == null) {
+ return PERMISSION_GRANTED;
+ }
+
+ if (packageName == null) {
+ String[] packageNames = context.getPackageManager().getPackagesForUid(uid);
+ if (packageNames == null || packageNames.length <= 0) {
+ return PERMISSION_DENIED;
+ }
+ packageName = packageNames[0];
+ }
+
+ if (forDataDelivery) {
+ if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid, message)
+ != AppOpsManager.MODE_ALLOWED) {
+ return PERMISSION_DENIED_APP_OP;
+ }
+ } else {
+ final int mode = appOpsManager.unsafeCheckOpRawNoThrow(op, uid, packageName);
+ if (mode != AppOpsManager.MODE_ALLOWED && mode != AppOpsManager.MODE_FOREGROUND) {
+ return PERMISSION_DENIED_APP_OP;
+ }
+ }
+
+ return PERMISSION_GRANTED;
+ }
+} \ No newline at end of file
diff --git a/core/java/android/content/om/IOverlayManager.aidl b/core/java/android/content/om/IOverlayManager.aidl
index 43a4fe5bc414..3d7e3befd9f1 100644
--- a/core/java/android/content/om/IOverlayManager.aidl
+++ b/core/java/android/content/om/IOverlayManager.aidl
@@ -157,4 +157,10 @@ interface IOverlayManager {
* Returns the list of default overlay packages, or an empty array if there are none.
*/
String[] getDefaultOverlayPackages();
+
+ /**
+ * Invalidates and removes the idmap for an overlay,
+ * @param packageName The name of the overlay package whose idmap should be deleted.
+ */
+ void invalidateCachesForOverlay(in String packageName, in int userIs);
}
diff --git a/core/java/android/content/om/OverlayManager.java b/core/java/android/content/om/OverlayManager.java
index f2716fedc186..853e8189ea8a 100644
--- a/core/java/android/content/om/OverlayManager.java
+++ b/core/java/android/content/om/OverlayManager.java
@@ -21,6 +21,7 @@ import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.RemoteException;
import android.os.ServiceManager;
@@ -163,4 +164,28 @@ public class OverlayManager {
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Returns information about all overlays for the given target package for
+ * the specified user. The returned list is ordered according to the
+ * overlay priority with the highest priority at the end of the list.
+ *
+ * @param targetPackageName The name of the target package.
+ * @param user The user to get the OverlayInfos for.
+ *
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(anyOf = {
+ "android.permission.INTERACT_ACROSS_USERS",
+ })
+ @NonNull
+ public void invalidateCachesForOverlay(@NonNull final String targetPackageName,
+ @NonNull UserHandle user) {
+ try {
+ mService.invalidateCachesForOverlay(targetPackageName, user.getIdentifier());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/content/pm/UserInfo.java b/core/java/android/content/pm/UserInfo.java
index 0a99142a9fbd..9f0bade9bd29 100644
--- a/core/java/android/content/pm/UserInfo.java
+++ b/core/java/android/content/pm/UserInfo.java
@@ -420,10 +420,10 @@ public class UserInfo implements Parcelable {
lastLoggedInTime = source.readLong();
lastLoggedInFingerprint = source.readString();
partial = source.readBoolean();
+ preCreated = source.readBoolean();
profileGroupId = source.readInt();
guestToRemove = source.readBoolean();
restrictedProfileParentId = source.readInt();
profileBadge = source.readInt();
- preCreated = source.readBoolean();
}
}
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index 69462ab99483..a35ad567ed81 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -188,7 +188,7 @@ public final class ApkAssets {
/**
* Closes this class and the contained {@link #mStringBlock}.
*/
- public void close() throws Throwable {
+ public void close() {
synchronized (this) {
if (mOpen) {
mOpen = false;
diff --git a/core/java/android/content/res/StringBlock.java b/core/java/android/content/res/StringBlock.java
index b7bc8229fa45..2ae1932c3437 100644
--- a/core/java/android/content/res/StringBlock.java
+++ b/core/java/android/content/res/StringBlock.java
@@ -175,7 +175,7 @@ final class StringBlock {
}
}
- public void close() throws Throwable {
+ public void close() {
synchronized (this) {
if (mOpen) {
mOpen = false;
diff --git a/core/java/android/hardware/location/ContextHubClientCallback.java b/core/java/android/hardware/location/ContextHubClientCallback.java
index cc2fe65dcb7e..20fa7538e2d5 100644
--- a/core/java/android/hardware/location/ContextHubClientCallback.java
+++ b/core/java/android/hardware/location/ContextHubClientCallback.java
@@ -66,7 +66,9 @@ public class ContextHubClientCallback {
public void onNanoAppAborted(ContextHubClient client, long nanoAppId, int abortCode) {}
/**
- * Callback invoked when a nanoapp is loaded at the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically loaded at the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}. This callback is not invoked for a
+ * nanoapp that is loaded internally by CHRE (e.g. nanoapps that are preloaded by the system).
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been loaded
@@ -74,7 +76,8 @@ public class ContextHubClientCallback {
public void onNanoAppLoaded(ContextHubClient client, long nanoAppId) {}
/**
- * Callback invoked when a nanoapp is unloaded from the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically unloaded from the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}.
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been unloaded
@@ -82,7 +85,8 @@ public class ContextHubClientCallback {
public void onNanoAppUnloaded(ContextHubClient client, long nanoAppId) {}
/**
- * Callback invoked when a nanoapp is enabled at the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically enabled at the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}.
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been enabled
@@ -90,7 +94,8 @@ public class ContextHubClientCallback {
public void onNanoAppEnabled(ContextHubClient client, long nanoAppId) {}
/**
- * Callback invoked when a nanoapp is disabled at the attached Context Hub.
+ * Callback invoked when a nanoapp is dynamically disabled at the attached Context Hub through
+ * the {@link android.hardware.location.ContextHubManager}.
*
* @param client the client that is associated with this callback
* @param nanoAppId the ID of the nanoapp that had been disabled
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 3c26df3c560b..e4e8bf791d47 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7908,16 +7908,6 @@ public final class Settings {
public static final String NOTIFICATION_BADGING = "notification_badging";
/**
- * Whether the notification bubbles are globally enabled
- * The value is boolean (1 or 0).
- * @hide
- * @deprecated use {@link Global#NOTIFICATION_BUBBLES} instead.
- */
- @TestApi
- @Deprecated
- public static final String NOTIFICATION_BUBBLES = "notification_bubbles";
-
- /**
* Whether notifications are dismissed by a right-to-left swipe (instead of a left-to-right
* swipe).
*
diff --git a/core/java/android/service/autofill/AutofillFieldClassificationService.java b/core/java/android/service/autofill/AutofillFieldClassificationService.java
index 320dcec675cc..28842a7fa1d7 100644
--- a/core/java/android/service/autofill/AutofillFieldClassificationService.java
+++ b/core/java/android/service/autofill/AutofillFieldClassificationService.java
@@ -93,6 +93,13 @@ public abstract class AutofillFieldClassificationService extends Service {
*/
public static final String REQUIRED_ALGORITHM_EXACT_MATCH = "EXACT_MATCH";
+ /**
+ * Field classification algorithm that compares a credit card string to known last four digits.
+ *
+ * <p>Service implementation must provide this algorithm.</p>
+ */
+ public static final String REQUIRED_ALGORITHM_CREDIT_CARD = "CREDIT_CARD";
+
/** {@hide} **/
public static final String EXTRA_SCORES = "scores";
diff --git a/core/java/android/speech/RecognitionService.java b/core/java/android/speech/RecognitionService.java
index 70dfef574ca5..dfc5c8217fda 100644
--- a/core/java/android/speech/RecognitionService.java
+++ b/core/java/android/speech/RecognitionService.java
@@ -170,13 +170,23 @@ public abstract class RecognitionService extends Service {
* Checks whether the caller has sufficient permissions
*
* @param listener to send the error message to in case of error
+ * @param forDataDelivery If the permission check is for delivering the sensitive data.
* @return {@code true} if the caller has enough permissions, {@code false} otherwise
*/
- private boolean checkPermissions(IRecognitionListener listener) {
+ private boolean checkPermissions(IRecognitionListener listener, boolean forDataDelivery) {
if (DBG) Log.d(TAG, "checkPermissions");
- if (PermissionChecker.checkCallingOrSelfPermission(this,
- android.Manifest.permission.RECORD_AUDIO) == PermissionChecker.PERMISSION_GRANTED) {
- return true;
+ if (forDataDelivery) {
+ if (PermissionChecker.checkCallingOrSelfPermissionForDataDelivery(this,
+ android.Manifest.permission.RECORD_AUDIO, null /*message*/)
+ == PermissionChecker.PERMISSION_GRANTED) {
+ return true;
+ }
+ } else {
+ if (PermissionChecker.checkCallingOrSelfPermissionForPreflight(this,
+ android.Manifest.permission.RECORD_AUDIO)
+ == PermissionChecker.PERMISSION_GRANTED) {
+ return true;
+ }
}
try {
Log.e(TAG, "call for recognition service without RECORD_AUDIO permissions");
@@ -342,7 +352,7 @@ public abstract class RecognitionService extends Service {
public void startListening(Intent recognizerIntent, IRecognitionListener listener) {
if (DBG) Log.d(TAG, "startListening called by:" + listener.asBinder());
final RecognitionService service = mServiceRef.get();
- if (service != null && service.checkPermissions(listener)) {
+ if (service != null && service.checkPermissions(listener, true /*forDataDelivery*/)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_START_LISTENING, service.new StartListeningArgs(
recognizerIntent, listener, Binder.getCallingUid())));
@@ -353,7 +363,7 @@ public abstract class RecognitionService extends Service {
public void stopListening(IRecognitionListener listener) {
if (DBG) Log.d(TAG, "stopListening called by:" + listener.asBinder());
final RecognitionService service = mServiceRef.get();
- if (service != null && service.checkPermissions(listener)) {
+ if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_STOP_LISTENING, listener));
}
@@ -363,7 +373,7 @@ public abstract class RecognitionService extends Service {
public void cancel(IRecognitionListener listener) {
if (DBG) Log.d(TAG, "cancel called by:" + listener.asBinder());
final RecognitionService service = mServiceRef.get();
- if (service != null && service.checkPermissions(listener)) {
+ if (service != null && service.checkPermissions(listener, false /*forDataDelivery*/)) {
service.mHandler.sendMessage(Message.obtain(service.mHandler,
MSG_CANCEL, listener));
}
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index d9fa9f24f1ae..bb10ef10d79e 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -259,23 +259,38 @@ public final class AccessibilityInteractionClient
}
/**
- * Gets the info for all windows.
+ * Gets the info for all windows of the default display.
*
* @param connectionId The id of a connection for interacting with the system.
* @return The {@link AccessibilityWindowInfo} list.
*/
public List<AccessibilityWindowInfo> getWindows(int connectionId) {
+ final SparseArray<List<AccessibilityWindowInfo>> windows =
+ getWindowsOnAllDisplays(connectionId);
+ if (windows.size() > 0) {
+ return windows.valueAt(Display.DEFAULT_DISPLAY);
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * Gets the info for all windows of all displays.
+ *
+ * @param connectionId The id of a connection for interacting with the system.
+ * @return The SparseArray of {@link AccessibilityWindowInfo} list.
+ * The key of SparseArray is display ID.
+ */
+ public SparseArray<List<AccessibilityWindowInfo>> getWindowsOnAllDisplays(int connectionId) {
try {
IAccessibilityServiceConnection connection = getConnection(connectionId);
if (connection != null) {
- SparseArray<List<AccessibilityWindowInfo>> allWindows =
+ SparseArray<List<AccessibilityWindowInfo>> windows =
sAccessibilityCache.getWindowsOnAllDisplays();
- List<AccessibilityWindowInfo> windows;
- if (allWindows != null) {
+ if (windows != null) {
if (DEBUG) {
Log.i(LOG_TAG, "Windows cache hit");
}
- return allWindows.valueAt(Display.DEFAULT_DISPLAY);
+ return windows;
}
if (DEBUG) {
Log.i(LOG_TAG, "Windows cache miss");
@@ -287,9 +302,7 @@ public final class AccessibilityInteractionClient
Binder.restoreCallingIdentity(identityToken);
}
if (windows != null) {
- allWindows = new SparseArray<>();
- allWindows.put(Display.DEFAULT_DISPLAY, windows);
- sAccessibilityCache.setWindowsOnAllDisplays(allWindows);
+ sAccessibilityCache.setWindowsOnAllDisplays(windows);
return windows;
}
} else {
@@ -298,9 +311,11 @@ public final class AccessibilityInteractionClient
}
}
} catch (RemoteException re) {
- Log.e(LOG_TAG, "Error while calling remote getWindows", re);
+ Log.e(LOG_TAG, "Error while calling remote getWindowsOnAllDisplays", re);
}
- return Collections.emptyList();
+
+ final SparseArray<List<AccessibilityWindowInfo>> emptyWindows = new SparseArray<>();
+ return emptyWindows;
}
/**
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl b/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
index fdb25fb1ee61..c36c4aa5b00a 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.aidl
@@ -17,3 +17,4 @@
package android.view.accessibility;
parcelable AccessibilityWindowInfo;
+parcelable AccessibilityWindowInfo.WindowListSparseArray;
diff --git a/core/java/android/view/accessibility/AccessibilityWindowInfo.java b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
index 6a3af3478449..5fa8a6e0e06b 100644
--- a/core/java/android/view/accessibility/AccessibilityWindowInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityWindowInfo.java
@@ -26,9 +26,12 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.LongArray;
import android.util.Pools.SynchronizedPool;
+import android.util.SparseArray;
import android.view.Display;
import android.view.accessibility.AccessibilityEvent.WindowsChangeTypes;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
@@ -797,4 +800,49 @@ public final class AccessibilityWindowInfo implements Parcelable {
return new AccessibilityWindowInfo[size];
}
};
+
+ /**
+ * Transfers a sparsearray with lists having {@link AccessibilityWindowInfo}s across an IPC.
+ * The key of this sparsearray is display Id.
+ *
+ * @hide
+ */
+ public static final class WindowListSparseArray
+ extends SparseArray<List<AccessibilityWindowInfo>> implements Parcelable {
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ final int count = size();
+ dest.writeInt(count);
+ for (int i = 0; i < count; i++) {
+ dest.writeParcelableList(valueAt(i), 0);
+ dest.writeInt(keyAt(i));
+ }
+ }
+
+ public static final Parcelable.Creator<WindowListSparseArray> CREATOR =
+ new Parcelable.Creator<WindowListSparseArray>() {
+ public WindowListSparseArray createFromParcel(
+ Parcel source) {
+ final WindowListSparseArray array = new WindowListSparseArray();
+ final ClassLoader loader = array.getClass().getClassLoader();
+ final int count = source.readInt();
+ for (int i = 0; i < count; i++) {
+ List<AccessibilityWindowInfo> windows = new ArrayList<>();
+ source.readParcelableList(windows, loader);
+ array.put(source.readInt(), windows);
+ }
+ return array;
+ }
+
+ public WindowListSparseArray[] newArray(int size) {
+ return new WindowListSparseArray[size];
+ }
+ };
+ }
}
diff --git a/core/java/android/webkit/MimeTypeMap.java b/core/java/android/webkit/MimeTypeMap.java
index fc23c54e834e..358fdc78c0a0 100644
--- a/core/java/android/webkit/MimeTypeMap.java
+++ b/core/java/android/webkit/MimeTypeMap.java
@@ -19,7 +19,7 @@ package android.webkit;
import android.annotation.Nullable;
import android.text.TextUtils;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.util.regex.Pattern;
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index f997d6878a9c..31f50555af1d 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -23,6 +23,7 @@ import static android.view.accessibility.AccessibilityNodeInfo.EXTRA_DATA_TEXT_C
import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
import android.R;
+import android.annotation.CallSuper;
import android.annotation.CheckResult;
import android.annotation.ColorInt;
import android.annotation.DrawableRes;
@@ -10446,10 +10447,15 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
/**
* This method is called when the selection has changed, in case any
* subclasses would like to know.
+ * </p>
+ * <p class="note"><strong>Note:</strong> Always call the super implementation, which informs
+ * the accessibility subsystem about the selection change.
+ * </p>
*
* @param selStart The new selection start location.
* @param selEnd The new selection end location.
*/
+ @CallSuper
protected void onSelectionChanged(int selStart, int selEnd) {
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_TEXT_SELECTION_CHANGED);
}
diff --git a/core/java/com/android/internal/compat/IPlatformCompat.aidl b/core/java/com/android/internal/compat/IPlatformCompat.aidl
index e415b41459ab..4d8378a34599 100644
--- a/core/java/com/android/internal/compat/IPlatformCompat.aidl
+++ b/core/java/com/android/internal/compat/IPlatformCompat.aidl
@@ -43,11 +43,6 @@ interface IPlatformCompat
/**
* Reports that a compatibility change is affecting an app process now.
*
- * <p>Same as {@link #reportChange(long, ApplicationInfo)}, except it receives a package name
- * instead of an {@link ApplicationInfo}
- * object, and finds an app info object based on the package name. Returns {@code true} if
- * there is no installed package by that name.
- *
* <p>Note: for changes that are gated using {@link #isChangeEnabled(long, String)},
* you do not need to call this API directly. The change will be reported for you.
*
@@ -57,6 +52,17 @@ interface IPlatformCompat
void reportChangeByPackageName(long changeId, in String packageName);
/**
+ * Reports that a compatibility change is affecting an app process now.
+ *
+ * <p>Note: for changes that are gated using {@link #isChangeEnabled(long, int)},
+ * you do not need to call this API directly. The change will be reported for you.
+ *
+ * @param changeId The ID of the compatibility change taking effect.
+ * @param uid The UID of the app in question.
+ */
+ void reportChangeByUid(long changeId, int uid);
+
+ /**
* 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.
*
@@ -95,4 +101,28 @@ interface IPlatformCompat
* @return {@code true} if the change is enabled for the current app.
*/
boolean isChangeEnabledByPackageName(long changeId, in String packageName);
+
+ /**
+ * 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>Same as {@link #isChangeEnabled(long, ApplicationInfo)}, except it receives a uid
+ * instead of an {@link ApplicationInfo} object, and finds an app info object based on the
+ * uid (or objects if there's more than one package associated with the UID).
+ * Returns {@code true} if there are no installed packages for the required UID, or if the
+ * change is enabled for ALL of the installed packages associated with the provided UID. Please
+ * use a more specific API if you want a different behaviour for multi-package UIDs.
+ *
+ * <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>It will also report the change as {@link #reportChange(long, int)} would, so there is
+ * no need to call that method directly.
+ *
+ * @param changeId The ID of the compatibility change in question.
+ * @param uid The UID of the app in question.
+ * @return {@code true} if the change is enabled for the current app.
+ */
+ boolean isChangeEnabledByUid(long changeId, int uid);
} \ No newline at end of file
diff --git a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
index 5142d3cd2b99..033e9b2c6eba 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiDeviceConfigFlags.java
@@ -239,6 +239,13 @@ public final class SystemUiDeviceConfigFlags {
public static final String ASSIST_TRANSCRIPTION_MIN_DURATION =
"assist_transcription_min_duration";
+ /**
+ * (boolean) Whether or not to enable an extra section in the notification shade which
+ * filters for "people" related messages.
+ */
+ public static final String NOTIFICATIONS_USE_PEOPLE_FILTERING =
+ "notifications_use_people_filtering";
+
// Flags related to brightline falsing
/**
diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java
index 9fff447c2478..fd3cd42b07a1 100644
--- a/core/java/com/android/internal/os/RuntimeInit.java
+++ b/core/java/com/android/internal/os/RuntimeInit.java
@@ -35,7 +35,7 @@ import com.android.server.NetworkManagementSocketTagger;
import dalvik.system.RuntimeHooks;
import dalvik.system.VMRuntime;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
@@ -203,13 +203,15 @@ public class RuntimeInit {
public static void preForkInit() {
if (DEBUG) Slog.d(TAG, "Entered preForkInit.");
RuntimeInit.enableDdms();
+ // TODO(b/142019040#comment13): Decide whether to load the default instance eagerly, i.e.
+ // MimeMap.setDefault(DefaultMimeMapFactory.create());
/*
* Replace libcore's minimal default mapping between MIME types and file
* extensions with a mapping that's suitable for Android. Android's mapping
* contains many more entries that are derived from IANA registrations but
* with several customizations (extensions, overrides).
*/
- MimeMap.setDefault(DefaultMimeMapFactory.create());
+ MimeMap.setDefaultSupplier(DefaultMimeMapFactory::create);
}
@UnsupportedAppUsage
diff --git a/core/java/com/android/internal/util/MimeIconUtils.java b/core/java/com/android/internal/util/MimeIconUtils.java
index 2230c3134301..31ea5b2bf07c 100644
--- a/core/java/com/android/internal/util/MimeIconUtils.java
+++ b/core/java/com/android/internal/util/MimeIconUtils.java
@@ -27,7 +27,7 @@ import android.util.ArrayMap;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.util.Locale;
import java.util.Objects;
diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluation.java b/core/java/com/android/internal/util/function/DecConsumer.java
index 93c9adaac12d..0abb785bea32 100644
--- a/services/core/java/com/android/server/integrity/engine/RuleEvaluation.java
+++ b/core/java/com/android/internal/util/function/DecConsumer.java
@@ -14,16 +14,15 @@
* limitations under the License.
*/
-package com.android.server.integrity.engine;
+package com.android.internal.util.function;
+
+import java.util.function.Consumer;
/**
- * The engine used to evaluate rules against app installs.
+ * A 10-argument {@link Consumer}
*
- * <p>Every app install is evaluated against rules (pushed by the verifier) by the evaluation engine
- * to allow/block that install.
+ * @hide
*/
-public final class RuleEvaluation {
- private static final String TAG = "RuleEvaluation";
-
- // TODO: Add singleton injection.
+public interface DecConsumer<A, B, C, D, E, F, G, H, I, J> {
+ void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
}
diff --git a/core/java/com/android/internal/util/function/DecFunction.java b/core/java/com/android/internal/util/function/DecFunction.java
new file mode 100644
index 000000000000..59fc5e6e6562
--- /dev/null
+++ b/core/java/com/android/internal/util/function/DecFunction.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util.function;
+
+import java.util.function.Function;
+
+/**
+ * A 10-argument {@link Function}
+ *
+ * @hide
+ */
+public interface DecFunction<A, B, C, D, E, F, G, H, I, J, R> {
+ R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
+}
diff --git a/core/java/com/android/internal/util/function/DecPredicate.java b/core/java/com/android/internal/util/function/DecPredicate.java
new file mode 100644
index 000000000000..975993dc05dc
--- /dev/null
+++ b/core/java/com/android/internal/util/function/DecPredicate.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util.function;
+
+import java.util.function.Predicate;
+
+/**
+ * A 10-argument {@link Predicate}
+ *
+ * @hide
+ */
+public interface DecPredicate<A, B, C, D, E, F, G, H, I, J> {
+ boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j);
+}
diff --git a/core/java/com/android/internal/util/function/UndecConsumer.java b/core/java/com/android/internal/util/function/UndecConsumer.java
new file mode 100644
index 000000000000..1a1d4ca600af
--- /dev/null
+++ b/core/java/com/android/internal/util/function/UndecConsumer.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util.function;
+
+import java.util.function.Consumer;
+
+/**
+ * A 11-argument {@link Consumer}
+ *
+ * @hide
+ */
+public interface UndecConsumer<A, B, C, D, E, F, G, H, I, J, K> {
+ void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
+}
diff --git a/core/java/com/android/internal/util/function/UndecFunction.java b/core/java/com/android/internal/util/function/UndecFunction.java
new file mode 100644
index 000000000000..5cd324c2a7e5
--- /dev/null
+++ b/core/java/com/android/internal/util/function/UndecFunction.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util.function;
+
+import java.util.function.Function;
+
+/**
+ * A 11-argument {@link Function}
+ *
+ * @hide
+ */
+public interface UndecFunction<A, B, C, D, E, F, G, H, I, J, K, R> {
+ R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
+}
diff --git a/core/java/com/android/internal/util/function/UndecPredicate.java b/core/java/com/android/internal/util/function/UndecPredicate.java
new file mode 100644
index 000000000000..c09193eb7a11
--- /dev/null
+++ b/core/java/com/android/internal/util/function/UndecPredicate.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util.function;
+
+import java.util.function.Predicate;
+
+/**
+ * A 11-argument {@link Predicate}
+ *
+ * @hide
+ */
+public interface UndecPredicate<A, B, C, D, E, F, G, H, I, J, K> {
+ boolean test(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
+}
diff --git a/core/java/com/android/internal/util/function/pooled/OmniFunction.java b/core/java/com/android/internal/util/function/pooled/OmniFunction.java
index d74e715605bb..7a17253ffd35 100755
--- a/core/java/com/android/internal/util/function/pooled/OmniFunction.java
+++ b/core/java/com/android/internal/util/function/pooled/OmniFunction.java
@@ -18,6 +18,8 @@ package com.android.internal.util.function.pooled;
import com.android.internal.util.FunctionalUtils.ThrowingRunnable;
import com.android.internal.util.FunctionalUtils.ThrowingSupplier;
+import com.android.internal.util.function.DecConsumer;
+import com.android.internal.util.function.DecFunction;
import com.android.internal.util.function.HeptConsumer;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexConsumer;
@@ -32,6 +34,8 @@ import com.android.internal.util.function.QuintConsumer;
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.TriFunction;
+import com.android.internal.util.function.UndecConsumer;
+import com.android.internal.util.function.UndecFunction;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
@@ -43,62 +47,65 @@ import java.util.function.Function;
*
* @hide
*/
-abstract class OmniFunction<A, B, C, D, E, F, G, H, I, R> implements
+abstract class OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> implements
PooledFunction<A, R>, BiFunction<A, B, R>, TriFunction<A, B, C, R>,
QuadFunction<A, B, C, D, R>, QuintFunction<A, B, C, D, E, R>,
HexFunction<A, B, C, D, E, F, R>, HeptFunction<A, B, C, D, E, F, G, R>,
OctFunction<A, B, C, D, E, F, G, H, R>, NonaFunction<A, B, C, D, E, F, G, H, I, R>,
+ DecFunction<A, B, C, D, E, F, G, H, I, J, R>,
+ UndecFunction<A, B, C, D, E, F, G, H, I, J, K, R>,
PooledConsumer<A>, BiConsumer<A, B>, TriConsumer<A, B, C>, QuadConsumer<A, B, C, D>,
QuintConsumer<A, B, C, D, E>, HexConsumer<A, B, C, D, E, F>,
HeptConsumer<A, B, C, D, E, F, G>, OctConsumer<A, B, C, D, E, F, G, H>,
- NonaConsumer<A, B, C, D, E, F, G, H, I>, PooledPredicate<A>, BiPredicate<A, B>,
- PooledSupplier<R>, PooledRunnable, ThrowingRunnable, ThrowingSupplier<R>,
- PooledSupplier.OfInt, PooledSupplier.OfLong, PooledSupplier.OfDouble {
+ NonaConsumer<A, B, C, D, E, F, G, H, I>, DecConsumer<A, B, C, D, E, F, G, H, I, J>,
+ UndecConsumer<A, B, C, D, E, F, G, H, I, J, K>,
+ PooledPredicate<A>, BiPredicate<A, B>, PooledSupplier<R>, PooledRunnable, ThrowingRunnable,
+ ThrowingSupplier<R>, PooledSupplier.OfInt, PooledSupplier.OfLong, PooledSupplier.OfDouble {
- abstract R invoke(A a, B b, C c, D d, E e, F f, G g, H h, I i);
+ abstract R invoke(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k);
@Override
public R apply(A o, B o2) {
- return invoke(o, o2, null, null, null, null, null, null, null);
+ return invoke(o, o2, null, null, null, null, null, null, null, null, null);
}
@Override
public R apply(A o) {
- return invoke(o, null, null, null, null, null, null, null, null);
+ return invoke(o, null, null, null, null, null, null, null, null, null, null);
}
- public abstract <V> OmniFunction<A, B, C, D, E, F, G, H, I, V> andThen(
+ public abstract <V> OmniFunction<A, B, C, D, E, F, G, H, I, J, K, V> andThen(
Function<? super R, ? extends V> after);
- public abstract OmniFunction<A, B, C, D, E, F, G, H, I, R> negate();
+ public abstract OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> negate();
@Override
public void accept(A o, B o2) {
- invoke(o, o2, null, null, null, null, null, null, null);
+ invoke(o, o2, null, null, null, null, null, null, null, null, null);
}
@Override
public void accept(A o) {
- invoke(o, null, null, null, null, null, null, null, null);
+ invoke(o, null, null, null, null, null, null, null, null, null, null);
}
@Override
public void run() {
- invoke(null, null, null, null, null, null, null, null, null);
+ invoke(null, null, null, null, null, null, null, null, null, null, null);
}
@Override
public R get() {
- return invoke(null, null, null, null, null, null, null, null, null);
+ return invoke(null, null, null, null, null, null, null, null, null, null, null);
}
@Override
public boolean test(A o, B o2) {
- return (Boolean) invoke(o, o2, null, null, null, null, null, null, null);
+ return (Boolean) invoke(o, o2, null, null, null, null, null, null, null, null, null);
}
@Override
public boolean test(A o) {
- return (Boolean) invoke(o, null, null, null, null, null, null, null, null);
+ return (Boolean) invoke(o, null, null, null, null, null, null, null, null, null, null);
}
@Override
@@ -113,72 +120,92 @@ abstract class OmniFunction<A, B, C, D, E, F, G, H, I, R> implements
@Override
public R apply(A a, B b, C c) {
- return invoke(a, b, c, null, null, null, null, null, null);
+ return invoke(a, b, c, null, null, null, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c) {
- invoke(a, b, c, null, null, null, null, null, null);
+ invoke(a, b, c, null, null, null, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d) {
- return invoke(a, b, c, d, null, null, null, null, null);
+ return invoke(a, b, c, d, null, null, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e) {
- return invoke(a, b, c, d, e, null, null, null, null);
+ return invoke(a, b, c, d, e, null, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f) {
- return invoke(a, b, c, d, e, f, null, null, null);
+ return invoke(a, b, c, d, e, f, null, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f, G g) {
- return invoke(a, b, c, d, e, f, g, null, null);
+ return invoke(a, b, c, d, e, f, g, null, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f, G g, H h) {
- return invoke(a, b, c, d, e, f, g, h, null);
+ return invoke(a, b, c, d, e, f, g, h, null, null, null);
}
@Override
public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i) {
- return invoke(a, b, c, d, e, f, g, h, i);
+ return invoke(a, b, c, d, e, f, g, h, i, null, null);
+ }
+
+ @Override
+ public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) {
+ return invoke(a, b, c, d, e, f, g, h, i, j, null);
+ }
+
+ @Override
+ public R apply(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) {
+ return invoke(a, b, c, d, e, f, g, h, i, j, k);
}
@Override
public void accept(A a, B b, C c, D d) {
- invoke(a, b, c, d, null, null, null, null, null);
+ invoke(a, b, c, d, null, null, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e) {
- invoke(a, b, c, d, e, null, null, null, null);
+ invoke(a, b, c, d, e, null, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f) {
- invoke(a, b, c, d, e, f, null, null, null);
+ invoke(a, b, c, d, e, f, null, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f, G g) {
- invoke(a, b, c, d, e, f, g, null, null);
+ invoke(a, b, c, d, e, f, g, null, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f, G g, H h) {
- invoke(a, b, c, d, e, f, g, h, null);
+ invoke(a, b, c, d, e, f, g, h, null, null, null);
}
@Override
public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i) {
- invoke(a, b, c, d, e, f, g, h, i);
+ invoke(a, b, c, d, e, f, g, h, i, null, null);
+ }
+
+ @Override
+ public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) {
+ invoke(a, b, c, d, e, f, g, h, i, j, null);
+ }
+
+ @Override
+ public void accept(A a, B b, C c, D d, E e, F f, G g, H h, I i, J j, K k) {
+ invoke(a, b, c, d, e, f, g, h, i, j, k);
}
@Override
@@ -192,5 +219,5 @@ abstract class OmniFunction<A, B, C, D, E, F, G, H, I, R> implements
}
@Override
- public abstract OmniFunction<A, B, C, D, E, F, G, H, I, R> recycleOnUse();
+ public abstract OmniFunction<A, B, C, D, E, F, G, H, I, J, K, R> recycleOnUse();
}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambda.java b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
index c00932e7a8aa..b9bf9337c3d6 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambda.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambda.java
@@ -21,6 +21,8 @@ import static com.android.internal.util.function.pooled.PooledLambdaImpl.acquire
import android.os.Message;
+import com.android.internal.util.function.DecConsumer;
+import com.android.internal.util.function.DecFunction;
import com.android.internal.util.function.HeptConsumer;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexConsumer;
@@ -35,6 +37,8 @@ import com.android.internal.util.function.QuintConsumer;
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.TriFunction;
+import com.android.internal.util.function.UndecConsumer;
+import com.android.internal.util.function.UndecFunction;
import com.android.internal.util.function.pooled.PooledLambdaImpl.LambdaType.ReturnType;
import java.util.function.BiConsumer;
@@ -181,7 +185,7 @@ public interface PooledLambda {
A arg1) {
return acquire(PooledLambdaImpl.sPool,
function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -198,7 +202,7 @@ public interface PooledLambda {
A arg1) {
return acquire(PooledLambdaImpl.sPool,
function, 1, 0, ReturnType.BOOLEAN, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -215,7 +219,7 @@ public interface PooledLambda {
A arg1) {
return acquire(PooledLambdaImpl.sPool,
function, 1, 0, ReturnType.OBJECT, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -246,7 +250,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 1, 0, ReturnType.VOID, arg1, null, null, null, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -266,7 +270,7 @@ public interface PooledLambda {
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -284,7 +288,7 @@ public interface PooledLambda {
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 0, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -302,7 +306,7 @@ public interface PooledLambda {
A arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 0, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -320,7 +324,7 @@ public interface PooledLambda {
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -338,7 +342,7 @@ public interface PooledLambda {
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -356,7 +360,7 @@ public interface PooledLambda {
ArgumentPlaceholder<A> arg1, B arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -374,7 +378,7 @@ public interface PooledLambda {
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -392,7 +396,7 @@ public interface PooledLambda {
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.BOOLEAN, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -410,7 +414,7 @@ public interface PooledLambda {
A arg1, ArgumentPlaceholder<B> arg2) {
return acquire(PooledLambdaImpl.sPool,
function, 2, 1, ReturnType.OBJECT, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -442,7 +446,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 2, 0, ReturnType.VOID, arg1, arg2, null, null, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -463,7 +467,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -482,7 +486,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 0, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -501,7 +505,7 @@ public interface PooledLambda {
ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -520,7 +524,7 @@ public interface PooledLambda {
ArgumentPlaceholder<A> arg1, B arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -539,7 +543,7 @@ public interface PooledLambda {
A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -558,7 +562,7 @@ public interface PooledLambda {
A arg1, ArgumentPlaceholder<B> arg2, C arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -577,7 +581,7 @@ public interface PooledLambda {
A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -596,7 +600,7 @@ public interface PooledLambda {
A arg1, B arg2, ArgumentPlaceholder<C> arg3) {
return acquire(PooledLambdaImpl.sPool,
function, 3, 1, ReturnType.OBJECT, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -629,7 +633,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 3, 0, ReturnType.VOID, arg1, arg2, arg3, null, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -651,7 +655,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -671,7 +675,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -691,7 +695,7 @@ public interface PooledLambda {
ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -711,7 +715,7 @@ public interface PooledLambda {
ArgumentPlaceholder<A> arg1, B arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -731,7 +735,7 @@ public interface PooledLambda {
A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -751,7 +755,7 @@ public interface PooledLambda {
A arg1, ArgumentPlaceholder<B> arg2, C arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -771,7 +775,7 @@ public interface PooledLambda {
A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -791,7 +795,7 @@ public interface PooledLambda {
A arg1, B arg2, ArgumentPlaceholder<C> arg3, D arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -811,7 +815,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -831,7 +835,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, ArgumentPlaceholder<D> arg4) {
return acquire(PooledLambdaImpl.sPool,
function, 4, 1, ReturnType.OBJECT, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -865,7 +869,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 4, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, null, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -888,7 +892,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, D arg4, E arg5) {
return acquire(PooledLambdaImpl.sPool,
function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -909,7 +913,7 @@ public interface PooledLambda {
function, A arg1, B arg2, C arg3, D arg4, E arg5) {
return acquire(PooledLambdaImpl.sPool,
function, 5, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, null, null, null,
- null);
+ null, null, null);
}
/**
@@ -945,7 +949,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 5, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, null, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -969,7 +973,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
return acquire(PooledLambdaImpl.sPool,
function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
- null);
+ null, null, null);
}
/**
@@ -991,7 +995,7 @@ public interface PooledLambda {
? extends R> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6) {
return acquire(PooledLambdaImpl.sPool,
function, 6, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
- null);
+ null, null, null);
}
/**
@@ -1028,7 +1032,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 6, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, null, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -1053,7 +1057,7 @@ public interface PooledLambda {
? super G> function, A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
return acquire(PooledLambdaImpl.sPool,
function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
- null);
+ null, null, null);
}
/**
@@ -1077,7 +1081,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7) {
return acquire(PooledLambdaImpl.sPool,
function, 7, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
- null);
+ null, null, null);
}
/**
@@ -1115,7 +1119,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 7, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, null,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -1142,7 +1146,7 @@ public interface PooledLambda {
H arg8) {
return acquire(PooledLambdaImpl.sPool,
function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- null);
+ null, null, null);
}
/**
@@ -1167,7 +1171,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8) {
return acquire(PooledLambdaImpl.sPool,
function, 8, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- null);
+ null, null, null);
}
/**
@@ -1207,7 +1211,7 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 8, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- null);
+ null, null, null);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
@@ -1235,7 +1239,7 @@ public interface PooledLambda {
E arg5, F arg6, G arg7, H arg8, I arg9) {
return acquire(PooledLambdaImpl.sPool,
function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- arg9);
+ arg9, null, null);
}
/**
@@ -1261,7 +1265,7 @@ public interface PooledLambda {
A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9) {
return acquire(PooledLambdaImpl.sPool,
function, 9, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- arg9);
+ arg9, null, null);
}
/**
@@ -1302,7 +1306,209 @@ public interface PooledLambda {
synchronized (Message.sPoolSync) {
PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
function, 9, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
- arg9);
+ arg9, null, null);
+ return Message.obtain().setCallback(callback.recycleOnUse());
+ }
+ }
+
+ /**
+ * {@link PooledRunnable} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @return a {@link PooledRunnable}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J> PooledRunnable obtainRunnable(
+ DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3,
+ D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, null);
+ }
+
+ /**
+ * {@link PooledSupplier} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @return a {@link PooledSupplier}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J, R> PooledSupplier<R> obtainSupplier(
+ DecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? extends R> function,
+ A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 10, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, null);
+ }
+
+ /**
+ * Factory of {@link Message}s that contain an
+ * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
+ * {@link Message#getCallback internal callback}.
+ *
+ * The callback is equivalent to one obtainable via
+ * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
+ *
+ * Note that using this method with {@link android.os.Handler#handleMessage}
+ * is more efficient than the alternative of {@link android.os.Handler#post}
+ * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
+ * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
+ *
+ * You may optionally set a {@link Message#what} for the message if you want to be
+ * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
+ * there's no need to do so
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
+ * arg7, arg8, arg9, arg10) } when handled
+ */
+ static <A, B, C, D, E, F, G, H, I, J> Message obtainMessage(
+ DecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J> function, A arg1, B arg2, C arg3,
+ D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10) {
+ synchronized (Message.sPoolSync) {
+ PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
+ function, 10, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+ arg8, arg9, arg10, null);
+ return Message.obtain().setCallback(callback.recycleOnUse());
+ }
+ }
+
+ /**
+ * {@link PooledRunnable} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @param arg11 parameter supplied to {@code function} on call
+ * @return a {@link PooledRunnable}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
+ * arg11) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J, K> PooledRunnable obtainRunnable(
+ UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2,
+ C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, arg11);
+ }
+
+ /**
+ * {@link PooledSupplier} factory
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @param arg11 parameter supplied to {@code function} on call
+ * @return a {@link PooledSupplier}, equivalent to lambda:
+ * {@code () -> function(arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10,
+ * arg11) }
+ */
+ static <A, B, C, D, E, F, G, H, I, J, K, R> PooledSupplier<R> obtainSupplier(
+ UndecFunction<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? super K, ? extends R> function,
+ A arg1, B arg2, C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10,
+ K arg11) {
+ return acquire(PooledLambdaImpl.sPool,
+ function, 11, 0, ReturnType.OBJECT, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8,
+ arg9, arg10, arg11);
+ }
+
+ /**
+ * Factory of {@link Message}s that contain an
+ * ({@link PooledLambda#recycleOnUse auto-recycling}) {@link PooledRunnable} as its
+ * {@link Message#getCallback internal callback}.
+ *
+ * The callback is equivalent to one obtainable via
+ * {@link #obtainRunnable(QuintConsumer, Object, Object, Object, Object, Object)}
+ *
+ * Note that using this method with {@link android.os.Handler#handleMessage}
+ * is more efficient than the alternative of {@link android.os.Handler#post}
+ * with a {@link PooledRunnable} due to the lack of 2 separate synchronization points
+ * when obtaining {@link Message} and {@link PooledRunnable} from pools separately
+ *
+ * You may optionally set a {@link Message#what} for the message if you want to be
+ * able to cancel it via {@link android.os.Handler#removeMessages}, but otherwise
+ * there's no need to do so
+ *
+ * @param function non-capturing lambda(typically an unbounded method reference)
+ * to be invoked on call
+ * @param arg1 parameter supplied to {@code function} on call
+ * @param arg2 parameter supplied to {@code function} on call
+ * @param arg3 parameter supplied to {@code function} on call
+ * @param arg4 parameter supplied to {@code function} on call
+ * @param arg5 parameter supplied to {@code function} on call
+ * @param arg6 parameter supplied to {@code function} on call
+ * @param arg7 parameter supplied to {@code function} on call
+ * @param arg8 parameter supplied to {@code function} on call
+ * @param arg9 parameter supplied to {@code function} on call
+ * @param arg10 parameter supplied to {@code function} on call
+ * @param arg11 parameter supplied to {@code function} on call
+ * @return a {@link Message} invoking {@code function(arg1, arg2, arg3, arg4, arg5, arg6,
+ * arg7, arg8, arg9, arg10, arg11) } when handled
+ */
+ static <A, B, C, D, E, F, G, H, I, J, K> Message obtainMessage(
+ UndecConsumer<? super A, ? super B, ? super C, ? super D, ? super E, ? super F,
+ ? super G, ? super H, ? super I, ? super J, ? super K> function, A arg1, B arg2,
+ C arg3, D arg4, E arg5, F arg6, G arg7, H arg8, I arg9, J arg10, K arg11) {
+ synchronized (Message.sPoolSync) {
+ PooledRunnable callback = acquire(PooledLambdaImpl.sMessageCallbacksPool,
+ function, 11, 0, ReturnType.VOID, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+ arg8, arg9, arg10, arg11);
return Message.obtain().setCallback(callback.recycleOnUse());
}
}
diff --git a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
index e12c031f0036..c7502ef04f1b 100755
--- a/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
+++ b/core/java/com/android/internal/util/function/pooled/PooledLambdaImpl.java
@@ -26,6 +26,9 @@ import android.util.Pools;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.BitUtils;
import com.android.internal.util.Preconditions;
+import com.android.internal.util.function.DecConsumer;
+import com.android.internal.util.function.DecFunction;
+import com.android.internal.util.function.DecPredicate;
import com.android.internal.util.function.HeptConsumer;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HeptPredicate;
@@ -47,6 +50,9 @@ import com.android.internal.util.function.QuintPredicate;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.TriFunction;
import com.android.internal.util.function.TriPredicate;
+import com.android.internal.util.function.UndecConsumer;
+import com.android.internal.util.function.UndecFunction;
+import com.android.internal.util.function.UndecPredicate;
import java.util.Arrays;
import java.util.Objects;
@@ -63,12 +69,12 @@ import java.util.function.Supplier;
* @hide
*/
final class PooledLambdaImpl<R> extends OmniFunction<Object,
- Object, Object, Object, Object, Object, Object, Object, Object, R> {
+ Object, Object, Object, Object, Object, Object, Object, Object, Object, Object, R> {
private static final boolean DEBUG = false;
private static final String LOG_TAG = "PooledLambdaImpl";
- private static final int MAX_ARGS = 9;
+ private static final int MAX_ARGS = 11;
private static final int MAX_POOL_SIZE = 50;
@@ -134,7 +140,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
/**
* Bit schema:
- * AAAAAAAAABCDEEEEEEFFFFFF
+ * AAAAAAAAAAABCDEEEEEEFFFFFF
*
* Where:
* A - whether {@link #mArgs arg} at corresponding index was specified at
@@ -171,18 +177,18 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
@Override
R invoke(Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7,
- Object a8, Object a9) {
+ Object a8, Object a9, Object a10, Object a11) {
checkNotRecycled();
if (DEBUG) {
Log.i(LOG_TAG, this + ".invoke("
+ commaSeparateFirstN(
- new Object[] { a1, a2, a3, a4, a5, a6, a7, a8, a9 },
+ new Object[] { a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 },
LambdaType.decodeArgCount(getFlags(MASK_EXPOSED_AS)))
+ ")");
}
final boolean notUsed = fillInArg(a1) && fillInArg(a2) && fillInArg(a3) && fillInArg(a4)
&& fillInArg(a5) && fillInArg(a6) && fillInArg(a7) && fillInArg(a8)
- && fillInArg(a9);
+ && fillInArg(a9) && fillInArg(a10) && fillInArg(a11);
int argCount = LambdaType.decodeArgCount(getFlags(MASK_FUNC_TYPE));
if (argCount != LambdaType.MASK_ARG_COUNT) {
for (int i = 0; i < argCount; i++) {
@@ -410,6 +416,48 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
}
}
} break;
+
+ case 10: {
+ switch (returnType) {
+ case LambdaType.ReturnType.VOID: {
+ ((DecConsumer) mFunc).accept(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9));
+ return null;
+ }
+ case LambdaType.ReturnType.BOOLEAN: {
+ return (R) (Object) ((DecPredicate) mFunc).test(popArg(0),
+ popArg(1), popArg(2), popArg(3), popArg(4),
+ popArg(5), popArg(6), popArg(7), popArg(8), popArg(9));
+ }
+ case LambdaType.ReturnType.OBJECT: {
+ return (R) ((DecFunction) mFunc).apply(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9));
+ }
+ }
+ } break;
+
+ case 11: {
+ switch (returnType) {
+ case LambdaType.ReturnType.VOID: {
+ ((UndecConsumer) mFunc).accept(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9), popArg(10));
+ return null;
+ }
+ case LambdaType.ReturnType.BOOLEAN: {
+ return (R) (Object) ((UndecPredicate) mFunc).test(popArg(0),
+ popArg(1), popArg(2), popArg(3), popArg(4),
+ popArg(5), popArg(6), popArg(7), popArg(8), popArg(9), popArg(10));
+ }
+ case LambdaType.ReturnType.OBJECT: {
+ return (R) ((UndecFunction) mFunc).apply(popArg(0), popArg(1),
+ popArg(2), popArg(3), popArg(4), popArg(5),
+ popArg(6), popArg(7), popArg(8), popArg(9), popArg(10));
+ }
+ }
+ } break;
}
throw new IllegalStateException("Unknown function type: " + LambdaType.toString(funcType));
}
@@ -475,7 +523,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
*/
static <E extends PooledLambda> E acquire(Pool pool, Object func,
int fNumArgs, int numPlaceholders, int fReturnType, Object a, Object b, Object c,
- Object d, Object e, Object f, Object g, Object h, Object i) {
+ Object d, Object e, Object f, Object g, Object h, Object i, Object j, Object k) {
PooledLambdaImpl r = acquire(pool);
if (DEBUG) {
Log.i(LOG_TAG,
@@ -493,6 +541,8 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
+ ", g = " + g
+ ", h = " + h
+ ", i = " + i
+ + ", j = " + j
+ + ", k = " + k
+ ")");
}
r.mFunc = Preconditions.checkNotNull(func);
@@ -508,6 +558,8 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
setIfInBounds(r.mArgs, 6, g);
setIfInBounds(r.mArgs, 7, h);
setIfInBounds(r.mArgs, 8, i);
+ setIfInBounds(r.mArgs, 9, j);
+ setIfInBounds(r.mArgs, 10, k);
return (E) r;
}
@@ -564,13 +616,13 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
@Override
public OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object,
- R> negate() {
+ Object, Object, R> negate() {
throw new UnsupportedOperationException();
}
@Override
public <V> OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object,
- V> andThen(Function<? super R, ? extends V> after) {
+ Object, Object, V> andThen(Function<? super R, ? extends V> after) {
throw new UnsupportedOperationException();
}
@@ -591,7 +643,7 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
@Override
public OmniFunction<Object, Object, Object, Object, Object, Object, Object, Object, Object,
- R> recycleOnUse() {
+ Object, Object, R> recycleOnUse() {
if (DEBUG) Log.i(LOG_TAG, this + ".recycleOnUse()");
mFlags |= FLAG_RECYCLE_ON_USE;
return this;
@@ -683,6 +735,8 @@ final class PooledLambdaImpl<R> extends OmniFunction<Object,
case 7: return "Hept";
case 8: return "Oct";
case 9: return "Nona";
+ case 10: return "Dec";
+ case 11: return "Undec";
default: return "" + argCount + "arg";
}
}
diff --git a/core/jni/android_os_Debug.cpp b/core/jni/android_os_Debug.cpp
index cbb74dff0e49..9445319e47ec 100644
--- a/core/jni/android_os_Debug.cpp
+++ b/core/jni/android_os_Debug.cpp
@@ -321,6 +321,9 @@ static void load_maps(int pid, stats_t* stats, bool* foundSwapPss)
} else if (base::StartsWith(name, "/memfd:jit-cache")) {
which_heap = HEAP_DALVIK_OTHER;
sub_heap = HEAP_DALVIK_OTHER_APP_CODE_CACHE;
+ } else if (base::StartsWith(name, "/memfd:jit-zygote-cache")) {
+ which_heap = HEAP_DALVIK_OTHER;
+ sub_heap = HEAP_DALVIK_OTHER_ZYGOTE_CODE_CACHE;
} else if (base::StartsWith(name, "[anon:")) {
which_heap = HEAP_UNKNOWN;
if (base::StartsWith(name, "[anon:dalvik-")) {
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 8aa6f860aa61..3cefeea68406 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -191,9 +191,21 @@ jint android_os_Process_getGidForName(JNIEnv* env, jobject clazz, jstring name)
return -1;
}
+static bool verifyGroup(JNIEnv* env, int grp)
+{
+ if (grp < SP_DEFAULT || grp >= SP_CNT) {
+ signalExceptionForError(env, EINVAL, grp);
+ return false;
+ }
+ return true;
+}
+
void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int tid, jint grp)
{
ALOGV("%s tid=%d grp=%" PRId32, __func__, tid, grp);
+ if (!verifyGroup(env, grp)) {
+ return;
+ }
SchedPolicy sp = (SchedPolicy) grp;
int res = set_sched_policy(tid, sp);
if (res != NO_ERROR) {
@@ -204,6 +216,9 @@ void android_os_Process_setThreadGroup(JNIEnv* env, jobject clazz, int tid, jint
void android_os_Process_setThreadGroupAndCpuset(JNIEnv* env, jobject clazz, int tid, jint grp)
{
ALOGV("%s tid=%d grp=%" PRId32, __func__, tid, grp);
+ if (!verifyGroup(env, grp)) {
+ return;
+ }
SchedPolicy sp = (SchedPolicy) grp;
int res = set_sched_policy(tid, sp);
@@ -234,6 +249,9 @@ void android_os_Process_setProcessGroup(JNIEnv* env, jobject clazz, int pid, jin
grp = SP_FOREGROUND;
isDefault = true;
}
+ if (!verifyGroup(env, grp)) {
+ return;
+ }
SchedPolicy sp = (SchedPolicy) grp;
if (kDebugPolicy) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 7a0d0cbe6095..7ce370ff52be 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -794,6 +794,18 @@
android:permissionFlags="hardRestricted"
android:protectionLevel="dangerous" />
+ <!-- @SystemApi @TestApi Allows an application to forward cell broadcast messages to the cell
+ broadcast module. This is required in order to bind to the cell broadcast service, and
+ ensures that only the system can forward messages to it.
+
+ <p>Protection level: signature|privileged
+
+ @hide -->
+ <permission android:name="android.permission.BIND_CELL_BROADCAST_SERVICE"
+ android:label="@string/permlab_bindCellBroadcastService"
+ android:description="@string/permdesc_bindCellBroadcastService"
+ android:protectionLevel="signature" />
+
<!-- @SystemApi @TestApi Allows an application to read previously received cell broadcast
messages and to register a content observer to get notifications when
a cell broadcast has been received and added to the database. For
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e3337b7f9ae5..7eca699d9eca 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -433,6 +433,10 @@
-->
</string-array>
+ <!-- Package name for the default CellBroadcastService module [DO NOT TRANSLATE] -->
+ <string name="cellbroadcast_default_package" translatable="false">com.android.cellbroadcastreceiver
+ </string>
+
<!-- If the mobile hotspot feature requires provisioning, a package name and class name
can be provided to launch a supported application that provisions the devices.
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index b53a399f0c8a..4e327082047b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -890,6 +890,16 @@
messages. This means the app could monitor or delete messages sent to your
device without showing them to you.</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this.[CHAR LIMIT=NONE] -->
+ <string name="permlab_bindCellBroadcastService">Forward cell broadcast messages</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_bindCellBroadcastService">Allows the app to bind to the
+ cell broadcast module in order to forward cell broadcast messages
+ as they are received. Cell broadcast alerts are delivered in some
+ locations to warn you of emergency situations. Malicious apps may
+ interfere with the performance or operation of your device when an
+ emergency cell broadcast is received.</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_readCellBroadcasts">read cell broadcast messages</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e2f2b2c64b77..a8b534061aeb 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -747,6 +747,7 @@
<java-symbol type="string" name="config_default_dns_server" />
<java-symbol type="string" name="config_ethernet_iface_regex" />
<java-symbol type="array" name="config_ethernet_interfaces" />
+ <java-symbol type="string" name="cellbroadcast_default_package" />
<java-symbol type="string" name="config_forceVoiceInteractionServicePackage" />
<java-symbol type="string" name="config_mms_user_agent" />
<java-symbol type="string" name="config_mms_user_agent_profile_url" />
diff --git a/core/tests/bugreports/Android.bp b/core/tests/bugreports/Android.bp
index d3bf0dd7a7e8..e9d5bb135e02 100644
--- a/core/tests/bugreports/Android.bp
+++ b/core/tests/bugreports/Android.bp
@@ -20,7 +20,6 @@ android_test {
"android.test.base",
],
static_libs: ["androidx.test.rules", "truth-prebuilt"],
- test_suites: ["general-tests"],
sdk_version: "test_current",
platform_apis: true,
}
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
index 682416c58c72..3586216ad421 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityServiceConnectionImpl.java
@@ -23,8 +23,6 @@ import android.graphics.Region;
import android.os.Bundle;
import android.os.IBinder;
-import java.util.List;
-
/**
* Stub implementation of IAccessibilityServiceConnection so each test doesn't need to implement
* all of the methods
@@ -73,7 +71,7 @@ public class AccessibilityServiceConnectionImpl extends IAccessibilityServiceCon
return null;
}
- public List<AccessibilityWindowInfo> getWindows() {
+ public AccessibilityWindowInfo.WindowListSparseArray getWindows() {
return null;
}
diff --git a/data/etc/hiddenapi-package-whitelist.xml b/data/etc/hiddenapi-package-whitelist.xml
index 054f68ba9e5c..f1ba3f6f7859 100644
--- a/data/etc/hiddenapi-package-whitelist.xml
+++ b/data/etc/hiddenapi-package-whitelist.xml
@@ -53,6 +53,10 @@ Do NOT include any apps that are updatable via Play Store!
<hidden-api-whitelisted-app package="com.android.providers.media" />
<hidden-api-whitelisted-app package="com.android.providers.tv" />
<hidden-api-whitelisted-app package="com.android.providers.userdictionary" />
+ <!-- TODO (b/141954427): Remove networkstack -->
+ <hidden-api-whitelisted-app package="com.android.networkstack" />
+ <!-- TODO (b/141954427): Remove wifistack -->
+ <hidden-api-whitelisted-app package="com.android.server.wifistack" />
<hidden-api-whitelisted-app package="com.android.smspush" />
<hidden-api-whitelisted-app package="com.android.spare_parts" />
<hidden-api-whitelisted-app package="com.android.statementservice" />
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 89523d6bbefb..51136b993e57 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -127,6 +127,7 @@ applications that come with the platform
<permission name="android.permission.ACCESS_IMS_CALL_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_MESSAGING_SERVICE"/>
<permission name="android.permission.BIND_CARRIER_SERVICES"/>
+ <permission name="android.permission.BIND_CELL_BROADCAST_SERVICE"/>
<permission name="android.permission.BIND_IMS_SERVICE"/>
<permission name="android.permission.BIND_TELEPHONY_DATA_SERVICE"/>
<permission name="android.permission.BIND_VISUAL_VOICEMAIL_SERVICE"/>
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 68480ced0692..f3d68755a513 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -940,9 +940,8 @@ public class LocationManager {
@Nullable LocationRequest locationRequest,
@NonNull LocationListener listener,
@Nullable Looper looper) {
- requestLocationUpdates(locationRequest,
- new LocationListenerTransport(looper == null ? new Handler() : new Handler(looper),
- listener));
+ Handler handler = looper == null ? new Handler() : new Handler(looper);
+ requestLocationUpdates(locationRequest, new HandlerExecutor(handler), listener);
}
/**
@@ -969,7 +968,31 @@ public class LocationManager {
@Nullable LocationRequest locationRequest,
@NonNull @CallbackExecutor Executor executor,
@NonNull LocationListener listener) {
- requestLocationUpdates(locationRequest, new LocationListenerTransport(executor, listener));
+ synchronized (mListeners) {
+ LocationListenerTransport transport = mListeners.get(listener);
+ if (transport != null) {
+ transport.unregister();
+ } else {
+ transport = new LocationListenerTransport(listener);
+ mListeners.put(listener, transport);
+ }
+ transport.register(executor);
+
+ boolean registered = false;
+ try {
+ mService.requestLocationUpdates(locationRequest, transport, null,
+ mContext.getPackageName());
+ registered = true;
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ } finally {
+ if (!registered) {
+ // allow gc after exception
+ transport.unregister();
+ mListeners.remove(listener);
+ }
+ }
+ }
}
/**
@@ -1009,23 +1032,6 @@ public class LocationManager {
}
}
- private void requestLocationUpdates(@Nullable LocationRequest request,
- @NonNull LocationListenerTransport transport) {
- synchronized (mListeners) {
- LocationListenerTransport oldTransport = mListeners.put(transport.getKey(), transport);
- if (oldTransport != null) {
- oldTransport.unregisterListener();
- }
-
- try {
- mService.requestLocationUpdates(request, transport, null,
- mContext.getPackageName());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- }
-
/**
* Set the last known location with a new location.
*
@@ -1079,7 +1085,7 @@ public class LocationManager {
if (transport == null) {
return;
}
- transport.unregisterListener();
+ transport.unregister();
try {
mService.removeUpdates(transport, null, mContext.getPackageName());
@@ -2237,49 +2243,45 @@ public class LocationManager {
private class LocationListenerTransport extends ILocationListener.Stub {
- private final Executor mExecutor;
- @Nullable private volatile LocationListener mListener;
+ private final LocationListener mListener;
+ @Nullable private volatile Executor mExecutor = null;
- private LocationListenerTransport(@NonNull Handler handler,
- @NonNull LocationListener listener) {
- Preconditions.checkArgument(handler != null, "invalid null handler");
+ private LocationListenerTransport(@NonNull LocationListener listener) {
Preconditions.checkArgument(listener != null, "invalid null listener");
-
- mExecutor = new HandlerExecutor(handler);
mListener = listener;
}
- private LocationListenerTransport(@NonNull Executor executor,
- @NonNull LocationListener listener) {
- Preconditions.checkArgument(executor != null, "invalid null executor");
- Preconditions.checkArgument(listener != null, "invalid null listener");
-
- mExecutor = executor;
- mListener = listener;
+ public LocationListener getKey() {
+ return mListener;
}
- private LocationListener getKey() {
- return mListener;
+ public void register(@NonNull Executor executor) {
+ Preconditions.checkArgument(executor != null, "invalid null executor");
+ mExecutor = executor;
}
- private void unregisterListener() {
- mListener = null;
+ public void unregister() {
+ mExecutor = null;
}
@Override
public void onLocationChanged(Location location) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onLocationChanged(location);
+ mListener.onLocationChanged(location);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2295,18 +2297,22 @@ public class LocationManager {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onStatusChanged(provider, status, extras);
+ mListener.onStatusChanged(provider, status, extras);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2322,18 +2328,22 @@ public class LocationManager {
@Override
public void onProviderEnabled(String provider) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onProviderEnabled(provider);
+ mListener.onProviderEnabled(provider);
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -2349,18 +2359,22 @@ public class LocationManager {
@Override
public void onProviderDisabled(String provider) {
+ Executor currentExecutor = mExecutor;
+ if (currentExecutor == null) {
+ return;
+ }
+
try {
- mExecutor.execute(() -> {
+ currentExecutor.execute(() -> {
try {
- LocationListener listener = mListener;
- if (listener == null) {
+ if (currentExecutor != mExecutor) {
return;
}
// we may be under the binder identity if a direct executor is used
long identity = Binder.clearCallingIdentity();
try {
- listener.onProviderDisabled(provider);
+ mListener.onProviderDisabled(provider);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/media/java/android/media/IMediaRouterService.aidl b/media/java/android/media/IMediaRouterService.aidl
index 1b713b6ab74b..81213b943c81 100644
--- a/media/java/android/media/IMediaRouterService.aidl
+++ b/media/java/android/media/IMediaRouterService.aidl
@@ -40,6 +40,7 @@ interface IMediaRouterService {
void setSelectedRoute(IMediaRouterClient client, String routeId, boolean explicit);
void requestSetVolume(IMediaRouterClient client, String routeId, int volume);
void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction);
+ void setControlCategories(IMediaRouterClient client, in List<String> categories);
// Methods for media router 2
void registerClient2(IMediaRouter2Client client, String packageName);
@@ -52,7 +53,7 @@ interface IMediaRouterService {
* @param route the route to be selected
*/
void selectRoute2(IMediaRouter2Client client, in @nullable MediaRoute2Info route);
- void setControlCategories(IMediaRouter2Client client, in List<String> categories);
+ void setControlCategories2(IMediaRouter2Client client, in List<String> categories);
void registerManager(IMediaRouter2Manager manager, String packageName);
void unregisterManager(IMediaRouter2Manager manager);
diff --git a/media/java/android/media/MediaFile.java b/media/java/android/media/MediaFile.java
index 8887c7c57ccb..09221a37cb13 100644
--- a/media/java/android/media/MediaFile.java
+++ b/media/java/android/media/MediaFile.java
@@ -23,7 +23,7 @@ import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.mtp.MtpConstants;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.util.HashMap;
diff --git a/media/java/android/media/MediaRouter.java b/media/java/android/media/MediaRouter.java
index d72231f40dcf..9cb78696f19b 100644
--- a/media/java/android/media/MediaRouter.java
+++ b/media/java/android/media/MediaRouter.java
@@ -49,6 +49,8 @@ import android.view.Display;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Objects;
@@ -82,6 +84,7 @@ public class MediaRouter {
final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
final ArrayList<RouteCategory> mCategories = new ArrayList<RouteCategory>();
+ List<String> mControlCategories = Collections.emptyList();
final RouteCategory mSystemCategory;
@@ -358,6 +361,18 @@ public class MediaRouter {
return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
}
+ public void setControlCategories(Collection<String> controlCategories) {
+ List<String> newControlCategories = new ArrayList<>(controlCategories);
+ mControlCategories = newControlCategories;
+ if (mClient != null) {
+ try {
+ mMediaRouterService.setControlCategories(mClient, newControlCategories);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Unable to set control categories.", ex);
+ }
+ }
+ }
+
private void updatePresentationDisplays(int changedDisplayId) {
final int count = mRoutes.size();
for (int i = 0; i < count; i++) {
@@ -406,6 +421,7 @@ public class MediaRouter {
try {
Client client = new Client();
mMediaRouterService.registerClientAsUser(client, mPackageName, userId);
+ mMediaRouterService.setControlCategories(client, mControlCategories);
mClient = client;
} catch (RemoteException ex) {
Log.e(TAG, "Unable to register media router client.", ex);
@@ -1302,6 +1318,19 @@ public class MediaRouter {
sStatic.rebindAsUser(userId);
}
+ /**
+ * Sets the control categories of the application.
+ * Routes that support at least one of the given control categories only exists and are handled
+ * by the media router.
+ *
+ * @hide
+ */
+ public void setControlCategories(@NonNull Collection<String> controlCategories) {
+ Objects.requireNonNull(controlCategories, "control categories must not be null");
+
+ sStatic.setControlCategories(controlCategories);
+ }
+
static void updateRoute(final RouteInfo info) {
dispatchRouteChanged(info);
}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 8e29e34caa14..ed35ef6a7ac7 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -129,7 +129,7 @@ public class MediaRouter2 {
Client client = new Client();
try {
mMediaRouterService.registerClient2(client, mPackageName);
- mMediaRouterService.setControlCategories(client, mControlCategories);
+ mMediaRouterService.setControlCategories2(client, mControlCategories);
mClient = client;
} catch (RemoteException ex) {
Log.e(TAG, "Unable to register media router.", ex);
@@ -188,7 +188,7 @@ public class MediaRouter2 {
}
if (client != null) {
try {
- mMediaRouterService.setControlCategories(client, newControlCategories);
+ mMediaRouterService.setControlCategories2(client, newControlCategories);
} catch (RemoteException ex) {
Log.e(TAG, "Unable to set control categories.", ex);
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
index 38f0175579ad..481f4796951d 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/MediaFileTest.java
@@ -31,7 +31,7 @@ import android.mtp.MtpConstants;
import androidx.test.runner.AndroidJUnit4;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import org.junit.Test;
import org.junit.runner.RunWith;
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
index 3abf0a4941e6..a3ed07a6dee3 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouterManagerTest.java
@@ -27,6 +27,7 @@ import static org.mockito.Mockito.verify;
import android.content.Context;
import android.content.Intent;
import android.media.MediaRoute2Info;
+import android.media.MediaRouter;
import android.media.MediaRouter2;
import android.media.MediaRouter2Manager;
import android.support.test.InstrumentationRegistry;
@@ -72,7 +73,8 @@ public class MediaRouterManagerTest {
private Context mContext;
private MediaRouter2Manager mManager;
- private MediaRouter2 mRouter;
+ private MediaRouter mRouter;
+ private MediaRouter2 mRouter2;
private Executor mExecutor;
private String mPackageName;
@@ -89,7 +91,8 @@ public class MediaRouterManagerTest {
public void setUp() throws Exception {
mContext = InstrumentationRegistry.getTargetContext();
mManager = MediaRouter2Manager.getInstance(mContext);
- mRouter = MediaRouter2.getInstance(mContext);
+ mRouter = (MediaRouter) mContext.getSystemService(Context.MEDIA_ROUTER_SERVICE);
+ mRouter2 = MediaRouter2.getInstance(mContext);
//TODO: If we need to support thread pool executors, change this to thread pool executor.
mExecutor = Executors.newSingleThreadExecutor();
mPackageName = mContext.getPackageName();
@@ -131,12 +134,12 @@ public class MediaRouterManagerTest {
//TODO: Figure out a more proper way to test.
// (Control requests shouldn't be used in this way.)
- mRouter.setControlCategories(CONTROL_CATEGORIES_ALL);
- mRouter.registerCallback(mExecutor, mockRouterCallback);
- mRouter.sendControlRequest(
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_ALL);
+ mRouter2.registerCallback(mExecutor, mockRouterCallback);
+ mRouter2.sendControlRequest(
new MediaRoute2Info.Builder(ROUTE_ID2, ROUTE_NAME2).build(),
new Intent(ACTION_REMOVE_ROUTE));
- mRouter.unregisterCallback(mockRouterCallback);
+ mRouter2.unregisterCallback(mockRouterCallback);
verify(mockCallback, timeout(TIMEOUT_MS)).onRouteRemoved(argThat(
(MediaRoute2Info info) ->
@@ -148,15 +151,41 @@ public class MediaRouterManagerTest {
* Tests if we get proper routes for application that has special control category.
*/
@Test
+ public void testControlCategoryWithMediaRouter() throws Exception {
+ MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
+ mManager.registerCallback(mExecutor, mockCallback);
+
+ MediaRouter.Callback mockRouterCallback = mock(MediaRouter.Callback.class);
+
+ mRouter.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
+ mRouter.addCallback(MediaRouter.ROUTE_TYPE_USER, mockRouterCallback);
+
+ verify(mockCallback, timeout(TIMEOUT_MS))
+ .onRoutesChanged(argThat(routes -> routes.size() > 0));
+
+ Map<String, MediaRoute2Info> routes =
+ createRouteMap(mManager.getAvailableRoutes(mPackageName));
+
+ Assert.assertEquals(1, routes.size());
+ Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
+
+ mRouter.removeCallback(mockRouterCallback);
+ mManager.unregisterCallback(mockCallback);
+ }
+
+ /**
+ * Tests if we get proper routes for application that has special control category.
+ */
+ @Test
public void testControlCategory() throws Exception {
MediaRouter2Manager.Callback mockCallback = mock(MediaRouter2Manager.Callback.class);
mManager.registerCallback(mExecutor, mockCallback);
MediaRouter2.Callback mockRouterCallback = mock(MediaRouter2.Callback.class);
- mRouter.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
- mRouter.registerCallback(mExecutor, mockRouterCallback);
- mRouter.unregisterCallback(mockRouterCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
+ mRouter2.registerCallback(mExecutor, mockRouterCallback);
+ mRouter2.unregisterCallback(mockRouterCallback);
verify(mockCallback, timeout(TIMEOUT_MS))
.onRoutesChanged(argThat(routes -> routes.size() > 0));
@@ -177,15 +206,15 @@ public class MediaRouterManagerTest {
public void testGetRoutes() throws Exception {
MediaRouter2.Callback mockCallback = mock(MediaRouter2.Callback.class);
- mRouter.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
- mRouter.registerCallback(mExecutor, mockCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_SPECIAL);
+ mRouter2.registerCallback(mExecutor, mockCallback);
verify(mockCallback, timeout(TIMEOUT_MS).atLeastOnce())
.onRoutesChanged(argThat(routes -> routes.size() > 0));
- Map<String, MediaRoute2Info> routes = createRouteMap(mRouter.getRoutes());
+ Map<String, MediaRoute2Info> routes = createRouteMap(mRouter2.getRoutes());
Assert.assertEquals(1, routes.size());
Assert.assertNotNull(routes.get(ROUTE_ID_SPECIAL_CATEGORY));
- mRouter.unregisterCallback(mockCallback);
+ mRouter2.unregisterCallback(mockCallback);
}
@Test
@@ -194,8 +223,8 @@ public class MediaRouterManagerTest {
MediaRouter2Manager.Callback managerCallback = mock(MediaRouter2Manager.Callback.class);
mManager.registerCallback(mExecutor, managerCallback);
- mRouter.setControlCategories(CONTROL_CATEGORIES_ALL);
- mRouter.registerCallback(mExecutor, mockRouterCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_ALL);
+ mRouter2.registerCallback(mExecutor, mockRouterCallback);
verify(managerCallback, timeout(TIMEOUT_MS))
.onRoutesChanged(argThat(routes -> routes.size() > 0));
@@ -211,7 +240,7 @@ public class MediaRouterManagerTest {
.onRouteAdded(argThat(route -> route.equals(routeToSelect)));
mManager.unregisterCallback(managerCallback);
- mRouter.unregisterCallback(mockRouterCallback);
+ mRouter2.unregisterCallback(mockRouterCallback);
}
/**
@@ -223,8 +252,8 @@ public class MediaRouterManagerTest {
MediaRouter2.Callback routerCallback = mock(MediaRouter2.Callback.class);
mManager.registerCallback(mExecutor, managerCallback);
- mRouter.setControlCategories(CONTROL_CATEGORIES_ALL);
- mRouter.registerCallback(mExecutor, routerCallback);
+ mRouter2.setControlCategories(CONTROL_CATEGORIES_ALL);
+ mRouter2.registerCallback(mExecutor, routerCallback);
verify(managerCallback, timeout(TIMEOUT_MS))
.onRoutesChanged(argThat(routes -> routes.size() > 0));
@@ -248,7 +277,7 @@ public class MediaRouterManagerTest {
.onRouteChanged(argThat(routeInfo -> TextUtils.equals(ROUTE_ID2, routeInfo.getId())
&& TextUtils.equals(routeInfo.getClientPackageName(), null)));
- mRouter.unregisterCallback(routerCallback);
+ mRouter2.unregisterCallback(routerCallback);
mManager.unregisterCallback(managerCallback);
}
diff --git a/mime/java/android/content/type/DefaultMimeMapFactory.java b/mime/java/android/content/type/DefaultMimeMapFactory.java
index 13039a4ab1e2..03b685df644e 100644
--- a/mime/java/android/content/type/DefaultMimeMapFactory.java
+++ b/mime/java/android/content/type/DefaultMimeMapFactory.java
@@ -16,7 +16,7 @@
package android.content.type;
-import libcore.net.MimeMap;
+import libcore.content.type.MimeMap;
import java.io.BufferedReader;
import java.io.IOException;
diff --git a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
index 9a063aa7b791..5ec1baee5b14 100644
--- a/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
+++ b/packages/CarSystemUI/src/com/android/systemui/CarSystemUIModule.java
@@ -29,6 +29,7 @@ import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.EnhancedEstimatesImpl;
import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationLockscreenUserManagerImpl;
+import com.android.systemui.statusbar.car.CarStatusBar;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
import com.android.systemui.statusbar.notification.collection.NotificationData;
@@ -42,6 +43,8 @@ import javax.inject.Singleton;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
@Module
abstract class CarSystemUIModule {
@@ -94,4 +97,9 @@ abstract class CarSystemUIModule {
@Binds
abstract SystemUIRootComponent bindSystemUIRootComponent(
CarSystemUIRootComponent systemUIRootComponent);
+
+ @Binds
+ @IntoMap
+ @ClassKey(StatusBar.class)
+ public abstract SystemUI providesStatusBar(CarStatusBar statusBar);
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
index a107dd793551..c205bb49228c 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarNotificationEntryManager.java
@@ -15,11 +15,11 @@
*/
package com.android.systemui.car;
-import android.content.Context;
import android.service.notification.NotificationListenerService;
import android.service.notification.StatusBarNotification;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.collection.NotificationData;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -34,8 +34,8 @@ import javax.inject.Singleton;
public class CarNotificationEntryManager extends NotificationEntryManager {
@Inject
- public CarNotificationEntryManager(Context context) {
- super(context);
+ public CarNotificationEntryManager(NotificationData notificationData) {
+ super(notificationData);
}
@Override
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
index b0ab5b49f340..d21f09ce160a 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarStatusBar.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.car;
+import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
@@ -34,6 +36,7 @@ import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.InputMethodService;
import android.os.IBinder;
+import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.GestureDetector;
@@ -57,36 +60,83 @@ import com.android.car.notification.NotificationClickHandlerFactory;
import com.android.car.notification.NotificationDataManager;
import com.android.car.notification.NotificationViewController;
import com.android.car.notification.PreprocessingManager;
+import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.BatteryMeterView;
import com.android.systemui.CarSystemUIFactory;
import com.android.systemui.Dependency;
+import com.android.systemui.ForegroundServiceController;
import com.android.systemui.Prefs;
import com.android.systemui.R;
import com.android.systemui.SystemUIFactory;
+import com.android.systemui.UiOffloadThread;
+import com.android.systemui.appops.AppOpsController;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.broadcast.BroadcastDispatcher;
+import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.classifier.FalsingLog;
+import com.android.systemui.colorextraction.SysuiColorExtractor;
+import com.android.systemui.doze.DozeLog;
import com.android.systemui.fragments.FragmentHostManager;
+import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
+import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.qs.car.CarQSFragment;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.statusbar.NavigationBarController;
+import com.android.systemui.statusbar.NotificationListener;
+import com.android.systemui.statusbar.NotificationLockscreenUserManager;
+import com.android.systemui.statusbar.NotificationMediaManager;
+import com.android.systemui.statusbar.NotificationRemoteInputManager;
+import com.android.systemui.statusbar.NotificationViewHierarchyManager;
+import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.StatusBarState;
+import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.car.hvac.HvacController;
import com.android.systemui.statusbar.car.hvac.TemperatureView;
+import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotifPipelineInitializer;
+import com.android.systemui.statusbar.notification.NotificationAlertingManager;
+import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationInterruptionStateProvider;
+import com.android.systemui.statusbar.notification.NotificationWakeUpCoordinator;
+import com.android.systemui.statusbar.notification.VisualStabilityManager;
+import com.android.systemui.statusbar.notification.logging.NotificationLogger;
+import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
+import com.android.systemui.statusbar.phone.AutoHideController;
import com.android.systemui.statusbar.phone.CollapsedStatusBarFragment;
+import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
+import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.statusbar.phone.LightBarController;
+import com.android.systemui.statusbar.phone.NotificationGroupAlertTransferHelper;
+import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.StatusBar;
+import com.android.systemui.statusbar.phone.StatusBarIconController;
+import com.android.systemui.statusbar.phone.StatusBarWindowController;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
+import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
+import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.Map;
+import javax.inject.Inject;
+import javax.inject.Named;
+
/**
* A status bar (and navigation bar) tailored for the automotive use case.
*/
@@ -175,6 +225,8 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
private boolean mHideNavBarForKeyboard;
private boolean mBottomNavBarVisible;
+ private final NavigationBarController mNavigationBarController;
+
private final CarPowerStateListener mCarPowerStateListener =
(int state) -> {
// When the car powers on, clear all notifications and mute/unread states.
@@ -189,6 +241,116 @@ public class CarStatusBar extends StatusBar implements CarBatteryController.Batt
}
};
+ @Inject
+ public CarStatusBar(
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ DozeLog dozeLog,
+ InjectionInflationController injectionInflationController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowNotificationLongPress,
+ NotifPipelineInitializer notifPipelineInitializer,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationEntryManager notificationEntryManager,
+ NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ ForegroundServiceController foregroundServiceController,
+ AppOpsController appOpsController,
+ KeyguardViewMediator keyguardViewMediator,
+ ZenModeController zenModeController,
+ NotificationAlertingManager notificationAlertingManager,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ UiOffloadThread uiOffloadThread,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ NotificationGroupAlertTransferHelper groupAlertTransferHelper,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ AssistManager assistManager,
+ NotificationListener notificationListener,
+ ConfigurationController configurationController,
+ StatusBarWindowController statusBarWindowController) {
+ super(
+ lightBarController,
+ autoHideController,
+ keyguardUpdateMonitor,
+ statusBarIconController,
+ dozeLog,
+ injectionInflationController,
+ pulseExpansionHandler,
+ notificationWakeUpCoordinator,
+ keyguardBypassController,
+ keyguardStateController,
+ headsUpManagerPhone,
+ dynamicPrivacyController,
+ bypassHeadsUpNotifier,
+ allowNotificationLongPress,
+ notifPipelineInitializer,
+ falsingManager,
+ broadcastDispatcher,
+ remoteInputQuickSettingsDisabler,
+ notificationGutsManager,
+ notificationLogger,
+ notificationEntryManager,
+ notificationInterruptionStateProvider,
+ notificationViewHierarchyManager,
+ foregroundServiceController,
+ appOpsController,
+ keyguardViewMediator,
+ zenModeController,
+ notificationAlertingManager,
+ displayMetrics,
+ metricsLogger,
+ uiOffloadThread,
+ notificationMediaManager,
+ lockScreenUserManager,
+ remoteInputManager,
+ userSwitcherController,
+ networkController,
+ batteryController,
+ colorExtractor,
+ screenLifecycle,
+ wakefulnessLifecycle,
+ statusBarStateController,
+ vibratorHelper,
+ bubbleController,
+ groupManager,
+ groupAlertTransferHelper,
+ visualStabilityManager,
+ deviceProvisionedController,
+ navigationBarController,
+ assistManager,
+ notificationListener,
+ configurationController,
+ statusBarWindowController);
+ mNavigationBarController = navigationBarController;
+ }
+
@Override
public void start() {
// get the provisioned state before calling the parent class since it's that flow that
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
index ea39317fb045..81ca9eaf8e36 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationAccesses.java
@@ -111,8 +111,9 @@ public class RecentLocationAccesses {
for (int op : LOCATION_OPS) {
final String permission = AppOpsManager.opToPermission(op);
final int permissionFlags = pm.getPermissionFlags(permission, packageName, user);
- if (PermissionChecker.checkPermission(mContext, permission, -1, uid, packageName)
- == PermissionChecker.PERMISSION_GRANTED) {
+ if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+ PermissionChecker.PID_UNKNOWN, uid, packageName)
+ == PermissionChecker.PERMISSION_GRANTED) {
if ((permissionFlags
& PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED) == 0) {
showApp = false;
diff --git a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
index 60c9984e5ed4..104cc8f9841c 100644
--- a/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
+++ b/packages/SettingsLib/src/com/android/settingslib/location/RecentLocationApps.java
@@ -110,9 +110,9 @@ public class RecentLocationApps {
final String permission = AppOpsManager.opToPermission(op);
final int permissionFlags = pm.getPermissionFlags(permission, packageName,
user);
- if (PermissionChecker.checkPermission(mContext, permission, -1, uid,
- packageName)
- == PermissionChecker.PERMISSION_GRANTED) {
+ if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+ PermissionChecker.PID_UNKNOWN, uid, packageName)
+ == PermissionChecker.PERMISSION_GRANTED) {
if ((permissionFlags
& PackageManager.FLAG_PERMISSION_USER_SENSITIVE_WHEN_GRANTED)
== 0) {
diff --git a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
index 8c2e43170cc2..b8372adfa074 100644
--- a/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
+++ b/packages/SettingsProvider/src/android/provider/settings/backup/SecureSettings.java
@@ -114,7 +114,6 @@ public class SecureSettings {
Settings.Secure.ASSIST_GESTURE_WAKE_ENABLED,
Settings.Secure.VR_DISPLAY_MODE,
Settings.Secure.NOTIFICATION_BADGING,
- Settings.Secure.NOTIFICATION_BUBBLES,
Settings.Secure.NOTIFICATION_DISMISS_RTL,
Settings.Secure.QS_AUTO_ADDED_TILES,
Settings.Secure.SCREENSAVER_ENABLED,
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
index f160edc6e446..976f3365ab98 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SecureSettingsValidators.java
@@ -157,7 +157,6 @@ public class SecureSettingsValidators {
VALIDATORS.put(Secure.ASSIST_GESTURE_WAKE_ENABLED, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.VR_DISPLAY_MODE, new DiscreteValueValidator(new String[] {"0", "1"}));
VALIDATORS.put(Secure.NOTIFICATION_BADGING, BOOLEAN_VALIDATOR);
- VALIDATORS.put(Secure.NOTIFICATION_BUBBLES, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.NOTIFICATION_DISMISS_RTL, BOOLEAN_VALIDATOR);
VALIDATORS.put(Secure.QS_AUTO_ADDED_TILES, TILE_LIST_VALIDATOR);
VALIDATORS.put(Secure.SCREENSAVER_ENABLED, BOOLEAN_VALIDATOR);
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 720266a72423..16c96e67c85a 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -4385,8 +4385,7 @@ public class SettingsProvider extends ContentProvider {
if (currentVersion == 182) {
// Remove secure bubble settings.
- getSecureSettingsLocked(userId).deleteSettingLocked(
- Secure.NOTIFICATION_BUBBLES);
+ getSecureSettingsLocked(userId).deleteSettingLocked("notification_bubbles");
// Add global bubble settings.
getGlobalSettingsLocked().insertSettingLocked(Global.NOTIFICATION_BUBBLES,
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index a8ce196cc359..a3d420ee4cdf 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -104,12 +104,6 @@ it should be shown.
Shows the drag handle for the divider between two apps when in split screen
mode.
-### [com.android.systemui.SystemBars](/packages/SystemUI/src/com/android/systemui/SystemBars.java)
-
-This is a proxy to the actual SystemUI for the status bar. This loads from
-config_statusBarComponent which defaults to StatusBar. (maybe this should be
-removed and copy how config_systemUiVendorServiceComponent works)
-
### [com.android.systemui.status.phone.StatusBar](/packages/SystemUI/src/com/android/systemui/status/phone/StatusBar.java)
This shows the UI for the status bar and the notification shade it contains.
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 61210d3e0011..105b27eb7e1b 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -279,7 +279,7 @@
<item>com.android.systemui.recents.Recents</item>
<item>com.android.systemui.volume.VolumeUI</item>
<item>com.android.systemui.stackdivider.Divider</item>
- <item>com.android.systemui.SystemBars</item>
+ <item>com.android.systemui.statusbar.phone.StatusBar</item>
<item>com.android.systemui.usb.StorageNotification</item>
<item>com.android.systemui.power.PowerUI</item>
<item>com.android.systemui.media.RingtonePlayer</item>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 8d167e8783bf..b9fe9334d14c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -76,7 +76,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
// How much you need to drag the bouncer to trigger an auth retry (in dps.)
private static final float MIN_DRAG_SIZE = 10;
// How much to scale the default slop by, to avoid accidental drags.
- private static final float SLOP_SCALE = 2f;
+ private static final float SLOP_SCALE = 4f;
private KeyguardSecurityModel mSecurityModel;
private LockPatternUtils mLockPatternUtils;
@@ -128,7 +128,7 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
public KeyguardSecurityContainer(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- mSecurityModel = new KeyguardSecurityModel(context);
+ mSecurityModel = Dependency.get(KeyguardSecurityModel.class);
mLockPatternUtils = new LockPatternUtils(context);
mUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index bb89959b7a11..1395fd9e3482 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -25,6 +25,10 @@ import com.android.internal.telephony.IccCardConstants;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Dependency;
+import javax.inject.Inject;
+import javax.inject.Singleton;
+
+@Singleton
public class KeyguardSecurityModel {
/**
@@ -46,6 +50,7 @@ public class KeyguardSecurityModel {
private LockPatternUtils mLockPatternUtils;
+ @Inject
KeyguardSecurityModel(Context context) {
mContext = context;
mLockPatternUtils = new LockPatternUtils(context);
@@ -57,7 +62,7 @@ public class KeyguardSecurityModel {
mLockPatternUtils = utils;
}
- SecurityMode getSecurityMode(int userId) {
+ public SecurityMode getSecurityMode(int userId) {
KeyguardUpdateMonitor monitor = Dependency.get(KeyguardUpdateMonitor.class);
if (mIsPukScreenAvailable && SubscriptionManager.isValidSubscriptionId(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index a6b3be23417e..dc8ee16e8645 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -58,6 +58,7 @@ import android.content.IntentFilter;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
+import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.hardware.biometrics.BiometricManager;
import android.hardware.biometrics.BiometricSourceType;
@@ -329,6 +330,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
private SparseBooleanArray mUserIsUnlocked = new SparseBooleanArray();
private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
+ private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray();
private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
@@ -472,6 +474,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
public void onTrustManagedChanged(boolean managed, int userId) {
checkIsHandlerThread();
mUserTrustIsManaged.put(userId, managed);
+ mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
@@ -925,6 +928,14 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
}
+ /**
+ * Cached version of {@link TrustManager#isTrustUsuallyManaged(int)}.
+ */
+ public boolean isTrustUsuallyManaged(int userId) {
+ checkIsHandlerThread();
+ return mUserTrustIsUsuallyManaged.get(userId);
+ }
+
public boolean isUnlockingWithBiometricAllowed() {
return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
}
@@ -1474,9 +1485,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
mUserIsUnlocked.put(userId, mUserManager.isUserUnlocked(userId));
}
- private void handleUserRemoved(int userId) {
+ @VisibleForTesting
+ void handleUserRemoved(int userId) {
checkIsHandlerThread();
mUserIsUnlocked.delete(userId);
+ mUserTrustIsUsuallyManaged.delete(userId);
}
@VisibleForTesting
@@ -1662,7 +1675,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
e.rethrowAsRuntimeException();
}
- mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
+ mTrustManager = context.getSystemService(TrustManager.class);
mTrustManager.registerTrustListener(this);
mLockPatternUtils = new LockPatternUtils(context);
mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
@@ -1697,6 +1710,11 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
+ List<UserInfo> allUsers = mUserManager.getUsers();
+ for (UserInfo userInfo : allUsers) {
+ mUserTrustIsUsuallyManaged.put(userInfo.id,
+ mTrustManager.isTrustUsuallyManaged(userInfo.id));
+ }
updateAirplaneModeState();
TelephonyManager telephony =
@@ -2048,6 +2066,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
*/
private void handleUserSwitching(int userId, IRemoteCallback reply) {
checkIsHandlerThread();
+ mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
if (cb != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 37bb54cc1b11..07bfa7194413 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -30,6 +30,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.Preconditions;
+import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.clock.ClockManager;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
@@ -316,6 +317,7 @@ public class Dependency {
@Inject Lazy<FalsingManager> mFalsingManager;
@Inject Lazy<SysUiState> mSysUiStateFlagsContainer;
@Inject Lazy<AlarmManager> mAlarmManager;
+ @Inject Lazy<KeyguardSecurityModel> mKeyguardSecurityModel;
@Inject
public Dependency() {
@@ -501,6 +503,7 @@ public class Dependency {
mProviders.put(FalsingManager.class, mFalsingManager::get);
mProviders.put(SysUiState.class, mSysUiStateFlagsContainer::get);
mProviders.put(AlarmManager.class, mAlarmManager::get);
+ mProviders.put(KeyguardSecurityModel.class, mKeyguardSecurityModel::get);
// TODO(b/118592525): to support multi-display , we start to add something which is
// per-display, while others may be global. I think it's time to add
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
index c4dce1e70051..f9f0f1bad2fa 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyBinder.java
@@ -200,6 +200,12 @@ public abstract class DependencyBinder {
/**
*/
@Binds
+ public abstract SysuiStatusBarStateController providesSysuiStatusBarStateController(
+ StatusBarStateControllerImpl statusBarStateControllerImpl);
+
+ /**
+ */
+ @Binds
public abstract StatusBarIconController provideStatusBarIconController(
StatusBarIconControllerImpl controllerImpl);
@@ -235,10 +241,4 @@ public abstract class DependencyBinder {
*/
@Binds
public abstract FalsingManager provideFalsingmanager(FalsingManagerProxy falsingManagerImpl);
-
- /**
- */
- @Binds
- public abstract SysuiStatusBarStateController providesSysuiStatusBarStateController(
- StatusBarStateControllerImpl statusBarStateControllerImpl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
index 239cbfe38975..0d24321d8db7 100644
--- a/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/DependencyProvider.java
@@ -40,6 +40,7 @@ import android.view.WindowManagerGlobal;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
+import com.android.internal.widget.LockPatternUtils;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.systemui.plugins.PluginInitializerImpl;
import com.android.systemui.shared.plugins.PluginManager;
@@ -238,4 +239,10 @@ public class DependencyProvider {
public AlarmManager provideAlarmManager(Context context) {
return context.getSystemService(AlarmManager.class);
}
+
+ /** */
+ @Provides
+ public LockPatternUtils provideLockPatternUtils(Context context) {
+ return new LockPatternUtils(context);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemBars.java b/packages/SystemUI/src/com/android/systemui/SystemBars.java
deleted file mode 100644
index c4c0fd6da124..000000000000
--- a/packages/SystemUI/src/com/android/systemui/SystemBars.java
+++ /dev/null
@@ -1,88 +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.systemui;
-
-import android.util.Log;
-
-import com.android.systemui.statusbar.phone.StatusBar;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-
-/**
- * Ensure a single status bar service implementation is running at all times, using the in-process
- * implementation according to the product config.
- */
-public class SystemBars extends SystemUI {
- private static final String TAG = "SystemBars";
- private static final boolean DEBUG = false;
- private static final int WAIT_FOR_BARS_TO_DIE = 500;
-
- // in-process fallback implementation, per the product config
- private SystemUI mStatusBar;
-
- @Override
- public void start() {
- if (DEBUG) Log.d(TAG, "start");
- createStatusBarFromConfig();
- }
-
- @Override
- public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
- if (mStatusBar != null) {
- mStatusBar.dump(fd, pw, args);
- }
- }
-
- @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);
- if (clsName == null || clsName.length() == 0) {
- throw andLog("No status bar component configured", null);
- }
- Class<?> cls = null;
- try {
- cls = mContext.getClassLoader().loadClass(clsName);
- } catch (Throwable t) {
- throw andLog("Error loading status bar component: " + clsName, t);
- }
- try {
- mStatusBar = (SystemUI) cls.newInstance();
- } catch (Throwable t) {
- throw andLog("Error creating status bar component: " + clsName, t);
- }
- mStatusBar.mContext = mContext;
- mStatusBar.mComponents = mComponents;
- if (mStatusBar instanceof StatusBar) {
- SystemUIFactory.getInstance().getRootComponent()
- .getStatusBarInjector()
- .createStatusBar((StatusBar) mStatusBar);
- }
- mStatusBar.start();
- if (DEBUG) Log.d(TAG, "started " + mStatusBar.getClass().getSimpleName());
- }
-
- private RuntimeException andLog(String msg, Throwable t) {
- Log.w(TAG, msg, t);
- throw new RuntimeException(msg, t);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
index ba2dec0ff116..785038f2b7f7 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIBinder.java
@@ -44,7 +44,7 @@ public abstract class SystemUIBinder {
@ClassKey(PowerUI.class)
public abstract SystemUI bindPowerUI(PowerUI sysui);
- /** Inject into StatusBar. */
+ /** Inject into Recents. */
@Binds
@IntoMap
@ClassKey(Recents.class)
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
index 262b5ec50d83..72831e99e122 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIDefaultModule.java
@@ -40,6 +40,8 @@ import javax.inject.Singleton;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
+import dagger.multibindings.ClassKey;
+import dagger.multibindings.IntoMap;
/**
* A dagger module for injecting default implementations of components of System UI that may be
@@ -76,6 +78,11 @@ abstract class SystemUIDefaultModule {
return SysUiServiceProvider.getComponent(context, StatusBar.class);
}
+ @Binds
+ @IntoMap
+ @ClassKey(StatusBar.class)
+ public abstract SystemUI providesStatusBar(StatusBar statusBar);
+
@Singleton
@Provides
@Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java
index cb7c998fad8e..8105c6a6e940 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingLog.java
@@ -37,7 +37,7 @@ import java.util.Locale;
* adb shell setprop debug.falsing_log true
*
* The log gets dumped as part of the SystemUI services. To dump on demand:
- * adb shell dumpsys activity service com.android.systemui SystemBars | grep -A 999 FALSING | less
+ * adb shell dumpsys activity service com.android.systemui StatusBar | grep -A 999 FALSING | less
*
* To dump into logcat:
* adb shell setprop debug.falsing_logcat true
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index f159d8c1d431..a8027c025cf2 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -234,7 +234,7 @@ public class KeyguardViewMediator extends SystemUI {
*/
private PowerManager.WakeLock mShowKeyguardWakeLock;
- private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
+ private final StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
// these are protected by synchronized (this)
@@ -317,7 +317,7 @@ public class KeyguardViewMediator extends SystemUI {
* the keyguard.
*/
private boolean mWaitingUntilKeyguardVisible = false;
- private LockPatternUtils mLockPatternUtils;
+ private final LockPatternUtils mLockPatternUtils;
private boolean mKeyguardDonePending = false;
private boolean mHideAnimationRun = false;
private boolean mHideAnimationRunning = false;
@@ -650,29 +650,26 @@ public class KeyguardViewMediator extends SystemUI {
@Override
public int getBouncerPromptReason() {
- // TODO(b/140053364)
- return whitelistIpcs(() -> {
- int currentUser = ActivityManager.getCurrentUser();
- boolean trust = mTrustManager.isTrustUsuallyManaged(currentUser);
- boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
- boolean any = trust || biometrics;
- KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
- mUpdateMonitor.getStrongAuthTracker();
- int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
-
- if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
- return KeyguardSecurityView.PROMPT_REASON_RESTART;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
- } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
- } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
- return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
- }
- return KeyguardSecurityView.PROMPT_REASON_NONE;
- });
+ int currentUser = KeyguardUpdateMonitor.getCurrentUser();
+ boolean trust = mUpdateMonitor.isTrustUsuallyManaged(currentUser);
+ boolean biometrics = mUpdateMonitor.isUnlockingWithBiometricsPossible(currentUser);
+ boolean any = trust || biometrics;
+ KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
+ mUpdateMonitor.getStrongAuthTracker();
+ int strongAuth = strongAuthTracker.getStrongAuthForUser(currentUser);
+
+ if (any && !strongAuthTracker.hasUserAuthenticatedSinceBoot()) {
+ return KeyguardSecurityView.PROMPT_REASON_RESTART;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_TIMEOUT) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_TIMEOUT;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN;
+ } else if (trust && (strongAuth & SOME_AUTH_REQUIRED_AFTER_USER_REQUEST) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_USER_REQUEST;
+ } else if (any && (strongAuth & STRONG_AUTH_REQUIRED_AFTER_LOCKOUT) != 0) {
+ return KeyguardSecurityView.PROMPT_REASON_AFTER_LOCKOUT;
+ }
+ return KeyguardSecurityView.PROMPT_REASON_NONE;
}
@Override
@@ -684,10 +681,21 @@ public class KeyguardViewMediator extends SystemUI {
};
@Inject
- public KeyguardViewMediator(FalsingManager falsingManager) {
+ public KeyguardViewMediator(
+ Context context,
+ FalsingManager falsingManager,
+ LockPatternUtils lockPatternUtils) {
super();
+ mContext = context;
mFalsingManager = falsingManager;
+
+ mLockPatternUtils = lockPatternUtils;
+ mStatusBarKeyguardViewManager =
+ SystemUIFactory.getInstance().createStatusBarKeyguardViewManager(
+ mContext,
+ mViewMediatorCallback,
+ mLockPatternUtils);
}
public void userActivity() {
@@ -701,7 +709,7 @@ public class KeyguardViewMediator extends SystemUI {
private void setupLocked() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- mTrustManager = (TrustManager) mContext.getSystemService(Context.TRUST_SERVICE);
+ mTrustManager = mContext.getSystemService(TrustManager.class);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
mShowKeyguardWakeLock.setReferenceCounted(false);
@@ -725,7 +733,6 @@ public class KeyguardViewMediator extends SystemUI {
mUpdateMonitor = Dependency.get(KeyguardUpdateMonitor.class);
- mLockPatternUtils = new LockPatternUtils(mContext);
KeyguardUpdateMonitor.setCurrentUser(ActivityManager.getCurrentUser());
// Assume keyguard is showing (unless it's disabled) until we know for sure, unless Keyguard
@@ -739,9 +746,6 @@ public class KeyguardViewMediator extends SystemUI {
setShowingLocked(false /* showing */, true /* forceCallbacks */);
}
- mStatusBarKeyguardViewManager =
- SystemUIFactory.getInstance().createStatusBarKeyguardViewManager(mContext,
- mViewMediatorCallback, mLockPatternUtils);
final ContentResolver cr = mContext.getContentResolver();
mDeviceInteractive = mPM.isInteractive();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
index 90301c59dc68..148a1a87f305 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManager.java
@@ -20,7 +20,6 @@ import static android.service.notification.NotificationListenerService.REASON_ER
import android.annotation.Nullable;
import android.app.Notification;
-import android.content.Context;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
@@ -124,8 +123,8 @@ public class NotificationEntryManager implements
}
@Inject
- public NotificationEntryManager(Context context) {
- mNotificationData = new NotificationData(context);
+ public NotificationEntryManager(NotificationData notificationData) {
+ mNotificationData = notificationData;
}
/** Adds a {@link NotificationEntryListener}. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
new file mode 100644
index 000000000000..480cb78efbba
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
@@ -0,0 +1,73 @@
+/*
+ * 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.notification
+
+import android.content.Context
+import android.provider.DeviceConfig
+
+import com.android.internal.annotations.VisibleForTesting
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
+import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_ALERTING
+import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_PEOPLE
+import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager.BUCKET_SILENT
+import com.android.systemui.util.DeviceConfigProxy
+
+import javax.inject.Inject
+
+private var sUsePeopleFiltering: Boolean? = null
+
+/**
+ * Feature controller for the NOTIFICATIONS_USE_PEOPLE_FILTERING config.
+ */
+class NotificationSectionsFeatureManager @Inject constructor(
+ val proxy: DeviceConfigProxy,
+ val context: Context
+) {
+
+ fun isFilteringEnabled(): Boolean {
+ return usePeopleFiltering(proxy)
+ }
+
+ fun getNotificationBuckets(): IntArray {
+ return when {
+ isFilteringEnabled() ->
+ intArrayOf(BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT)
+ NotificationUtils.useNewInterruptionModel(context) ->
+ intArrayOf(BUCKET_ALERTING, BUCKET_SILENT)
+ else ->
+ intArrayOf(BUCKET_ALERTING)
+ }
+ }
+
+ fun getNumberOfBuckets(): Int {
+ return getNotificationBuckets().size
+ }
+
+ @VisibleForTesting
+ fun clearCache() {
+ sUsePeopleFiltering = null
+ }
+}
+
+private fun usePeopleFiltering(proxy: DeviceConfigProxy): Boolean {
+ if (sUsePeopleFiltering == null) {
+ sUsePeopleFiltering = proxy.getBoolean(
+ DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, false)
+ }
+
+ return sUsePeopleFiltering!!
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
index dfbbf987dd96..1af47dd0f4c0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.java
@@ -36,7 +36,6 @@ public class NotificationUtils {
private static final int[] sLocationOffset = new int[2];
@Nullable private static Boolean sUseNewInterruptionModel = null;
- @Nullable private static Boolean sUsePeopleFiltering = null;
public static boolean isGrayscale(ImageView v, ContrastColorUtil colorUtil) {
Object isGrayscale = v.getTag(R.id.icon_is_grayscale);
@@ -88,17 +87,4 @@ public class NotificationUtils {
}
return sUseNewInterruptionModel;
}
-
- /**
- * Caches and returns the value of the people filtering setting. Cannot change except through
- * process restarts.
- */
- public static boolean usePeopleFiltering(Context context) {
- if (sUsePeopleFiltering == null) {
- sUsePeopleFiltering = context.getResources().getBoolean(
- R.bool.config_usePeopleFiltering);
- }
-
- return sUsePeopleFiltering;
- }
}
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 aacb2dd0682f..cf0fbbb5d9c1 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
@@ -24,7 +24,6 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Person;
-import android.content.Context;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.SnoozeCriterion;
@@ -35,7 +34,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dependency;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.notification.NotificationFilter;
-import com.android.systemui.statusbar.notification.NotificationUtils;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.policy.HeadsUpManager;
@@ -46,6 +45,8 @@ import java.util.Comparator;
import java.util.List;
import java.util.Objects;
+import javax.inject.Inject;
+
/**
* The list of currently displaying notifications.
*/
@@ -73,8 +74,9 @@ public class NotificationData {
private final Ranking mTmpRanking = new Ranking();
private final boolean mUsePeopleFiltering;
- public NotificationData(Context context) {
- mUsePeopleFiltering = NotificationUtils.usePeopleFiltering(context);
+ @Inject
+ public NotificationData(NotificationSectionsFeatureManager sectionsFeatureManager) {
+ mUsePeopleFiltering = sectionsFeatureManager.isFilteringEnabled();
}
public void setHeadsUpManager(HeadsUpManager headsUpManager) {
@@ -483,19 +485,6 @@ public class NotificationData {
}
/**
- * Get the current set of buckets for notification entries, as defined here
- */
- public static int[] getNotificationBuckets(Context context) {
- if (NotificationUtils.usePeopleFiltering(context)) {
- return new int[]{BUCKET_PEOPLE, BUCKET_ALERTING, BUCKET_SILENT};
- } else if (NotificationUtils.useNewInterruptionModel(context)) {
- return new int[]{BUCKET_ALERTING, BUCKET_SILENT};
- } else {
- return new int[]{BUCKET_ALERTING};
- }
- }
-
- /**
* Provides access to keyguard state and user settings dependent data.
*/
public interface KeyguardEnvironment {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
index ec0c6348fd89..b4f7b59349d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManager.java
@@ -16,10 +16,9 @@
package com.android.systemui.statusbar.notification.stack;
-import android.content.Context;
import android.util.MathUtils;
-import com.android.systemui.statusbar.notification.collection.NotificationData;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -52,8 +51,8 @@ public class NotificationRoundnessManager implements OnHeadsUpChangedListener {
@Inject
NotificationRoundnessManager(
KeyguardBypassController keyguardBypassController,
- Context context) {
- int numberOfSections = NotificationData.getNotificationBuckets(context).length;
+ NotificationSectionsFeatureManager sectionsFeatureManager) {
+ int numberOfSections = sectionsFeatureManager.getNumberOfBuckets();
mFirstInSectionViews = new ActivatableNotificationView[numberOfSections];
mLastInSectionViews = new ActivatableNotificationView[numberOfSections];
mTmpFirstInSectionViews = new ActivatableNotificationView[numberOfSections];
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 a67018ef9710..f5705c5f643b 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
@@ -109,11 +109,11 @@ import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.FakeShadowView;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.NotificationUtils;
import com.android.systemui.statusbar.notification.ShadeViewRefactor;
import com.android.systemui.statusbar.notification.ShadeViewRefactor.RefactorComponent;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
-import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ActivatableNotificationView;
@@ -517,7 +517,8 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
StatusBarStateController statusBarStateController,
HeadsUpManagerPhone headsUpManager,
KeyguardBypassController keyguardBypassController,
- FalsingManager falsingManager) {
+ FalsingManager falsingManager,
+ NotificationSectionsFeatureManager sectionsFeatureManager) {
super(context, attrs, 0, 0);
Resources res = getResources();
@@ -531,7 +532,7 @@ public class NotificationStackScrollLayout extends ViewGroup implements ScrollAd
mKeyguardBypassController = keyguardBypassController;
mFalsingManager = falsingManager;
- int[] buckets = NotificationData.getNotificationBuckets(context);
+ int[] buckets = sectionsFeatureManager.getNotificationBuckets();
mSectionsManager =
new NotificationSectionsManager(
this,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 68eca8d68d90..cac33044ea13 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -117,6 +117,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private static final int DOZE_ANIMATION_STAGGER_DELAY = 48;
private static final int DOZE_ANIMATION_ELEMENT_DURATION = 250;
+ private final boolean mShowLeftAffordance;
+ private final boolean mShowCameraAffordance;
+
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
private ViewGroup mIndicationArea;
@@ -184,6 +187,9 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public KeyguardBottomAreaView(Context context, AttributeSet attrs, int defStyleAttr,
int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
+ mShowLeftAffordance = getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance);
+ mShowCameraAffordance = getResources()
+ .getBoolean(R.bool.config_keyguardShowCameraAffordance);
}
private AccessibilityDelegate mAccessibilityDelegate = new AccessibilityDelegate() {
@@ -371,8 +377,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
// Things are not set up yet; reply hazy, ask again later
return;
}
- mRightAffordanceView.setVisibility(!mDozing && mRightButton.getIcon().isVisible
- ? View.VISIBLE : View.GONE);
+ mRightAffordanceView.setVisibility(!mDozing && mShowCameraAffordance
+ && mRightButton.getIcon().isVisible ? View.VISIBLE : View.GONE);
}
/**
@@ -384,8 +390,12 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
}
private void updateLeftAffordanceIcon() {
+ if (!mShowLeftAffordance || mDozing) {
+ mLeftAffordanceView.setVisibility(GONE);
+ return;
+ }
IconState state = mLeftButton.getIcon();
- mLeftAffordanceView.setVisibility(!mDozing && state.isVisible ? View.VISIBLE : View.GONE);
+ mLeftAffordanceView.setVisibility(state.isVisible ? View.VISIBLE : View.GONE);
if (state.drawable != mLeftAffordanceView.getDrawable()
|| state.tint != mLeftAffordanceView.shouldTint()) {
mLeftAffordanceView.setImageDrawable(state.drawable, state.tint);
@@ -767,10 +777,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
@Override
public IconState getIcon() {
mLeftIsVoiceAssist = canLaunchVoiceAssist();
- final boolean showAffordance =
- getResources().getBoolean(R.bool.config_keyguardShowLeftAffordance);
if (mLeftIsVoiceAssist) {
- mIconState.isVisible = mUserSetupComplete && showAffordance;
+ mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance;
if (mLeftAssistIcon == null) {
mIconState.drawable = mContext.getDrawable(R.drawable.ic_mic_26dp);
} else {
@@ -779,7 +787,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mIconState.contentDescription = mContext.getString(
R.string.accessibility_voice_assist_button);
} else {
- mIconState.isVisible = mUserSetupComplete && showAffordance && isPhoneVisible();
+ mIconState.isVisible = mUserSetupComplete && mShowLeftAffordance
+ && isPhoneVisible();
mIconState.drawable = mContext.getDrawable(
com.android.internal.R.drawable.ic_phone);
mIconState.contentDescription = mContext.getString(
@@ -802,7 +811,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public IconState getIcon() {
boolean isCameraDisabled = (mStatusBar != null) && !mStatusBar.isCameraAllowedByAdmin();
mIconState.isVisible = !isCameraDisabled
- && getResources().getBoolean(R.bool.config_keyguardShowCameraAffordance)
+ && mShowCameraAffordance
&& mUserSetupComplete
&& resolveCameraIntent() != null;
mIconState.drawable = mContext.getDrawable(R.drawable.ic_camera_alt_24dp);
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 c3de84366d4b..f34c15c7099d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.phone;
import static com.android.keyguard.KeyguardSecurityModel.SecurityMode;
-import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import android.content.Context;
@@ -38,11 +37,13 @@ import android.view.WindowInsets;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView;
+import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardSecurityView;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.FalsingManager;
@@ -461,15 +462,9 @@ public class KeyguardBouncer {
* notifications on Keyguard, like SIM PIN/PUK.
*/
public boolean needsFullscreenBouncer() {
- // TODO(b/140059518)
- return whitelistIpcs(() -> {
- ensureView();
- if (mKeyguardView != null) {
- SecurityMode mode = mKeyguardView.getSecurityMode();
- return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
- }
- return false;
- });
+ SecurityMode mode = Dependency.get(KeyguardSecurityModel.class).getSecurityMode(
+ KeyguardUpdateMonitor.getCurrentUser());
+ return mode == SecurityMode.SimPin || mode == SecurityMode.SimPuk;
}
/**
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 e79f14175377..b1825c8ce667 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -25,7 +25,6 @@ import static android.app.StatusBarManager.WindowVisibleState;
import static android.app.StatusBarManager.windowStateToString;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY;
-import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.Dependency.ALLOW_NOTIFICATION_LONG_PRESS_NAME;
import static com.android.systemui.Dependency.BG_HANDLER;
import static com.android.systemui.Dependency.MAIN_HANDLER;
@@ -347,10 +346,9 @@ public class StatusBar extends SystemUI implements DemoMode,
private BrightnessMirrorController mBrightnessMirrorController;
private boolean mBrightnessMirrorVisible;
protected BiometricUnlockController mBiometricUnlockController;
- @Inject LightBarController mLightBarController;
+ private final LightBarController mLightBarController;
protected LockscreenWallpaper mLockscreenWallpaper;
- @VisibleForTesting
- @Inject AutoHideController mAutoHideController;
+ private final AutoHideController mAutoHideController;
private int mNaturalBarHeight = -1;
@@ -360,8 +358,7 @@ public class StatusBar extends SystemUI implements DemoMode,
protected PhoneStatusBarView mStatusBarView;
private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
protected StatusBarWindowController mStatusBarWindowController;
- @VisibleForTesting
- @Inject KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
@VisibleForTesting
DozeServiceHost mDozeServiceHost = new DozeServiceHost();
private boolean mWakeUpComingFromTouch;
@@ -369,38 +366,21 @@ public class StatusBar extends SystemUI implements DemoMode,
private final Object mQueueLock = new Object();
- @Inject StatusBarIconController mIconController;
- @Inject
- DozeLog mDozeLog;
- @Inject
- InjectionInflationController mInjectionInflater;
- @Inject
- PulseExpansionHandler mPulseExpansionHandler;
- @Inject
- NotificationWakeUpCoordinator mWakeUpCoordinator;
- @Inject
- KeyguardBypassController mKeyguardBypassController;
- @Inject
- KeyguardStateController mKeyguardStateController;
- @Inject
- protected HeadsUpManagerPhone mHeadsUpManager;
- @Inject
- DynamicPrivacyController mDynamicPrivacyController;
- @Inject
- BypassHeadsUpNotifier mBypassHeadsUpNotifier;
- @Nullable
- @Inject
- protected KeyguardLiftController mKeyguardLiftController;
- @Inject
- @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME)
- boolean mAllowNotificationLongPress;
- @Inject
- protected NotifPipelineInitializer mNotifPipelineInitializer;
- @Inject
- protected FalsingManager mFalsingManager;
-
- @VisibleForTesting
- @Inject BroadcastDispatcher mBroadcastDispatcher;
+ private final StatusBarIconController mIconController;
+ private final DozeLog mDozeLog;
+ private final InjectionInflationController mInjectionInflater;
+ private final PulseExpansionHandler mPulseExpansionHandler;
+ private final NotificationWakeUpCoordinator mWakeUpCoordinator;
+ private final KeyguardBypassController mKeyguardBypassController;
+ private final KeyguardStateController mKeyguardStateController;
+ private final HeadsUpManagerPhone mHeadsUpManager;
+ private final DynamicPrivacyController mDynamicPrivacyController;
+ private final BypassHeadsUpNotifier mBypassHeadsUpNotifier;
+ private final boolean mAllowNotificationLongPress;
+ private final NotifPipelineInitializer mNotifPipelineInitializer;
+ private final FalsingManager mFalsingManager;
+ private final BroadcastDispatcher mBroadcastDispatcher;
+ private final ConfigurationController mConfigurationController;
// expanded notifications
protected NotificationPanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -413,7 +393,7 @@ public class StatusBar extends SystemUI implements DemoMode,
// RemoteInputView to be activated after unlock
private View mPendingRemoteInputView;
- @Inject RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
+ private final RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
private View mReportRejectedTouch;
@@ -422,17 +402,17 @@ public class StatusBar extends SystemUI implements DemoMode,
private final int[] mAbsPos = new int[2];
private final ArrayList<Runnable> mPostCollapseRunnables = new ArrayList<>();
- @Inject NotificationGutsManager mGutsManager;
- @Inject NotificationLogger mNotificationLogger;
- @Inject NotificationEntryManager mEntryManager;
+ private final NotificationGutsManager mGutsManager;
+ private final NotificationLogger mNotificationLogger;
+ private final NotificationEntryManager mEntryManager;
private NotificationListController mNotificationListController;
- @Inject NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
- @Inject NotificationViewHierarchyManager mViewHierarchyManager;
- @Inject ForegroundServiceController mForegroundServiceController;
- @Inject AppOpsController mAppOpsController;
- @Inject KeyguardViewMediator mKeyguardViewMediator;
- @Inject ZenModeController mZenController;
- @Inject NotificationAlertingManager mNotificationAlertingManager;
+ private final NotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
+ private final NotificationViewHierarchyManager mViewHierarchyManager;
+ private final ForegroundServiceController mForegroundServiceController;
+ private final AppOpsController mAppOpsController;
+ private final KeyguardViewMediator mKeyguardViewMediator;
+ private final ZenModeController mZenController;
+ private final NotificationAlertingManager mNotificationAlertingManager;
// for disabling the status bar
private int mDisabled1 = 0;
@@ -443,7 +423,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private final Rect mLastFullscreenStackBounds = new Rect();
private final Rect mLastDockedStackBounds = new Rect();
- @Inject DisplayMetrics mDisplayMetrics;
+ private final DisplayMetrics mDisplayMetrics;
// XXX: gesture research
private final GestureRecorder mGestureRec = DEBUG_GESTURES
@@ -452,7 +432,7 @@ public class StatusBar extends SystemUI implements DemoMode,
private ScreenPinningRequest mScreenPinningRequest;
- @Inject MetricsLogger mMetricsLogger;
+ private final MetricsLogger mMetricsLogger;
// ensure quick settings is disabled until the current user makes it through the setup wizard
@VisibleForTesting
@@ -489,14 +469,14 @@ public class StatusBar extends SystemUI implements DemoMode,
private ViewMediatorCallback mKeyguardViewMediatorCallback;
protected ScrimController mScrimController;
protected DozeScrimController mDozeScrimController;
- @Inject UiOffloadThread mUiOffloadThread;
+ private final UiOffloadThread mUiOffloadThread;
protected boolean mDozing;
private boolean mDozingRequested;
- @Inject NotificationMediaManager mMediaManager;
- @Inject NotificationLockscreenUserManager mLockscreenUserManager;
- @Inject NotificationRemoteInputManager mRemoteInputManager;
+ private final NotificationMediaManager mMediaManager;
+ private final NotificationLockscreenUserManager mLockscreenUserManager;
+ private final NotificationRemoteInputManager mRemoteInputManager;
private boolean mWallpaperSupported;
private final BroadcastReceiver mWallpaperChangedReceiver = new BroadcastReceiver() {
@@ -567,18 +547,18 @@ public class StatusBar extends SystemUI implements DemoMode,
};
private KeyguardUserSwitcher mKeyguardUserSwitcher;
- @Inject UserSwitcherController mUserSwitcherController;
- @Inject NetworkController mNetworkController;
- @Inject BatteryController mBatteryController;
+ private final UserSwitcherController mUserSwitcherController;
+ private final NetworkController mNetworkController;
+ private final BatteryController mBatteryController;
protected boolean mPanelExpanded;
private UiModeManager mUiModeManager;
protected boolean mIsKeyguard;
private LogMaker mStatusBarStateLog;
protected NotificationIconAreaController mNotificationIconAreaController;
@Nullable private View mAmbientIndicationContainer;
- @Inject SysuiColorExtractor mColorExtractor;
- @Inject ScreenLifecycle mScreenLifecycle;
- @Inject @VisibleForTesting WakefulnessLifecycle mWakefulnessLifecycle;
+ private final SysuiColorExtractor mColorExtractor;
+ private final ScreenLifecycle mScreenLifecycle;
+ private final WakefulnessLifecycle mWakefulnessLifecycle;
private final View.OnClickListener mGoToLockedShadeListener = v -> {
if (mState == StatusBarState.KEYGUARD) {
@@ -587,7 +567,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
};
private boolean mNoAnimationOnNextBarModeChange;
- @Inject SysuiStatusBarStateController mStatusBarStateController;
+ private final SysuiStatusBarStateController mStatusBarStateController;
private final KeyguardUpdateMonitorCallback mUpdateCallback =
new KeyguardUpdateMonitorCallback() {
@@ -608,17 +588,13 @@ public class StatusBar extends SystemUI implements DemoMode,
private HeadsUpAppearanceController mHeadsUpAppearanceController;
private boolean mVibrateOnOpening;
- @Inject VibratorHelper mVibratorHelper;
+ private final VibratorHelper mVibratorHelper;
private ActivityLaunchAnimator mActivityLaunchAnimator;
protected StatusBarNotificationPresenter mPresenter;
private NotificationActivityStarter mNotificationActivityStarter;
private boolean mPulsing;
- @Inject BubbleController mBubbleController;
- private final BubbleController.BubbleExpandListener mBubbleExpandListener =
- (isExpanding, key) -> {
- mEntryManager.updateNotifications();
- updateScrimController();
- };
+ private final BubbleController mBubbleController;
+ private final BubbleController.BubbleExpandListener mBubbleExpandListener;
private ActivityIntentHelper mActivityIntentHelper;
@Override
@@ -635,6 +611,120 @@ public class StatusBar extends SystemUI implements DemoMode,
AppOpsManager.OP_COARSE_LOCATION,
AppOpsManager.OP_FINE_LOCATION};
+ @Inject
+ public StatusBar(
+ LightBarController lightBarController,
+ AutoHideController autoHideController,
+ KeyguardUpdateMonitor keyguardUpdateMonitor,
+ StatusBarIconController statusBarIconController,
+ DozeLog dozeLog,
+ InjectionInflationController injectionInflationController,
+ PulseExpansionHandler pulseExpansionHandler,
+ NotificationWakeUpCoordinator notificationWakeUpCoordinator,
+ KeyguardBypassController keyguardBypassController,
+ KeyguardStateController keyguardStateController,
+ HeadsUpManagerPhone headsUpManagerPhone,
+ DynamicPrivacyController dynamicPrivacyController,
+ BypassHeadsUpNotifier bypassHeadsUpNotifier,
+ @Named(ALLOW_NOTIFICATION_LONG_PRESS_NAME) boolean allowNotificationLongPress,
+ NotifPipelineInitializer notifPipelineInitializer,
+ FalsingManager falsingManager,
+ BroadcastDispatcher broadcastDispatcher,
+ RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
+ NotificationGutsManager notificationGutsManager,
+ NotificationLogger notificationLogger,
+ NotificationEntryManager notificationEntryManager,
+ NotificationInterruptionStateProvider notificationInterruptionStateProvider,
+ NotificationViewHierarchyManager notificationViewHierarchyManager,
+ ForegroundServiceController foregroundServiceController,
+ AppOpsController appOpsController,
+ KeyguardViewMediator keyguardViewMediator,
+ ZenModeController zenModeController,
+ NotificationAlertingManager notificationAlertingManager,
+ DisplayMetrics displayMetrics,
+ MetricsLogger metricsLogger,
+ UiOffloadThread uiOffloadThread,
+ NotificationMediaManager notificationMediaManager,
+ NotificationLockscreenUserManager lockScreenUserManager,
+ NotificationRemoteInputManager remoteInputManager,
+ UserSwitcherController userSwitcherController,
+ NetworkController networkController,
+ BatteryController batteryController,
+ SysuiColorExtractor colorExtractor,
+ ScreenLifecycle screenLifecycle,
+ WakefulnessLifecycle wakefulnessLifecycle,
+ SysuiStatusBarStateController statusBarStateController,
+ VibratorHelper vibratorHelper,
+ BubbleController bubbleController,
+ NotificationGroupManager groupManager,
+ NotificationGroupAlertTransferHelper groupAlertTransferHelper,
+ VisualStabilityManager visualStabilityManager,
+ DeviceProvisionedController deviceProvisionedController,
+ NavigationBarController navigationBarController,
+ AssistManager assistManager,
+ NotificationListener notificationListener,
+ ConfigurationController configurationController,
+ StatusBarWindowController statusBarWindowController) {
+ mLightBarController = lightBarController;
+ mAutoHideController = autoHideController;
+ mKeyguardUpdateMonitor = keyguardUpdateMonitor;
+ mIconController = statusBarIconController;
+ mDozeLog = dozeLog;
+ mInjectionInflater = injectionInflationController;
+ mPulseExpansionHandler = pulseExpansionHandler;
+ mWakeUpCoordinator = notificationWakeUpCoordinator;
+ mKeyguardBypassController = keyguardBypassController;
+ mKeyguardStateController = keyguardStateController;
+ mHeadsUpManager = headsUpManagerPhone;
+ mDynamicPrivacyController = dynamicPrivacyController;
+ mBypassHeadsUpNotifier = bypassHeadsUpNotifier;
+ mAllowNotificationLongPress = allowNotificationLongPress;
+ mNotifPipelineInitializer = notifPipelineInitializer;
+ mFalsingManager = falsingManager;
+ mBroadcastDispatcher = broadcastDispatcher;
+ mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler;
+ mGutsManager = notificationGutsManager;
+ mNotificationLogger = notificationLogger;
+ mEntryManager = notificationEntryManager;
+ mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
+ mViewHierarchyManager = notificationViewHierarchyManager;
+ mForegroundServiceController = foregroundServiceController;
+ mAppOpsController = appOpsController;
+ mKeyguardViewMediator = keyguardViewMediator;
+ mZenController = zenModeController;
+ mNotificationAlertingManager = notificationAlertingManager;
+ mDisplayMetrics = displayMetrics;
+ mMetricsLogger = metricsLogger;
+ mUiOffloadThread = uiOffloadThread;
+ mMediaManager = notificationMediaManager;
+ mLockscreenUserManager = lockScreenUserManager;
+ mRemoteInputManager = remoteInputManager;
+ mUserSwitcherController = userSwitcherController;
+ mNetworkController = networkController;
+ mBatteryController = batteryController;
+ mColorExtractor = colorExtractor;
+ mScreenLifecycle = screenLifecycle;
+ mWakefulnessLifecycle = wakefulnessLifecycle;
+ mStatusBarStateController = statusBarStateController;
+ mVibratorHelper = vibratorHelper;
+ mBubbleController = bubbleController;
+ mGroupManager = groupManager;
+ mGroupAlertTransferHelper = groupAlertTransferHelper;
+ mVisualStabilityManager = visualStabilityManager;
+ mDeviceProvisionedController = deviceProvisionedController;
+ mNavigationBarController = navigationBarController;
+ mAssistManager = assistManager;
+ mNotificationListener = notificationListener;
+ mConfigurationController = configurationController;
+ mStatusBarWindowController = statusBarWindowController;
+
+ mBubbleExpandListener =
+ (isExpanding, key) -> {
+ mEntryManager.updateNotifications();
+ updateScrimController();
+ };
+ }
+
@Override
public void start() {
mNotificationListener.registerAsSystemService();
@@ -772,7 +862,7 @@ public class StatusBar extends SystemUI implements DemoMode,
Dependency.get(ActivityStarterDelegate.class).setActivityStarterImpl(this);
- Dependency.get(ConfigurationController.class).addCallback(this);
+ mConfigurationController.addCallback(this);
// set the initial view visibility
Dependency.get(InitController.class).addPostInitTask(this::updateAreThereNotifications);
@@ -805,6 +895,8 @@ public class StatusBar extends SystemUI implements DemoMode,
NotificationListContainer notifListContainer = (NotificationListContainer) mStackScroller;
mNotificationLogger.setUpWithContainer(notifListContainer);
+ // TODO: make this injectable. Currently that would create a circular dependency between
+ // NotificationIconAreaController and StatusBar.
mNotificationIconAreaController = SystemUIFactory.getInstance()
.createNotificationIconAreaController(context, this,
mWakeUpCoordinator, mKeyguardBypassController,
@@ -869,7 +961,7 @@ public class StatusBar extends SystemUI implements DemoMode,
.commit();
mHeadsUpManager.setUp(mStatusBarWindow, mGroupManager, this, mVisualStabilityManager);
- Dependency.get(ConfigurationController.class).addCallback(mHeadsUpManager);
+ mConfigurationController.addCallback(mHeadsUpManager);
mHeadsUpManager.addListener(this);
mHeadsUpManager.addListener(mNotificationPanel);
mHeadsUpManager.addListener(mGroupManager);
@@ -1004,11 +1096,10 @@ public class StatusBar extends SystemUI implements DemoMode,
});
}
- PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
- if (!pm.isScreenOn()) {
+ if (!mPowerManager.isScreenOn()) {
mBroadcastReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
}
- mGestureWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
+ mGestureWakeLock = mPowerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
"GestureWakeLock");
mVibrator = mContext.getSystemService(Vibrator.class);
int[] pattern = mContext.getResources().getIntArray(
@@ -1131,8 +1222,8 @@ public class StatusBar extends SystemUI implements DemoMode,
@Override
public void wakeUpIfDozing(long time, View where, String why) {
if (mDozing) {
- PowerManager pm = mContext.getSystemService(PowerManager.class);
- pm.wakeUp(time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
+ mPowerManager.wakeUp(
+ time, PowerManager.WAKE_REASON_GESTURE, "com.android.systemui:" + why);
mWakeUpComingFromTouch = true;
where.getLocationInWindow(mTmpInt2);
mWakeUpTouchLocation = new PointF(mTmpInt2[0] + where.getWidth() / 2,
@@ -1232,13 +1323,12 @@ public class StatusBar extends SystemUI implements DemoMode,
protected void startKeyguard() {
Trace.beginSection("StatusBar#startKeyguard");
- KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
mBiometricUnlockController = new BiometricUnlockController(mContext,
- mDozeScrimController, keyguardViewMediator,
+ mDozeScrimController, mKeyguardViewMediator,
mScrimController, this, mKeyguardStateController, new Handler(),
mKeyguardUpdateMonitor, mKeyguardBypassController);
putComponent(BiometricUnlockController.class, mBiometricUnlockController);
- mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
+ mStatusBarKeyguardViewManager = mKeyguardViewMediator.registerStatusBar(this,
getBouncerContainer(), mNotificationPanel, mBiometricUnlockController,
mStatusBarWindow.findViewById(R.id.lock_icon_container), mStackScroller,
mKeyguardBypassController);
@@ -1248,7 +1338,7 @@ public class StatusBar extends SystemUI implements DemoMode,
mRemoteInputManager.getController().addCallback(mStatusBarKeyguardViewManager);
mDynamicPrivacyController.setStatusBarKeyguardViewManager(mStatusBarKeyguardViewManager);
- mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
+ mKeyguardViewMediatorCallback = mKeyguardViewMediator.getViewMediatorCallback();
mLightBarController.setBiometricUnlockController(mBiometricUnlockController);
mMediaManager.setBiometricUnlockController(mBiometricUnlockController);
Dependency.get(KeyguardDismissUtil.class).setDismissHandler(this::executeWhenUnlocked);
@@ -1734,6 +1824,16 @@ public class StatusBar extends SystemUI implements DemoMode,
return mPresenter;
}
+ @VisibleForTesting
+ void setBarStateForTest(int state) {
+ mState = state;
+ }
+
+ @VisibleForTesting
+ void setUserSetupForTest(boolean userSetup) {
+ mUserSetup = userSetup;
+ }
+
/**
* All changes to the status bar and notifications funnel through here and are batched.
*/
@@ -2425,7 +2525,6 @@ public class StatusBar extends SystemUI implements DemoMode,
public void createAndAddWindows(@Nullable RegisterStatusBarResult result) {
makeStatusBarView(result);
- mStatusBarWindowController = Dependency.get(StatusBarWindowController.class);
mStatusBarWindowController.add(mStatusBarWindow, getStatusBarHeight());
}
@@ -2669,7 +2768,6 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- // SystemUIService notifies SystemBars of configuration changes, which then calls down here
@Override
public void onConfigChanged(Configuration newConfig) {
updateResources();
@@ -3251,7 +3349,7 @@ public class StatusBar extends SystemUI implements DemoMode,
final int themeResId = lockDarkText ? R.style.Theme_SystemUI_Light : R.style.Theme_SystemUI;
if (mContext.getThemeResId() != themeResId) {
mContext.setTheme(themeResId);
- Dependency.get(ConfigurationController.class).notifyThemeChanged();
+ mConfigurationController.notifyThemeChanged();
}
}
@@ -3798,8 +3896,7 @@ public class StatusBar extends SystemUI implements DemoMode,
return;
}
if (!mDeviceInteractive) {
- PowerManager pm = mContext.getSystemService(PowerManager.class);
- pm.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
+ mPowerManager.wakeUp(SystemClock.uptimeMillis(), PowerManager.WAKE_REASON_CAMERA_LAUNCH,
"com.android.systemui:CAMERA_GESTURE");
}
vibrateForCameraGesture();
@@ -3838,20 +3935,17 @@ public class StatusBar extends SystemUI implements DemoMode,
}
boolean isCameraAllowedByAdmin() {
- // TODO(b/140060745)
- return whitelistIpcs(() -> {
- if (mDevicePolicyManager.getCameraDisabled(null,
- mLockscreenUserManager.getCurrentUserId())) {
- return false;
- } else if (mStatusBarKeyguardViewManager == null
- || (isKeyguardShowing() && isKeyguardSecure())) {
- // Check if the admin has disabled the camera specifically for the keyguard
- return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
- mLockscreenUserManager.getCurrentUserId())
- & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
- }
- return true;
- });
+ if (mDevicePolicyManager.getCameraDisabled(null,
+ mLockscreenUserManager.getCurrentUserId())) {
+ return false;
+ } else if (mStatusBarKeyguardViewManager == null
+ || (isKeyguardShowing() && isKeyguardSecure())) {
+ // Check if the admin has disabled the camera specifically for the keyguard
+ return (mDevicePolicyManager.getKeyguardDisabledFeatures(null,
+ mLockscreenUserManager.getCurrentUserId())
+ & DevicePolicyManager.KEYGUARD_DISABLE_SECURE_CAMERA) == 0;
+ }
+ return true;
}
private boolean isGoingToSleep() {
@@ -4188,11 +4282,11 @@ public class StatusBar extends SystemUI implements DemoMode,
// all notifications
protected ViewGroup mStackScroller;
- @Inject NotificationGroupManager mGroupManager;
- @Inject NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
+ private final NotificationGroupManager mGroupManager;
+ private final NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
// handling reordering
- @Inject VisualStabilityManager mVisualStabilityManager;
+ private final VisualStabilityManager mVisualStabilityManager;
protected AccessibilityManager mAccessibilityManager;
@@ -4208,9 +4302,9 @@ public class StatusBar extends SystemUI implements DemoMode,
protected StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
protected KeyguardManager mKeyguardManager;
- @Inject DeviceProvisionedController mDeviceProvisionedController;
+ private final DeviceProvisionedController mDeviceProvisionedController;
- @Inject protected NavigationBarController mNavigationBarController;
+ private final NavigationBarController mNavigationBarController;
// UI-specific methods
@@ -4226,7 +4320,7 @@ public class StatusBar extends SystemUI implements DemoMode,
protected NotificationShelf mNotificationShelf;
protected EmptyShadeView mEmptyShadeView;
- @Inject AssistManager mAssistManager;
+ private final AssistManager mAssistManager;
public boolean isDeviceInteractive() {
return mDeviceInteractive;
@@ -4285,7 +4379,7 @@ public class StatusBar extends SystemUI implements DemoMode,
}
}
- @Inject NotificationListener mNotificationListener;
+ private final NotificationListener mNotificationListener;
public void setNotificationSnoozed(StatusBarNotification sbn, SnoozeOption snoozeOption) {
if (snoozeOption.getSnoozeCriterion() != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
index cd1f0cc13297..47b56e097ec9 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbPermissionActivity.java
@@ -92,7 +92,7 @@ public class UsbPermissionActivity extends AlertActivity
mDisconnectedReceiver = new UsbDisconnectedReceiver(this, mAccessory);
} else {
boolean hasRecordPermission =
- PermissionChecker.checkPermission(
+ PermissionChecker.checkPermissionForPreflight(
this, android.Manifest.permission.RECORD_AUDIO, -1, aInfo.uid,
mPackageName)
== android.content.pm.PackageManager.PERMISSION_GRANTED;
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index ad7bba1e0790..57b09872f9c1 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -25,6 +25,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
@@ -481,6 +482,25 @@ public class KeyguardUpdateMonitorTest extends SysuiTestCase {
assertThat(mKeyguardUpdateMonitor.isUserUnlocked(randomUser)).isFalse();
}
+ @Test
+ public void testTrustUsuallyManaged_whenTrustChanges() {
+ int user = KeyguardUpdateMonitor.getCurrentUser();
+ when(mTrustManager.isTrustUsuallyManaged(eq(user))).thenReturn(true);
+ mKeyguardUpdateMonitor.onTrustManagedChanged(false /* managed */, user);
+ assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isTrue();
+ }
+
+ @Test
+ public void testTrustUsuallyManaged_resetWhenUserIsRemoved() {
+ int user = KeyguardUpdateMonitor.getCurrentUser();
+ when(mTrustManager.isTrustUsuallyManaged(eq(user))).thenReturn(true);
+ mKeyguardUpdateMonitor.onTrustManagedChanged(false /* managed */, user);
+ assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isTrue();
+
+ mKeyguardUpdateMonitor.handleUserRemoved(user);
+ assertThat(mKeyguardUpdateMonitor.isTrustUsuallyManaged(user)).isFalse();
+ }
+
private Intent putPhoneInfo(Intent intent, Bundle data, Boolean simInited) {
int subscription = simInited
? 1/* mock subid=1 */ : SubscriptionManager.DUMMY_SUBSCRIPTION_ID_BASE;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
index 30e02e6b46d2..52f7e679b49c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationEntryManagerTest.java
@@ -41,7 +41,6 @@ import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
-import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Icon;
import android.os.Handler;
@@ -145,8 +144,8 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
private class TestableNotificationEntryManager extends NotificationEntryManager {
private final CountDownLatch mCountDownLatch;
- TestableNotificationEntryManager(Context context) {
- super(context);
+ TestableNotificationEntryManager() {
+ super(new NotificationData(mock(NotificationSectionsFeatureManager.class)));
mCountDownLatch = new CountDownLatch(1);
}
@@ -250,7 +249,7 @@ public class NotificationEntryManagerTest extends SysuiTestCase {
mEntry.expandedIcon = mock(StatusBarIconView.class);
- mEntryManager = new TestableNotificationEntryManager(mContext);
+ mEntryManager = new TestableNotificationEntryManager();
Dependency.get(InitController.class).executePostInitTasks();
mEntryManager.setUpWithPresenter(mPresenter, mListContainer, mHeadsUpManager);
mEntryManager.addNotificationEntryListener(mEntryListener);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
index 8d496a72e3b2..6d275419ee94 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
@@ -46,6 +46,7 @@ import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
+import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.Before;
import org.junit.Test;
@@ -73,7 +74,9 @@ public class NotificationListControllerTest extends SysuiTestCase {
private DeviceProvisionedListener mProvisionedListener;
// TODO: Remove this once EntryManager no longer needs to be mocked
- private NotificationData mNotificationData = new NotificationData(mContext);
+ private NotificationData mNotificationData =
+ new NotificationData(new NotificationSectionsFeatureManager(
+ new DeviceConfigProxyFake(), mContext));
private int mNextNotifId = 0;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
new file mode 100644
index 000000000000..b3d0d22445b6
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
@@ -0,0 +1,69 @@
+/*
+ * 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.notification
+
+import android.provider.DeviceConfig
+import android.provider.Settings
+import android.provider.Settings.Secure.NOTIFICATION_NEW_INTERRUPTION_MODEL
+import android.testing.AndroidTestingRunner
+
+import androidx.test.filters.SmallTest
+
+import com.android.internal.config.sysui.SystemUiDeviceConfigFlags.NOTIFICATIONS_USE_PEOPLE_FILTERING
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.DeviceConfigProxyFake
+
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class NotificationSectionsFeatureManagerTest : SysuiTestCase() {
+ var manager: NotificationSectionsFeatureManager? = null
+ val proxyFake = DeviceConfigProxyFake()
+
+ @Before
+ public fun setup() {
+ Settings.Secure.putInt(mContext.getContentResolver(),
+ NOTIFICATION_NEW_INTERRUPTION_MODEL, 1)
+ manager = NotificationSectionsFeatureManager(proxyFake, mContext)
+ manager!!.clearCache()
+ }
+
+ @Test
+ public fun testPeopleFilteringOff_newInterruptionModelOn() {
+ proxyFake.setProperty(
+ DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, "false", false)
+
+ assertFalse("People filtering should be disabled", manager!!.isFilteringEnabled())
+ assertTrue("Expecting 2 buckets when people filtering is disabled",
+ manager!!.getNumberOfBuckets() == 2)
+ }
+
+ @Test
+ public fun testPeopleFilteringOn_newInterruptionModelOn() {
+ proxyFake.setProperty(
+ DeviceConfig.NAMESPACE_SYSTEMUI, NOTIFICATIONS_USE_PEOPLE_FILTERING, "true", false)
+
+ assertTrue("People filtering should be enabled", manager!!.isFilteringEnabled())
+ assertTrue("Expecting 3 buckets when people filtering is enabled",
+ manager!!.getNumberOfBuckets() == 3)
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
index 657ec61dfd11..5fbacb1d7adf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotificationDataTest.java
@@ -50,7 +50,6 @@ import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Person;
-import android.content.Context;
import android.content.Intent;
import android.content.pm.IPackageManager;
import android.content.pm.PackageManager;
@@ -78,6 +77,7 @@ import com.android.systemui.statusbar.NotificationEntryBuilder;
import com.android.systemui.statusbar.NotificationTestHelper;
import com.android.systemui.statusbar.RankingBuilder;
import com.android.systemui.statusbar.SbnBuilder;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationData.KeyguardEnvironment;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
@@ -139,7 +139,8 @@ public class NotificationDataTest extends SysuiTestCase {
mDependency.injectTestDependency(KeyguardEnvironment.class, mEnvironment);
when(mEnvironment.isDeviceProvisioned()).thenReturn(true);
when(mEnvironment.isNotificationForCurrentProfiles(any())).thenReturn(true);
- mNotificationData = new TestableNotificationData(mContext);
+ mNotificationData = new TestableNotificationData(
+ mock(NotificationSectionsFeatureManager.class));
mNotificationData.updateRanking(mock(NotificationListenerService.RankingMap.class));
mRow = new NotificationTestHelper(getContext()).createRow();
Dependency.get(InitController.class).executePostInitTasks();
@@ -631,8 +632,8 @@ public class NotificationDataTest extends SysuiTestCase {
}
public static class TestableNotificationData extends NotificationData {
- public TestableNotificationData(Context context) {
- super(context);
+ public TestableNotificationData(NotificationSectionsFeatureManager sectionsFeatureManager) {
+ super(sectionsFeatureManager);
}
public static final String OVERRIDE_RANK = "r";
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
index addceb5def6e..3f467eae1d57 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationRoundnessManagerTest.java
@@ -32,10 +32,12 @@ import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationTestHelper;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
+import com.android.systemui.util.DeviceConfigProxy;
import org.junit.Assert;
import org.junit.Before;
@@ -64,7 +66,9 @@ public class NotificationRoundnessManagerTest extends SysuiTestCase {
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
- mRoundnessManager = new NotificationRoundnessManager(mBypassController, mContext);
+ mRoundnessManager = new NotificationRoundnessManager(
+ mBypassController,
+ new NotificationSectionsFeatureManager(new DeviceConfigProxy(), mContext));
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
NotificationTestHelper testHelper = new NotificationTestHelper(getContext());
mFirst = testHelper.createRow();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
index 31054260eb15..11ae0cc34787 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutTest.java
@@ -55,7 +55,6 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.EmptyShadeView;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
@@ -65,6 +64,7 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.SysuiStatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import com.android.systemui.statusbar.notification.NotificationSectionsFeatureManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -79,6 +79,7 @@ import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.statusbar.phone.StatusBar;
import com.android.systemui.statusbar.phone.StatusBarTest.TestableNotificationEntryManager;
import com.android.systemui.statusbar.policy.ConfigurationController;
+import com.android.systemui.util.DeviceConfigProxyFake;
import org.junit.After;
import org.junit.Before;
@@ -144,11 +145,10 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mDependency.injectMockDependency(ShadeController.class);
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
- mEntryManager = new TestableNotificationEntryManager(mContext);
+ mEntryManager = new TestableNotificationEntryManager(mNotificationData);
mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
Dependency.get(InitController.class).executePostInitTasks();
- mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, mHeadsUpManager,
- mNotificationData);
+ mEntryManager.setUpForTest(mock(NotificationPresenter.class), null, mHeadsUpManager);
NotificationShelf notificationShelf = mock(NotificationShelf.class);
@@ -166,7 +166,8 @@ public class NotificationStackScrollLayoutTest extends SysuiTestCase {
mock(SysuiStatusBarStateController.class),
mHeadsUpManager,
mKeyguardBypassController,
- new FalsingManagerFake());
+ new FalsingManagerFake(),
+ new NotificationSectionsFeatureManager(new DeviceConfigProxyFake(), mContext));
mStackScroller = spy(mStackScrollerInternal);
mStackScroller.setShelf(notificationShelf);
mStackScroller.setStatusBar(mBar);
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 3ba3e281dc81..cb87d7d842a4 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
@@ -89,6 +89,8 @@ public class KeyguardBouncerTest extends SysuiTestCase {
private KeyguardBypassController mKeyguardBypassController;
@Mock
private Handler mHandler;
+ @Mock
+ private KeyguardSecurityModel mKeyguardSecurityModel;
private KeyguardBouncer mBouncer;
@@ -97,6 +99,9 @@ public class KeyguardBouncerTest extends SysuiTestCase {
com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
MockitoAnnotations.initMocks(this);
mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
+ mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel);
+ when(mKeyguardSecurityModel.getSecurityMode(anyInt()))
+ .thenReturn(KeyguardSecurityModel.SecurityMode.None);
DejankUtils.setImmediate(true);
final ViewGroup container = new FrameLayout(getContext());
when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
@@ -306,14 +311,6 @@ public class KeyguardBouncerTest extends SysuiTestCase {
}
@Test
- public void testNeedsFullscreenBouncer_asksKeyguardView() {
- mBouncer.ensureView();
- mBouncer.needsFullscreenBouncer();
- verify(mKeyguardHostView).getSecurityMode();
- verify(mKeyguardHostView, never()).getCurrentSecurityMode();
- }
-
- @Test
public void testIsFullscreenBouncer_asksKeyguardView() {
mBouncer.ensureView();
mBouncer.isFullscreenBouncer();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
index f163886193b4..2631ced77972 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarTest.java
@@ -65,7 +65,7 @@ import android.view.ViewGroup.LayoutParams;
import androidx.test.filters.SmallTest;
-import com.android.internal.logging.MetricsLogger;
+import com.android.internal.colorextraction.ColorExtractor;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.logging.testing.FakeMetricsLogger;
import com.android.internal.statusbar.IStatusBarService;
@@ -89,7 +89,6 @@ import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
-import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.KeyguardIndicationController;
@@ -100,14 +99,15 @@ import com.android.systemui.statusbar.NotificationLockscreenUserManager;
import com.android.systemui.statusbar.NotificationMediaManager;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
-import com.android.systemui.statusbar.NotificationShelf;
import com.android.systemui.statusbar.NotificationViewHierarchyManager;
import com.android.systemui.statusbar.PulseExpansionHandler;
import com.android.systemui.statusbar.RemoteInputController;
import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.StatusBarStateControllerImpl;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
+import com.android.systemui.statusbar.VibratorHelper;
import com.android.systemui.statusbar.notification.BypassHeadsUpNotifier;
+import com.android.systemui.statusbar.notification.DynamicPrivacyController;
+import com.android.systemui.statusbar.notification.NotifPipelineInitializer;
import com.android.systemui.statusbar.notification.NotificationAlertingManager;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -122,10 +122,14 @@ import com.android.systemui.statusbar.notification.row.NotificationGutsManager;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.policy.BatteryController;
+import com.android.systemui.statusbar.policy.ConfigurationController;
import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.KeyguardStateController;
+import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RemoteInputQuickSettingsDisabler;
import com.android.systemui.statusbar.policy.UserSwitcherController;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.InjectionInflationController;
import org.junit.Before;
import org.junit.Test;
@@ -144,6 +148,15 @@ import java.util.HashSet;
@RunWith(AndroidTestingRunner.class)
@RunWithLooper(setAsMainLooper = true)
public class StatusBarTest extends SysuiTestCase {
+
+ private StatusBar mStatusBar;
+ private FakeMetricsLogger mMetricsLogger;
+ private PowerManager mPowerManager;
+ private TestableNotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
+ private CommandQueue mCommandQueue;
+
+ @Mock private LightBarController mLightBarController;
+ @Mock private StatusBarIconController mStatusBarIconController;
@Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
@Mock private KeyguardStateController mKeyguardStateController;
@Mock private KeyguardIndicationController mKeyguardIndicationController;
@@ -158,7 +171,6 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private BiometricUnlockController mBiometricUnlockController;
@Mock private NotificationData mNotificationData;
@Mock private NotificationInterruptionStateProvider.HeadsUpSuppressor mHeadsUpSuppressor;
- @Mock private NotificationViewHierarchyManager mViewHierarchyManager;
@Mock private VisualStabilityManager mVisualStabilityManager;
@Mock private NotificationListener mNotificationListener;
@Mock private KeyguardViewMediator mKeyguardViewMediator;
@@ -185,17 +197,25 @@ public class StatusBarTest extends SysuiTestCase {
@Mock private NavigationBarController mNavigationBarController;
@Mock private BypassHeadsUpNotifier mBypassHeadsUpNotifier;
@Mock private SysuiColorExtractor mColorExtractor;
+ @Mock private ColorExtractor.GradientColors mGradientColors;
@Mock private DozeLog mDozeLog;
@Mock private PulseExpansionHandler mPulseExpansionHandler;
- @Mock private RemoteInputQuickSettingsDisabler mRemoteInputQuickSettingsDisabler;
@Mock private NotificationWakeUpCoordinator mNotificationWakeUpCoordinator;
@Mock private KeyguardBypassController mKeyguardBypassController;
-
- private TestableStatusBar mStatusBar;
- private FakeMetricsLogger mMetricsLogger;
- private PowerManager mPowerManager;
- private TestableNotificationInterruptionStateProvider mNotificationInterruptionStateProvider;
- private CommandQueue mCommandQueue;
+ @Mock private InjectionInflationController mInjectionInflationController;
+ @Mock private DynamicPrivacyController mDynamicPrivacyController;
+ @Mock private NotifPipelineInitializer mNotifPipelineInitializer;
+ @Mock private ZenModeController mZenModeController;
+ @Mock private AutoHideController mAutoHideController;
+ @Mock private NotificationViewHierarchyManager mNotificationViewHierarchyManager;
+ @Mock private UserSwitcherController mUserSwitcherController;
+ @Mock private NetworkController mNetworkController;
+ @Mock private VibratorHelper mVibratorHelper;
+ @Mock private BubbleController mBubbleController;
+ @Mock private NotificationGroupManager mGroupManager;
+ @Mock private NotificationGroupAlertTransferHelper mGroupAlertTransferHelper;
+ @Mock private StatusBarWindowController mStatusBarWindowController;
+ @Mock private NotificationIconAreaController mNotificationIconAreaController;
@Before
public void setup() throws Exception {
@@ -216,7 +236,7 @@ public class StatusBarTest extends SysuiTestCase {
mMetricsLogger = new FakeMetricsLogger();
TestableNotificationEntryManager entryManager = new TestableNotificationEntryManager(
- mContext);
+ mNotificationData);
NotificationLogger notificationLogger = new NotificationLogger(mNotificationListener,
Dependency.get(UiOffloadThread.class), entryManager, mStatusBarStateController,
mExpansionStateLogger);
@@ -249,69 +269,92 @@ public class StatusBarTest extends SysuiTestCase {
mHeadsUpManager, mHeadsUpSuppressor);
when(mRemoteInputManager.getController()).thenReturn(mRemoteInputController);
- mStatusBar = new TestableStatusBar(
- mStatusBarKeyguardViewManager,
- mKeyguardIndicationController,
- mStackScroller,
- mPowerManager,
- mNotificationPanelView,
- mBarService,
- mNotificationListener,
- notificationLogger,
- mVisualStabilityManager,
- mViewHierarchyManager,
- entryManager,
- mScrimController,
- mBiometricUnlockController,
- mKeyguardViewMediator,
- mRemoteInputManager,
- mock(NotificationGroupManager.class),
- mock(NotificationGroupAlertTransferHelper.class),
- new FalsingManagerFake(),
- mock(StatusBarWindowController.class),
- mock(NotificationIconAreaController.class),
- mDozeScrimController,
- mock(NotificationShelf.class),
- mLockscreenUserManager,
- mCommandQueue,
- mNotificationPresenter,
- mock(BubbleController.class),
- mNavigationBarController,
- mock(AutoHideController.class),
+
+ WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
+ wakefulnessLifecycle.dispatchStartedWakingUp();
+ wakefulnessLifecycle.dispatchFinishedWakingUp();
+
+ when(mGradientColors.supportsDarkText()).thenReturn(true);
+ when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
+ ConfigurationController configurationController = new ConfigurationControllerImpl(mContext);
+
+ mStatusBar = new StatusBar(
+ mLightBarController,
+ mAutoHideController,
mKeyguardUpdateMonitor,
- mStatusBarWindowView,
+ mStatusBarIconController,
+ mDozeLog,
+ mInjectionInflationController,
+ mPulseExpansionHandler,
+ mNotificationWakeUpCoordinator,
+ mKeyguardBypassController,
+ mKeyguardStateController,
+ mHeadsUpManager,
+ mDynamicPrivacyController,
+ mBypassHeadsUpNotifier,
+ true,
+ mNotifPipelineInitializer,
+ new FalsingManagerFake(),
mBroadcastDispatcher,
- mAssistManager,
+ new RemoteInputQuickSettingsDisabler(
+ mContext,
+ configurationController
+ ),
mNotificationGutsManager,
- mNotificationMediaManager,
+ notificationLogger,
+ entryManager,
+ mNotificationInterruptionStateProvider,
+ mNotificationViewHierarchyManager,
mForegroundServiceController,
mAppOpsController,
- mStatusBarStateController,
- mDeviceProvisionedController,
+ mKeyguardViewMediator,
+ mZenModeController,
mNotificationAlertingManager,
- mNotificationInterruptionStateProvider,
- mMetricsLogger,
- mHeadsUpManager,
- mKeyguardStateController,
- new ScreenLifecycle(),
- mBypassHeadsUpNotifier,
- mColorExtractor,
new DisplayMetrics(),
+ mMetricsLogger,
Dependency.get(UiOffloadThread.class),
- mDozeLog,
- mPulseExpansionHandler,
- new RemoteInputQuickSettingsDisabler(
- mContext,
- new ConfigurationControllerImpl(mContext)
- ),
- mNotificationWakeUpCoordinator,
- mKeyguardBypassController);
+ mNotificationMediaManager,
+ mLockscreenUserManager,
+ mRemoteInputManager,
+ mUserSwitcherController,
+ mNetworkController,
+ mBatteryController,
+ mColorExtractor,
+ new ScreenLifecycle(),
+ wakefulnessLifecycle,
+ mStatusBarStateController,
+ mVibratorHelper,
+ mBubbleController,
+ mGroupManager,
+ mGroupAlertTransferHelper,
+ mVisualStabilityManager,
+ mDeviceProvisionedController,
+ mNavigationBarController,
+ mAssistManager,
+ mNotificationListener,
+ configurationController,
+ mStatusBarWindowController);
+ // TODO: we should be able to call mStatusBar.start() and have all the below values
+ // initialized automatically.
mStatusBar.mContext = mContext;
mStatusBar.mComponents = mContext.getComponents();
+ mStatusBar.mStatusBarKeyguardViewManager = mStatusBarKeyguardViewManager;
+ mStatusBar.mStatusBarWindow = mStatusBarWindowView;
+ mStatusBar.mBiometricUnlockController = mBiometricUnlockController;
+ mStatusBar.mScrimController = mScrimController;
+ mStatusBar.mNotificationPanel = mNotificationPanelView;
+ mStatusBar.mCommandQueue = mCommandQueue;
+ mStatusBar.mDozeScrimController = mDozeScrimController;
+ mStatusBar.mNotificationIconAreaController = mNotificationIconAreaController;
+ mStatusBar.mPresenter = mNotificationPresenter;
+ mStatusBar.mKeyguardIndicationController = mKeyguardIndicationController;
+ mStatusBar.mPowerManager = mPowerManager;
+ mStatusBar.mBarService = mBarService;
+ mStatusBar.mStackScroller = mStackScroller;
mStatusBar.putComponent(StatusBar.class, mStatusBar);
Dependency.get(InitController.class).executePostInitTasks();
entryManager.setUpForTest(mock(NotificationPresenter.class), mStackScroller,
- mHeadsUpManager, mNotificationData);
+ mHeadsUpManager);
entryManager.addNotificationEntryListener(mEntryListener);
notificationLogger.setUpWithContainer(mStackScroller);
}
@@ -636,8 +679,8 @@ public class StatusBarTest extends SysuiTestCase {
@Test
@RunWithLooper(setAsMainLooper = true)
public void testUpdateKeyguardState_DoesNotCrash() {
- mStatusBar.mState = StatusBarState.KEYGUARD;
- when(mStatusBar.mLockscreenUserManager.getCurrentProfiles()).thenReturn(
+ mStatusBar.setBarStateForTest(StatusBarState.KEYGUARD);
+ when(mLockscreenUserManager.getCurrentProfiles()).thenReturn(
new SparseArray<>());
mStatusBar.onStateChanged(StatusBarState.SHADE);
}
@@ -768,8 +811,7 @@ public class StatusBarTest extends SysuiTestCase {
verify(mStatusBarStateController).setState(eq(StatusBarState.KEYGUARD));
// If useFullscreenUserSwitcher is true, state is set to FULLSCREEN_USER_SWITCHER.
- mStatusBar.mUserSwitcherController = mock(UserSwitcherController.class);
- when(mStatusBar.mUserSwitcherController.useFullscreenUserSwitcher()).thenReturn(true);
+ when(mUserSwitcherController.useFullscreenUserSwitcher()).thenReturn(true);
mStatusBar.showKeyguardImpl();
verify(mStatusBarStateController).setState(eq(StatusBarState.FULLSCREEN_USER_SWITCHER));
}
@@ -821,155 +863,23 @@ public class StatusBarTest extends SysuiTestCase {
any(UserHandle.class));
}
- static class TestableStatusBar extends StatusBar {
- public TestableStatusBar(StatusBarKeyguardViewManager man,
- KeyguardIndicationController key,
- NotificationStackScrollLayout stack,
- PowerManager pm, NotificationPanelView panelView,
- IStatusBarService barService, NotificationListener notificationListener,
- NotificationLogger notificationLogger,
- VisualStabilityManager visualStabilityManager,
- NotificationViewHierarchyManager viewHierarchyManager,
- TestableNotificationEntryManager entryManager, ScrimController scrimController,
- BiometricUnlockController biometricUnlockController,
- KeyguardViewMediator keyguardViewMediator,
- NotificationRemoteInputManager notificationRemoteInputManager,
- NotificationGroupManager notificationGroupManager,
- NotificationGroupAlertTransferHelper notificationGroupAlertTransferHelper,
- FalsingManager falsingManager,
- StatusBarWindowController statusBarWindowController,
- NotificationIconAreaController notificationIconAreaController,
- DozeScrimController dozeScrimController,
- NotificationShelf notificationShelf,
- NotificationLockscreenUserManager notificationLockscreenUserManager,
- CommandQueue commandQueue,
- StatusBarNotificationPresenter notificationPresenter,
- BubbleController bubbleController,
- NavigationBarController navBarController,
- AutoHideController autoHideController,
- KeyguardUpdateMonitor keyguardUpdateMonitor,
- StatusBarWindowView statusBarWindow,
- BroadcastDispatcher broadcastDispatcher,
- AssistManager assistManager,
- NotificationGutsManager notificationGutsManager,
- NotificationMediaManager notificationMediaManager,
- ForegroundServiceController foregroundServiceController,
- AppOpsController appOpsController,
- SysuiStatusBarStateController statusBarStateController,
- DeviceProvisionedController deviceProvisionedController,
- NotificationAlertingManager notificationAlertingManager,
- NotificationInterruptionStateProvider notificationInterruptionStateProvider,
- MetricsLogger metricsLogger,
- HeadsUpManagerPhone headsUpManager,
- KeyguardStateController keyguardStateController,
- ScreenLifecycle screenLifecycle,
- BypassHeadsUpNotifier bypassHeadsUpNotifier,
- SysuiColorExtractor colorExtractor, DisplayMetrics displayMetrics,
- UiOffloadThread uiOffloadThread,
- DozeLog dozeLog,
- PulseExpansionHandler pulseExpansionHandler,
- RemoteInputQuickSettingsDisabler remoteInputQuickSettingsDisabler,
- NotificationWakeUpCoordinator notificationWakeUpCoordinator,
- KeyguardBypassController keyguardBypassController) {
- mStatusBarKeyguardViewManager = man;
- mKeyguardIndicationController = key;
- mStackScroller = stack;
- mPowerManager = pm;
- mNotificationPanel = panelView;
- mBarService = barService;
- mNotificationListener = notificationListener;
- mNotificationLogger = notificationLogger;
- mWakefulnessLifecycle = createAwakeWakefulnessLifecycle();
- mVisualStabilityManager = visualStabilityManager;
- mViewHierarchyManager = viewHierarchyManager;
- mEntryManager = entryManager;
- mScrimController = scrimController;
- mBiometricUnlockController = biometricUnlockController;
- mKeyguardViewMediator = keyguardViewMediator;
- mRemoteInputManager = notificationRemoteInputManager;
- mGroupManager = notificationGroupManager;
- mGroupAlertTransferHelper = notificationGroupAlertTransferHelper;
- mFalsingManager = falsingManager;
- mStatusBarWindowController = statusBarWindowController;
- mNotificationIconAreaController = notificationIconAreaController;
- mDozeScrimController = dozeScrimController;
- mNotificationShelf = notificationShelf;
- mLockscreenUserManager = notificationLockscreenUserManager;
- mCommandQueue = commandQueue;
- mPresenter = notificationPresenter;
- mGestureWakeLock = mock(PowerManager.WakeLock.class);
- mBubbleController = bubbleController;
- mNavigationBarController = navBarController;
- mAutoHideController = autoHideController;
- mKeyguardUpdateMonitor = keyguardUpdateMonitor;
- mStatusBarWindow = statusBarWindow;
- mDozeServiceHost.mWakeLockScreenPerformsAuth = false;
- mBroadcastDispatcher = broadcastDispatcher;
- mAssistManager = assistManager;
- mGutsManager = notificationGutsManager;
- mMediaManager = notificationMediaManager;
- mForegroundServiceController = foregroundServiceController;
- mAppOpsController = appOpsController;
- mStatusBarStateController = statusBarStateController;
- mDeviceProvisionedController = deviceProvisionedController;
- mNotificationAlertingManager = notificationAlertingManager;
- mNotificationInterruptionStateProvider = notificationInterruptionStateProvider;
- mMetricsLogger = metricsLogger;
- mHeadsUpManager = headsUpManager;
- mKeyguardStateController = keyguardStateController;
- mScreenLifecycle = screenLifecycle;
- mBypassHeadsUpNotifier = bypassHeadsUpNotifier;
- mColorExtractor = colorExtractor;
- mDisplayMetrics = displayMetrics;
- mUiOffloadThread = uiOffloadThread;
- mDozeLog = dozeLog;
- mPulseExpansionHandler = pulseExpansionHandler;
- mRemoteInputQuickSettingsDisabler = remoteInputQuickSettingsDisabler;
- mWakeUpCoordinator = notificationWakeUpCoordinator;
- mKeyguardBypassController = keyguardBypassController;
- }
-
- private WakefulnessLifecycle createAwakeWakefulnessLifecycle() {
- WakefulnessLifecycle wakefulnessLifecycle = new WakefulnessLifecycle();
- wakefulnessLifecycle.dispatchStartedWakingUp();
- wakefulnessLifecycle.dispatchFinishedWakingUp();
- return wakefulnessLifecycle;
- }
-
- @Override
- protected void updateTheme() {
- // Do nothing for now, until we have more mocking and StatusBar is smaller.
- }
-
- public void setBarStateForTest(int state) {
- mState = state;
- }
-
- public void setUserSetupForTest(boolean userSetup) {
- mUserSetup = userSetup;
- }
-
- }
-
public static class TestableNotificationEntryManager extends NotificationEntryManager {
- public TestableNotificationEntryManager(Context context) {
- super(context);
+ public TestableNotificationEntryManager(NotificationData notificationData) {
+ super(notificationData);
}
public void setUpForTest(NotificationPresenter presenter,
NotificationListContainer listContainer,
- HeadsUpManagerPhone headsUpManager,
- NotificationData notificationData) {
+ HeadsUpManagerPhone headsUpManager) {
super.setUpWithPresenter(presenter, listContainer, headsUpManager);
- mNotificationData = notificationData;
}
}
public static class TestableNotificationInterruptionStateProvider extends
NotificationInterruptionStateProvider {
- public TestableNotificationInterruptionStateProvider(
+ TestableNotificationInterruptionStateProvider(
Context context,
PowerManager powerManager,
IDreamManager dreamManager,
diff --git a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
index 4f021ad3cee0..514eb77c3201 100644
--- a/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
+++ b/services/accessibility/java/com/android/server/accessibility/AbstractAccessibilityServiceConnection.java
@@ -350,9 +350,9 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
protected abstract boolean hasRightsToCurrentUserLocked();
+ @Nullable
@Override
- public List<AccessibilityWindowInfo> getWindows() {
- ensureWindowsAvailableTimed(Display.DEFAULT_DISPLAY);
+ public AccessibilityWindowInfo.WindowListSparseArray getWindows() {
synchronized (mLock) {
if (!hasRightsToCurrentUserLocked()) {
return null;
@@ -362,38 +362,39 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
if (!permissionGranted) {
return null;
}
- List<AccessibilityWindowInfo> internalWindowList =
- mA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY);
- if (internalWindowList == null) {
- return null;
- }
if (!mSecurityPolicy.checkAccessibilityAccess(this)) {
return null;
}
- List<AccessibilityWindowInfo> returnedWindowList = new ArrayList<>();
- final int windowCount = internalWindowList.size();
- for (int i = 0; i < windowCount; i++) {
- AccessibilityWindowInfo window = internalWindowList.get(i);
- AccessibilityWindowInfo windowClone =
- AccessibilityWindowInfo.obtain(window);
- windowClone.setConnectionId(mId);
- returnedWindowList.add(windowClone);
+ final AccessibilityWindowInfo.WindowListSparseArray allWindows =
+ new AccessibilityWindowInfo.WindowListSparseArray();
+ final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked();
+ final int displayListCounts = displayList.size();
+ if (displayListCounts > 0) {
+ for (int i = 0; i < displayListCounts; i++) {
+ final int displayId = displayList.get(i);
+ ensureWindowsAvailableTimedLocked(displayId);
+
+ final List<AccessibilityWindowInfo> windowList = getWindowsByDisplayLocked(
+ displayId);
+ if (windowList != null) {
+ allWindows.put(displayId, windowList);
+ }
+ }
}
- return returnedWindowList;
+ return allWindows;
}
}
@Override
public AccessibilityWindowInfo getWindow(int windowId) {
- int displayId = Display.INVALID_DISPLAY;
synchronized (mLock) {
+ int displayId = Display.INVALID_DISPLAY;
if (windowId != AccessibilityWindowInfo.UNDEFINED_WINDOW_ID) {
displayId = mA11yWindowManager.getDisplayIdByUserIdAndWindowIdLocked(
mSystemSupport.getCurrentUserIdLocked(), windowId);
}
- }
- ensureWindowsAvailableTimed(displayId);
- synchronized (mLock) {
+ ensureWindowsAvailableTimedLocked(displayId);
+
if (!hasRightsToCurrentUserLocked()) {
return null;
}
@@ -1316,35 +1317,33 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
*
* @param displayId The logical display id.
*/
- private void ensureWindowsAvailableTimed(int displayId) {
- synchronized (mLock) {
- if (mA11yWindowManager.getWindowListLocked(displayId) != null) {
- return;
- }
- // If we have no registered callback, update the state we
- // we may have to register one but it didn't happen yet.
- if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
- // Invokes client change to make sure tracking window enabled.
- mSystemSupport.onClientChangeLocked(false);
- }
- // We have no windows but do not care about them, done.
- if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
+ private void ensureWindowsAvailableTimedLocked(int displayId) {
+ if (mA11yWindowManager.getWindowListLocked(displayId) != null) {
+ return;
+ }
+ // If we have no registered callback, update the state we
+ // we may have to register one but it didn't happen yet.
+ if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
+ // Invokes client change to make sure tracking window enabled.
+ mSystemSupport.onClientChangeLocked(false);
+ }
+ // We have no windows but do not care about them, done.
+ if (!mA11yWindowManager.isTrackingWindowsLocked(displayId)) {
+ return;
+ }
+
+ // Wait for the windows with a timeout.
+ final long startMillis = SystemClock.uptimeMillis();
+ while (mA11yWindowManager.getWindowListLocked(displayId) == null) {
+ final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
+ final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis;
+ if (remainMillis <= 0) {
return;
}
-
- // Wait for the windows with a timeout.
- final long startMillis = SystemClock.uptimeMillis();
- while (mA11yWindowManager.getWindowListLocked(displayId) == null) {
- final long elapsedMillis = SystemClock.uptimeMillis() - startMillis;
- final long remainMillis = WAIT_WINDOWS_TIMEOUT_MILLIS - elapsedMillis;
- if (remainMillis <= 0) {
- return;
- }
- try {
- mLock.wait(remainMillis);
- } catch (InterruptedException ie) {
- /* ignore */
- }
+ try {
+ mLock.wait(remainMillis);
+ } catch (InterruptedException ie) {
+ /* ignore */
}
}
}
@@ -1442,6 +1441,24 @@ abstract class AbstractAccessibilityServiceConnection extends IAccessibilityServ
interrogatingPid, interrogatingTid);
}
+ private List<AccessibilityWindowInfo> getWindowsByDisplayLocked(int displayId) {
+ final List<AccessibilityWindowInfo> internalWindowList =
+ mA11yWindowManager.getWindowListLocked(displayId);
+ if (internalWindowList == null) {
+ return null;
+ }
+ final List<AccessibilityWindowInfo> returnedWindowList = new ArrayList<>();
+ final int windowCount = internalWindowList.size();
+ for (int i = 0; i < windowCount; i++) {
+ AccessibilityWindowInfo window = internalWindowList.get(i);
+ AccessibilityWindowInfo windowClone =
+ AccessibilityWindowInfo.obtain(window);
+ windowClone.setConnectionId(mId);
+ returnedWindowList.add(windowClone);
+ }
+ return returnedWindowList;
+ }
+
public ComponentName getComponentName() {
return mComponentName;
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
index 0038a27db384..cb858ac11b00 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityWindowManager.java
@@ -1472,11 +1472,27 @@ public class AccessibilityWindowManager {
public int getDisplayIdByUserIdAndWindowIdLocked(int userId, int windowId) {
final IBinder windowToken = getWindowTokenForUserAndWindowIdLocked(userId, windowId);
final int displayId = mWindowManagerInternal.getDisplayIdForWindow(windowToken);
-
return displayId;
}
/**
+ * Returns the display list including all displays which are tracking windows.
+ *
+ * @return The display list.
+ */
+ public ArrayList<Integer> getDisplayListLocked() {
+ final ArrayList<Integer> displayList = new ArrayList<>();
+ final int count = mDisplayWindowsObservers.size();
+ for (int i = 0; i < count; i++) {
+ final DisplayWindowsObserver observer = mDisplayWindowsObservers.valueAt(i);
+ if (observer != null) {
+ displayList.add(observer.mDisplayId);
+ }
+ }
+ return displayList;
+ }
+
+ /**
* Gets current input focused window token from window manager, and returns its windowId.
*
* @param userId The userId
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java b/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java
index 7e8fb295d036..3dfe59e142a6 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/AccessibilityGestureDetector.java
@@ -408,9 +408,6 @@ class AccessibilityGestureDetector extends GestureDetector.SimpleOnGestureListen
cancelGesture();
}
- public boolean firstTapDetected() {
- return mFirstTapDetected;
- }
@Override
public void onLongPress(MotionEvent e) {
diff --git a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
index c60e35e2cc6d..b62e260aacad 100644
--- a/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
+++ b/services/accessibility/java/com/android/server/accessibility/gestures/TouchExplorer.java
@@ -411,24 +411,12 @@ public class TouchExplorer extends BaseEventStreamTransformation
// we resent the delayed callback and wait again.
mSendHoverEnterAndMoveDelayed.cancel();
mSendHoverExitDelayed.cancel();
-
// If a touch exploration gesture is in progress send events for its end.
if (mState.isTouchExploring()) {
sendHoverExitAndTouchExplorationGestureEndIfNeeded(policyFlags);
}
- // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double
- // tap.
- if (!mGestureDetector.firstTapDetected() && mState.isClear()) {
- mSendTouchExplorationEndDelayed.forceSendAndRemove();
- mSendTouchInteractionEndDelayed.forceSendAndRemove();
- mDispatcher.sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
- } else {
- // Let gesture to handle to avoid duplicated TYPE_TOUCH_INTERACTION_END event.
- mSendTouchInteractionEndDelayed.cancel();
- }
-
- if (!mGestureDetector.firstTapDetected() && !mState.isTouchExploring()) {
+ if (mState.isClear()) {
if (!mSendHoverEnterAndMoveDelayed.isPending()) {
// Queue a delayed transition to STATE_TOUCH_EXPLORING.
// If we do not detect that this is a gesture, delegation or drag the transition
@@ -441,6 +429,12 @@ public class TouchExplorer extends BaseEventStreamTransformation
// Cache the event until we discern exploration from gesturing.
mSendHoverEnterAndMoveDelayed.addEvent(event, rawEvent);
}
+ mSendTouchExplorationEndDelayed.forceSendAndRemove();
+ mSendTouchInteractionEndDelayed.forceSendAndRemove();
+ mDispatcher.sendAccessibilityEvent(AccessibilityEvent.TYPE_TOUCH_INTERACTION_START);
+ } else {
+ // Avoid duplicated TYPE_TOUCH_INTERACTION_START event when 2nd tap of double tap.
+ mSendTouchInteractionEndDelayed.cancel();
}
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index ee98af4020ad..7cbd1fcebb94 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9736,6 +9736,10 @@ public class ActivityManagerService extends IActivityManager.Stub
sb.append("Foreground: ")
.append(process.isInterestingToUserLocked() ? "Yes" : "No")
.append("\n");
+ if (process.startTime > 0) {
+ long runtimeMillis = SystemClock.elapsedRealtime() - process.startTime;
+ sb.append("Process-Runtime: ").append(runtimeMillis).append("\n");
+ }
}
if (activityShortComponentName != null) {
sb.append("Activity: ").append(activityShortComponentName).append("\n");
diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING
index 21d4925722d0..bc4707f04724 100644
--- a/services/core/java/com/android/server/am/TEST_MAPPING
+++ b/services/core/java/com/android/server/am/TEST_MAPPING
@@ -33,7 +33,6 @@
},
{
"name": "FrameworksMockingServicesTests",
- "file_patterns": ["AppCompactor\\.java"],
"options": [
{
"include-filter": "com.android.server.am."
diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java
index 8e4474c462ab..175419117898 100644
--- a/services/core/java/com/android/server/am/UserController.java
+++ b/services/core/java/com/android/server/am/UserController.java
@@ -1184,7 +1184,7 @@ class UserController implements Handler.Callback {
updateStartedUserArrayLU();
}
needStart = true;
- t.traceBegin("updateStateStopping");
+ t.traceEnd();
}
if (uss.state == UserState.STATE_BOOTING) {
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index 8e09d0e5958e..852b26d1ff07 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -47,7 +47,8 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@Override
public void reportChange(long changeId, ApplicationInfo appInfo) {
- reportChange(changeId, appInfo, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
+ reportChange(changeId, appInfo.uid,
+ StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
}
@Override
@@ -60,13 +61,18 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
@Override
+ public void reportChangeByUid(long changeId, int uid) {
+ reportChange(changeId, uid, StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__LOGGED);
+ }
+
+ @Override
public boolean isChangeEnabled(long changeId, ApplicationInfo appInfo) {
if (CompatConfig.get().isChangeEnabled(changeId, appInfo)) {
- reportChange(changeId, appInfo,
+ reportChange(changeId, appInfo.uid,
StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__ENABLED);
return true;
}
- reportChange(changeId, appInfo,
+ reportChange(changeId, appInfo.uid,
StatsLog.APP_COMPATIBILITY_CHANGE_REPORTED__STATE__DISABLED);
return false;
}
@@ -81,6 +87,19 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
@Override
+ public boolean isChangeEnabledByUid(long changeId, int uid) {
+ String[] packages = mContext.getPackageManager().getPackagesForUid(uid);
+ if (packages == null || packages.length == 0) {
+ return true;
+ }
+ boolean enabled = true;
+ for (String packageName : packages) {
+ enabled = enabled && isChangeEnabledByPackageName(changeId, packageName);
+ }
+ return enabled;
+ }
+
+ @Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, "platform_compat", pw)) return;
CompatConfig.get().dumpConfig(pw);
@@ -95,8 +114,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
return null;
}
- private void reportChange(long changeId, ApplicationInfo appInfo, int state) {
- int uid = appInfo.uid;
+ private void reportChange(long changeId, int uid, int state) {
mChangeReporter.reportChange(uid, changeId, state);
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 4f4baab204e6..61d4d4bf9ac1 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -850,36 +850,25 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
mAddress, Constants.ADDR_BROADCAST, systemAudioStatusOn));
if (systemAudioStatusOn) {
+ // If TV sends out SAM Request with a path of a non-CEC device, which should not show
+ // up in the CEC device list and not under the current AVR device, the AVR would switch
+ // to ARC.
int sourcePhysicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
- if (sourcePhysicalAddress != getActiveSource().physicalAddress) {
- // If the Active Source recorded by the current device is not synced up with TV,
- // update the Active Source internally.
- if (sourcePhysicalAddress == mService.getPhysicalAddress()) {
- // If the active path is the current device itself, update with local info
- if (mService.playback() != null) {
- setActiveSource(mService.playback().mAddress, sourcePhysicalAddress);
- } else {
- setActiveSource(mAddress, sourcePhysicalAddress);
- }
- } else {
- // If it's not the current device, look for the device info from the list
- for (HdmiDeviceInfo info : HdmiUtils.sparseArrayToList(mDeviceInfos)) {
- if (info.getPhysicalAddress() == sourcePhysicalAddress) {
- setActiveSource(info.getLogicalAddress(), info.getPhysicalAddress());
- break;
- }
- }
- }
- // If the Active path from TV's System Audio Mode request does not belong to any
- // device in the local device list, record the new Active physicalAddress with an
- // unregistered logical address first. Then query the Active Source again.
- if (sourcePhysicalAddress != getActiveSource().physicalAddress) {
- setActiveSource(Constants.ADDR_UNREGISTERED, sourcePhysicalAddress);
- mService.sendCecCommand(
- HdmiCecMessageBuilder.buildRequestActiveSource(mAddress));
+ if (HdmiUtils.getLocalPortFromPhysicalAddress(
+ sourcePhysicalAddress, getDeviceInfo().getPhysicalAddress())
+ != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE) {
+ return true;
+ }
+ boolean isDeviceInCecDeviceList = false;
+ for (HdmiDeviceInfo info : HdmiUtils.sparseArrayToList(mDeviceInfos)) {
+ if (info.getPhysicalAddress() == sourcePhysicalAddress) {
+ isDeviceInCecDeviceList = true;
+ break;
}
}
- switchInputOnReceivingNewActivePath(sourcePhysicalAddress);
+ if (!isDeviceInCecDeviceList) {
+ switchInputOnReceivingNewActivePath(sourcePhysicalAddress);
+ }
}
return true;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index c3354e1d7e0f..1794df3b602e 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -311,6 +311,11 @@ public class HdmiControlService extends SystemService {
private IHdmiControlCallback mDisplayStatusCallback = null;
@Nullable
+ // Save callback when the device is still under logcial address allocation
+ // Invoke once new local device is ready.
+ private IHdmiControlCallback mOtpCallbackPendingAddressAllocation = null;
+
+ @Nullable
private HdmiCecController mCecController;
// HDMI port information. Stored in the unmodifiable list to keep the static information
@@ -785,17 +790,21 @@ public class HdmiControlService extends SystemService {
// Address allocation completed for all devices. Notify each device.
if (allocatingDevices.size() == ++finished[0]) {
mAddressAllocated = true;
- // Reinvoke the saved display status callback once the local device is ready.
- if (mDisplayStatusCallback != null) {
- queryDisplayStatus(mDisplayStatusCallback);
- mDisplayStatusCallback = null;
- }
if (initiatedBy != INITIATED_BY_HOTPLUG) {
// In case of the hotplug we don't call onInitializeCecComplete()
// since we reallocate the logical address only.
onInitializeCecComplete(initiatedBy);
}
notifyAddressAllocated(allocatedDevices, initiatedBy);
+ // Reinvoke the saved display status callback once the local device is ready.
+ if (mDisplayStatusCallback != null) {
+ queryDisplayStatus(mDisplayStatusCallback);
+ mDisplayStatusCallback = null;
+ }
+ if (mOtpCallbackPendingAddressAllocation != null) {
+ oneTouchPlay(mOtpCallbackPendingAddressAllocation);
+ mOtpCallbackPendingAddressAllocation = null;
+ }
mCecMessageBuffer.processMessages();
}
}
@@ -2246,8 +2255,16 @@ public class HdmiControlService extends SystemService {
}
@ServiceThreadOnly
- private void oneTouchPlay(final IHdmiControlCallback callback) {
+ @VisibleForTesting
+ protected void oneTouchPlay(final IHdmiControlCallback callback) {
assertRunOnServiceThread();
+ if (!mAddressAllocated) {
+ mOtpCallbackPendingAddressAllocation = callback;
+ Slog.d(TAG, "Local device is under address allocation. "
+ + "Save OTP callback for later process.");
+ return;
+ }
+
HdmiCecLocalDeviceSource source = playback();
if (source == null) {
source = audioSystem();
diff --git a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
index c8fc5fc96e59..4962af176f18 100644
--- a/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
+++ b/services/core/java/com/android/server/hdmi/OneTouchPlayAction.java
@@ -77,7 +77,6 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
sendCommand(HdmiCecMessageBuilder.buildTextViewOn(getSourceAddress(), mTargetAddress));
broadcastActiveSource();
queryDevicePowerStatus();
- mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
addTimer(mState, HdmiConfig.TIMEOUT_MS);
return true;
}
@@ -99,6 +98,7 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
}
private void queryDevicePowerStatus() {
+ mState = STATE_WAITING_FOR_REPORT_POWER_STATUS;
sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(),
mTargetAddress));
}
diff --git a/services/core/java/com/android/server/integrity/TEST_MAPPING b/services/core/java/com/android/server/integrity/TEST_MAPPING
new file mode 100644
index 000000000000..b45b4eaa1ba7
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/TEST_MAPPING
@@ -0,0 +1,18 @@
+{
+ "presubmit": [
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.integrity."
+ },
+ {
+ "include-annotation": "android.platform.test.annotations.Presubmit"
+ },
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java b/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
new file mode 100644
index 000000000000..fc4430640b90
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/engine/RuleEvaluationEngine.java
@@ -0,0 +1,55 @@
+/*
+ * 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.integrity.engine;
+
+import com.android.server.integrity.model.Rule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The engine used to evaluate rules against app installs.
+ *
+ * <p>Every app install is evaluated against rules (pushed by the verifier) by the evaluation engine
+ * to allow/block that install.
+ */
+public final class RuleEvaluationEngine {
+ private static final String TAG = "RuleEvaluation";
+
+ // The engine for loading rules, retrieving metadata for app installs, and evaluating app
+ // installs against rules.
+ private static RuleEvaluationEngine sRuleEvaluationEngine;
+
+ // The subset of rules loaded to be used to evaluate an app install request.
+ // TODO: Load rules relevant to app installs.
+ private List<Rule> mRules;
+
+ private RuleEvaluationEngine() {
+ // Initialize rules with the empty rule set.
+ mRules = new ArrayList<>();
+ }
+
+ /**
+ * Provide a singleton instance of the rule evaluation engine.
+ */
+ public static synchronized RuleEvaluationEngine getRuleEvaluationEngine() {
+ if (sRuleEvaluationEngine == null) {
+ return new RuleEvaluationEngine();
+ }
+ return sRuleEvaluationEngine;
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/engine/RuleLoader.java b/services/core/java/com/android/server/integrity/engine/RuleLoader.java
new file mode 100644
index 000000000000..af24d7a21dc8
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/engine/RuleLoader.java
@@ -0,0 +1,61 @@
+/*
+ * 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.integrity.engine;
+
+import com.android.server.integrity.model.Rule;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A helper class for loading rules to the rule evaluation engine.
+ *
+ * <p>Expose fine-grained APIs for loading rules to be passed to the rule evaluation engine.
+ *
+ * <p>It supports:
+ * <ul>
+ * <li>Loading rules based on some keys, such as PACKAGE_NAME and APP_CERT.</li>
+ * </ul>
+ *
+ * <p>It does NOT support:
+ * <ul>
+ * <li>Loading the list of all rules.</li>
+ * <li>Merging rules resulting from different APIs.</li>
+ * </ul>
+ */
+final class RuleLoader {
+
+ List<Rule> loadRulesByPackageName(String packageName) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+
+ List<Rule> loadRulesByAppCertificate(String appCertificate) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+
+ List<Rule> loadRulesByInstallerName(String installerName) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+
+ List<Rule> loadRulesByInstallerCertificate(String installerCertificate) {
+ // TODO: Add logic based on rule storage.
+ return new ArrayList<>();
+ }
+}
diff --git a/services/core/java/com/android/server/integrity/engine/AppInstallMetadata.java b/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java
index c2ed3df0ffff..814b8e1d783b 100644
--- a/services/core/java/com/android/server/integrity/engine/AppInstallMetadata.java
+++ b/services/core/java/com/android/server/integrity/model/AppInstallMetadata.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server.integrity.engine;
+package com.android.server.integrity.model;
/**
* The app install metadata.
@@ -32,7 +32,7 @@ public final class AppInstallMetadata {
final int mVersionCode;
final boolean mIsPreInstalled;
- AppInstallMetadata(String packageName, String appCertificate, String installerName,
+ public AppInstallMetadata(String packageName, String appCertificate, String installerName,
String installerCertificate, int versionCode, boolean isPreInstalled) {
this.mPackageName = packageName;
this.mAppCertificate = appCertificate;
diff --git a/services/core/java/com/android/server/integrity/model/Rule.java b/services/core/java/com/android/server/integrity/model/Rule.java
new file mode 100644
index 000000000000..a6e08d8504ed
--- /dev/null
+++ b/services/core/java/com/android/server/integrity/model/Rule.java
@@ -0,0 +1,160 @@
+/*
+ * 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.integrity.model;
+
+import static com.android.internal.util.Preconditions.checkNotNull;
+
+import android.annotation.Nullable;
+
+/**
+ * Represent rules to be used in the rule evaluation engine to match against app installs.
+ *
+ * <p>Instances of this class are immutable.
+ */
+public final class Rule {
+
+ // Holds an empty rule instance.
+ public static final Rule EMPTY = new Rule();
+
+ enum Key {
+ PACKAGE_NAME,
+ APP_CERTIFICATE,
+ INSTALLER_NAME,
+ INSTALLER_CERTIFICATE,
+ VERSION_CODE,
+ PRE_INSTALLED
+ }
+
+ enum Effect {
+ DENY
+ }
+
+ enum Operator {
+ EQ,
+ LT,
+ LE,
+ GT,
+ GE
+ }
+
+ enum Connector {
+ AND,
+ OR,
+ NOT
+ }
+
+ private final Formula mFormula;
+ private final Effect mEffect;
+
+ private Rule() {
+ this.mFormula = null;
+ this.mEffect = null;
+ }
+
+ public Rule(Formula formula, Effect effect) {
+ this.mFormula = checkNotNull(formula);
+ this.mEffect = checkNotNull(effect);
+ }
+
+ /**
+ * Indicates whether the rule is empty or not.
+ *
+ * @return {@code true} if the rule is empty, and {@code false} otherwise.
+ */
+ public boolean isEmpty() {
+ return mFormula == null && mEffect == null;
+ }
+
+ public Formula getFormula() {
+ return mFormula;
+ }
+
+ public Effect getEffect() {
+ return mEffect;
+ }
+
+ // TODO: Consider moving the sub-components to their respective model class.
+
+ /**
+ * Represents a rule logic/content.
+ */
+ abstract static class Formula {
+
+ }
+
+ /**
+ * Represents a simple formula consisting of an app install metadata field and a value.
+ */
+ public static final class AtomicFormula extends Formula {
+
+ final Key mKey;
+ final Operator mOperator;
+
+ // The value of a key can take either 1 of 3 forms: String, Integer, or Boolean.
+ // It cannot have multiple values.
+ @Nullable
+ final String mStringValue;
+ @Nullable
+ final Integer mIntValue;
+ @Nullable
+ final Boolean mBoolValue;
+
+ public AtomicFormula(Key key, Operator operator, String stringValue) {
+ // TODO: Add validators
+ this.mKey = key;
+ this.mOperator = operator;
+ this.mStringValue = stringValue;
+ this.mIntValue = null;
+ this.mBoolValue = null;
+ }
+
+ public AtomicFormula(Key key, Operator operator, Integer intValue) {
+ // TODO: Add validators
+ this.mKey = key;
+ this.mOperator = operator;
+ this.mStringValue = null;
+ this.mIntValue = intValue;
+ this.mBoolValue = null;
+ }
+
+ public AtomicFormula(Key key, Operator operator, Boolean boolValue) {
+ // TODO: Add validators
+ this.mKey = key;
+ this.mOperator = operator;
+ this.mStringValue = null;
+ this.mIntValue = null;
+ this.mBoolValue = boolValue;
+ }
+ }
+
+ /**
+ * Represents a complex formula consisting of other simple and complex formulas.
+ */
+ public static final class OpenFormula extends Formula {
+
+ final Connector mConnector;
+ final Formula mMainFormula;
+ final Formula mAuxiliaryFormula;
+
+ public OpenFormula(Connector connector, Formula mainFormula,
+ @Nullable Formula auxiliaryFormula) {
+ this.mConnector = checkNotNull(connector);
+ this.mMainFormula = checkNotNull(mainFormula);
+ this.mAuxiliaryFormula = auxiliaryFormula;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java
index 378d9ebdaaa8..bad484fa3807 100644
--- a/services/core/java/com/android/server/locksettings/LockSettingsService.java
+++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java
@@ -61,7 +61,10 @@ import android.database.ContentObserver;
import android.database.sqlite.SQLiteDatabase;
import android.hardware.authsecret.V1_0.IAuthSecret;
import android.hardware.biometrics.BiometricManager;
+import android.hardware.face.Face;
import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.Fingerprint;
+import android.hardware.fingerprint.FingerprintManager;
import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
@@ -117,6 +120,7 @@ import com.android.internal.widget.LockPatternUtils.CredentialType;
import com.android.internal.widget.LockSettingsInternal;
import com.android.internal.widget.VerifyCredentialResponse;
import com.android.server.LocalServices;
+import com.android.server.ServiceThread;
import com.android.server.SystemService;
import com.android.server.locksettings.LockSettingsStorage.CredentialHash;
import com.android.server.locksettings.LockSettingsStorage.PersistentData;
@@ -387,8 +391,15 @@ public class LockSettingsService extends ILockSettings.Stub {
return mContext;
}
- public Handler getHandler() {
- return new Handler();
+ public ServiceThread getServiceThread() {
+ ServiceThread handlerThread = new ServiceThread(TAG, Process.THREAD_PRIORITY_BACKGROUND,
+ true /*allowIo*/);
+ handlerThread.start();
+ return handlerThread;
+ }
+
+ public Handler getHandler(ServiceThread handlerThread) {
+ return new Handler(handlerThread.getLooper());
}
public LockSettingsStorage getStorage() {
@@ -483,6 +494,23 @@ public class LockSettingsService extends ILockSettings.Stub {
public boolean isGsiRunning() {
return SystemProperties.getInt(GSI_RUNNING_PROP, 0) > 0;
}
+
+ public FingerprintManager getFingerprintManager() {
+ if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
+ return (FingerprintManager) mContext.getSystemService(Context.FINGERPRINT_SERVICE);
+ } else {
+ return null;
+ }
+ }
+
+ public FaceManager getFaceManager() {
+ if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
+ return (FaceManager) mContext.getSystemService(Context.FACE_SERVICE);
+ } else {
+ return null;
+ }
+ }
+
}
public LockSettingsService(Context context) {
@@ -495,7 +523,7 @@ public class LockSettingsService extends ILockSettings.Stub {
mContext = injector.getContext();
mKeyStore = injector.getKeyStore();
mRecoverableKeyStoreManager = injector.getRecoverableKeyStoreManager(mKeyStore);
- mHandler = injector.getHandler();
+ mHandler = injector.getHandler(injector.getServiceThread());
mStrongAuth = injector.getStrongAuth();
mActivityManager = injector.getActivityManager();
@@ -2713,6 +2741,7 @@ public class LockSettingsService extends ILockSettings.Stub {
fixateNewestUserKeyAuth(userId);
unlockKeystore(auth.deriveKeyStorePassword(), userId);
setKeystorePassword(null, userId);
+ removeBiometricsForUser(userId);
}
setSyntheticPasswordHandleLocked(newHandle, userId);
synchronizeUnifiedWorkChallengeForProfiles(userId, profilePasswords);
@@ -2728,6 +2757,85 @@ public class LockSettingsService extends ILockSettings.Stub {
return newHandle;
}
+ private void removeBiometricsForUser(int userId) {
+ removeAllFingerprintForUser(userId);
+ removeAllFaceForUser(userId);
+ }
+
+ private void removeAllFingerprintForUser(final int userId) {
+ FingerprintManager mFingerprintManager = mInjector.getFingerprintManager();
+ if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
+ if (mFingerprintManager.hasEnrolledFingerprints(userId)) {
+ mFingerprintManager.setActiveUser(userId);
+ CountDownLatch latch = new CountDownLatch(1);
+ // For the purposes of M and N, groupId is the same as userId.
+ Fingerprint finger = new Fingerprint(null, userId, 0, 0);
+ mFingerprintManager.remove(finger, userId,
+ fingerprintManagerRemovalCallback(latch));
+ try {
+ latch.await(10000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Latch interrupted when removing fingerprint", e);
+ }
+ }
+ }
+ }
+
+ private void removeAllFaceForUser(final int userId) {
+ FaceManager mFaceManager = mInjector.getFaceManager();
+ if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
+ if (mFaceManager.hasEnrolledTemplates(userId)) {
+ mFaceManager.setActiveUser(userId);
+ CountDownLatch latch = new CountDownLatch(1);
+ Face face = new Face(null, 0, 0);
+ mFaceManager.remove(face, userId, faceManagerRemovalCallback(latch));
+ try {
+ latch.await(10000, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Slog.e(TAG, "Latch interrupted when removing face", e);
+ }
+ }
+ }
+ }
+
+ private FingerprintManager.RemovalCallback fingerprintManagerRemovalCallback(
+ CountDownLatch latch) {
+ return new FingerprintManager.RemovalCallback() {
+ @Override
+ public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence err) {
+ Slog.e(TAG, String.format(
+ "Can't remove fingerprint %d in group %d. Reason: %s",
+ fp.getBiometricId(), fp.getGroupId(), err));
+ latch.countDown();
+ }
+
+ @Override
+ public void onRemovalSucceeded(Fingerprint fp, int remaining) {
+ if (remaining == 0) {
+ latch.countDown();
+ }
+ }
+ };
+ }
+
+ private FaceManager.RemovalCallback faceManagerRemovalCallback(CountDownLatch latch) {
+ return new FaceManager.RemovalCallback() {
+ @Override
+ public void onRemovalError(Face face, int errMsgId, CharSequence err) {
+ Slog.e(TAG, String.format("Can't remove face %d. Reason: %s",
+ face.getBiometricId(), err));
+ latch.countDown();
+ }
+
+ @Override
+ public void onRemovalSucceeded(Face face, int remaining) {
+ if (remaining == 0) {
+ latch.countDown();
+ }
+ }
+ };
+ }
+
@GuardedBy("mSpManager")
private boolean spBasedSetLockCredentialInternalLocked(byte[] credential, int credentialType,
byte[] savedCredential, int requestedQuality, int userId,
diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING
index c1cba5f7f22d..56f5cc034f05 100644
--- a/services/core/java/com/android/server/locksettings/TEST_MAPPING
+++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING
@@ -1,5 +1,5 @@
{
- "presubmit": [
+ "presubmit-devicepolicy": [
{
"name": "CtsDevicePolicyManagerTestCases",
"options": [
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 043c834230d1..668f2be158c6 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -26,6 +26,7 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.media.IMediaRouter2Client;
import android.media.IMediaRouter2Manager;
+import android.media.IMediaRouterClient;
import android.media.MediaRoute2Info;
import android.media.MediaRoute2ProviderInfo;
import android.os.Binder;
@@ -86,7 +87,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- registerClientLocked(client, uid, pid, packageName, userId, trusted);
+ registerClient2Locked(client, uid, pid, packageName, userId, trusted);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -99,7 +100,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- unregisterClientLocked(client, false);
+ unregisterClient2Locked(client, false);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -155,14 +156,30 @@ class MediaRouter2ServiceImpl {
}
}
- public void setControlCategories(@NonNull IMediaRouter2Client client,
+ //TODO: What would happen if a media app used MediaRouter and MediaRouter2 simultaneously?
+ public void setControlCategories(@NonNull IMediaRouterClient client,
+ @Nullable List<String> categories) {
+ Objects.requireNonNull(client, "client must not be null");
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+ setControlCategoriesLocked(clientRecord, categories);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ public void setControlCategories2(@NonNull IMediaRouter2Client client,
@Nullable List<String> categories) {
Objects.requireNonNull(client, "client must not be null");
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- setControlCategoriesLocked(client, categories);
+ ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+ setControlCategoriesLocked(clientRecord, categories);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -174,7 +191,7 @@ class MediaRouter2ServiceImpl {
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
- selectRoute2Locked(client, route);
+ selectRoute2Locked(mAllClientRecords.get(client.asBinder()), route);
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -193,6 +210,36 @@ class MediaRouter2ServiceImpl {
}
}
+ public void registerClient(@NonNull IMediaRouterClient client, @NonNull String packageName) {
+ Objects.requireNonNull(client, "client must not be null");
+
+ final int uid = Binder.getCallingUid();
+ final int pid = Binder.getCallingPid();
+ final int userId = UserHandle.getUserId(uid);
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ registerClient1Locked(client, packageName, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
+ public void unregisterClient(@NonNull IMediaRouterClient client) {
+ Objects.requireNonNull(client, "client must not be null");
+
+ final long token = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ unregisterClient1Locked(client);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ }
+
//TODO: Review this is handling multi-user properly.
void switchUser() {
synchronized (mLock) {
@@ -217,9 +264,9 @@ class MediaRouter2ServiceImpl {
}
}
- void clientDied(ClientRecord clientRecord) {
+ void clientDied(Client2Record clientRecord) {
synchronized (mLock) {
- unregisterClientLocked(clientRecord.mClient, true);
+ unregisterClient2Locked(clientRecord.mClient, true);
}
}
@@ -229,18 +276,18 @@ class MediaRouter2ServiceImpl {
}
}
- private void registerClientLocked(IMediaRouter2Client client,
+ private void registerClient2Locked(IMediaRouter2Client client,
int uid, int pid, String packageName, int userId, boolean trusted) {
final IBinder binder = client.asBinder();
- ClientRecord clientRecord = mAllClientRecords.get(binder);
- if (clientRecord == null) {
+ if (mAllClientRecords.get(binder) == null) {
boolean newUser = false;
UserRecord userRecord = mUserRecords.get(userId);
if (userRecord == null) {
userRecord = new UserRecord(userId);
newUser = true;
}
- clientRecord = new ClientRecord(userRecord, client, uid, pid, packageName, trusted);
+ Client2Record clientRecord = new Client2Record(userRecord, client, uid, pid,
+ packageName, trusted);
try {
binder.linkToDeath(clientRecord, 0);
} catch (RemoteException ex) {
@@ -261,8 +308,8 @@ class MediaRouter2ServiceImpl {
}
}
- private void unregisterClientLocked(IMediaRouter2Client client, boolean died) {
- ClientRecord clientRecord = mAllClientRecords.remove(client.asBinder());
+ private void unregisterClient2Locked(IMediaRouter2Client client, boolean died) {
+ Client2Record clientRecord = (Client2Record) mAllClientRecords.remove(client.asBinder());
if (clientRecord != null) {
UserRecord userRecord = clientRecord.mUserRecord;
userRecord.mClientRecords.remove(clientRecord);
@@ -272,8 +319,7 @@ class MediaRouter2ServiceImpl {
}
}
- private void selectRoute2Locked(IMediaRouter2Client client, MediaRoute2Info route) {
- ClientRecord clientRecord = mAllClientRecords.get(client.asBinder());
+ private void selectRoute2Locked(ClientRecord clientRecord, MediaRoute2Info route) {
if (clientRecord != null) {
MediaRoute2Info oldRoute = clientRecord.mSelectedRoute;
clientRecord.mSelectedRoute = route;
@@ -294,10 +340,7 @@ class MediaRouter2ServiceImpl {
}
}
- private void setControlCategoriesLocked(IMediaRouter2Client client, List<String> categories) {
- final IBinder binder = client.asBinder();
- ClientRecord clientRecord = mAllClientRecords.get(binder);
-
+ private void setControlCategoriesLocked(ClientRecord clientRecord, List<String> categories) {
if (clientRecord != null) {
clientRecord.mControlCategories = categories;
@@ -349,9 +392,7 @@ class MediaRouter2ServiceImpl {
obtainMessage(UserHandler::notifyProviderInfosUpdatedToManager,
userRecord.mHandler, manager));
- final int count = userRecord.mClientRecords.size();
- for (int i = 0; i < count; i++) {
- ClientRecord clientRecord = userRecord.mClientRecords.get(i);
+ for (ClientRecord clientRecord : userRecord.mClientRecords) {
clientRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::updateClientUsage,
clientRecord.mUserRecord.mHandler, clientRecord));
@@ -378,7 +419,7 @@ class MediaRouter2ServiceImpl {
Slog.w(TAG, "Ignoring route selection for unknown client.");
}
if (clientRecord != null && managerRecord.mTrusted) {
- selectRoute2Locked(clientRecord.mClient, route);
+ selectRoute2Locked(clientRecord, route);
}
}
}
@@ -409,6 +450,37 @@ class MediaRouter2ServiceImpl {
}
}
+ private void registerClient1Locked(IMediaRouterClient client, String packageName,
+ int userId) {
+ final IBinder binder = client.asBinder();
+ if (mAllClientRecords.get(binder) == null) {
+ boolean newUser = false;
+ UserRecord userRecord = mUserRecords.get(userId);
+ if (userRecord == null) {
+ userRecord = new UserRecord(userId);
+ newUser = true;
+ }
+ ClientRecord clientRecord = new Client1Record(userRecord, client, packageName);
+
+ if (newUser) {
+ mUserRecords.put(userId, userRecord);
+ initializeUserLocked(userRecord);
+ }
+
+ userRecord.mClientRecords.add(clientRecord);
+ mAllClientRecords.put(binder, clientRecord);
+ }
+ }
+
+ private void unregisterClient1Locked(IMediaRouterClient client) {
+ ClientRecord clientRecord = mAllClientRecords.remove(client.asBinder());
+ if (clientRecord != null) {
+ UserRecord userRecord = clientRecord.mUserRecord;
+ userRecord.mClientRecords.remove(clientRecord);
+ disposeUserIfNeededLocked(userRecord);
+ }
+ }
+
final class UserRecord {
public final int mUserId;
final ArrayList<ClientRecord> mClientRecords = new ArrayList<>();
@@ -430,25 +502,43 @@ class MediaRouter2ServiceImpl {
}
}
- final class ClientRecord implements IBinder.DeathRecipient {
+ class ClientRecord {
public final UserRecord mUserRecord;
+ public final String mPackageName;
+ public List<String> mControlCategories;
+ public MediaRoute2Info mSelectedRoute;
+
+ ClientRecord(UserRecord userRecord, String packageName) {
+ mUserRecord = userRecord;
+ mPackageName = packageName;
+ mControlCategories = Collections.emptyList();
+ }
+ }
+
+ final class Client1Record extends ClientRecord {
+ public final IMediaRouterClient mClient;
+
+ Client1Record(UserRecord userRecord, IMediaRouterClient client,
+ String packageName) {
+ super(userRecord, packageName);
+ mClient = client;
+ }
+ }
+
+ final class Client2Record extends ClientRecord
+ implements IBinder.DeathRecipient {
public final IMediaRouter2Client mClient;
public final int mUid;
public final int mPid;
- public final String mPackageName;
public final boolean mTrusted;
- public List<String> mControlCategories;
- public MediaRoute2Info mSelectedRoute;
- ClientRecord(UserRecord userRecord, IMediaRouter2Client client,
+ Client2Record(UserRecord userRecord, IMediaRouter2Client client,
int uid, int pid, String packageName, boolean trusted) {
- mUserRecord = userRecord;
+ super(userRecord, packageName);
mClient = client;
mUid = uid;
mPid = pid;
- mPackageName = packageName;
mTrusted = trusted;
- mControlCategories = Collections.emptyList();
}
public void dispose() {
@@ -622,7 +712,9 @@ class MediaRouter2ServiceImpl {
managers.add(managerRecord.mManager);
}
for (ClientRecord clientRecord : mUserRecord.mClientRecords) {
- clients.add(clientRecord.mClient);
+ if (clientRecord instanceof Client2Record) {
+ clients.add(((Client2Record) clientRecord).mClient);
+ }
}
}
for (IMediaRouter2Manager manager : managers) {
diff --git a/services/core/java/com/android/server/media/MediaRouterService.java b/services/core/java/com/android/server/media/MediaRouterService.java
index 2670cd8247ac..796a25d7e295 100644
--- a/services/core/java/com/android/server/media/MediaRouterService.java
+++ b/services/core/java/com/android/server/media/MediaRouterService.java
@@ -249,6 +249,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
synchronized (mLock) {
registerClientLocked(client, uid, pid, packageName, resolvedUserId, trusted);
}
+ mService2.registerClient(client, packageName);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -289,6 +290,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
synchronized (mLock) {
unregisterClientLocked(client, false);
}
+ mService2.unregisterClient(client);
} finally {
Binder.restoreCallingIdentity(token);
}
@@ -395,6 +397,12 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
+ public void setControlCategories(IMediaRouterClient client, List<String> controlCategories) {
+ mService2.setControlCategories(client, controlCategories);
+ }
+
+ // Binder call
+ @Override
public void requestUpdateVolume(IMediaRouterClient client, String routeId, int direction) {
if (client == null) {
throw new IllegalArgumentException("client must not be null");
@@ -487,8 +495,8 @@ public final class MediaRouterService extends IMediaRouterService.Stub
// Binder call
@Override
- public void setControlCategories(IMediaRouter2Client client, List<String> categories) {
- mService2.setControlCategories(client, categories);
+ public void setControlCategories2(IMediaRouter2Client client, List<String> categories) {
+ mService2.setControlCategories2(client, categories);
}
void restoreBluetoothA2dp() {
@@ -561,6 +569,7 @@ public final class MediaRouterService extends IMediaRouterService.Stub
synchronized (mLock) {
unregisterClientLocked(clientRecord.mClient, true);
}
+ mService2.unregisterClient(clientRecord.mClient);
}
private void registerClientLocked(IMediaRouterClient client,
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index d480cb6e9800..3341991aa0ae 100644..100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -94,7 +94,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
import static com.android.server.am.PendingIntentRecord.FLAG_ACTIVITY_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_BROADCAST_SENDER;
import static com.android.server.am.PendingIntentRecord.FLAG_SERVICE_SENDER;
-import static com.android.server.notification.PreferencesHelper.DEFAULT_ALLOW_BUBBLE;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG_CRITICAL;
import static com.android.server.utils.PriorityDump.PRIORITY_ARG_NORMAL;
@@ -1331,16 +1330,15 @@ public class NotificationManagerService extends SystemService {
uidList = new int[] {intent.getIntExtra(Intent.EXTRA_UID, -1)};
}
if (pkgList != null && (pkgList.length > 0)) {
- for (String pkgName : pkgList) {
- if (cancelNotifications) {
+ if (cancelNotifications) {
+ for (String pkgName : pkgList) {
cancelAllNotificationsInt(MY_UID, MY_PID, pkgName, null, 0, 0,
!queryRestart, changeUserId, reason, null);
- } else if (hideNotifications) {
- hideNotificationsForPackages(pkgList);
- } else if (unhideNotifications) {
- unhideNotificationsForPackages(pkgList);
}
-
+ } else if (hideNotifications) {
+ hideNotificationsForPackages(pkgList);
+ } else if (unhideNotifications) {
+ unhideNotificationsForPackages(pkgList);
}
}
@@ -1429,10 +1427,8 @@ public class NotificationManagerService extends SystemService {
private final class SettingsObserver extends ContentObserver {
private final Uri NOTIFICATION_BADGING_URI
= Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BADGING);
- private final Uri NOTIFICATION_BUBBLES_URI_GLOBAL
+ private final Uri NOTIFICATION_BUBBLES_URI
= Settings.Global.getUriFor(Settings.Global.NOTIFICATION_BUBBLES);
- private final Uri NOTIFICATION_BUBBLES_URI_SECURE
- = Settings.Secure.getUriFor(Settings.Secure.NOTIFICATION_BUBBLES);
private final Uri NOTIFICATION_LIGHT_PULSE_URI
= Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
private final Uri NOTIFICATION_RATE_LIMIT_URI
@@ -1450,9 +1446,7 @@ public class NotificationManagerService extends SystemService {
false, this, UserHandle.USER_ALL);
resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI_GLOBAL,
- false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI_SECURE,
+ resolver.registerContentObserver(NOTIFICATION_BUBBLES_URI,
false, this, UserHandle.USER_ALL);
update(null);
}
@@ -1479,41 +1473,9 @@ public class NotificationManagerService extends SystemService {
if (uri == null || NOTIFICATION_BADGING_URI.equals(uri)) {
mPreferencesHelper.updateBadgingEnabled();
}
- // In QPR we moved the setting to Global rather than Secure so that the setting
- // applied to work profiles. Unfortunately we need to maintain both to pass CTS without
- // a change to CTS outside of a normal letter release.
- if (uri == null || NOTIFICATION_BUBBLES_URI_GLOBAL.equals(uri)) {
- syncBubbleSettings(resolver, NOTIFICATION_BUBBLES_URI_GLOBAL);
+ if (uri == null || NOTIFICATION_BUBBLES_URI.equals(uri)) {
mPreferencesHelper.updateBubblesEnabled();
}
- if (NOTIFICATION_BUBBLES_URI_SECURE.equals(uri)) {
- syncBubbleSettings(resolver, NOTIFICATION_BUBBLES_URI_SECURE);
- }
- }
-
- private void syncBubbleSettings(ContentResolver resolver, Uri settingToFollow) {
- boolean followSecureSetting = settingToFollow.equals(NOTIFICATION_BUBBLES_URI_SECURE);
-
- int secureSettingValue = Settings.Secure.getInt(resolver,
- Settings.Secure.NOTIFICATION_BUBBLES, DEFAULT_ALLOW_BUBBLE ? 1 : 0);
- int globalSettingValue = Settings.Global.getInt(resolver,
- Settings.Global.NOTIFICATION_BUBBLES, DEFAULT_ALLOW_BUBBLE ? 1 : 0);
-
- if (globalSettingValue == secureSettingValue) {
- return;
- }
-
- if (followSecureSetting) {
- // Global => secure
- Settings.Global.putInt(resolver,
- Settings.Global.NOTIFICATION_BUBBLES,
- secureSettingValue);
- } else {
- // Secure => Global
- Settings.Secure.putInt(resolver,
- Settings.Secure.NOTIFICATION_BADGING,
- globalSettingValue);
- }
}
}
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 83bea9dd1efc..9e7b46485d4c 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -738,6 +738,25 @@ public final class OverlayManagerService extends SystemService {
}
@Override
+ public void invalidateCachesForOverlay(@Nullable String packageName, int userId)
+ throws RemoteException {
+ if (packageName == null) {
+ return;
+ }
+
+ enforceChangeOverlayPackagesPermission("invalidateCachesForOverlay");
+ userId = handleIncomingUser(userId, "invalidateCachesForOverlay");
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ mImpl.removeIdmapForOverlay(packageName, userId);
+ }
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
+
+ @Override
public void onShellCommand(@NonNull final FileDescriptor in,
@NonNull final FileDescriptor out, @NonNull final FileDescriptor err,
@NonNull final String[] args, @NonNull final ShellCallback callback,
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 934511bf88d1..019c9528f8ab 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -651,6 +651,11 @@ final class OverlayManagerServiceImpl {
return mDefaultOverlays;
}
+ void removeIdmapForOverlay(String packageName, int userId) {
+ final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
+ removeIdmapIfPossible(oi);
+ }
+
List<String> getEnabledOverlayPackageNames(@NonNull final String targetPackageName,
final int userId) {
final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName,
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 8b242242cbe3..a7d423784b4b 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -259,6 +259,10 @@ public class PackageInstallerService extends IPackageInstaller.Stub implements
// Don't hold mSessions lock when calling restoreSession, since it might trigger an APK
// atomic install which needs to query sessions, which requires lock on mSessions.
for (PackageInstallerSession session : stagedSessionsToRestore) {
+ if (mPm.isDeviceUpgrading()) {
+ session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
+ "Build fingerprint has changed");
+ }
mStagingManager.restoreSession(session);
}
// Broadcasts are not sent while we restore sessions on boot, since no processes would be
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index 282fed8434ed..aac0f906feaa 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -51,7 +51,6 @@ import android.os.ShellCallback;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.service.sms.FinancialSmsService;
-import android.telephony.IFinancialSmsCallback;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -702,40 +701,6 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
dumpOutputStream.flush();
}
- /**
- * Get filtered SMS messages for financial app.
- */
- @Override
- public void getSmsMessagesForFinancialApp(
- String callingPkg, Bundle params, IFinancialSmsCallback callback) {
- int mode = PermissionChecker.checkCallingOrSelfPermission(
- getContext(),
- AppOpsManager.OPSTR_SMS_FINANCIAL_TRANSACTIONS);
-
- if (mode == PermissionChecker.PERMISSION_GRANTED) {
- FinancialSmsManager financialSmsManager = new FinancialSmsManager(getContext());
- financialSmsManager.getSmsMessages(new RemoteCallback((result) -> {
- CursorWindow messages = null;
- if (result == null) {
- Slog.w(LOG_TAG, "result is null.");
- } else {
- messages = result.getParcelable(FinancialSmsService.EXTRA_SMS_MSGS);
- }
- try {
- callback.onGetSmsMessagesForFinancialApp(messages);
- } catch (RemoteException e) {
- // do nothing
- }
- }), params);
- } else {
- try {
- callback.onGetSmsMessagesForFinancialApp(null);
- } catch (RemoteException e) {
- // do nothing
- }
- }
- }
-
private int getUidForPackage(String packageName) {
long ident = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/rollback/RollbackStore.java b/services/core/java/com/android/server/rollback/RollbackStore.java
index eadd09cf46ee..425da374a5a8 100644
--- a/services/core/java/com/android/server/rollback/RollbackStore.java
+++ b/services/core/java/com/android/server/rollback/RollbackStore.java
@@ -28,6 +28,7 @@ import android.util.Slog;
import android.util.SparseLongArray;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
import libcore.io.IoUtils;
@@ -288,19 +289,25 @@ class RollbackStore {
JSONObject dataJson = new JSONObject(
IoUtils.readFileAsString(rollbackJsonFile.getAbsolutePath()));
- return new Rollback(
- rollbackInfoFromJson(dataJson.getJSONObject("info")),
- backupDir,
- Instant.parse(dataJson.getString("timestamp")),
- dataJson.getInt("stagedSessionId"),
- rollbackStateFromString(dataJson.getString("state")),
- dataJson.getInt("apkSessionId"),
- dataJson.getBoolean("restoreUserDataInProgress"));
+ return rollbackFromJson(dataJson, backupDir);
} catch (JSONException | DateTimeParseException | ParseException e) {
throw new IOException(e);
}
}
+ @VisibleForTesting
+ static Rollback rollbackFromJson(JSONObject dataJson, File backupDir)
+ throws JSONException, ParseException {
+ return new Rollback(
+ rollbackInfoFromJson(dataJson.getJSONObject("info")),
+ backupDir,
+ Instant.parse(dataJson.getString("timestamp")),
+ dataJson.getInt("stagedSessionId"),
+ rollbackStateFromString(dataJson.getString("state")),
+ dataJson.getInt("apkSessionId"),
+ dataJson.getBoolean("restoreUserDataInProgress"));
+ }
+
private static JSONObject toJson(VersionedPackage pkg) throws JSONException {
JSONObject json = new JSONObject();
json.put("packageName", pkg.getPackageName());
diff --git a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
index 4c935643da55..5493afd1b123 100644
--- a/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
+++ b/services/core/java/com/android/server/textclassifier/TextClassificationManagerService.java
@@ -365,10 +365,16 @@ public final class TextClassificationManagerService extends ITextClassifierServi
protected void dump(FileDescriptor fd, PrintWriter fout, String[] args) {
if (!DumpUtils.checkDumpPermission(mContext, LOG_TAG, fout)) return;
IndentingPrintWriter pw = new IndentingPrintWriter(fout, " ");
- TextClassificationManager tcm = mContext.getSystemService(TextClassificationManager.class);
- tcm.dump(pw);
- pw.printPair("context", mContext); pw.println();
+ // Create a TCM instance with the system server identity. TCM creates a ContentObserver
+ // to listen for settings changes. It does not pass the checkContentProviderAccess check
+ // if we are using the shell identity, because AMS does not track of processes spawn from
+ // shell.
+ Binder.withCleanCallingIdentity(
+ () -> mContext.getSystemService(TextClassificationManager.class).dump(pw));
+
+ pw.printPair("context", mContext);
+ pw.println();
synchronized (mLock) {
int size = mUserStates.size();
pw.print("Number user states: "); pw.println(size);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index c3ff28530b7f..b118cdfeb84d 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -11902,10 +11902,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager {
try {
int uid = packageManager.getPackageUidAsUser(packageName,
user.getIdentifier());
-
- // TODO: Prevent noting the app-op
- granted = PermissionChecker.checkPermission(mContext, permission, -1,
- uid, packageName);
+ if (PermissionChecker.checkPermissionForPreflight(mContext, permission,
+ PermissionChecker.PID_UNKNOWN, uid, packageName)
+ != PermissionChecker.PERMISSION_GRANTED) {
+ granted = PackageManager.PERMISSION_DENIED;
+ } else {
+ granted = PackageManager.PERMISSION_GRANTED;
+ }
} catch (NameNotFoundException e) {
throw new RemoteException(
"Cannot check if " + permission + "is a runtime permission", e,
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
index 1685b04cf2ca..8b3c85e8a7f3 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/MockingOomAdjusterTests.java
@@ -82,6 +82,7 @@ import android.os.Build;
import android.os.IBinder;
import android.os.PowerManagerInternal;
import android.os.SystemClock;
+import android.platform.test.annotations.Presubmit;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.SparseArray;
@@ -103,6 +104,7 @@ import java.util.ArrayList;
* Build/Install/Run:
* atest MockingOomAdjusterTests
*/
+@Presubmit
public class MockingOomAdjusterTests {
private static final int MOCKAPP_PID = 12345;
private static final int MOCKAPP_UID = 12345;
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
index 73dcb98abc8c..43f251a9281f 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AbstractAccessibilityServiceConnectionTest.java
@@ -46,6 +46,7 @@ import static android.view.accessibility.AccessibilityNodeInfo.ROOT_NODE_ID;
import static org.hamcrest.Matchers.hasItems;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
+import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -140,6 +141,8 @@ public class AbstractAccessibilityServiceConnectionTest {
private final List<AccessibilityWindowInfo> mA11yWindowInfosOnSecondDisplay = new ArrayList<>();
private Callable[] mFindA11yNodesFunctions;
private Callable<Boolean> mPerformA11yAction;
+ private ArrayList<Integer> mDisplayList = new ArrayList<>(Arrays.asList(
+ Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID));
// To mock package-private class.
@Rule public final DexmakerShareClassLoaderRule mDexmakerShareClassLoaderRule =
@@ -184,6 +187,7 @@ public class AbstractAccessibilityServiceConnectionTest {
addA11yWindowInfo(mA11yWindowInfos, PIP_WINDOWID, true, Display.DEFAULT_DISPLAY);
addA11yWindowInfo(mA11yWindowInfosOnSecondDisplay, WINDOWID_ONSECONDDISPLAY, false,
SECONDARY_DISPLAY_ID);
+ when(mMockA11yWindowManager.getDisplayListLocked()).thenReturn(mDisplayList);
when(mMockA11yWindowManager.getWindowListLocked(Display.DEFAULT_DISPLAY))
.thenReturn(mA11yWindowInfos);
when(mMockA11yWindowManager.findA11yWindowInfoByIdLocked(WINDOWID))
@@ -285,7 +289,14 @@ public class AbstractAccessibilityServiceConnectionTest {
@Test
public void getWindows() {
- assertThat(mServiceConnection.getWindows(), is(mA11yWindowInfos));
+ final AccessibilityWindowInfo.WindowListSparseArray allWindows =
+ mServiceConnection.getWindows();
+
+ assertEquals(2, allWindows.size());
+ assertThat(allWindows.get(Display.DEFAULT_DISPLAY), is(mA11yWindowInfos));
+ assertEquals(2, allWindows.get(Display.DEFAULT_DISPLAY).size());
+ assertThat(allWindows.get(SECONDARY_DISPLAY_ID), is(mA11yWindowInfosOnSecondDisplay));
+ assertEquals(1, allWindows.get(SECONDARY_DISPLAY_ID).size());
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
index b7b5a4eaacfa..b5e5deb9ff59 100644
--- a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityWindowManagerTest.java
@@ -67,6 +67,7 @@ import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
/**
@@ -104,6 +105,9 @@ public class AccessibilityWindowManagerTest {
// List of callback, mapping from displayId -> callback.
private final SparseArray<WindowsForAccessibilityCallback> mCallbackOfWindows =
new SparseArray<>();
+ // List of display ID.
+ private final ArrayList<Integer> mExpectedDisplayList = new ArrayList<>(Arrays.asList(
+ Display.DEFAULT_DISPLAY, SECONDARY_DISPLAY_ID));
private final MessageCapturingHandler mHandler = new MessageCapturingHandler(null);
@@ -692,6 +696,15 @@ public class AccessibilityWindowManagerTest {
assertTrue(windowId >= 0);
}
+ @Test
+ public void getDisplayList() throws RemoteException {
+ // Starts tracking window of second display.
+ startTrackingPerDisplay(SECONDARY_DISPLAY_ID);
+
+ final ArrayList<Integer> displayList = mA11yWindowManager.getDisplayListLocked();
+ assertTrue(displayList.equals(mExpectedDisplayList));
+ }
+
private void startTrackingPerDisplay(int displayId) throws RemoteException {
ArrayList<WindowInfo> windowInfosForDisplay = new ArrayList<>();
// Adds RemoteAccessibilityConnection into AccessibilityWindowManager, and copy
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
index 11bd29d8a163..ad3e040aca72 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -28,6 +28,7 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@@ -114,6 +115,7 @@ public class ArcTerminationActionFromAvrTest {
}
@Test
+ @Ignore("b/120845532")
public void testSendMessage_notSuccess() {
mSendCecCommandSuccess = false;
mShouldDispatchReportArcTerminated = false;
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
index a89198ae3708..0a1899be8c1f 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -232,6 +232,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
}
@Test
+ @Ignore("b/120845532")
public void handleGiveSystemAudioModeStatus_originalOff() throws Exception {
HdmiCecMessage expectedMessage =
HdmiCecMessageBuilder.buildReportSystemAudioMode(
@@ -301,6 +302,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
}
@Test
+ @Ignore("b/120845532")
public void handleSetSystemAudioMode_setOn_orignalOff() throws Exception {
mMusicMute = true;
HdmiCecMessage messageSet =
@@ -328,6 +330,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
}
@Test
+ @Ignore("b/120845532")
public void handleSystemAudioModeRequest_turnOffByTv() throws Exception {
assertThat(mMusicMute).isFalse();
// Check if feature correctly turned off
@@ -497,6 +500,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
}
@Test
+ @Ignore("b/120845532")
public void handleRequestArcTerminate_arcIsNotOn() throws Exception {
assertThat(mHdmiCecLocalDeviceAudioSystem.isArcEnabled()).isFalse();
HdmiCecMessage message =
@@ -671,6 +675,7 @@ public class HdmiCecLocalDeviceAudioSystemTest {
}
@Test
+ @Ignore("b/120845532")
public void handleReportPhysicalAddress_differentPath_addDevice() {
assertThat(mInvokeDeviceEventState).isNotEqualTo(DEVICE_EVENT_ADD_DEVICE);
HdmiDeviceInfo oldDevice = new HdmiDeviceInfo(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index b8799c3f16f7..0062a1751802 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -99,6 +99,7 @@ public class HdmiCecLocalDevicePlaybackTest {
}
@Test
+ @Ignore("b/120845532")
public void handleSetSystemAudioModeOn_audioSystemBroadcast() {
mHdmiControlService.setSystemAudioActivated(false);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
@@ -110,6 +111,7 @@ public class HdmiCecLocalDevicePlaybackTest {
}
@Test
+ @Ignore("b/120845532")
public void handleSetSystemAudioModeOff_audioSystemToPlayback() {
mHdmiCecLocalDevicePlayback.mService.setSystemAudioActivated(true);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
@@ -123,6 +125,7 @@ public class HdmiCecLocalDevicePlaybackTest {
}
@Test
+ @Ignore("b/120845532")
public void handleSystemAudioModeStatusOn_DirectltToLocalDeviceFromAudioSystem() {
mHdmiControlService.setSystemAudioActivated(false);
assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
new file mode 100644
index 000000000000..c6cf9b116a1d
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceBinderAPITest.java
@@ -0,0 +1,212 @@
+/*
+ * 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.hdmi;
+
+import static android.os.SystemClock.sleep;
+import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
+import static com.google.common.truth.Truth.assertThat;
+import static junit.framework.Assert.assertEquals;
+
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiPortInfo;
+import android.hardware.hdmi.IHdmiControlCallback;
+import android.os.Looper;
+import android.os.SystemProperties;
+import android.os.test.TestLooper;
+import android.util.Slog;
+
+import androidx.test.InstrumentationRegistry;
+import androidx.test.filters.SmallTest;
+
+import java.util.ArrayList;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Tests for {@link HdmiControlServiceBinderAPITest} class.
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class HdmiControlServiceBinderAPITest {
+
+ private class HdmiCecLocalDeviceMyDevice extends HdmiCecLocalDevice {
+
+ private boolean mCanGoToStandby;
+ private boolean mIsStandby;
+ private boolean mIsDisabled;
+
+ protected HdmiCecLocalDeviceMyDevice(HdmiControlService service, int deviceType) {
+ super(service, deviceType);
+ }
+
+ @Override
+ protected void onAddressAllocated(int logicalAddress, int reason) {
+ }
+
+ @Override
+ protected int getPreferredAddress() {
+ return 0;
+ }
+
+ @Override
+ protected void setPreferredAddress(int addr) {
+ }
+
+ @Override
+ protected boolean canGoToStandby() {
+ return mCanGoToStandby;
+ }
+
+ @Override
+ protected void disableDevice(
+ boolean initiatedByCec, final PendingActionClearedCallback originalCallback) {
+ mIsDisabled = true;
+ originalCallback.onCleared(this);
+ }
+
+ @Override
+ protected void onStandby(boolean initiatedByCec, int standbyAction) {
+ mIsStandby = true;
+ }
+
+ protected boolean isStandby() {
+ return mIsStandby;
+ }
+
+ protected boolean isDisabled() {
+ return mIsDisabled;
+ }
+
+ protected void setCanGoToStandby(boolean canGoToStandby) {
+ mCanGoToStandby = canGoToStandby;
+ }
+ }
+
+ private static final String TAG = "HdmiControlServiceBinderAPITest";
+ private HdmiControlService mHdmiControlService;
+ private HdmiCecController mHdmiCecController;
+ private HdmiCecLocalDevicePlayback mPlaybackDevice;
+ private FakeNativeWrapper mNativeWrapper;
+ private Looper mMyLooper;
+ private TestLooper mTestLooper = new TestLooper();
+ private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
+ private HdmiPortInfo[] mHdmiPortInfo;
+ private int mResult;
+ private int mPowerStatus;
+
+ @Before
+ public void SetUp() {
+ mHdmiControlService =
+ new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
+ @Override
+ void sendCecCommand(HdmiCecMessage command) {
+ switch (command.getOpcode()) {
+ case Constants.MESSAGE_GIVE_DEVICE_POWER_STATUS:
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildReportPowerStatus(
+ Constants.ADDR_TV,
+ Constants.ADDR_PLAYBACK_1,
+ HdmiControlManager.POWER_STATUS_ON);
+ handleCecCommand(message);
+ break;
+ default:
+ return;
+ }
+ }
+
+ @Override
+ boolean isPowerStandby() {
+ return mPowerStatus == HdmiControlManager.POWER_STATUS_STANDBY;
+ }
+ };
+ mMyLooper = mTestLooper.getLooper();
+
+ mPlaybackDevice = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
+ @Override
+ void setIsActiveSource(boolean on) {
+ mIsActiveSource = on;
+ }
+
+ @Override
+ protected void wakeUpIfActiveSource() {}
+
+ @Override
+ protected void setPreferredAddress(int addr) {}
+
+ @Override
+ protected int getPreferredAddress() {
+ return Constants.ADDR_PLAYBACK_1;
+ }
+ };
+ mPlaybackDevice.init();
+
+ mHdmiControlService.setIoLooper(mMyLooper);
+
+ mNativeWrapper = new FakeNativeWrapper();
+ mHdmiCecController =
+ HdmiCecController.createWithNativeWrapper(mHdmiControlService, mNativeWrapper);
+ mHdmiControlService.setCecController(mHdmiCecController);
+ mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
+ mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
+
+ mLocalDevices.add(mPlaybackDevice);
+ mHdmiPortInfo = new HdmiPortInfo[1];
+ mHdmiPortInfo[0] =
+ new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false);
+ mNativeWrapper.setPortInfo(mHdmiPortInfo);
+ mHdmiControlService.initPortInfo();
+ mResult = -1;
+ mPowerStatus = HdmiControlManager.POWER_STATUS_ON;
+
+ mTestLooper.dispatchAll();
+ }
+
+ @Test
+ public void oneTouchPlay_addressNotAllocated() {
+ assertThat(mHdmiControlService.isAddressAllocated()).isFalse();
+ mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
+ @Override
+ public void onComplete(int result) {
+ mResult = result;
+ }
+ });
+ assertEquals(mResult, -1);
+ assertThat(mPlaybackDevice.mIsActiveSource).isFalse();
+
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
+ assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
+ assertThat(mPlaybackDevice.mIsActiveSource).isTrue();
+ }
+
+ @Test
+ public void oneTouchPlay_addressAllocated() {
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+ assertThat(mHdmiControlService.isAddressAllocated()).isTrue();
+ mHdmiControlService.oneTouchPlay(new IHdmiControlCallback.Stub() {
+ @Override
+ public void onComplete(int result) {
+ mResult = result;
+ }
+ });
+ assertEquals(mResult, HdmiControlManager.RESULT_SUCCESS);
+ assertThat(mPlaybackDevice.mIsActiveSource).isTrue();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
index 440a49ab81fc..6dcff3574faf 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -221,6 +221,7 @@ public class SystemAudioInitiationActionFromAvrTest {
}
@Test
+ @Ignore("b/120845532")
public void testTvSupport() {
resetTestVariables();
mShouldDispatchActiveSource = true;
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
new file mode 100644
index 000000000000..4321c21f68b2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/integrity/model/RuleTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.integrity.model;
+
+import static com.android.server.testutils.TestUtils.assertExpectException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+@RunWith(JUnit4.class)
+public class RuleTest {
+
+ private static final Rule.Effect DENY_EFFECT = Rule.Effect.DENY;
+ private static final Rule.Formula SIMPLE_FORMULA =
+ new Rule.AtomicFormula(Rule.Key.PACKAGE_NAME, Rule.Operator.EQ, "com.test.app");
+
+ @Test
+ public void testEmptyRule() {
+ Rule emptyRule = Rule.EMPTY;
+
+ assertNull(emptyRule.getFormula());
+ assertNull(emptyRule.getEffect());
+ }
+
+ @Test
+ public void testValidRule() {
+ Rule validRule = new Rule(SIMPLE_FORMULA, DENY_EFFECT);
+
+ assertEquals(SIMPLE_FORMULA, validRule.getFormula());
+ assertEquals(DENY_EFFECT, validRule.getEffect());
+ }
+
+ @Test
+ public void testInvalidRule_invalidEffect() {
+ assertExpectException(
+ NullPointerException.class,
+ /* expectedExceptionMessageRegex */ null,
+ () -> new Rule(SIMPLE_FORMULA, null));
+ }
+
+ @Test
+ public void testInvalidRule_invalidFormula() {
+ assertExpectException(
+ NullPointerException.class,
+ /* expectedExceptionMessageRegex */ null,
+ () -> new Rule(null, DENY_EFFECT));
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
index 7cece1f5cecc..f9ac02271a27 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java
@@ -32,8 +32,11 @@ import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.DeviceStateCache;
import android.app.trust.TrustManager;
import android.content.ComponentName;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.hardware.authsecret.V1_0.IAuthSecret;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.FileUtils;
import android.os.IProgressListener;
import android.os.RemoteException;
@@ -95,6 +98,9 @@ public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
RecoverableKeyStoreManager mRecoverableKeyStoreManager;
UserManagerInternal mUserManagerInternal;
DeviceStateCache mDeviceStateCache;
+ FingerprintManager mFingerprintManager;
+ FaceManager mFaceManager;
+ PackageManager mPackageManager;
protected boolean mHasSecureLockScreen;
@Override
@@ -114,6 +120,9 @@ public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
mRecoverableKeyStoreManager = mock(RecoverableKeyStoreManager.class);
mUserManagerInternal = mock(UserManagerInternal.class);
mDeviceStateCache = mock(DeviceStateCache.class);
+ mFingerprintManager = mock(FingerprintManager.class);
+ mFaceManager = mock(FaceManager.class);
+ mPackageManager = mock(PackageManager.class);
LocalServices.removeServiceForTest(LockSettingsInternal.class);
LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class);
@@ -123,7 +132,7 @@ public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
mContext = new MockLockSettingsContext(getContext(), mUserManager, mNotificationManager,
mDevicePolicyManager, mock(StorageManager.class), mock(TrustManager.class),
- mock(KeyguardManager.class));
+ mock(KeyguardManager.class), mFingerprintManager, mFaceManager, mPackageManager);
mStorage = new LockSettingsStorageTestable(mContext,
new File(getContext().getFilesDir(), "locksettings"));
File storageDir = mStorage.mStorageDir;
@@ -181,6 +190,8 @@ public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
new ComponentName("com.dummy.package", ".FakeDeviceOwner"));
when(mUserManagerInternal.isDeviceManaged()).thenReturn(true);
when(mDeviceStateCache.isDeviceProvisioned()).thenReturn(true);
+ mockBiometricsHardwareFingerprintsAndTemplates(PRIMARY_USER_ID);
+ mockBiometricsHardwareFingerprintsAndTemplates(MANAGED_PROFILE_USER_ID);
mLocalService = LocalServices.getService(LockSettingsInternal.class);
}
@@ -233,6 +244,18 @@ public abstract class BaseLockSettingsServiceTests extends AndroidTestCase {
return sm;
}
+ private void mockBiometricsHardwareFingerprintsAndTemplates(int userId) {
+ // Hardware must be detected and fingerprints must be enrolled
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)).thenReturn(true);
+ when(mFingerprintManager.isHardwareDetected()).thenReturn(true);
+ when(mFingerprintManager.hasEnrolledFingerprints(userId)).thenReturn(true);
+
+ // Hardware must be detected and templates must be enrolled
+ when(mPackageManager.hasSystemFeature(PackageManager.FEATURE_FACE)).thenReturn(true);
+ when(mFaceManager.isHardwareDetected()).thenReturn(true);
+ when(mFaceManager.hasEnrolledTemplates(userId)).thenReturn(true);
+ }
+
@Override
protected void tearDown() throws Exception {
super.tearDown();
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
index 65d6f45b5c6c..fcd98e0742ea 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java
@@ -23,7 +23,6 @@ import android.app.admin.DeviceStateCache;
import android.content.Context;
import android.hardware.authsecret.V1_0.IAuthSecret;
import android.os.Handler;
-import android.os.Looper;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserManagerInternal;
@@ -32,6 +31,7 @@ import android.security.KeyStore;
import android.security.keystore.KeyPermanentlyInvalidatedException;
import com.android.internal.widget.LockPatternUtils;
+import com.android.server.ServiceThread;
import com.android.server.locksettings.recoverablekeystore.RecoverableKeyStoreManager;
import java.io.FileNotFoundException;
@@ -70,8 +70,8 @@ public class LockSettingsServiceTestable extends LockSettingsService {
}
@Override
- public Handler getHandler() {
- return new Handler(Looper.getMainLooper());
+ public Handler getHandler(ServiceThread handlerThread) {
+ return new Handler(handlerThread.getLooper());
}
@Override
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
index 7354ad4b9ac3..5818133aa2a4 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java
@@ -330,6 +330,27 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests {
.lockScreenSecretChanged(CREDENTIAL_TYPE_NONE, null, MANAGED_PROFILE_USER_ID);
}
+ public void testSetLockCredential_nullCredential_removeBiometrics() throws RemoteException {
+ final String oldCredential = "oldPassword";
+
+ initializeStorageWithCredential(
+ PRIMARY_USER_ID,
+ oldCredential,
+ CREDENTIAL_TYPE_PATTERN,
+ PASSWORD_QUALITY_SOMETHING);
+ mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null);
+
+ mService.setLockCredential(null, CREDENTIAL_TYPE_NONE, oldCredential.getBytes(),
+ PASSWORD_QUALITY_UNSPECIFIED, PRIMARY_USER_ID, false);
+
+ // Verify fingerprint is removed
+ verify(mFingerprintManager).remove(any(), eq(PRIMARY_USER_ID), any());
+ verify(mFaceManager).remove(any(), eq(PRIMARY_USER_ID), any());
+
+ verify(mFingerprintManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any());
+ verify(mFaceManager).remove(any(), eq(MANAGED_PROFILE_USER_ID), any());
+ }
+
public void testSetLockCredential_forUnifiedToSeparateChallengeProfile_sendsNewCredentials()
throws Exception {
final String parentPassword = "parentPassword";
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
index 8e0d7be5f44f..2a169b775ca3 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsStorageTests.java
@@ -24,8 +24,11 @@ import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.database.sqlite.SQLiteDatabase;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.FileUtils;
import android.os.SystemClock;
import android.os.UserManager;
@@ -86,7 +89,9 @@ public class LockSettingsStorageTests extends AndroidTestCase {
MockLockSettingsContext context = new MockLockSettingsContext(getContext(), mockUserManager,
mock(NotificationManager.class), mock(DevicePolicyManager.class),
- mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class));
+ mock(StorageManager.class), mock(TrustManager.class), mock(KeyguardManager.class),
+ mock(FingerprintManager.class), mock(FaceManager.class),
+ mock(PackageManager.class));
mStorage = new LockSettingsStorageTestable(context,
new File(getContext().getFilesDir(), "locksettings"));
mStorage.setDatabaseOnCreateCallback(new LockSettingsStorage.Callback() {
diff --git a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
index b33253264317..2b9a05c3ef63 100644
--- a/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
+++ b/services/tests/servicestests/src/com/android/server/locksettings/MockLockSettingsContext.java
@@ -23,6 +23,8 @@ import android.app.trust.TrustManager;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.pm.PackageManager;
+import android.hardware.face.FaceManager;
+import android.hardware.fingerprint.FingerprintManager;
import android.os.UserManager;
import android.os.storage.StorageManager;
@@ -34,11 +36,15 @@ public class MockLockSettingsContext extends ContextWrapper {
private StorageManager mStorageManager;
private TrustManager mTrustManager;
private KeyguardManager mKeyguardManager;
+ private FingerprintManager mFingerprintManager;
+ private FaceManager mFaceManager;
+ private PackageManager mPackageManager;
public MockLockSettingsContext(Context base, UserManager userManager,
NotificationManager notificationManager, DevicePolicyManager devicePolicyManager,
StorageManager storageManager, TrustManager trustManager,
- KeyguardManager keyguardManager) {
+ KeyguardManager keyguardManager, FingerprintManager fingerprintManager,
+ FaceManager faceManager, PackageManager packageManager) {
super(base);
mUserManager = userManager;
mNotificationManager = notificationManager;
@@ -46,6 +52,9 @@ public class MockLockSettingsContext extends ContextWrapper {
mStorageManager = storageManager;
mTrustManager = trustManager;
mKeyguardManager = keyguardManager;
+ mFingerprintManager = fingerprintManager;
+ mFaceManager = faceManager;
+ mPackageManager = packageManager;
}
@Override
@@ -62,12 +71,21 @@ public class MockLockSettingsContext extends ContextWrapper {
return mTrustManager;
} else if (KEYGUARD_SERVICE.equals(name)) {
return mKeyguardManager;
+ } else if (FINGERPRINT_SERVICE.equals(name)) {
+ return mFingerprintManager;
+ } else if (FACE_SERVICE.equals(name)) {
+ return mFaceManager;
} else {
throw new RuntimeException("System service not mocked: " + name);
}
}
@Override
+ public PackageManager getPackageManager() {
+ return mPackageManager;
+ }
+
+ @Override
public void enforceCallingOrSelfPermission(String permission, String message) {
// Skip permission checks for unit tests.
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
index 806c71a7a9b8..6d5b994a63bb 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserManagerServiceUserInfoTest.java
@@ -132,6 +132,7 @@ public class UserManagerServiceUserInfoTest {
user.profileBadge = 2;
user.partial = true;
user.guestToRemove = true;
+ user.preCreated = true;
return user;
}
@@ -147,5 +148,6 @@ public class UserManagerServiceUserInfoTest {
assertEquals("profile badge not preseved", one.profileBadge, two.profileBadge);
assertEquals("partial not preseved", one.partial, two.partial);
assertEquals("guestToRemove not preseved", one.guestToRemove, two.guestToRemove);
+ assertEquals("preCreated not preseved", one.preCreated, two.preCreated);
}
}
diff --git a/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
new file mode 100644
index 000000000000..ee3b15a97f26
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/rollback/RollbackStoreTest.java
@@ -0,0 +1,318 @@
+/*
+ * 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.rollback;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.content.pm.VersionedPackage;
+import android.content.rollback.PackageRollbackInfo;
+import android.util.IntArray;
+import android.util.SparseLongArray;
+
+import com.google.common.truth.Correspondence;
+
+import org.json.JSONObject;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.File;
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+@RunWith(JUnit4.class)
+public class RollbackStoreTest {
+
+ private static final int ID = 123;
+
+ private static final Correspondence<VersionedPackage, VersionedPackage> VER_PKG_CORR =
+ new Correspondence<VersionedPackage, VersionedPackage>() {
+ @Override
+ public boolean compare(VersionedPackage a, VersionedPackage b) {
+ if (a == null || b == null) {
+ return a == b;
+ }
+ return a.getLongVersionCode() == b.getLongVersionCode()
+ && Objects.equals(a.getPackageName(), b.getPackageName());
+ }
+
+ @Override
+ public String toString() {
+ return "is the same as";
+ }
+ };
+
+ private static final Correspondence<PackageRollbackInfo.RestoreInfo,
+ PackageRollbackInfo.RestoreInfo>
+ RESTORE_INFO_CORR =
+ new Correspondence<PackageRollbackInfo.RestoreInfo, PackageRollbackInfo.RestoreInfo>() {
+ @Override
+ public boolean compare(PackageRollbackInfo.RestoreInfo a,
+ PackageRollbackInfo.RestoreInfo b) {
+ if (a == null || b == null) {
+ return a == b;
+ }
+ return a.userId == b.userId
+ && a.appId == b.appId
+ && Objects.equals(a.seInfo, b.seInfo);
+ }
+
+ @Override
+ public String toString() {
+ return "is the same as";
+ }
+ };
+
+ private static final String JSON_ROLLBACK = "{'info':{'rollbackId':123,'packages':"
+ + "[{'versionRolledBackFrom':{'packageName':'blah','longVersionCode':55},"
+ + "'versionRolledBackTo':{'packageName':'blah1','longVersionCode':50},'pendingBackups':"
+ + "[59,1245,124544],'pendingRestores':[{'userId':498,'appId':32322,'seInfo':'wombles'},"
+ + "{'userId':-895,'appId':1,'seInfo':'pingu'}],'isApex':false,'installedUsers':"
+ + "[498468432,1111,98464],'ceSnapshotInodes':[{'userId':1,'ceSnapshotInode':-6},"
+ + "{'userId':2222,'ceSnapshotInode':81641654445},{'userId':546546,"
+ + "'ceSnapshotInode':345689375}]},{'versionRolledBackFrom':{'packageName':'chips',"
+ + "'longVersionCode':28},'versionRolledBackTo':{'packageName':'com.chips.test',"
+ + "'longVersionCode':48},'pendingBackups':[5],'pendingRestores':[{'userId':18,"
+ + "'appId':-12,'seInfo':''}],'isApex':false,'installedUsers':[55,79],"
+ + "'ceSnapshotInodes':[]}],'isStaged':false,'causePackages':[{'packageName':'hello',"
+ + "'longVersionCode':23},{'packageName':'something','longVersionCode':999}],"
+ + "'committedSessionId':45654465},'timestamp':'2019-10-01T12:29:08.855Z',"
+ + "'stagedSessionId':-1,'state':'enabling','apkSessionId':-1,"
+ + "'restoreUserDataInProgress':true}";
+
+ @Rule
+ public TemporaryFolder mFolder = new TemporaryFolder();
+
+ private File mRollbackDir;
+
+ private RollbackStore mRollbackStore;
+
+ @Before
+ public void setUp() throws Exception {
+ mRollbackStore = new RollbackStore(mFolder.getRoot());
+ mRollbackDir = mFolder.newFolder(ID + "");
+ mFolder.newFile("rollback.json");
+ }
+
+ @Test
+ public void createNonStaged() {
+ Rollback rollback = mRollbackStore.createNonStagedRollback(ID);
+
+ assertThat(rollback.getBackupDir().getAbsolutePath())
+ .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
+
+ assertThat(rollback.isStaged()).isFalse();
+ assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
+ assertThat(rollback.info.getPackages()).isEmpty();
+ assertThat(rollback.isEnabling()).isTrue();
+ }
+
+ @Test
+ public void createStaged() {
+ Rollback rollback = mRollbackStore.createStagedRollback(ID, 897);
+
+ assertThat(rollback.getBackupDir().getAbsolutePath())
+ .isEqualTo(mFolder.getRoot().getAbsolutePath() + "/" + ID);
+
+ assertThat(rollback.isStaged()).isTrue();
+ assertThat(rollback.getStagedSessionId()).isEqualTo(897);
+
+ assertThat(rollback.info.getRollbackId()).isEqualTo(ID);
+ assertThat(rollback.info.getPackages()).isEmpty();
+ assertThat(rollback.isEnabling()).isTrue();
+ }
+
+ @Test
+ public void saveAndLoadRollback() {
+ Rollback origRb = mRollbackStore.createNonStagedRollback(ID);
+
+ origRb.setRestoreUserDataInProgress(true);
+ origRb.info.getCausePackages().add(new VersionedPackage("com.made.up", 2));
+ origRb.info.getCausePackages().add(new VersionedPackage("com.pack.age", 99));
+ origRb.info.setCommittedSessionId(123456);
+
+ PackageRollbackInfo pkgInfo1 =
+ new PackageRollbackInfo(new VersionedPackage("com.made.up", 18),
+ new VersionedPackage("com.something.else", 5), new IntArray(),
+ new ArrayList<>(), false, new IntArray(), new SparseLongArray());
+ pkgInfo1.getPendingBackups().add(8);
+ pkgInfo1.getPendingBackups().add(888);
+ pkgInfo1.getPendingBackups().add(88885);
+ pkgInfo1.getCeSnapshotInodes().put(12, 424);
+ pkgInfo1.getCeSnapshotInodes().put(222772, 10000000000L);
+ pkgInfo1.getCeSnapshotInodes().put(10, -67);
+
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(4980, 3442322, "seInfo"));
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(-89, 15, "otherSeInfo"));
+
+ pkgInfo1.getSnapshottedUsers().add(11);
+ pkgInfo1.getSnapshottedUsers().add(1);
+ pkgInfo1.getSnapshottedUsers().add(0);
+
+ PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(
+ new VersionedPackage("another.package", 2),
+ new VersionedPackage("com.test.ing", 48888), new IntArray(), new ArrayList<>(),
+ false, new IntArray(), new SparseLongArray());
+ pkgInfo2.getPendingBackups().add(57);
+
+ pkgInfo2.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(180, -120, ""));
+
+ origRb.info.getPackages().add(pkgInfo1);
+ origRb.info.getPackages().add(pkgInfo2);
+
+ RollbackStore.saveRollback(origRb);
+
+ List<Rollback> loadedRollbacks = mRollbackStore.loadRollbacks();
+ assertThat(loadedRollbacks).hasSize(1);
+ Rollback loadedRb = loadedRollbacks.get(0);
+
+ assertRollbacksAreEquivalent(loadedRb, origRb);
+ }
+
+ @Test
+ public void loadFromJson() throws Exception {
+ Rollback expectedRb = mRollbackStore.createNonStagedRollback(ID);
+
+ expectedRb.setTimestamp(Instant.parse("2019-10-01T12:29:08.855Z"));
+ expectedRb.setRestoreUserDataInProgress(true);
+ expectedRb.info.getCausePackages().add(new VersionedPackage("hello", 23));
+ expectedRb.info.getCausePackages().add(new VersionedPackage("something", 999));
+ expectedRb.info.setCommittedSessionId(45654465);
+
+ PackageRollbackInfo pkgInfo1 = new PackageRollbackInfo(new VersionedPackage("blah", 55),
+ new VersionedPackage("blah1", 50), new IntArray(), new ArrayList<>(),
+ false, new IntArray(), new SparseLongArray());
+ pkgInfo1.getPendingBackups().add(59);
+ pkgInfo1.getPendingBackups().add(1245);
+ pkgInfo1.getPendingBackups().add(124544);
+ pkgInfo1.getCeSnapshotInodes().put(546546, 345689375);
+ pkgInfo1.getCeSnapshotInodes().put(2222, 81641654445L);
+ pkgInfo1.getCeSnapshotInodes().put(1, -6);
+
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(498, 32322, "wombles"));
+ pkgInfo1.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(-895, 1, "pingu"));
+
+ pkgInfo1.getSnapshottedUsers().add(498468432);
+ pkgInfo1.getSnapshottedUsers().add(1111);
+ pkgInfo1.getSnapshottedUsers().add(98464);
+
+ PackageRollbackInfo pkgInfo2 = new PackageRollbackInfo(new VersionedPackage("chips", 28),
+ new VersionedPackage("com.chips.test", 48), new IntArray(), new ArrayList<>(),
+ false, new IntArray(), new SparseLongArray());
+ pkgInfo2.getPendingBackups().add(5);
+
+ pkgInfo2.getPendingRestores().add(
+ new PackageRollbackInfo.RestoreInfo(18, -12, ""));
+
+ pkgInfo2.getSnapshottedUsers().add(55);
+ pkgInfo2.getSnapshottedUsers().add(79);
+
+ expectedRb.info.getPackages().add(pkgInfo1);
+ expectedRb.info.getPackages().add(pkgInfo2);
+
+ Rollback parsedRb = RollbackStore.rollbackFromJson(
+ new JSONObject(JSON_ROLLBACK), expectedRb.getBackupDir());
+
+ assertRollbacksAreEquivalent(parsedRb, expectedRb);
+ }
+
+ @Test
+ public void saveAndDelete() {
+ Rollback rollback = mRollbackStore.createNonStagedRollback(ID);
+
+ RollbackStore.saveRollback(rollback);
+
+ File expectedFile = new File(mRollbackDir.getAbsolutePath() + "/rollback.json");
+
+ assertThat(expectedFile.exists()).isTrue();
+
+ RollbackStore.deleteRollback(rollback);
+
+ assertThat(expectedFile.exists()).isFalse();
+ }
+
+ private void assertRollbacksAreEquivalent(Rollback b, Rollback a) {
+ assertThat(b.info.getRollbackId()).isEqualTo(ID);
+
+ assertThat(b.getBackupDir()).isEqualTo(a.getBackupDir());
+
+ assertThat(b.isRestoreUserDataInProgress())
+ .isEqualTo(a.isRestoreUserDataInProgress());
+
+ assertThat(b.getTimestamp()).isEqualTo(a.getTimestamp());
+
+ assertThat(b.isEnabling()).isEqualTo(a.isEnabling());
+ assertThat(b.isAvailable()).isEqualTo(a.isAvailable());
+ assertThat(b.isCommitted()).isEqualTo(a.isCommitted());
+
+ assertThat(b.isStaged()).isEqualTo(a.isStaged());
+
+ assertThat(b.getApexPackageNames())
+ .containsExactlyElementsIn(a.getApexPackageNames());
+
+ assertThat(b.getStagedSessionId()).isEqualTo(a.getStagedSessionId());
+
+ assertThat(b.info.getCommittedSessionId()).isEqualTo(a.info.getCommittedSessionId());
+
+ assertThat(b.info.getCausePackages()).comparingElementsUsing(VER_PKG_CORR)
+ .containsExactlyElementsIn(a.info.getCausePackages());
+
+ assertThat(b.info.getPackages()).hasSize(a.info.getPackages().size());
+
+ for (int i = 0; i < b.info.getPackages().size(); i++) {
+ assertPackageRollbacksAreEquivalent(
+ b.info.getPackages().get(i), a.info.getPackages().get(i));
+ }
+ }
+
+ private void assertPackageRollbacksAreEquivalent(PackageRollbackInfo b, PackageRollbackInfo a) {
+ assertThat(b.getPackageName()).isEqualTo(a.getPackageName());
+
+ assertThat(b.getVersionRolledBackFrom().getLongVersionCode())
+ .isEqualTo(a.getVersionRolledBackFrom().getLongVersionCode());
+ assertThat(b.getVersionRolledBackFrom().getPackageName())
+ .isEqualTo(a.getVersionRolledBackFrom().getPackageName());
+
+ assertThat(b.getVersionRolledBackTo().getLongVersionCode())
+ .isEqualTo(a.getVersionRolledBackTo().getLongVersionCode());
+ assertThat(b.getVersionRolledBackTo().getPackageName())
+ .isEqualTo(a.getVersionRolledBackTo().getPackageName());
+
+ assertThat(b.getPendingBackups().toArray()).isEqualTo(a.getPendingBackups().toArray());
+
+ assertThat(b.getPendingRestores()).comparingElementsUsing(RESTORE_INFO_CORR)
+ .containsExactlyElementsIn(a.getPendingRestores());
+
+ assertThat(b.isApex()).isEqualTo(a.isApex());
+
+ assertThat(b.getSnapshottedUsers().toArray()).isEqualTo(a.getSnapshottedUsers().toArray());
+
+ assertThat(b.getCeSnapshotInodes().toString())
+ .isEqualTo(a.getCeSnapshotInodes().toString());
+ }
+
+}
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 2de8d0579ec4..e80c6291b42a 100644..100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -3864,7 +3864,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.simulatePackageDistractionBroadcast(
PackageManager.RESTRICTION_HIDE_NOTIFICATIONS, new String[] {"a", "b"});
ArgumentCaptor<List<NotificationRecord>> captorHide = ArgumentCaptor.forClass(List.class);
- verify(mListeners, times(2)).notifyHiddenLocked(captorHide.capture());
+
+ // should be called only once.
+ verify(mListeners, times(1)).notifyHiddenLocked(captorHide.capture());
assertEquals(2, captorHide.getValue().size());
assertEquals("a", captorHide.getValue().get(0).sbn.getPackageName());
assertEquals("b", captorHide.getValue().get(1).sbn.getPackageName());
@@ -3873,7 +3875,9 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mService.simulatePackageDistractionBroadcast(
PackageManager.RESTRICTION_HIDE_FROM_SUGGESTIONS, new String[] {"a", "b"});
ArgumentCaptor<List<NotificationRecord>> captorUnhide = ArgumentCaptor.forClass(List.class);
- verify(mListeners, times(2)).notifyUnhiddenLocked(captorUnhide.capture());
+
+ // should be called only once.
+ verify(mListeners, times(1)).notifyUnhiddenLocked(captorUnhide.capture());
assertEquals(2, captorUnhide.getValue().size());
assertEquals("a", captorUnhide.getValue().get(0).sbn.getPackageName());
assertEquals("b", captorUnhide.getValue().get(1).sbn.getPackageName());
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 59d07357ff56..34eb3f16bf2a 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -97,6 +97,8 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
@@ -159,7 +161,7 @@ public class UsageStatsService extends SystemService implements
int mUsageSource;
/** Manages the standby state of apps. */
- AppStandbyController mAppStandby;
+ AppStandbyInternal mAppStandby;
/** Manages app time limit observers */
AppTimeLimitController mAppTimeLimit;
@@ -208,7 +210,9 @@ public class UsageStatsService extends SystemService implements
mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
mHandler = new H(BackgroundThread.get().getLooper());
- mAppStandby = new AppStandbyController(getContext(), BackgroundThread.get().getLooper());
+ mAppStandby = AppStandbyInternal.newAppStandbyController(
+ UsageStatsService.class.getClassLoader(), getContext(),
+ BackgroundThread.get().getLooper());
mAppTimeLimit = new AppTimeLimitController(
new AppTimeLimitController.TimeLimitCallbackListener() {
@@ -1010,7 +1014,7 @@ public class UsageStatsService extends SystemService implements
pw.println("Flushed stats to disk");
return;
} else if ("is-app-standby-enabled".equals(arg)) {
- pw.println(mAppStandby.mAppIdleEnabled);
+ pw.println(mAppStandby.isAppIdleEnabled());
return;
} else if ("apptimelimit".equals(arg)) {
if (i + 1 >= args.length) {
diff --git a/telephony/java/android/telephony/CellBroadcastService.java b/telephony/java/android/telephony/CellBroadcastService.java
new file mode 100644
index 000000000000..d5e447e6c73d
--- /dev/null
+++ b/telephony/java/android/telephony/CellBroadcastService.java
@@ -0,0 +1,112 @@
+/*
+ * 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.telephony;
+
+import android.annotation.CallSuper;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.os.IBinder;
+
+/**
+ * A service which exposes the cell broadcast handling module to the system.
+ * <p>
+ * To extend this class, you must declare the service in your manifest file to require the
+ * {@link android.Manifest.permission#BIND_CELL_BROADCAST_SERVICE} permission and include an intent
+ * filter with the {@link #CELL_BROADCAST_SERVICE_INTERFACE}.
+ * Implementations of this service should run in the phone process and with its UID.
+ * <p>
+ * For example:
+ * <pre>{@code
+ * <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ * android:sharedUserId="android.uid.phone">
+ * <service android:name=".MyCellBroadcastService"
+ * android:label="@string/service_name"
+ * android:process="com.android.phone"
+ * android:exported="true"
+ * android:permission="android.permission.BIND_CELL_BROADCAST_SERVICE">
+ * <intent-filter>
+ * <action android:name="android.telephony.CellBroadcastService" />
+ * </intent-filter>
+ * </service>
+ * </manifest>
+ * }</pre>
+ * @hide
+ */
+@SystemApi
+public abstract class CellBroadcastService extends Service {
+
+ public static final String CELL_BROADCAST_SERVICE_INTERFACE =
+ "android.telephony.CellBroadcastService";
+
+ private final ICellBroadcastService.Stub mStubWrapper;
+
+ public CellBroadcastService() {
+ mStubWrapper = new ICellBroadcastServiceWrapper();
+ }
+
+ /**
+ * Handle a GSM cell broadcast SMS message forwarded from the system.
+ * @param slotIndex the index of the slot which received the message
+ * @param message the SMS PDU
+ */
+ public abstract void onGsmCellBroadcastSms(int slotIndex, byte[] message);
+
+ /**
+ * Handle a CDMA cell broadcast SMS message forwarded from the system.
+ * @param slotIndex the index of the slot which received the message
+ * @param message the SMS PDU
+ */
+ public abstract void onCdmaCellBroadcastSms(int slotIndex, byte[] message);
+
+ /**
+ * If overriding this method, call through to the super method for any unknown actions.
+ * {@inheritDoc}
+ */
+ @Override
+ @CallSuper
+ public IBinder onBind(Intent intent) {
+ return mStubWrapper;
+ }
+
+ /**
+ * A wrapper around ICellBroadcastService that forwards calls to implementations of
+ * {@link CellBroadcastService}.
+ * @hide
+ */
+ public class ICellBroadcastServiceWrapper extends ICellBroadcastService.Stub {
+ /**
+ * Handle a GSM cell broadcast SMS.
+ * @param slotIndex the index of the slot which received the broadcast
+ * @param message the SMS message PDU
+ */
+ @Override
+ public void handleGsmCellBroadcastSms(int slotIndex, byte[] message) {
+ CellBroadcastService.this.onGsmCellBroadcastSms(slotIndex, message);
+ }
+
+ /**
+ * Handle a CDMA cell broadcast SMS.
+ * @param slotIndex the index of the slot which received the broadcast
+ * @param message the SMS message PDU
+ */
+ @Override
+ public void handleCdmaCellBroadcastSms(int slotIndex, byte[] message) {
+ CellBroadcastService.this.onCdmaCellBroadcastSms(slotIndex, message);
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/ICellBroadcastService.aidl b/telephony/java/android/telephony/ICellBroadcastService.aidl
new file mode 100644
index 000000000000..eff64a2e35ba
--- /dev/null
+++ b/telephony/java/android/telephony/ICellBroadcastService.aidl
@@ -0,0 +1,32 @@
+/**
+ * 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.telephony;
+
+/**
+ * Service bound to by the system to allow custom handling of cell broadcast messages.
+ * <p>
+ * @see android.telephony.CellBroadcastService
+ * @hide
+ */
+interface ICellBroadcastService {
+
+ /** @see android.telephony.CellBroadcastService#onGsmCellBroadcastSms */
+ oneway void handleGsmCellBroadcastSms(int slotId, in byte[] message);
+
+ /** @see android.telephony.CellBroadcastService#onCdmaCellBroadcastSms */
+ oneway void handleCdmaCellBroadcastSms(int slotId, in byte[] message);
+}
diff --git a/telephony/java/android/telephony/IFinancialSmsCallback.aidl b/telephony/java/android/telephony/IFinancialSmsCallback.aidl
deleted file mode 100644
index aa88615c15cf..000000000000
--- a/telephony/java/android/telephony/IFinancialSmsCallback.aidl
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-** Copyright 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.telephony;
-
-import android.app.PendingIntent;
-import android.database.CursorWindow;
-import android.net.Uri;
-import android.os.Bundle;
-import com.android.internal.telephony.SmsRawData;
-
-/** Interface for returning back the financial sms messages asynchrously.
- * @hide
- */
-interface IFinancialSmsCallback {
- /**
- * Return sms messages back to calling financial app.
- *
- * @param messages the sms messages returned for cinancial app.
- */
- oneway void onGetSmsMessagesForFinancialApp(in CursorWindow messages);
-}
diff --git a/telephony/java/android/telephony/PhoneStateListener.java b/telephony/java/android/telephony/PhoneStateListener.java
index c2028f900508..1801caeb0660 100644
--- a/telephony/java/android/telephony/PhoneStateListener.java
+++ b/telephony/java/android/telephony/PhoneStateListener.java
@@ -878,6 +878,7 @@ public class PhoneStateListener {
* @hide
*/
@SystemApi
+ @TestApi
public void onOutgoingEmergencyCall(@NonNull EmergencyNumber placedEmergencyNumber) {
// default implementation empty
}
@@ -889,6 +890,7 @@ public class PhoneStateListener {
* @hide
*/
@SystemApi
+ @TestApi
public void onOutgoingEmergencySms(@NonNull EmergencyNumber sentEmergencyNumber) {
// default implementation empty
}
diff --git a/telephony/java/android/telephony/SmsManager.java b/telephony/java/android/telephony/SmsManager.java
index 71fcf23cb6ee..f4330fa0b725 100644
--- a/telephony/java/android/telephony/SmsManager.java
+++ b/telephony/java/android/telephony/SmsManager.java
@@ -33,6 +33,7 @@ import android.content.pm.PackageManager;
import android.database.CursorWindow;
import android.net.Uri;
import android.os.Binder;
+import android.os.BaseBundle;
import android.os.Build;
import android.os.Bundle;
import android.os.RemoteException;
@@ -2080,7 +2081,9 @@ public final class SmsManager {
}
}
- /** callback for providing asynchronous sms messages for financial app. */
+ /**
+ * callback for providing asynchronous sms messages for financial app.
+ */
public abstract static class FinancialSmsCallback {
/**
* Callback to send sms messages back to financial app asynchronously.
@@ -2106,24 +2109,14 @@ public final class SmsManager {
* @param params the parameters to filter SMS messages returned.
* @param executor the executor on which callback will be invoked.
* @param callback a callback to receive CursorWindow with SMS messages.
+ *
*/
@RequiresPermission(android.Manifest.permission.SMS_FINANCIAL_TRANSACTIONS)
public void getSmsMessagesForFinancialApp(
Bundle params,
@NonNull @CallbackExecutor Executor executor,
@NonNull FinancialSmsCallback callback) {
- try {
- ISms iccSms = getISmsServiceOrThrow();
- iccSms.getSmsMessagesForFinancialApp(
- getSubscriptionId(), ActivityThread.currentPackageName(), params,
- new IFinancialSmsCallback.Stub() {
- public void onGetSmsMessagesForFinancialApp(CursorWindow msgs) {
- Binder.withCleanCallingIdentity(() -> executor.execute(
- () -> callback.onFinancialSmsMessages(msgs)));
- }});
- } catch (RemoteException ex) {
- ex.rethrowFromSystemServer();
- }
+ // This API is not functional and thus removed to avoid future confusion.
}
/**
diff --git a/telephony/java/com/android/internal/telephony/ISms.aidl b/telephony/java/com/android/internal/telephony/ISms.aidl
index 7441c26a8061..f3a335d93a6c 100644
--- a/telephony/java/com/android/internal/telephony/ISms.aidl
+++ b/telephony/java/com/android/internal/telephony/ISms.aidl
@@ -19,7 +19,6 @@ package com.android.internal.telephony;
import android.app.PendingIntent;
import android.net.Uri;
import android.os.Bundle;
-import android.telephony.IFinancialSmsCallback;
import com.android.internal.telephony.SmsRawData;
/**
@@ -570,17 +569,6 @@ interface ISms {
int subId, String callingPkg, String prefixes, in PendingIntent intent);
/**
- * Get sms inbox messages for the calling financial app.
- *
- * @param subId the SIM id.
- * @param callingPkg the package name of the calling app.
- * @param params parameters to filter the sms messages.
- * @param callback the callback interface to deliver the result.
- */
- void getSmsMessagesForFinancialApp(
- int subId, String callingPkg, in Bundle params, in IFinancialSmsCallback callback);
-
- /**
* Check if the destination is a possible premium short code.
*
* @param destAddress the destination address to test for possible short code
diff --git a/telephony/java/com/android/internal/telephony/ISmsImplBase.java b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
index aa1f94f2355a..2096325b09f2 100644
--- a/telephony/java/com/android/internal/telephony/ISmsImplBase.java
+++ b/telephony/java/com/android/internal/telephony/ISmsImplBase.java
@@ -19,7 +19,6 @@ package com.android.internal.telephony;
import android.app.PendingIntent;
import android.net.Uri;
import android.os.Bundle;
-import android.telephony.IFinancialSmsCallback;
import java.util.List;
@@ -198,12 +197,6 @@ public class ISmsImplBase extends ISms.Stub {
}
@Override
- public void getSmsMessagesForFinancialApp(
- int subId, String callingPkg, Bundle params, IFinancialSmsCallback callback) {
- throw new UnsupportedOperationException();
- }
-
- @Override
public int checkSmsShortCodeDestination(
int subid, String callingApk, String destAddress, String countryIso) {
throw new UnsupportedOperationException();
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
index 6eea118787a7..c65c45fa015b 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmSmsCbMessage.java
@@ -461,7 +461,11 @@ public class GsmSmsCbMessage {
}
}
- static final class GeoFencingTriggerMessage {
+ /**
+ * Part of a GSM SMS cell broadcast message which may trigger geo-fencing logic.
+ * @hide
+ */
+ public static final class GeoFencingTriggerMessage {
/**
* Indicate the list of active alerts share their warning area coordinates which means the
* broadcast area is the union of the broadcast areas of the active alerts in this list.
@@ -476,6 +480,11 @@ public class GsmSmsCbMessage {
this.cbIdentifiers = cbIdentifiers;
}
+ /**
+ * Whether the trigger message indicates that the broadcast areas are shared between all
+ * active alerts.
+ * @return true if broadcast areas are to be shared
+ */
boolean shouldShareBroadcastArea() {
return type == TYPE_ACTIVE_ALERT_SHARE_WAC;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
index 6bbff4b91ee7..cbe521182667 100644
--- a/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
+++ b/telephony/java/com/android/internal/telephony/gsm/SmsCbHeader.java
@@ -74,22 +74,22 @@ public class SmsCbHeader {
/**
* Length of SMS-CB header
*/
- static final int PDU_HEADER_LENGTH = 6;
+ public static final int PDU_HEADER_LENGTH = 6;
/**
* GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1
*/
- static final int FORMAT_GSM = 1;
+ public static final int FORMAT_GSM = 1;
/**
* UMTS pdu format, as defined in 3gpp TS 23.041, section 9.4.2
*/
- static final int FORMAT_UMTS = 2;
+ public static final int FORMAT_UMTS = 2;
/**
- * GSM pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
+ * ETWS pdu format, as defined in 3gpp TS 23.041, section 9.4.1.3
*/
- static final int FORMAT_ETWS_PRIMARY = 3;
+ public static final int FORMAT_ETWS_PRIMARY = 3;
/**
* Message type value as defined in 3gpp TS 25.324, section 11.1.
@@ -230,43 +230,43 @@ public class SmsCbHeader {
}
@UnsupportedAppUsage
- int getGeographicalScope() {
+ public int getGeographicalScope() {
return mGeographicalScope;
}
@UnsupportedAppUsage
- int getSerialNumber() {
+ public int getSerialNumber() {
return mSerialNumber;
}
@UnsupportedAppUsage
- int getServiceCategory() {
+ public int getServiceCategory() {
return mMessageIdentifier;
}
- int getDataCodingScheme() {
+ public int getDataCodingScheme() {
return mDataCodingScheme;
}
- DataCodingScheme getDataCodingSchemeStructedData() {
+ public DataCodingScheme getDataCodingSchemeStructedData() {
return mDataCodingSchemeStructedData;
}
@UnsupportedAppUsage
- int getPageIndex() {
+ public int getPageIndex() {
return mPageIndex;
}
@UnsupportedAppUsage
- int getNumberOfPages() {
+ public int getNumberOfPages() {
return mNrOfPages;
}
- SmsCbEtwsInfo getEtwsInfo() {
+ public SmsCbEtwsInfo getEtwsInfo() {
return mEtwsInfo;
}
- SmsCbCmasInfo getCmasInfo() {
+ public SmsCbCmasInfo getCmasInfo() {
return mCmasInfo;
}
@@ -274,7 +274,7 @@ public class SmsCbHeader {
* Return whether this broadcast is an emergency (PWS) message type.
* @return true if this message is emergency type; false otherwise
*/
- boolean isEmergencyMessage() {
+ public boolean isEmergencyMessage() {
return mMessageIdentifier >= SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER
&& mMessageIdentifier <= SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER;
}
@@ -292,7 +292,7 @@ public class SmsCbHeader {
* Return whether this broadcast is an ETWS primary notification.
* @return true if this message is an ETWS primary notification; false otherwise
*/
- boolean isEtwsPrimaryNotification() {
+ public boolean isEtwsPrimaryNotification() {
return mFormat == FORMAT_ETWS_PRIMARY;
}
@@ -300,7 +300,7 @@ public class SmsCbHeader {
* Return whether this broadcast is in UMTS format.
* @return true if this message is in UMTS format; false otherwise
*/
- boolean isUmtsFormat() {
+ public boolean isUmtsFormat() {
return mFormat == FORMAT_UMTS;
}
diff --git a/tests/Codegen/runTest.sh b/tests/Codegen/runTest.sh
index 614cbb7c9eb6..01522735ec3c 100755
--- a/tests/Codegen/runTest.sh
+++ b/tests/Codegen/runTest.sh
@@ -13,6 +13,7 @@ else
header_and_eval m -j16 codegen_cli && \
header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java && \
header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java && \
+ header_and_eval codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java && \
cd $ANDROID_BUILD_TOP &&
header_and_eval mmma -j16 frameworks/base/tests/Codegen && \
header_and_eval adb install -r -t $ANDROID_PRODUCT_OUT/testcases/CodegenTests/arm64/CodegenTests.apk && \
diff --git a/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
new file mode 100644
index 000000000000..2d4125783990
--- /dev/null
+++ b/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
@@ -0,0 +1,362 @@
+/*
+ * 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.codegentest;
+
+import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
+
+import com.android.internal.util.AnnotationValidations;
+import com.android.internal.util.DataClass;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Additional test for various parcelling corner-cases.
+ */
+@DataClass(
+ genBuilder = true,
+ genAidl = false,
+ genToString = true)
+public class ParcelAllTheThingsDataClass implements Parcelable {
+
+ @NonNull String[] mStringArray = null;
+ @NonNull int[] mIntArray = null;
+ @NonNull List<String> mStringList = null;
+
+ @NonNull Map<String, SampleWithCustomBuilder> mMap = null;
+ @NonNull Map<String, String> mStringMap = null;
+
+ @NonNull SparseArray<SampleWithCustomBuilder> mSparseArray = null;
+ @NonNull SparseIntArray mSparseIntArray = null;
+
+
+
+ // Code below generated by codegen v1.0.4.
+ //
+ // DO NOT MODIFY!
+ // CHECKSTYLE:OFF Generated code
+ //
+ // To regenerate run:
+ // $ codegen $ANDROID_BUILD_TOP/frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java
+
+
+ @DataClass.Generated.Member
+ /* package-private */ ParcelAllTheThingsDataClass(
+ @NonNull String[] stringArray,
+ @NonNull int[] intArray,
+ @NonNull List<String> stringList,
+ @NonNull Map<String,SampleWithCustomBuilder> map,
+ @NonNull Map<String,String> stringMap,
+ @NonNull SparseArray<SampleWithCustomBuilder> sparseArray,
+ @NonNull SparseIntArray sparseIntArray) {
+ this.mStringArray = stringArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringArray);
+ this.mIntArray = intArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mIntArray);
+ this.mStringList = stringList;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringList);
+ this.mMap = map;
+ AnnotationValidations.validate(
+ NonNull.class, null, mMap);
+ this.mStringMap = stringMap;
+ AnnotationValidations.validate(
+ NonNull.class, null, mStringMap);
+ this.mSparseArray = sparseArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mSparseArray);
+ this.mSparseIntArray = sparseIntArray;
+ AnnotationValidations.validate(
+ NonNull.class, null, mSparseIntArray);
+
+ // onConstructed(); // You can define this method to get a callback
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull String[] getStringArray() {
+ return mStringArray;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull int[] getIntArray() {
+ return mIntArray;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull List<String> getStringList() {
+ return mStringList;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Map<String,SampleWithCustomBuilder> getMap() {
+ return mMap;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Map<String,String> getStringMap() {
+ return mStringMap;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull SparseArray<SampleWithCustomBuilder> getSparseArray() {
+ return mSparseArray;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull SparseIntArray getSparseIntArray() {
+ return mSparseIntArray;
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "ParcelAllTheThingsDataClass { " +
+ "stringArray = " + java.util.Arrays.toString(mStringArray) + ", " +
+ "intArray = " + java.util.Arrays.toString(mIntArray) + ", " +
+ "stringList = " + mStringList + ", " +
+ "map = " + mMap + ", " +
+ "stringMap = " + mStringMap + ", " +
+ "sparseArray = " + mSparseArray + ", " +
+ "sparseIntArray = " + mSparseIntArray +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeStringArray(mStringArray);
+ dest.writeIntArray(mIntArray);
+ dest.writeStringList(mStringList);
+ dest.writeMap(mMap);
+ dest.writeMap(mStringMap);
+ dest.writeSparseArray(mSparseArray);
+ dest.writeSparseIntArray(mSparseIntArray);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<ParcelAllTheThingsDataClass> CREATOR
+ = new Parcelable.Creator<ParcelAllTheThingsDataClass>() {
+ @Override
+ public ParcelAllTheThingsDataClass[] newArray(int size) {
+ return new ParcelAllTheThingsDataClass[size];
+ }
+
+ @Override
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ public ParcelAllTheThingsDataClass createFromParcel(Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ String[] stringArray = in.createStringArray();
+ int[] intArray = in.createIntArray();
+ List<String> stringList = new java.util.ArrayList<>();
+ in.readStringList(stringList);
+ Map<String,SampleWithCustomBuilder> map = new java.util.LinkedHashMap<>();
+ in.readMap(map, SampleWithCustomBuilder.class.getClassLoader());
+ Map<String,String> stringMap = new java.util.LinkedHashMap<>();
+ in.readMap(stringMap, String.class.getClassLoader());
+ SparseArray<SampleWithCustomBuilder> sparseArray = (SparseArray) in.readSparseArray(SampleWithCustomBuilder.class.getClassLoader());
+ SparseIntArray sparseIntArray = (SparseIntArray) in.readSparseIntArray();
+ return new ParcelAllTheThingsDataClass(
+ stringArray,
+ intArray,
+ stringList,
+ map,
+ stringMap,
+ sparseArray,
+ sparseIntArray);
+ }
+ };
+
+ /**
+ * A builder for {@link ParcelAllTheThingsDataClass}
+ */
+ @SuppressWarnings("WeakerAccess")
+ @DataClass.Generated.Member
+ public static class Builder {
+
+ private @NonNull String[] mStringArray;
+ private @NonNull int[] mIntArray;
+ private @NonNull List<String> mStringList;
+ private @NonNull Map<String,SampleWithCustomBuilder> mMap;
+ private @NonNull Map<String,String> mStringMap;
+ private @NonNull SparseArray<SampleWithCustomBuilder> mSparseArray;
+ private @NonNull SparseIntArray mSparseIntArray;
+
+ private long mBuilderFieldsSet = 0L;
+
+ public Builder() {
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setStringArray(@NonNull String... value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x1;
+ mStringArray = value;
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setIntArray(@NonNull int... value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x2;
+ mIntArray = value;
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setStringList(@NonNull List<String> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x4;
+ mStringList = value;
+ return this;
+ }
+
+ /** @see #setStringList */
+ @DataClass.Generated.Member
+ public @NonNull Builder addStringList(String value) {
+ // You can refine this method's name by providing item's singular name, e.g.:
+ // @DataClass.PluralOf("item")) mItems = ...
+
+ if (mStringList == null) setStringList(new java.util.ArrayList<>());
+ mStringList.add(value);
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setMap(@NonNull Map<String,SampleWithCustomBuilder> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x8;
+ mMap = value;
+ return this;
+ }
+
+ /** @see #setMap */
+ @DataClass.Generated.Member
+ public @NonNull Builder addMap(String key, SampleWithCustomBuilder value) {
+ // You can refine this method's name by providing item's singular name, e.g.:
+ // @DataClass.PluralOf("item")) mItems = ...
+
+ if (mMap == null) setMap(new java.util.LinkedHashMap());
+ mMap.put(key, value);
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setStringMap(@NonNull Map<String,String> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x10;
+ mStringMap = value;
+ return this;
+ }
+
+ /** @see #setStringMap */
+ @DataClass.Generated.Member
+ public @NonNull Builder addStringMap(String key, String value) {
+ // You can refine this method's name by providing item's singular name, e.g.:
+ // @DataClass.PluralOf("item")) mItems = ...
+
+ if (mStringMap == null) setStringMap(new java.util.LinkedHashMap());
+ mStringMap.put(key, value);
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setSparseArray(@NonNull SparseArray<SampleWithCustomBuilder> value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x20;
+ mSparseArray = value;
+ return this;
+ }
+
+ @DataClass.Generated.Member
+ public @NonNull Builder setSparseIntArray(@NonNull SparseIntArray value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x40;
+ mSparseIntArray = value;
+ return this;
+ }
+
+ /** Builds the instance. This builder should not be touched after calling this! */
+ public ParcelAllTheThingsDataClass build() {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x80; // Mark builder used
+
+ if ((mBuilderFieldsSet & 0x1) == 0) {
+ mStringArray = null;
+ }
+ if ((mBuilderFieldsSet & 0x2) == 0) {
+ mIntArray = null;
+ }
+ if ((mBuilderFieldsSet & 0x4) == 0) {
+ mStringList = null;
+ }
+ if ((mBuilderFieldsSet & 0x8) == 0) {
+ mMap = null;
+ }
+ if ((mBuilderFieldsSet & 0x10) == 0) {
+ mStringMap = null;
+ }
+ if ((mBuilderFieldsSet & 0x20) == 0) {
+ mSparseArray = null;
+ }
+ if ((mBuilderFieldsSet & 0x40) == 0) {
+ mSparseIntArray = null;
+ }
+ ParcelAllTheThingsDataClass o = new ParcelAllTheThingsDataClass(
+ mStringArray,
+ mIntArray,
+ mStringList,
+ mMap,
+ mStringMap,
+ mSparseArray,
+ mSparseIntArray);
+ return o;
+ }
+
+ private void checkNotUsed() {
+ if ((mBuilderFieldsSet & 0x80) != 0) {
+ throw new IllegalStateException(
+ "This Builder should not be reused. Use a new Builder instance instead");
+ }
+ }
+ }
+
+ @DataClass.Generated(
+ time = 1570139502128L,
+ codegenVersion = "1.0.4",
+ sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/ParcelAllTheThingsDataClass.java",
+ inputSignatures = " @android.annotation.NonNull java.lang.String[] mStringArray\n @android.annotation.NonNull int[] mIntArray\n @android.annotation.NonNull java.util.List<java.lang.String> mStringList\n @android.annotation.NonNull java.util.Map<java.lang.String,com.android.codegentest.SampleWithCustomBuilder> mMap\n @android.annotation.NonNull java.util.Map<java.lang.String,java.lang.String> mStringMap\n @android.annotation.NonNull android.util.SparseArray<com.android.codegentest.SampleWithCustomBuilder> mSparseArray\n @android.annotation.NonNull android.util.SparseIntArray mSparseIntArray\nclass ParcelAllTheThingsDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)")
+ @Deprecated
+ private void __metadata() {}
+
+}
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
index 66c7d06d6ff4..0631f7ded8ae 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClass.java
@@ -342,7 +342,7 @@ public final class SampleDataClass implements Parcelable {
- // Code below generated by codegen v1.0.3.
+ // Code below generated by codegen v1.0.4.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -1798,8 +1798,8 @@ public final class SampleDataClass implements Parcelable {
}
@DataClass.Generated(
- time = 1569956013899L,
- codegenVersion = "1.0.3",
+ time = 1570139500112L,
+ codegenVersion = "1.0.4",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleDataClass.java",
inputSignatures = "public static final java.lang.String STATE_NAME_UNDEFINED\npublic static final java.lang.String STATE_NAME_ON\npublic static final java.lang.String STATE_NAME_OFF\npublic static final int STATE_UNDEFINED\npublic static final int STATE_ON\npublic static final int STATE_OFF\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_MANUAL_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_COMPATIBILITY_MODE_REQUEST\npublic static final @com.android.codegentest.SampleDataClass.RequestFlags int FLAG_AUGMENTED_REQUEST\nprivate int mNum\nprivate int mNum2\nprivate int mNum4\nprivate @android.annotation.Nullable java.lang.String mName\nprivate @android.annotation.NonNull java.lang.String mName2\nprivate @android.annotation.NonNull java.lang.String mName4\nprivate @android.annotation.Nullable android.view.accessibility.AccessibilityNodeInfo mOtherParcelable\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.codegentest.MyDateParcelling.class) @android.annotation.NonNull java.util.Date mDate\nprivate @com.android.internal.util.DataClass.ParcelWith(com.android.internal.util.Parcelling.BuiltIn.ForPattern.class) @android.annotation.NonNull java.util.regex.Pattern mPattern\nprivate @android.annotation.NonNull java.util.List<android.net.LinkAddress> mLinkAddresses2\nprivate @com.android.internal.util.DataClass.PluralOf(\"linkAddress\") @android.annotation.NonNull java.util.ArrayList<android.net.LinkAddress> mLinkAddresses\nprivate @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses4\nprivate @com.android.codegentest.SampleDataClass.StateName @android.annotation.NonNull java.lang.String mStateName\nprivate @com.android.codegentest.SampleDataClass.RequestFlags int mFlags\nprivate @com.android.codegentest.SampleDataClass.State int mState\npublic @android.annotation.NonNull java.lang.CharSequence charSeq\nprivate final @android.annotation.Nullable android.net.LinkAddress[] mLinkAddresses5\nprivate transient android.net.LinkAddress[] mLinkAddresses6\ntransient int[] mTmpStorage\nprivate @android.annotation.StringRes int mStringRes\nprivate @android.annotation.IntRange(from=0L, to=6L) int mDayOfWeek\nprivate @android.annotation.Size(2L) @android.annotation.NonNull @com.android.internal.util.DataClass.Each @android.annotation.FloatRange(from=0.0) float[] mCoords\nprivate static java.lang.String defaultName4()\nprivate int[] lazyInitTmpStorage()\npublic android.net.LinkAddress[] getLinkAddresses4()\nprivate boolean patternEquals(java.util.regex.Pattern)\nprivate int patternHashCode()\nprivate void onConstructed()\npublic void dump(java.io.PrintWriter)\nclass SampleDataClass extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genConstructor=true, genEqualsHashCode=true, genToString=true, genForEachField=true, genSetters=true)")
@Deprecated
diff --git a/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
index 663620743af9..c7a773530963 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleDataClassTest.java
@@ -25,9 +25,14 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
import android.net.LinkAddress;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.SparseArray;
+import android.util.SparseIntArray;
import androidx.test.runner.AndroidJUnit4;
@@ -36,6 +41,9 @@ import org.junit.runner.RunWith;
import java.util.Arrays;
import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -209,6 +217,32 @@ public class SampleDataClassTest {
newBuilder().setDayOfWeek(42).build();
}
+ @Test
+ public void testDataStructures_parcelCorrectly() {
+ SampleWithCustomBuilder otherParcelable = new SampleWithCustomBuilder.Builder().setDelay(3, SECONDS).build();
+
+ ParcelAllTheThingsDataClass instance = new ParcelAllTheThingsDataClass.Builder()
+ .setIntArray(40, 41)
+ .addMap("foo", otherParcelable)
+ .setSparseArray(new SparseArray<SampleWithCustomBuilder>() {{
+ put(45, otherParcelable);
+ }})
+ .setSparseIntArray(new SparseIntArray() {{
+ put(48, 49);
+ }})
+ .addStringMap("foo2", "fooValue")
+ .setStringArray("foo", "bar")
+ .addStringList("foo")
+ .build();
+
+ ParcelAllTheThingsDataClass unparceledInstance =
+ parcelAndUnparcel(instance, ParcelAllTheThingsDataClass.CREATOR);
+
+ // SparseArray and friends don't implement equals
+ // so just compare string representations instead
+ assertEquals(instance.toString(), unparceledInstance.toString());
+ }
+
private static <T extends Parcelable> T parcelAndUnparcel(
T original, Parcelable.Creator<T> creator) {
Parcel p = Parcel.obtain();
diff --git a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
index c6bc8de3bb9e..0f8c663f5d4b 100644
--- a/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
+++ b/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java
@@ -17,14 +17,16 @@
package com.android.codegentest;
import android.annotation.NonNull;
+import android.os.Parcel;
+import android.os.Parcelable;
import android.os.SystemClock;
import com.android.internal.util.DataClass;
import java.util.concurrent.TimeUnit;
-@DataClass(genBuilder = true)
-public class SampleWithCustomBuilder {
+@DataClass(genBuilder = true, genAidl = false, genToString = true)
+public class SampleWithCustomBuilder implements Parcelable {
long delayAmount = 0;
@NonNull
@@ -73,8 +75,17 @@ public class SampleWithCustomBuilder {
}
+ private static TimeUnit unparcelDelayUnit(Parcel p) {
+ return TimeUnit.values()[p.readInt()];
+ }
+
+ private void parcelDelayUnit(Parcel p, int flags) {
+ p.writeInt(delayUnit.ordinal());
+ }
- // Code below generated by codegen v1.0.3.
+
+
+ // Code below generated by codegen v1.0.4.
//
// DO NOT MODIFY!
// CHECKSTYLE:OFF Generated code
@@ -112,6 +123,58 @@ public class SampleWithCustomBuilder {
return creationTimestamp;
}
+ @Override
+ @DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "SampleWithCustomBuilder { " +
+ "delayAmount = " + delayAmount + ", " +
+ "delayUnit = " + delayUnit + ", " +
+ "creationTimestamp = " + creationTimestamp +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public void writeToParcel(Parcel dest, int flags) {
+ // You can override field parcelling by defining methods like:
+ // void parcelFieldName(Parcel dest, int flags) { ... }
+
+ dest.writeLong(delayAmount);
+ parcelDelayUnit(dest, flags);
+ dest.writeLong(creationTimestamp);
+ }
+
+ @Override
+ @DataClass.Generated.Member
+ public int describeContents() { return 0; }
+
+ @DataClass.Generated.Member
+ public static final @NonNull Parcelable.Creator<SampleWithCustomBuilder> CREATOR
+ = new Parcelable.Creator<SampleWithCustomBuilder>() {
+ @Override
+ public SampleWithCustomBuilder[] newArray(int size) {
+ return new SampleWithCustomBuilder[size];
+ }
+
+ @Override
+ @SuppressWarnings({"unchecked", "RedundantCast"})
+ public SampleWithCustomBuilder createFromParcel(Parcel in) {
+ // You can override field unparcelling by defining methods like:
+ // static FieldType unparcelFieldName(Parcel in) { ... }
+
+ long _delayAmount = in.readLong();
+ TimeUnit _delayUnit = unparcelDelayUnit(in);
+ long _creationTimestamp = in.readLong();
+ return new SampleWithCustomBuilder(
+ _delayAmount,
+ _delayUnit,
+ _creationTimestamp);
+ }
+ };
+
/**
* A builder for {@link SampleWithCustomBuilder}
*/
@@ -176,10 +239,10 @@ public class SampleWithCustomBuilder {
}
@DataClass.Generated(
- time = 1569956014908L,
- codegenVersion = "1.0.3",
+ time = 1570139501160L,
+ codegenVersion = "1.0.4",
sourceFile = "frameworks/base/tests/Codegen/src/com/android/codegentest/SampleWithCustomBuilder.java",
- inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nclass SampleWithCustomBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genBuilder=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
+ inputSignatures = " long delayAmount\n @android.annotation.NonNull java.util.concurrent.TimeUnit delayUnit\n long creationTimestamp\nprivate static java.util.concurrent.TimeUnit unparcelDelayUnit(android.os.Parcel)\nprivate void parcelDelayUnit(android.os.Parcel,int)\nclass SampleWithCustomBuilder extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genBuilder=true, genAidl=false, genToString=true)\nabstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayAmount(long)\npublic abstract com.android.codegentest.SampleWithCustomBuilder.Builder setDelayUnit(java.util.concurrent.TimeUnit)\npublic com.android.codegentest.SampleWithCustomBuilder.Builder setDelay(long,java.util.concurrent.TimeUnit)\nclass BaseBuilder extends java.lang.Object implements []")
@Deprecated
private void __metadata() {}
diff --git a/tools/codegen/src/com/android/codegen/Generators.kt b/tools/codegen/src/com/android/codegen/Generators.kt
index 914e475cfe41..865340566019 100644
--- a/tools/codegen/src/com/android/codegen/Generators.kt
+++ b/tools/codegen/src/com/android/codegen/Generators.kt
@@ -341,7 +341,7 @@ private fun ClassPrinter.generateBuilderSetters(visibility: String) {
}
}
- if (Type.contains("Map<")) {
+ if (FieldClass.endsWith("Map") && FieldInnerType != null) {
generateBuilderMethod(
name = adderName,
defVisibility = visibility,
@@ -533,7 +533,7 @@ fun ClassPrinter.generateParcelable() {
} else if (Type !in PRIMITIVE_TYPES + "String" + "Bundle" &&
(!isArray || FieldInnerType !in PRIMITIVE_TYPES + "String") &&
ParcelMethodsSuffix != "Parcelable") {
- !"($Type) "
+ !"($FieldClass) "
}
}
@@ -541,12 +541,15 @@ fun ClassPrinter.generateParcelable() {
when {
ParcelMethodsSuffix == "Parcelable" ->
methodArgs += "$FieldClass.class.getClassLoader()"
+ ParcelMethodsSuffix == "SparseArray" ->
+ methodArgs += "$FieldInnerClass.class.getClassLoader()"
ParcelMethodsSuffix == "TypedObject" ->
methodArgs += "$FieldClass.CREATOR"
ParcelMethodsSuffix == "TypedArray" ->
methodArgs += "$FieldInnerClass.CREATOR"
+ ParcelMethodsSuffix == "Map" ->
+ methodArgs += "${fieldTypeGenegicArgs[1].substringBefore("<")}.class.getClassLoader()"
ParcelMethodsSuffix.startsWith("Parcelable")
- || FieldClass == "Map"
|| (isList || isArray)
&& FieldInnerType !in PRIMITIVE_TYPES + "String" ->
methodArgs += "$FieldInnerClass.class.getClassLoader()"
diff --git a/tools/codegen/src/com/android/codegen/SharedConstants.kt b/tools/codegen/src/com/android/codegen/SharedConstants.kt
index 1e3973eaa022..1cc7ef338cc3 100644
--- a/tools/codegen/src/com/android/codegen/SharedConstants.kt
+++ b/tools/codegen/src/com/android/codegen/SharedConstants.kt
@@ -1,7 +1,7 @@
package com.android.codegen
const val CODEGEN_NAME = "codegen"
-const val CODEGEN_VERSION = "1.0.3"
+const val CODEGEN_VERSION = "1.0.4"
const val CANONICAL_BUILDER_CLASS = "Builder"
const val BASE_BUILDER_CLASS = "BaseBuilder"