summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Android.bp101
-rw-r--r--PREUPLOAD.cfg3
-rw-r--r--apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt18
-rw-r--r--core/api/current.txt32
-rw-r--r--core/api/module-lib-current.txt16
-rw-r--r--core/api/system-current.txt66
-rw-r--r--core/api/test-current.txt2
-rw-r--r--core/java/android/app/Activity.java12
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java6
-rw-r--r--core/java/android/content/pm/PackageManager.java18
-rw-r--r--core/java/android/content/res/ApkAssets.java13
-rw-r--r--core/java/android/hardware/display/ColorDisplayManager.java20
-rw-r--r--core/java/android/hardware/display/DeviceProductInfo.java99
-rw-r--r--core/java/android/net/INetworkStatsService.aidl4
-rw-r--r--core/java/android/net/IpSecAlgorithm.java26
-rw-r--r--core/java/android/net/NetworkIdentity.java44
-rw-r--r--core/java/android/net/NetworkStateSnapshot.java47
-rw-r--r--core/java/android/net/PacProxySelector.java (renamed from packages/Connectivity/framework/src/android/net/PacProxySelector.java)0
-rw-r--r--core/java/android/net/Proxy.java (renamed from packages/Connectivity/framework/src/android/net/Proxy.java)0
-rw-r--r--core/java/android/net/VpnService.java3
-rw-r--r--core/java/android/net/util/SocketUtils.java (renamed from packages/Connectivity/framework/src/android/net/util/SocketUtils.java)5
-rw-r--r--core/java/android/os/BatterySaverPolicyConfig.java1
-rw-r--r--core/java/android/os/INetworkManagementService.aidl8
-rw-r--r--core/java/android/provider/Settings.java24
-rw-r--r--core/java/android/util/OWNERS4
-rw-r--r--core/java/android/util/SparseArray.java7
-rw-r--r--core/java/android/util/apk/OWNERS1
-rw-r--r--core/java/android/view/AccessibilityInteractionController.java351
-rw-r--r--core/java/android/view/Display.java13
-rw-r--r--core/java/android/view/OWNERS1
-rw-r--r--core/java/android/view/WindowManager.java31
-rw-r--r--core/java/android/view/accessibility/AccessibilityInteractionClient.java93
-rw-r--r--core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl9
-rw-r--r--core/java/android/view/translation/TranslationSpec.java18
-rw-r--r--core/java/android/view/translation/Translator.java7
-rw-r--r--core/java/android/view/translation/UiTranslationController.java18
-rw-r--r--core/java/android/widget/RemoteViews.java8
-rw-r--r--core/java/com/android/internal/net/NetworkUtilsInternal.java16
-rw-r--r--core/java/com/android/server/SystemConfig.java3
-rw-r--r--core/jni/Android.bp3
-rw-r--r--core/jni/android_content_res_ApkAssets.cpp17
-rw-r--r--core/jni/android_net_NetworkUtils.cpp (renamed from core/jni/android_net_NetUtils.cpp)13
-rw-r--r--core/jni/android_view_SurfaceControl.cpp23
-rw-r--r--core/jni/com_android_internal_net_NetworkUtilsInternal.cpp13
-rw-r--r--core/proto/OWNERS1
-rw-r--r--core/res/res/values/config.xml11
-rw-r--r--core/res/res/values/symbols.xml3
-rw-r--r--core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java9
-rw-r--r--core/tests/coretests/src/android/view/accessibility/OWNERS1
-rw-r--r--data/etc/car/android.car.cluster.xml2
-rw-r--r--data/etc/car/com.android.car.bugreport.xml1
-rw-r--r--data/etc/car/com.android.car.carlauncher.xml3
-rw-r--r--data/etc/car/com.android.car.dialer.xml1
-rw-r--r--data/etc/car/com.android.car.hvac.xml1
-rw-r--r--data/etc/car/com.android.car.radio.xml2
-rw-r--r--data/etc/car/com.google.android.car.kitchensink.xml36
-rw-r--r--data/etc/privapp-permissions-platform.xml3
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUILayout.java13
-rwxr-xr-xlibs/androidfw/ApkAssets.cpp6
-rw-r--r--libs/androidfw/AssetManager2.cpp86
-rw-r--r--libs/androidfw/AssetsProvider.cpp29
-rw-r--r--libs/androidfw/include/androidfw/ApkAssets.h12
-rw-r--r--libs/androidfw/include/androidfw/AssetManager2.h2
-rw-r--r--libs/androidfw/include/androidfw/AssetsProvider.h10
-rw-r--r--packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java26
-rw-r--r--packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl (renamed from core/java/android/net/QosFilterParcelable.aidl)0
-rw-r--r--packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl (renamed from core/java/android/net/QosSession.aidl)0
-rw-r--r--packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl (renamed from core/java/android/net/QosSocketInfo.aidl)0
-rw-r--r--packages/Connectivity/framework/api/current.txt10
-rw-r--r--packages/Connectivity/framework/api/module-lib-current.txt4
-rw-r--r--packages/Connectivity/framework/api/system-current.txt63
-rw-r--r--packages/Connectivity/framework/src/android/net/ConnectivityManager.java25
-rw-r--r--packages/Connectivity/framework/src/android/net/IOnSetOemNetworkPreferenceListener.aidl (renamed from core/java/android/net/IOnSetOemNetworkPreferenceListener.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/IQosCallback.aidl (renamed from core/java/android/net/IQosCallback.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkReleasedException.java (renamed from core/java/android/net/NetworkReleasedException.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/NetworkUtils.java16
-rw-r--r--packages/Connectivity/framework/src/android/net/QosCallback.java (renamed from core/java/android/net/QosCallback.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosCallbackConnection.java (renamed from core/java/android/net/QosCallbackConnection.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosCallbackException.java (renamed from core/java/android/net/QosCallbackException.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosFilter.java (renamed from core/java/android/net/QosFilter.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosFilterParcelable.java (renamed from core/java/android/net/QosFilterParcelable.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosSession.java (renamed from core/java/android/net/QosSession.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosSessionAttributes.java (renamed from core/java/android/net/QosSessionAttributes.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosSocketFilter.java (renamed from core/java/android/net/QosSocketFilter.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/QosSocketInfo.java (renamed from core/java/android/net/QosSocketInfo.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java (renamed from core/java/android/net/SocketLocalAddressChangedException.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/SocketNotBoundException.java (renamed from core/java/android/net/SocketNotBoundException.java)0
-rw-r--r--packages/Connectivity/framework/src/android/net/UidRange.aidl (renamed from core/java/android/net/UidRange.aidl)0
-rw-r--r--packages/Connectivity/framework/src/android/net/UidRange.java (renamed from core/java/android/net/UidRange.java)31
-rw-r--r--packages/Connectivity/service/Android.bp1
-rw-r--r--packages/Connectivity/service/jarjar-rules.txt3
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java9
-rw-r--r--packages/Shell/AndroidManifest.xml1
-rw-r--r--packages/SystemUI/README.md4
-rw-r--r--packages/SystemUI/docs/media-controls-pipeline.pngbin0 -> 84005 bytes
-rw-r--r--packages/SystemUI/docs/media-controls.md94
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml2
-rw-r--r--packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml3
-rw-r--r--packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml20
-rw-r--r--packages/SystemUI/res-keyguard/values/config.xml1
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml4
-rw-r--r--packages/SystemUI/res/layout/long_screenshot.xml2
-rw-r--r--packages/SystemUI/res/values/config.xml1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java226
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java1
-rw-r--r--packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/Dependency.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java68
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java140
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java13
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java47
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/CropView.java36
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java25
-rw-r--r--packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java40
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java71
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java40
-rw-r--r--packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java152
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java38
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java42
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java2
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java7
-rw-r--r--services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java221
-rw-r--r--services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java15
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java94
-rw-r--r--services/core/java/com/android/server/ConnectivityServiceInitializer.java9
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java36
-rw-r--r--services/core/java/com/android/server/TestNetworkService.java10
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java2
-rw-r--r--services/core/java/com/android/server/clipboard/ClipboardService.java6
-rw-r--r--services/core/java/com/android/server/compat/CompatChange.java87
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java35
-rw-r--r--services/core/java/com/android/server/connectivity/DataConnectionStats.java4
-rw-r--r--services/core/java/com/android/server/connectivity/KeepaliveTracker.java2
-rw-r--r--services/core/java/com/android/server/connectivity/Nat464Xlat.java23
-rw-r--r--services/core/java/com/android/server/connectivity/NetworkAgentInfo.java7
-rw-r--r--services/core/java/com/android/server/devicestate/DeviceStateManagerService.java17
-rw-r--r--services/core/java/com/android/server/display/DisplayModeDirector.java30
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java92
-rw-r--r--services/core/java/com/android/server/graphics/fonts/FontManagerService.java33
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java7
-rw-r--r--services/core/java/com/android/server/location/GeocoderProxy.java2
-rw-r--r--services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java4
-rw-r--r--services/core/java/com/android/server/location/geofence/GeofenceProxy.java2
-rw-r--r--services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java4
-rw-r--r--services/core/java/com/android/server/net/NetworkStatsService.java41
-rw-r--r--services/core/java/com/android/server/pm/DataLoaderManagerService.java28
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java20
-rw-r--r--services/core/java/com/android/server/servicewatcher/OWNERS5
-rw-r--r--services/core/java/com/android/server/servicewatcher/ServiceWatcher.java (renamed from services/core/java/com/android/server/ServiceWatcher.java)3
-rw-r--r--services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java4
-rw-r--r--services/core/java/com/android/server/vibrator/InputDeviceDelegate.java23
-rw-r--r--services/core/java/com/android/server/vibrator/VibrationSettings.java84
-rw-r--r--services/core/java/com/android/server/vibrator/VibratorManagerService.java16
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java289
-rw-r--r--services/core/java/com/android/server/wm/InsetsStateController.java3
-rw-r--r--services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java6
-rw-r--r--services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java27
-rw-r--r--services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java581
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java131
-rw-r--r--services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java89
-rw-r--r--services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java90
-rw-r--r--services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java77
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java7
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java52
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java137
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java9
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java19
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java49
-rw-r--r--services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java101
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java12
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java10
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java9
-rw-r--r--services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java3
-rw-r--r--services/translation/java/com/android/server/translation/TranslationManagerService.java104
-rw-r--r--services/translation/java/com/android/server/translation/TranslationManagerServiceShellCommand.java79
-rw-r--r--telephony/java/android/telephony/NetworkRegistrationInfo.java1
-rw-r--r--tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt2
-rw-r--r--tests/UpdatableSystemFontTest/Android.bp4
-rw-r--r--tests/UpdatableSystemFontTest/AndroidTest.xml1
-rw-r--r--tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java25
-rw-r--r--tests/net/common/java/android/net/NetworkStateSnapshotTest.kt6
-rw-r--r--tests/net/common/java/android/net/UidRangeTest.java113
-rw-r--r--tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt2
-rw-r--r--tests/net/java/android/net/IpSecAlgorithmTest.java1
-rw-r--r--tests/net/java/android/net/NetworkTemplateTest.kt29
-rw-r--r--tests/net/java/android/net/UidRangeTest.java67
-rw-r--r--tests/net/java/com/android/server/ConnectivityServiceTest.java22
-rw-r--r--tests/net/java/com/android/server/connectivity/LingerMonitorTest.java6
-rw-r--r--tests/net/java/com/android/server/connectivity/Nat464XlatTest.java20
-rw-r--r--tests/net/java/com/android/server/net/NetworkStatsServiceTest.java92
-rw-r--r--tools/aapt2/cmd/Link.cpp10
-rw-r--r--tools/aapt2/cmd/Link_test.cpp77
-rw-r--r--tools/aapt2/format/binary/TableFlattener.cpp1
-rw-r--r--tools/aapt2/java/ClassDefinition.h29
-rw-r--r--tools/aapt2/java/JavaClassGenerator.cpp63
-rw-r--r--tools/aapt2/java/JavaClassGenerator.h2
-rw-r--r--tools/aapt2/java/JavaClassGenerator_test.cpp2
-rw-r--r--tools/aapt2/process/SymbolTable.cpp4
-rw-r--r--tools/aapt2/test/Fixture.cpp85
-rw-r--r--tools/aapt2/test/Fixture.h35
223 files changed, 4508 insertions, 1987 deletions
diff --git a/Android.bp b/Android.bp
index 14b5b309ebdf..20ca1b7c1020 100644
--- a/Android.bp
+++ b/Android.bp
@@ -344,8 +344,8 @@ filegroup {
genrule {
name: "statslog-telephony-common-java-gen",
tools: ["stats-log-api-gen"],
- cmd: "$(location stats-log-api-gen) --java $(out) --module telephony_common" +
- " --javaPackage com.android.internal.telephony --javaClass TelephonyCommonStatsLog",
+ cmd: "$(location stats-log-api-gen) --java $(out) --module telephony_common"
+ + " --javaPackage com.android.internal.telephony --javaClass TelephonyCommonStatsLog",
out: ["com/android/internal/telephony/TelephonyCommonStatsLog.java"],
}
@@ -421,6 +421,7 @@ filegroup {
":resourcemanager_aidl",
":storaged_aidl",
":vold_aidl",
+ ":deviceproductinfoconstants_aidl",
// For the generated R.java and Manifest.java
":framework-res{.aapt.srcjar}",
@@ -749,8 +750,8 @@ java_library {
}
platform_compat_config {
- name: "framework-platform-compat-config",
- src: ":framework-minus-apex",
+ name: "framework-platform-compat-config",
+ src: ":framework-minus-apex",
}
// A temporary build target that is conditionally included on the bootclasspath if
@@ -771,7 +772,7 @@ genrule {
name: "statslog-framework-java-gen",
tools: ["stats-log-api-gen"],
cmd: "$(location stats-log-api-gen) --java $(out) --module framework" +
- " --javaPackage com.android.internal.util --javaClass FrameworkStatsLog --worksource",
+ " --javaPackage com.android.internal.util --javaClass FrameworkStatsLog --worksource",
out: ["com/android/internal/util/FrameworkStatsLog.java"],
}
@@ -880,7 +881,7 @@ filegroup {
java_library {
name: "framework-annotations-lib",
- srcs: [":framework-annotations"],
+ srcs: [ ":framework-annotations" ],
sdk_version: "core_current",
}
@@ -1158,6 +1159,7 @@ cc_library {
},
}
+
// This is the full proto version of libplatformprotos. It may only
// be used by test code that is not shipped on the device.
cc_library {
@@ -1223,58 +1225,68 @@ filegroup {
path: "core/java",
}
-cc_defaults {
- name: "incremental_default",
- host_supported: true,
- cflags: [
- "-Wall",
- "-Wextra",
- "-Wextra-semi",
- "-Werror",
- "-Wzero-as-null-pointer-constant",
- "-DANDROID_BASE_UNIQUE_FD_DISABLE_IMPLICIT_CONVERSION",
- ],
- shared_libs: [
- "libbinder",
- "libutils",
- ],
- aidl: {
- include_dirs: [
- "frameworks/native/aidl/binder",
- ],
- export_aidl_headers: true,
- },
-}
-
-cc_library {
- name: "libincremental_aidl-cpp",
+aidl_interface {
+ name: "libincremental_aidl",
+ unstable: true,
srcs: [
":incremental_aidl",
],
- defaults: ["incremental_default"],
+ backend: {
+ java: {
+ sdk_version: "28",
+ },
+ cpp: {
+ enabled: true,
+ },
+ ndk: {
+ enabled: true,
+ },
+ },
}
-cc_library {
- name: "libdataloader_aidl-cpp",
+aidl_interface {
+ name: "libdataloader_aidl",
+ unstable: true,
srcs: [
":dataloader_aidl",
],
- defaults: ["incremental_default"],
- shared_libs: [
- "libincremental_aidl-cpp",
+ imports: [
+ "libincremental_aidl",
],
+ backend: {
+ java: {
+ sdk_version: "28",
+ },
+ cpp: {
+ enabled: true,
+ },
+ ndk: {
+ enabled: false,
+ },
+ },
}
-cc_library {
- name: "libincremental_manager_aidl-cpp",
+aidl_interface {
+ name: "libincremental_manager_aidl",
+ unstable: true,
srcs: [
":incremental_manager_aidl",
],
- defaults: ["incremental_default"],
- shared_libs: [
- "libincremental_aidl-cpp",
- "libdataloader_aidl-cpp",
+ imports: [
+ "libincremental_aidl",
+ "libdataloader_aidl",
],
+ backend: {
+ java: {
+ sdk_version: "28",
+ },
+ cpp: {
+ enabled: true,
+ },
+ ndk: {
+ enabled: false,
+ },
+ },
}
// TODO(b/77285514): remove this once the last few hidl interfaces have been
@@ -1303,7 +1315,7 @@ java_library {
"core/java/android/os/RemoteException.java",
"core/java/android/util/AndroidException.java",
],
- libs: ["unsupportedappusage"],
+ libs: [ "unsupportedappusage" ],
dxflags: ["--core-library"],
installable: false,
@@ -1522,5 +1534,4 @@ java_library {
":protolog-common-src",
],
}
-
// protolog end
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 175fb38bafc7..30ed7de92614 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,6 +1,5 @@
[Builtin Hooks]
clang_format = true
-bpfmt = true
[Builtin Hooks Options]
# Only turn on clang-format check for the following subfolders.
@@ -16,7 +15,7 @@ clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
services/incremental/
tests/
tools/
-bpfmt = -d
+
[Hook Scripts]
checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --sha ${PREUPLOAD_COMMIT}
diff --git a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
index 1d94d7e8eca2..d5ed95f18f93 100644
--- a/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
+++ b/apct-tests/perftests/core/src/android/os/PackageParsingPerfTest.kt
@@ -97,11 +97,21 @@ class PackageParsingPerfTest {
private val state: BenchmarkState get() = perfStatusReporter.benchmarkState
private val apks: List<File> get() = params.apks
+ private fun safeParse(parser: ParallelParser<*>, file: File) {
+ try {
+ parser.parse(file)
+ } catch (e: Exception) {
+ // ignore
+ }
+ }
+
@Test
fun sequentialNoCache() {
params.cacheDirToParser(null).use { parser ->
while (state.keepRunning()) {
- apks.forEach { parser.parse(it) }
+ apks.forEach {
+ safeParse(parser, it)
+ }
}
}
}
@@ -110,10 +120,10 @@ class PackageParsingPerfTest {
fun sequentialCached() {
params.cacheDirToParser(testFolder.newFolder()).use { parser ->
// Fill the cache
- apks.forEach { parser.parse(it) }
+ apks.forEach { safeParse(parser, it) }
while (state.keepRunning()) {
- apks.forEach { parser.parse(it) }
+ apks.forEach { safeParse(parser, it) }
}
}
}
@@ -132,7 +142,7 @@ class PackageParsingPerfTest {
fun parallelCached() {
params.cacheDirToParser(testFolder.newFolder()).use { parser ->
// Fill the cache
- apks.forEach { parser.parse(it) }
+ apks.forEach { safeParse(parser, it) }
while (state.keepRunning()) {
apks.forEach { parser.submit(it) }
diff --git a/core/api/current.txt b/core/api/current.txt
index f1b9cef113cc..4f1235c54b7c 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -18569,6 +18569,23 @@ package android.hardware.camera2.params {
package android.hardware.display {
+ public final class DeviceProductInfo implements android.os.Parcelable {
+ method public int describeContents();
+ method public int getConnectionToSinkType();
+ method public int getManufactureWeek();
+ method public int getManufactureYear();
+ method @NonNull public String getManufacturerPnpId();
+ method public int getModelYear();
+ method @Nullable public String getName();
+ method @NonNull public String getProductId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field public static final int CONNECTION_TO_SINK_BUILT_IN = 1; // 0x1
+ field public static final int CONNECTION_TO_SINK_DIRECT = 2; // 0x2
+ field public static final int CONNECTION_TO_SINK_TRANSITIVE = 3; // 0x3
+ field public static final int CONNECTION_TO_SINK_UNKNOWN = 0; // 0x0
+ field @NonNull public static final android.os.Parcelable.Creator<android.hardware.display.DeviceProductInfo> CREATOR;
+ }
+
public final class DisplayManager {
method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface, int);
method public android.hardware.display.VirtualDisplay createVirtualDisplay(@NonNull String, int, int, int, @Nullable android.view.Surface, int, @Nullable android.hardware.display.VirtualDisplay.Callback, @Nullable android.os.Handler);
@@ -25870,6 +25887,7 @@ package android.net {
method @NonNull public static java.util.Set<java.lang.String> getSupportedAlgorithms();
method public int getTruncationLengthBits();
method public void writeToParcel(android.os.Parcel, int);
+ field public static final String AUTH_AES_CMAC = "cmac(aes)";
field public static final String AUTH_AES_XCBC = "xcbc(aes)";
field public static final String AUTH_CRYPT_AES_GCM = "rfc4106(gcm(aes))";
field public static final String AUTH_CRYPT_CHACHA20_POLY1305 = "rfc7539esp(chacha20,poly1305)";
@@ -26011,6 +26029,16 @@ package android.net {
field public static final int TYPE_IKEV2_IPSEC_USER_PASS = 6; // 0x6
}
+ public final class Proxy {
+ ctor public Proxy();
+ method @Deprecated public static String getDefaultHost();
+ method @Deprecated public static int getDefaultPort();
+ method @Deprecated public static String getHost(android.content.Context);
+ method @Deprecated public static int getPort(android.content.Context);
+ field @Deprecated public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
+ field public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
+ }
+
@Deprecated public class SSLCertificateSocketFactory extends javax.net.ssl.SSLSocketFactory {
ctor @Deprecated public SSLCertificateSocketFactory(int);
method @Deprecated public java.net.Socket createSocket(java.net.Socket, String, int, boolean) throws java.io.IOException;
@@ -41316,7 +41344,6 @@ package android.telephony {
method @NonNull public java.util.List<java.lang.Integer> getAvailableServices();
method @Nullable public android.telephony.CellIdentity getCellIdentity();
method public int getDomain();
- method public int getNrState();
method @Nullable public String getRegisteredPlmn();
method public int getTransportType();
method public boolean isRegistered();
@@ -45852,7 +45879,7 @@ package android.util {
method public void clear();
method public android.util.SparseArray<E> clone();
method public boolean contains(int);
- method public boolean contentEquals(@Nullable android.util.SparseArray<E>);
+ method public boolean contentEquals(@Nullable android.util.SparseArray<?>);
method public int contentHashCode();
method public void delete(int);
method public E get(int);
@@ -46248,6 +46275,7 @@ package android.view {
method public long getAppVsyncOffsetNanos();
method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
method @Nullable public android.view.DisplayCutout getCutout();
+ method @Nullable public android.hardware.display.DeviceProductInfo getDeviceProductInfo();
method public int getDisplayId();
method public int getFlags();
method public android.view.Display.HdrCapabilities getHdrCapabilities();
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 7ea7d61ac3c5..60325b3cbd37 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -167,10 +167,26 @@ package android.net {
method public int getResourceId();
}
+ public final class NetworkStateSnapshot implements android.os.Parcelable {
+ ctor public NetworkStateSnapshot(@NonNull android.net.Network, @NonNull android.net.NetworkCapabilities, @NonNull android.net.LinkProperties, @Nullable String, int);
+ method public int describeContents();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.NetworkStateSnapshot> CREATOR;
+ field public final int legacyType;
+ field @NonNull public final android.net.LinkProperties linkProperties;
+ field @NonNull public final android.net.Network network;
+ field @NonNull public final android.net.NetworkCapabilities networkCapabilities;
+ field @Nullable public final String subscriberId;
+ }
+
public class NetworkWatchlistManager {
method @Nullable public byte[] getWatchlistConfigHash();
}
+ public final class Proxy {
+ method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
+ }
+
public final class UnderlyingNetworkInfo implements android.os.Parcelable {
ctor public UnderlyingNetworkInfo(int, @NonNull String, @NonNull java.util.List<java.lang.String>);
method public int describeContents();
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index c7744a415db5..02925c59bf61 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -2552,8 +2552,7 @@ package android.content.pm {
field public static final String FEATURE_BROADCAST_RADIO = "android.hardware.broadcastradio";
field public static final String FEATURE_CAMERA_TOGGLE = "android.hardware.camera.toggle";
field public static final String FEATURE_CONTEXT_HUB = "android.hardware.context_hub";
- field @Deprecated public static final String FEATURE_INCREMENTAL_DELIVERY = "android.software.incremental_delivery";
- field public static final String FEATURE_INCREMENTAL_DELIVERY_VERSION = "android.software.incremental_delivery_version";
+ field public static final String FEATURE_INCREMENTAL_DELIVERY = "android.software.incremental_delivery";
field public static final String FEATURE_MICROPHONE_TOGGLE = "android.hardware.microphone.toggle";
field public static final String FEATURE_REBOOT_ESCROW = "android.hardware.reboot_escrow";
field public static final String FEATURE_TELEPHONY_CARRIERLOCK = "android.hardware.telephony.carrierlock";
@@ -7151,9 +7150,6 @@ package android.net {
method public abstract void onRequestScores(android.net.NetworkKey[]);
}
- public class NetworkReleasedException extends java.lang.Exception {
- }
-
public class NetworkScoreManager {
method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public boolean clearScores() throws java.lang.SecurityException;
method @RequiresPermission(anyOf={android.Manifest.permission.SCORE_NETWORKS, android.Manifest.permission.REQUEST_NETWORK_SCORES}) public void disableScoring() throws java.lang.SecurityException;
@@ -7237,47 +7233,6 @@ package android.net {
method @NonNull public android.net.OemNetworkPreferences.Builder clearNetworkPreference(@NonNull String);
}
- public abstract class QosCallback {
- ctor public QosCallback();
- method public void onError(@NonNull android.net.QosCallbackException);
- method public void onQosSessionAvailable(@NonNull android.net.QosSession, @NonNull android.net.QosSessionAttributes);
- method public void onQosSessionLost(@NonNull android.net.QosSession);
- }
-
- public static class QosCallback.QosCallbackRegistrationException extends java.lang.RuntimeException {
- }
-
- public final class QosCallbackException extends java.lang.Exception {
- }
-
- public abstract class QosFilter {
- method @NonNull public abstract android.net.Network getNetwork();
- method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
- }
-
- public final class QosSession implements android.os.Parcelable {
- ctor public QosSession(int, int);
- method public int describeContents();
- method public int getSessionId();
- method public int getSessionType();
- method public long getUniqueId();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
- field public static final int TYPE_EPS_BEARER = 1; // 0x1
- }
-
- public interface QosSessionAttributes {
- }
-
- public final class QosSocketInfo implements android.os.Parcelable {
- ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
- method public int describeContents();
- method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
- method @NonNull public android.net.Network getNetwork();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
- }
-
public class RssiCurve implements android.os.Parcelable {
ctor public RssiCurve(int, int, byte[]);
ctor public RssiCurve(int, int, byte[], int);
@@ -7309,12 +7264,6 @@ package android.net {
field public final android.net.RssiCurve rssiCurve;
}
- public class SocketLocalAddressChangedException extends java.lang.Exception {
- }
-
- public class SocketNotBoundException extends java.lang.Exception {
- }
-
public class TrafficStats {
method public static void setThreadStatsTagApp();
method public static void setThreadStatsTagBackup();
@@ -7544,6 +7493,19 @@ package android.net.sip {
}
+package android.net.util {
+
+ public final class SocketUtils {
+ method public static void bindSocketToInterface(@NonNull java.io.FileDescriptor, @NonNull String) throws android.system.ErrnoException;
+ method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
+ method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
+ method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
+ method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
+ method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
+ }
+
+}
+
package android.net.vcn {
public class VcnManager {
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 76295545ad17..1e5a6f12f96b 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -399,6 +399,8 @@ package android.app.admin {
method @RequiresPermission("android.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS") public void forceRemoveActiveAdmin(@NonNull android.content.ComponentName, int);
method @RequiresPermission(android.Manifest.permission.FORCE_DEVICE_POLICY_MANAGER_LOGS) public long forceSecurityLogs();
method public void forceUpdateUserSetupComplete();
+ method @NonNull public java.util.Set<java.lang.String> getDefaultCrossProfilePackages();
+ method @NonNull public java.util.Set<java.lang.String> getDisallowedSystemApps(@NonNull android.content.ComponentName, int, @NonNull String);
method public long getLastBugReportRequestTime();
method public long getLastNetworkLogRetrievalTime();
method public long getLastSecurityLogRetrievalTime();
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index cc2d36379c88..f5f0b422a69d 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -7119,6 +7119,9 @@ public class Activity extends ContextThemeWrapper
case "--contentcapture":
dumpContentCaptureManager(prefix, writer);
return;
+ case "--translation":
+ dumpUiTranslation(prefix, writer);
+ return;
}
}
writer.print(prefix); writer.print("Local Activity ");
@@ -7159,6 +7162,7 @@ public class Activity extends ContextThemeWrapper
dumpAutofillManager(prefix, writer);
dumpContentCaptureManager(prefix, writer);
+ dumpUiTranslation(prefix, writer);
ResourcesManager.getInstance().dump(prefix, writer);
}
@@ -7183,6 +7187,14 @@ public class Activity extends ContextThemeWrapper
}
}
+ void dumpUiTranslation(String prefix, PrintWriter writer) {
+ if (mUiTranslationController != null) {
+ mUiTranslationController.dump(prefix, writer);
+ } else {
+ writer.print(prefix); writer.println("No UiTranslationController");
+ }
+ }
+
/**
* Bit indicating that this activity is "immersive" and should not be
* interrupted by notifications if possible.
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index bb1ff6051d56..b919bfc92e79 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -12239,8 +12239,9 @@ public class DevicePolicyManager {
*
* @hide
*/
- public Set<String> getDisallowedSystemApps(ComponentName admin, int userId,
- String provisioningAction) {
+ @TestApi
+ public @NonNull Set<String> getDisallowedSystemApps(@NonNull ComponentName admin,
+ @UserIdInt int userId, @NonNull String provisioningAction) {
try {
return new ArraySet<>(
mService.getDisallowedSystemApps(admin, userId, provisioningAction));
@@ -13004,6 +13005,7 @@ public class DevicePolicyManager {
*
* @hide
*/
+ @TestApi
public @NonNull Set<String> getDefaultCrossProfilePackages() {
throwIfParentInstance("getDefaultCrossProfilePackages");
if (mService != null) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 3bc61444f1d1..7b62f3b2f1a2 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -3584,30 +3584,18 @@ public abstract class PackageManager {
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}: The device has
* the requisite kernel support to support incremental delivery aka Incremental FileSystem.
*
- * @see IncrementalManager#isFeatureEnabled
- * @hide
- *
- * @deprecated Use {@link #FEATURE_INCREMENTAL_DELIVERY_VERSION} instead.
- */
- @Deprecated
- @SystemApi
- @SdkConstant(SdkConstantType.FEATURE)
- public static final String FEATURE_INCREMENTAL_DELIVERY =
- "android.software.incremental_delivery";
-
- /**
- * Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
* feature not present - IncFs is not present on the device.
* 1 - IncFs v1, core features, no PerUid support. Optional in R.
* 2 - IncFs v2, PerUid support, fs-verity support. Required in S.
*
+ * @see IncrementalManager#isFeatureEnabled
* @see IncrementalManager#getVersion()
* @hide
*/
@SystemApi
@SdkConstant(SdkConstantType.FEATURE)
- public static final String FEATURE_INCREMENTAL_DELIVERY_VERSION =
- "android.software.incremental_delivery_version";
+ public static final String FEATURE_INCREMENTAL_DELIVERY =
+ "android.software.incremental_delivery";
/**
* Feature for {@link #getSystemAvailableFeatures} and {@link #hasSystemFeature}:
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java
index 2d381eb85e90..de48ed75746d 100644
--- a/core/java/android/content/res/ApkAssets.java
+++ b/core/java/android/content/res/ApkAssets.java
@@ -22,6 +22,7 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.content.om.OverlayableInfo;
import android.content.res.loader.AssetsProvider;
import android.content.res.loader.ResourcesProvider;
+import android.text.TextUtils;
import com.android.internal.annotations.GuardedBy;
@@ -344,7 +345,14 @@ public final class ApkAssets {
@UnsupportedAppUsage
public @NonNull String getAssetPath() {
synchronized (this) {
- return nativeGetAssetPath(mNativePtr);
+ return TextUtils.emptyIfNull(nativeGetAssetPath(mNativePtr));
+ }
+ }
+
+ /** @hide */
+ public @NonNull String getDebugName() {
+ synchronized (this) {
+ return nativeGetDebugName(mNativePtr);
}
}
@@ -422,7 +430,7 @@ public final class ApkAssets {
@Override
public String toString() {
- return "ApkAssets{path=" + getAssetPath() + "}";
+ return "ApkAssets{path=" + getDebugName() + "}";
}
/**
@@ -450,6 +458,7 @@ public final class ApkAssets {
@NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length,
@PropertyFlags int flags, @Nullable AssetsProvider asset) throws IOException;
private static native @NonNull String nativeGetAssetPath(long ptr);
+ private static native @NonNull String nativeGetDebugName(long ptr);
private static native long nativeGetStringBlock(long ptr);
private static native boolean nativeIsUpToDate(long ptr);
private static native long nativeOpenXml(long ptr, @NonNull String fileName) throws IOException;
diff --git a/core/java/android/hardware/display/ColorDisplayManager.java b/core/java/android/hardware/display/ColorDisplayManager.java
index e247df320115..aafa7d520632 100644
--- a/core/java/android/hardware/display/ColorDisplayManager.java
+++ b/core/java/android/hardware/display/ColorDisplayManager.java
@@ -537,6 +537,26 @@ public final class ColorDisplayManager {
}
/**
+ * Returns the minimum allowed brightness reduction strength in percentage when activated.
+ *
+ * @hide
+ */
+ public static int getMinimumReduceBrightColorsStrength(Context context) {
+ return context.getResources()
+ .getInteger(R.integer.config_reduceBrightColorsStrengthMin);
+ }
+
+ /**
+ * Returns the maximum allowed brightness reduction strength in percentage when activated.
+ *
+ * @hide
+ */
+ public static int getMaximumReduceBrightColorsStrength(Context context) {
+ return context.getResources()
+ .getInteger(R.integer.config_reduceBrightColorsStrengthMax);
+ }
+
+ /**
* Check if the color transforms are color accelerated. Some transforms are experimental only
* on non-accelerated platforms due to the performance implications.
*
diff --git a/core/java/android/hardware/display/DeviceProductInfo.java b/core/java/android/hardware/display/DeviceProductInfo.java
index 41126b70c89f..9457d8f1aac4 100644
--- a/core/java/android/hardware/display/DeviceProductInfo.java
+++ b/core/java/android/hardware/display/DeviceProductInfo.java
@@ -16,40 +16,69 @@
package android.hardware.display;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
-import java.util.Arrays;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
* Product-specific information about the display or the directly connected device on the
* display chain. For example, if the display is transitively connected, this field may contain
* product information about the intermediate device.
- * @hide
*/
public final class DeviceProductInfo implements Parcelable {
+ /** @hide */
+ @IntDef(prefix = {"CONNECTION_TO_SINK_"}, value = {
+ CONNECTION_TO_SINK_UNKNOWN,
+ CONNECTION_TO_SINK_BUILT_IN,
+ CONNECTION_TO_SINK_DIRECT,
+ CONNECTION_TO_SINK_TRANSITIVE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface ConnectionToSinkType { }
+
+ /** The device connection to the display sink is unknown. */
+ public static final int CONNECTION_TO_SINK_UNKNOWN =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_UNKNOWN;
+
+ /** The display sink is built-in to the device */
+ public static final int CONNECTION_TO_SINK_BUILT_IN =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_BUILT_IN;
+
+ /** The device is directly connected to the display sink. */
+ public static final int CONNECTION_TO_SINK_DIRECT =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_DIRECT;
+
+ /** The device is transitively connected to the display sink. */
+ public static final int CONNECTION_TO_SINK_TRANSITIVE =
+ IDeviceProductInfoConstants.CONNECTION_TO_SINK_TRANSITIVE;
+
private final String mName;
private final String mManufacturerPnpId;
private final String mProductId;
private final Integer mModelYear;
private final ManufactureDate mManufactureDate;
- private final int[] mRelativeAddress;
+ private final @ConnectionToSinkType int mConnectionToSinkType;
+ /** @hide */
public DeviceProductInfo(
String name,
String manufacturerPnpId,
String productId,
Integer modelYear,
ManufactureDate manufactureDate,
- int[] relativeAddress) {
+ int connectionToSinkType) {
this.mName = name;
this.mManufacturerPnpId = manufacturerPnpId;
this.mProductId = productId;
this.mModelYear = modelYear;
this.mManufactureDate = manufactureDate;
- this.mRelativeAddress = relativeAddress;
+ this.mConnectionToSinkType = connectionToSinkType;
}
private DeviceProductInfo(Parcel in) {
@@ -58,12 +87,13 @@ public final class DeviceProductInfo implements Parcelable {
mProductId = (String) in.readValue(null);
mModelYear = (Integer) in.readValue(null);
mManufactureDate = (ManufactureDate) in.readValue(null);
- mRelativeAddress = in.createIntArray();
+ mConnectionToSinkType = in.readInt();
}
/**
* @return Display name.
*/
+ @Nullable
public String getName() {
return mName;
}
@@ -71,6 +101,7 @@ public final class DeviceProductInfo implements Parcelable {
/**
* @return Manufacturer Plug and Play ID.
*/
+ @NonNull
public String getManufacturerPnpId() {
return mManufacturerPnpId;
}
@@ -78,32 +109,58 @@ public final class DeviceProductInfo implements Parcelable {
/**
* @return Manufacturer product ID.
*/
+ @NonNull
public String getProductId() {
return mProductId;
}
/**
- * @return Model year of the device. Typically exactly one of model year or
- * manufacture date will be present.
+ * @return Model year of the device. Return -1 if not available. Typically,
+ * one of model year or manufacture year is available.
*/
- public Integer getModelYear() {
- return mModelYear;
+ public int getModelYear() {
+ return mModelYear != null ? mModelYear : -1;
+ }
+
+ /**
+ * @return The year of manufacture, or -1 it is not available. Typically,
+ * one of model year or manufacture year is available.
+ */
+ public int getManufactureYear() {
+ if (mManufactureDate == null) {
+ return -1;
+ }
+ return mManufactureDate.mYear != null ? mManufactureDate.mYear : -1;
+ }
+
+ /**
+ * @return The week of manufacture, or -1 it is not available. Typically,
+ * not present if model year is available.
+ */
+ public int getManufactureWeek() {
+ if (mManufactureDate == null) {
+ return -1;
+ }
+ return mManufactureDate.mWeek != null ? mManufactureDate.mWeek : -1;
}
/**
* @return Manufacture date. Typically exactly one of model year or manufacture
* date will be present.
+ *
+ * @hide
*/
public ManufactureDate getManufactureDate() {
return mManufactureDate;
}
/**
- * @return Relative address in the display network. For example, for HDMI connected devices this
- * can be its physical address. Each component of the address is in the range [0, 255].
+ * @return How the current device is connected to the display sink. For example, the display
+ * can be connected immediately to the device or there can be a receiver in between.
*/
- public int[] getRelativeAddress() {
- return mRelativeAddress;
+ @ConnectionToSinkType
+ public int getConnectionToSinkType() {
+ return mConnectionToSinkType;
}
@Override
@@ -119,8 +176,8 @@ public final class DeviceProductInfo implements Parcelable {
+ mModelYear
+ ", manufactureDate="
+ mManufactureDate
- + ", relativeAddress="
- + Arrays.toString(mRelativeAddress)
+ + ", connectionToSinkType="
+ + mConnectionToSinkType
+ '}';
}
@@ -134,16 +191,16 @@ public final class DeviceProductInfo implements Parcelable {
&& Objects.equals(mProductId, that.mProductId)
&& Objects.equals(mModelYear, that.mModelYear)
&& Objects.equals(mManufactureDate, that.mManufactureDate)
- && Arrays.equals(mRelativeAddress, that.mRelativeAddress);
+ && mConnectionToSinkType == that.mConnectionToSinkType;
}
@Override
public int hashCode() {
return Objects.hash(mName, mManufacturerPnpId, mProductId, mModelYear, mManufactureDate,
- Arrays.hashCode(mRelativeAddress));
+ mConnectionToSinkType);
}
- public static final Creator<DeviceProductInfo> CREATOR =
+ @NonNull public static final Creator<DeviceProductInfo> CREATOR =
new Creator<DeviceProductInfo>() {
@Override
public DeviceProductInfo createFromParcel(Parcel in) {
@@ -162,13 +219,13 @@ public final class DeviceProductInfo implements Parcelable {
}
@Override
- public void writeToParcel(Parcel dest, int flags) {
+ public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString(mName);
dest.writeString(mManufacturerPnpId);
dest.writeValue(mProductId);
dest.writeValue(mModelYear);
dest.writeValue(mManufactureDate);
- dest.writeIntArray(mRelativeAddress);
+ dest.writeInt(mConnectionToSinkType);
}
/**
diff --git a/core/java/android/net/INetworkStatsService.aidl b/core/java/android/net/INetworkStatsService.aidl
index 0baf11e850c7..dc3b88a7c3be 100644
--- a/core/java/android/net/INetworkStatsService.aidl
+++ b/core/java/android/net/INetworkStatsService.aidl
@@ -19,7 +19,7 @@ package android.net;
import android.net.DataUsageRequest;
import android.net.INetworkStatsSession;
import android.net.Network;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
@@ -68,7 +68,7 @@ interface INetworkStatsService {
/** Force update of ifaces. */
void forceUpdateIfaces(
in Network[] defaultNetworks,
- in NetworkState[] networkStates,
+ in NetworkStateSnapshot[] snapshots,
in String activeIface,
in UnderlyingNetworkInfo[] underlyingNetworkInfos);
/** Force update of statistics. */
diff --git a/core/java/android/net/IpSecAlgorithm.java b/core/java/android/net/IpSecAlgorithm.java
index e89451e4f4ef..8f1e2defd215 100644
--- a/core/java/android/net/IpSecAlgorithm.java
+++ b/core/java/android/net/IpSecAlgorithm.java
@@ -146,6 +146,25 @@ public final class IpSecAlgorithm implements Parcelable {
public static final String AUTH_AES_XCBC = "xcbc(aes)";
/**
+ * AES-CMAC Authentication/Integrity Algorithm.
+ *
+ * <p>Keys for this algorithm must be 128 bits in length.
+ *
+ * <p>The only valid truncation length is 96 bits.
+ *
+ * <p>This algorithm may be available on the device. Caller MUST check if it is supported before
+ * using it by calling {@link #getSupportedAlgorithms()} and checking if this algorithm is
+ * included in the returned algorithm set. The returned algorithm set will not change unless the
+ * device is rebooted. {@link IllegalArgumentException} will be thrown if this algorithm is
+ * requested on an unsupported device.
+ *
+ * <p>@see {@link #getSupportedAlgorithms()}
+ */
+ // This algorithm may be available on devices released before Android 12, and is guaranteed
+ // to be available on devices first shipped with Android 12 or later.
+ public static final String AUTH_AES_CMAC = "cmac(aes)";
+
+ /**
* AES-GCM Authentication/Integrity + Encryption/Ciphering Algorithm.
*
* <p>Valid lengths for keying material are {160, 224, 288}.
@@ -191,6 +210,7 @@ public final class IpSecAlgorithm implements Parcelable {
AUTH_HMAC_SHA384,
AUTH_HMAC_SHA512,
AUTH_AES_XCBC,
+ AUTH_AES_CMAC,
AUTH_CRYPT_AES_GCM,
AUTH_CRYPT_CHACHA20_POLY1305
})
@@ -215,6 +235,7 @@ public final class IpSecAlgorithm implements Parcelable {
// STOPSHIP: b/170424293 Use Build.VERSION_CODES.S when it is defined
ALGO_TO_REQUIRED_FIRST_SDK.put(CRYPT_AES_CTR, Build.VERSION_CODES.R + 1);
ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_XCBC, Build.VERSION_CODES.R + 1);
+ ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_AES_CMAC, Build.VERSION_CODES.R + 1);
ALGO_TO_REQUIRED_FIRST_SDK.put(AUTH_CRYPT_CHACHA20_POLY1305, Build.VERSION_CODES.R + 1);
}
@@ -383,6 +404,10 @@ public final class IpSecAlgorithm implements Parcelable {
isValidLen = keyLen == 128;
isValidTruncLen = truncLen == 96;
break;
+ case AUTH_AES_CMAC:
+ isValidLen = keyLen == 128;
+ isValidTruncLen = truncLen == 96;
+ break;
case AUTH_CRYPT_AES_GCM:
// The keying material for GCM is a key plus a 32-bit salt
isValidLen = keyLen == 128 + 32 || keyLen == 192 + 32 || keyLen == 256 + 32;
@@ -416,6 +441,7 @@ public final class IpSecAlgorithm implements Parcelable {
case AUTH_HMAC_SHA384:
case AUTH_HMAC_SHA512:
case AUTH_AES_XCBC:
+ case AUTH_AES_CMAC:
return true;
default:
return false;
diff --git a/core/java/android/net/NetworkIdentity.java b/core/java/android/net/NetworkIdentity.java
index 303a40755d4e..a5ece7b713c7 100644
--- a/core/java/android/net/NetworkIdentity.java
+++ b/core/java/android/net/NetworkIdentity.java
@@ -18,7 +18,6 @@ package android.net;
import static android.net.ConnectivityManager.TYPE_WIFI;
-import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.net.wifi.WifiInfo;
@@ -180,29 +179,42 @@ public class NetworkIdentity implements Comparable<NetworkIdentity> {
}
/**
- * Build a {@link NetworkIdentity} from the given {@link NetworkState} and {@code subType},
- * assuming that any mobile networks are using the current IMSI. The subType if applicable,
- * should be set as one of the TelephonyManager.NETWORK_TYPE_* constants, or
- * {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
+ * Build a {@link NetworkIdentity} from the given {@link NetworkState} and
+ * {@code subType}, assuming that any mobile networks are using the current IMSI.
+ * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
+ * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
*/
- public static NetworkIdentity buildNetworkIdentity(Context context, NetworkState state,
- boolean defaultNetwork, @NetworkType int subType) {
- final int legacyType = state.legacyNetworkType;
+ // TODO: Delete this function after NetworkPolicyManagerService finishes the migration.
+ public static NetworkIdentity buildNetworkIdentity(Context context,
+ NetworkState state, boolean defaultNetwork, @NetworkType int subType) {
+ final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
+ state.networkCapabilities, state.linkProperties, state.subscriberId,
+ state.legacyNetworkType);
+ return buildNetworkIdentity(context, snapshot, defaultNetwork, subType);
+ }
- String subscriberId = null;
+ /**
+ * Build a {@link NetworkIdentity} from the given {@link NetworkStateSnapshot} and
+ * {@code subType}, assuming that any mobile networks are using the current IMSI.
+ * The subType if applicable, should be set as one of the TelephonyManager.NETWORK_TYPE_*
+ * constants, or {@link android.telephony.TelephonyManager#NETWORK_TYPE_UNKNOWN} if not.
+ */
+ public static NetworkIdentity buildNetworkIdentity(Context context,
+ NetworkStateSnapshot snapshot, boolean defaultNetwork, @NetworkType int subType) {
+ final int legacyType = snapshot.legacyType;
+
+ final String subscriberId = snapshot.subscriberId;
String networkId = null;
- boolean roaming = !state.networkCapabilities.hasCapability(
+ boolean roaming = !snapshot.networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING);
- boolean metered = !state.networkCapabilities.hasCapability(
+ boolean metered = !snapshot.networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_NOT_METERED);
- subscriberId = state.subscriberId;
-
- final int oemManaged = getOemBitfield(state.networkCapabilities);
+ final int oemManaged = getOemBitfield(snapshot.networkCapabilities);
if (legacyType == TYPE_WIFI) {
- if (state.networkCapabilities.getSsid() != null) {
- networkId = state.networkCapabilities.getSsid();
+ if (snapshot.networkCapabilities.getSsid() != null) {
+ networkId = snapshot.networkCapabilities.getSsid();
if (networkId == null) {
// TODO: Figure out if this code path never runs. If so, remove them.
final WifiManager wifi = (WifiManager) context.getSystemService(
diff --git a/core/java/android/net/NetworkStateSnapshot.java b/core/java/android/net/NetworkStateSnapshot.java
index 881b373fa241..b3d8d4e614da 100644
--- a/core/java/android/net/NetworkStateSnapshot.java
+++ b/core/java/android/net/NetworkStateSnapshot.java
@@ -16,8 +16,11 @@
package android.net;
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
@@ -28,31 +31,49 @@ import java.util.Objects;
*
* @hide
*/
+@SystemApi(client = MODULE_LIBRARIES)
public final class NetworkStateSnapshot implements Parcelable {
+ /** The network associated with this snapshot. */
@NonNull
- public final LinkProperties linkProperties;
+ public final Network network;
+
+ /** The {@link NetworkCapabilities} of the network associated with this snapshot. */
@NonNull
public final NetworkCapabilities networkCapabilities;
+
+ /** The {@link LinkProperties} of the network associated with this snapshot. */
@NonNull
- public final Network network;
+ public final LinkProperties linkProperties;
+
+ /**
+ * The Subscriber Id of the network associated with this snapshot. See
+ * {@link android.telephony.TelephonyManager#getSubscriberId()}.
+ */
@Nullable
public final String subscriberId;
+
+ /**
+ * The legacy type of the network associated with this snapshot. See
+ * {@code ConnectivityManager#TYPE_*}.
+ */
public final int legacyType;
- public NetworkStateSnapshot(@NonNull LinkProperties linkProperties,
- @NonNull NetworkCapabilities networkCapabilities, @NonNull Network network,
+ public NetworkStateSnapshot(@NonNull Network network,
+ @NonNull NetworkCapabilities networkCapabilities,
+ @NonNull LinkProperties linkProperties,
@Nullable String subscriberId, int legacyType) {
- this.linkProperties = Objects.requireNonNull(linkProperties);
- this.networkCapabilities = Objects.requireNonNull(networkCapabilities);
this.network = Objects.requireNonNull(network);
+ this.networkCapabilities = Objects.requireNonNull(networkCapabilities);
+ this.linkProperties = Objects.requireNonNull(linkProperties);
this.subscriberId = subscriberId;
this.legacyType = legacyType;
}
+ /** @hide */
public NetworkStateSnapshot(@NonNull Parcel in) {
- linkProperties = in.readParcelable(null);
- networkCapabilities = in.readParcelable(null);
network = in.readParcelable(null);
+ networkCapabilities = in.readParcelable(null);
+ linkProperties = in.readParcelable(null);
subscriberId = in.readString();
legacyType = in.readInt();
}
@@ -64,9 +85,9 @@ public final class NetworkStateSnapshot implements Parcelable {
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeParcelable(linkProperties, flags);
- out.writeParcelable(networkCapabilities, flags);
out.writeParcelable(network, flags);
+ out.writeParcelable(networkCapabilities, flags);
+ out.writeParcelable(linkProperties, flags);
out.writeString(subscriberId);
out.writeInt(legacyType);
}
@@ -93,14 +114,14 @@ public final class NetworkStateSnapshot implements Parcelable {
if (!(o instanceof NetworkStateSnapshot)) return false;
NetworkStateSnapshot that = (NetworkStateSnapshot) o;
return legacyType == that.legacyType
- && Objects.equals(linkProperties, that.linkProperties)
- && Objects.equals(networkCapabilities, that.networkCapabilities)
&& Objects.equals(network, that.network)
+ && Objects.equals(networkCapabilities, that.networkCapabilities)
+ && Objects.equals(linkProperties, that.linkProperties)
&& Objects.equals(subscriberId, that.subscriberId);
}
@Override
public int hashCode() {
- return Objects.hash(linkProperties, networkCapabilities, network, subscriberId, legacyType);
+ return Objects.hash(network, networkCapabilities, linkProperties, subscriberId, legacyType);
}
}
diff --git a/packages/Connectivity/framework/src/android/net/PacProxySelector.java b/core/java/android/net/PacProxySelector.java
index 326943a27d4e..326943a27d4e 100644
--- a/packages/Connectivity/framework/src/android/net/PacProxySelector.java
+++ b/core/java/android/net/PacProxySelector.java
diff --git a/packages/Connectivity/framework/src/android/net/Proxy.java b/core/java/android/net/Proxy.java
index 77c8a4f4579b..77c8a4f4579b 100644
--- a/packages/Connectivity/framework/src/android/net/Proxy.java
+++ b/core/java/android/net/Proxy.java
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index f90fbaf1e0fb..fa3ff8a26862 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -41,6 +41,7 @@ import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import com.android.internal.net.NetworkUtilsInternal;
import com.android.internal.net.VpnConfig;
import java.net.DatagramSocket;
@@ -254,7 +255,7 @@ public class VpnService extends Service {
* @return {@code true} on success.
*/
public boolean protect(int socket) {
- return NetworkUtils.protectFromVpn(socket);
+ return NetworkUtilsInternal.protectFromVpn(socket);
}
/**
diff --git a/packages/Connectivity/framework/src/android/net/util/SocketUtils.java b/core/java/android/net/util/SocketUtils.java
index e64060f1b220..69edc757ce8a 100644
--- a/packages/Connectivity/framework/src/android/net/util/SocketUtils.java
+++ b/core/java/android/net/util/SocketUtils.java
@@ -22,12 +22,13 @@ import static android.system.OsConstants.SO_BINDTODEVICE;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.net.NetworkUtils;
import android.system.ErrnoException;
import android.system.NetlinkSocketAddress;
import android.system.Os;
import android.system.PacketSocketAddress;
+import com.android.internal.net.NetworkUtilsInternal;
+
import libcore.io.IoBridge;
import java.io.FileDescriptor;
@@ -51,7 +52,7 @@ public final class SocketUtils {
// of struct ifreq is a NULL-terminated interface name.
// TODO: add a setsockoptString()
Os.setsockoptIfreq(socket, SOL_SOCKET, SO_BINDTODEVICE, iface);
- NetworkUtils.protectFromVpn(socket);
+ NetworkUtilsInternal.protectFromVpn(socket);
}
/**
diff --git a/core/java/android/os/BatterySaverPolicyConfig.java b/core/java/android/os/BatterySaverPolicyConfig.java
index 81c781bff06d..a999e658ce21 100644
--- a/core/java/android/os/BatterySaverPolicyConfig.java
+++ b/core/java/android/os/BatterySaverPolicyConfig.java
@@ -247,6 +247,7 @@ public final class BatterySaverPolicyConfig implements Parcelable {
/**
* Get the SoundTrigger mode while in Battery Saver.
*/
+ @PowerManager.SoundTriggerPowerSaveMode
public int getSoundTriggerMode() {
return mSoundTriggerMode;
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 874add5cdbd8..91d6a9bf69cb 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -23,7 +23,6 @@ import android.net.ITetheringStatsProvider;
import android.net.Network;
import android.net.NetworkStats;
import android.net.RouteInfo;
-import android.net.UidRange;
/**
* @hide
@@ -182,11 +181,6 @@ interface INetworkManagementService
String[] listTetheredInterfaces();
/**
- * Sets the list of DNS forwarders (in order of priority)
- */
- void setDnsForwarders(in Network network, in String[] dns);
-
- /**
* Returns the list of DNS forwarders (in order of priority)
*/
String[] getDnsForwarders();
@@ -300,8 +294,6 @@ interface INetworkManagementService
void setFirewallUidRules(int chain, in int[] uids, in int[] rules);
void setFirewallChainEnabled(int chain, boolean enable);
- void addLegacyRouteForNetId(int netId, in RouteInfo routeInfo, int uid);
-
/**
* Allow UID to call protect().
*/
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 617220e00f9d..85cef84d8d30 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -16564,30 +16564,6 @@ public final class Settings {
/**
* Performs a strict and comprehensive check of whether a calling package is allowed to
- * change the state of network, as the condition differs for pre-M, M+, and
- * privileged/preinstalled apps. The caller is expected to have either the
- * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
- * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
- * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
- * permission and cannot be revoked. See http://b/23597341
- *
- * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
- * of this app will be updated to the current time.
- * @hide
- */
- public static boolean checkAndNoteChangeNetworkStateOperation(Context context, int uid,
- String callingPackage, String callingAttributionTag, boolean throwException) {
- if (context.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
- == PackageManager.PERMISSION_GRANTED) {
- return true;
- }
- return isCallingPackageAllowedToPerformAppOpsProtectedOperation(context, uid,
- callingPackage, callingAttributionTag, throwException,
- AppOpsManager.OP_WRITE_SETTINGS, PM_CHANGE_NETWORK_STATE, true);
- }
-
- /**
- * Performs a strict and comprehensive check of whether a calling package is allowed to
* draw on top of other apps, as the conditions differs for pre-M, M+, and
* privileged/preinstalled apps. If the provided uid does not match the callingPackage,
* a negative result will be returned.
diff --git a/core/java/android/util/OWNERS b/core/java/android/util/OWNERS
index 14aa38682d2b..5425c214de1f 100644
--- a/core/java/android/util/OWNERS
+++ b/core/java/android/util/OWNERS
@@ -2,5 +2,7 @@ per-file FeatureFlagUtils.java = sbasi@google.com
per-file FeatureFlagUtils.java = tmfang@google.com
per-file FeatureFlagUtils.java = asapperstein@google.com
-per-file TypedValue.java = file:/core/java/android/content/res/OWNERS
per-file AttributeSet.java = file:/core/java/android/content/res/OWNERS
+per-file TypedValue.java = file:/core/java/android/content/res/OWNERS
+
+per-file PackageUtils.java = file:/core/java/android/content/pm/OWNERS
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index 6718e93f908c..05c8617294da 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -510,10 +510,12 @@ public class SparseArray<E> implements Cloneable {
}
/**
+ * Compares the contents of this {@link SparseArray} to the specified {@link SparseArray}.
+ *
* For backwards compatibility reasons, {@link Object#equals(Object)} cannot be implemented,
* so this serves as a manually invoked alternative.
*/
- public boolean contentEquals(@Nullable SparseArray<E> other) {
+ public boolean contentEquals(@Nullable SparseArray<?> other) {
if (other == null) {
return false;
}
@@ -534,6 +536,9 @@ public class SparseArray<E> implements Cloneable {
}
/**
+ * Returns a hash code value for the contents of this {@link SparseArray}, combining the
+ * {@link Objects#hashCode(Object)} result of all its keys and values.
+ *
* For backwards compatibility, {@link Object#hashCode()} cannot be implemented, so this serves
* as a manually invoked alternative.
*/
diff --git a/core/java/android/util/apk/OWNERS b/core/java/android/util/apk/OWNERS
new file mode 100644
index 000000000000..52c95501e541
--- /dev/null
+++ b/core/java/android/util/apk/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/content/pm/OWNERS
diff --git a/core/java/android/view/AccessibilityInteractionController.java b/core/java/android/view/AccessibilityInteractionController.java
index 9473845b15e6..0499f39f2fe4 100644
--- a/core/java/android/view/AccessibilityInteractionController.java
+++ b/core/java/android/view/AccessibilityInteractionController.java
@@ -86,12 +86,19 @@ public final class AccessibilityInteractionController {
// accessibility from hanging
private static final long REQUEST_PREPARER_TIMEOUT_MS = 500;
+ // Callbacks should have the same configuration of the flags below to allow satisfying a pending
+ // node request on prefetch
+ private static final int FLAGS_AFFECTING_REPORTED_DATA =
+ AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS
+ | AccessibilityNodeInfo.FLAG_REPORT_VIEW_IDS;
+
private final ArrayList<AccessibilityNodeInfo> mTempAccessibilityNodeInfoList =
new ArrayList<AccessibilityNodeInfo>();
private final Object mLock = new Object();
- private final PrivateHandler mHandler;
+ @VisibleForTesting
+ public final PrivateHandler mHandler;
private final ViewRootImpl mViewRootImpl;
@@ -114,6 +121,9 @@ public final class AccessibilityInteractionController {
private AddNodeInfosForViewId mAddNodeInfosForViewId;
@GuardedBy("mLock")
+ private ArrayList<Message> mPendingFindNodeByIdMessages;
+
+ @GuardedBy("mLock")
private int mNumActiveRequestPreparers;
@GuardedBy("mLock")
private List<MessageHolder> mMessagesWaitingForRequestPreparer;
@@ -128,6 +138,7 @@ public final class AccessibilityInteractionController {
mViewRootImpl = viewRootImpl;
mPrefetcher = new AccessibilityNodePrefetcher();
mA11yManager = mViewRootImpl.mContext.getSystemService(AccessibilityManager.class);
+ mPendingFindNodeByIdMessages = new ArrayList<>();
}
private void scheduleMessage(Message message, int interrogatingPid, long interrogatingTid,
@@ -177,6 +188,9 @@ public final class AccessibilityInteractionController {
args.arg4 = arguments;
message.obj = args;
+ synchronized (mLock) {
+ mPendingFindNodeByIdMessages.add(message);
+ }
scheduleMessage(message, interrogatingPid, interrogatingTid, CONSIDER_REQUEST_PREPARERS);
}
@@ -315,6 +329,9 @@ public final class AccessibilityInteractionController {
}
private void findAccessibilityNodeInfoByAccessibilityIdUiThread(Message message) {
+ synchronized (mLock) {
+ mPendingFindNodeByIdMessages.remove(message);
+ }
final int flags = message.arg1;
SomeArgs args = (SomeArgs) message.obj;
@@ -329,22 +346,58 @@ public final class AccessibilityInteractionController {
args.recycle();
- List<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList;
- infos.clear();
+ View rootView = null;
+ AccessibilityNodeInfo rootNode = null;
try {
if (mViewRootImpl.mView == null || mViewRootImpl.mAttachInfo == null) {
return;
}
mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = flags;
- final View root = findViewByAccessibilityId(accessibilityViewId);
- if (root != null && isShown(root)) {
- mPrefetcher.prefetchAccessibilityNodeInfos(
- root, virtualDescendantId, flags, infos, arguments);
+ rootView = findViewByAccessibilityId(accessibilityViewId);
+ if (rootView != null && isShown(rootView)) {
+ rootNode = populateAccessibilityNodeInfoForView(
+ rootView, arguments, virtualDescendantId);
}
} finally {
- updateInfosForViewportAndReturnFindNodeResult(
- infos, callback, interactionId, spec, interactiveRegion);
+ updateInfoForViewportAndReturnFindNodeResult(
+ rootNode == null ? null : AccessibilityNodeInfo.obtain(rootNode),
+ callback, interactionId, spec, interactiveRegion);
+ }
+ ArrayList<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList;
+ infos.clear();
+ mPrefetcher.prefetchAccessibilityNodeInfos(
+ rootView, rootNode == null ? null : AccessibilityNodeInfo.obtain(rootNode),
+ virtualDescendantId, flags, infos);
+ mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
+ updateInfosForViewPort(infos, spec, interactiveRegion);
+ returnPrefetchResult(interactionId, infos, callback);
+ returnPendingFindAccessibilityNodeInfosInPrefetch(rootNode, infos, flags);
+ }
+
+ private AccessibilityNodeInfo populateAccessibilityNodeInfoForView(
+ View view, Bundle arguments, int virtualViewId) {
+ AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
+ // Determine if we'll be populating extra data
+ final String extraDataRequested = (arguments == null) ? null
+ : arguments.getString(EXTRA_DATA_REQUESTED_KEY);
+ AccessibilityNodeInfo root = null;
+ if (provider == null) {
+ root = view.createAccessibilityNodeInfo();
+ if (root != null) {
+ if (extraDataRequested != null) {
+ view.addExtraDataToAccessibilityNodeInfo(root, extraDataRequested, arguments);
+ }
+ }
+ } else {
+ root = provider.createAccessibilityNodeInfo(virtualViewId);
+ if (root != null) {
+ if (extraDataRequested != null) {
+ provider.addExtraDataToAccessibilityNodeInfo(
+ virtualViewId, root, extraDataRequested, arguments);
+ }
+ }
}
+ return root;
}
public void findAccessibilityNodeInfosByViewIdClientThread(long accessibilityNodeId,
@@ -402,6 +455,7 @@ public final class AccessibilityInteractionController {
mAddNodeInfosForViewId.reset();
}
} finally {
+ mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfosForViewportAndReturnFindNodeResult(
infos, callback, interactionId, spec, interactiveRegion);
}
@@ -484,6 +538,7 @@ public final class AccessibilityInteractionController {
}
}
} finally {
+ mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfosForViewportAndReturnFindNodeResult(
infos, callback, interactionId, spec, interactiveRegion);
}
@@ -575,6 +630,7 @@ public final class AccessibilityInteractionController {
}
}
} finally {
+ mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfoForViewportAndReturnFindNodeResult(
focused, callback, interactionId, spec, interactiveRegion);
}
@@ -629,6 +685,7 @@ public final class AccessibilityInteractionController {
}
}
} finally {
+ mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
updateInfoForViewportAndReturnFindNodeResult(
next, callback, interactionId, spec, interactiveRegion);
}
@@ -785,33 +842,6 @@ public final class AccessibilityInteractionController {
}
}
- private void applyAppScaleAndMagnificationSpecIfNeeded(List<AccessibilityNodeInfo> infos,
- MagnificationSpec spec) {
- if (infos == null) {
- return;
- }
- final float applicationScale = mViewRootImpl.mAttachInfo.mApplicationScale;
- if (shouldApplyAppScaleAndMagnificationSpec(applicationScale, spec)) {
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i++) {
- AccessibilityNodeInfo info = infos.get(i);
- applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
- }
- }
- }
-
- private void adjustIsVisibleToUserIfNeeded(List<AccessibilityNodeInfo> infos,
- Region interactiveRegion) {
- if (interactiveRegion == null || infos == null) {
- return;
- }
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i++) {
- AccessibilityNodeInfo info = infos.get(i);
- adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
- }
- }
-
private void adjustIsVisibleToUserIfNeeded(AccessibilityNodeInfo info,
Region interactiveRegion) {
if (interactiveRegion == null || info == null) {
@@ -832,17 +862,6 @@ public final class AccessibilityInteractionController {
return false;
}
- private void adjustBoundsInScreenIfNeeded(List<AccessibilityNodeInfo> infos) {
- if (infos == null || shouldBypassAdjustBoundsInScreen()) {
- return;
- }
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i++) {
- final AccessibilityNodeInfo info = infos.get(i);
- adjustBoundsInScreenIfNeeded(info);
- }
- }
-
private void adjustBoundsInScreenIfNeeded(AccessibilityNodeInfo info) {
if (info == null || shouldBypassAdjustBoundsInScreen()) {
return;
@@ -890,17 +909,6 @@ public final class AccessibilityInteractionController {
return screenMatrix == null || screenMatrix.isIdentity();
}
- private void associateLeashedParentIfNeeded(List<AccessibilityNodeInfo> infos) {
- if (infos == null || shouldBypassAssociateLeashedParent()) {
- return;
- }
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i++) {
- final AccessibilityNodeInfo info = infos.get(i);
- associateLeashedParentIfNeeded(info);
- }
- }
-
private void associateLeashedParentIfNeeded(AccessibilityNodeInfo info) {
if (info == null || shouldBypassAssociateLeashedParent()) {
return;
@@ -974,18 +982,46 @@ public final class AccessibilityInteractionController {
return (appScale != 1.0f || (spec != null && !spec.isNop()));
}
+ private void updateInfosForViewPort(List<AccessibilityNodeInfo> infos, MagnificationSpec spec,
+ Region interactiveRegion) {
+ for (int i = 0; i < infos.size(); i++) {
+ updateInfoForViewPort(infos.get(i), spec, interactiveRegion);
+ }
+ }
+
+ private void updateInfoForViewPort(AccessibilityNodeInfo info, MagnificationSpec spec,
+ Region interactiveRegion) {
+ associateLeashedParentIfNeeded(info);
+ applyScreenMatrixIfNeeded(info);
+ adjustBoundsInScreenIfNeeded(info);
+ // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
+ // then impact the visibility result, we need to adjust visibility before apply scale.
+ adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
+ applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
+ }
+
private void updateInfosForViewportAndReturnFindNodeResult(List<AccessibilityNodeInfo> infos,
IAccessibilityInteractionConnectionCallback callback, int interactionId,
MagnificationSpec spec, Region interactiveRegion) {
+ if (infos != null) {
+ updateInfosForViewPort(infos, spec, interactiveRegion);
+ }
+ returnFindNodesResult(infos, callback, interactionId);
+ }
+
+ private void returnFindNodeResult(AccessibilityNodeInfo info,
+ IAccessibilityInteractionConnectionCallback callback,
+ int interactionId) {
+ try {
+ callback.setFindAccessibilityNodeInfoResult(info, interactionId);
+ } catch (RemoteException re) {
+ /* ignore - the other side will time out */
+ }
+ }
+
+ private void returnFindNodesResult(List<AccessibilityNodeInfo> infos,
+ IAccessibilityInteractionConnectionCallback callback, int interactionId) {
try {
- mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
- associateLeashedParentIfNeeded(infos);
- applyScreenMatrixIfNeeded(infos);
- adjustBoundsInScreenIfNeeded(infos);
- // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
- // then impact the visibility result, we need to adjust visibility before apply scale.
- adjustIsVisibleToUserIfNeeded(infos, interactiveRegion);
- applyAppScaleAndMagnificationSpecIfNeeded(infos, spec);
callback.setFindAccessibilityNodeInfosResult(infos, interactionId);
if (infos != null) {
infos.clear();
@@ -995,22 +1031,80 @@ public final class AccessibilityInteractionController {
}
}
+ private void returnPendingFindAccessibilityNodeInfosInPrefetch(AccessibilityNodeInfo rootNode,
+ List<AccessibilityNodeInfo> infos, int flags) {
+
+ AccessibilityNodeInfo satisfiedPendingRequestPrefetchedNode = null;
+ IAccessibilityInteractionConnectionCallback satisfiedPendingRequestCallback = null;
+ int satisfiedPendingRequestInteractionId = AccessibilityInteractionClient.NO_ID;
+
+ synchronized (mLock) {
+ for (int i = 0; i < mPendingFindNodeByIdMessages.size(); i++) {
+ final Message pendingMessage = mPendingFindNodeByIdMessages.get(i);
+ final int pendingFlags = pendingMessage.arg1;
+ if ((pendingFlags & FLAGS_AFFECTING_REPORTED_DATA)
+ != (flags & FLAGS_AFFECTING_REPORTED_DATA)) {
+ continue;
+ }
+ SomeArgs args = (SomeArgs) pendingMessage.obj;
+ final int accessibilityViewId = args.argi1;
+ final int virtualDescendantId = args.argi2;
+
+ satisfiedPendingRequestPrefetchedNode = nodeWithIdFromList(rootNode,
+ infos, AccessibilityNodeInfo.makeNodeId(
+ accessibilityViewId, virtualDescendantId));
+
+ if (satisfiedPendingRequestPrefetchedNode != null) {
+ satisfiedPendingRequestCallback =
+ (IAccessibilityInteractionConnectionCallback) args.arg1;
+ satisfiedPendingRequestInteractionId = args.argi3;
+ mHandler.removeMessages(
+ PrivateHandler.MSG_FIND_ACCESSIBILITY_NODE_INFO_BY_ACCESSIBILITY_ID,
+ pendingMessage.obj);
+ args.recycle();
+ break;
+ }
+ }
+ mPendingFindNodeByIdMessages.clear();
+ }
+
+ if (satisfiedPendingRequestPrefetchedNode != null) {
+ returnFindNodeResult(
+ AccessibilityNodeInfo.obtain(satisfiedPendingRequestPrefetchedNode),
+ satisfiedPendingRequestCallback, satisfiedPendingRequestInteractionId);
+ }
+ }
+
+ private AccessibilityNodeInfo nodeWithIdFromList(AccessibilityNodeInfo rootNode,
+ List<AccessibilityNodeInfo> infos, long nodeId) {
+ if (rootNode != null && rootNode.getSourceNodeId() == nodeId) {
+ return rootNode;
+ }
+ for (int j = 0; j < infos.size(); j++) {
+ AccessibilityNodeInfo info = infos.get(j);
+ if (info.getSourceNodeId() == nodeId) {
+ return info;
+ }
+ }
+ return null;
+ }
+
+ private void returnPrefetchResult(int interactionId, List<AccessibilityNodeInfo> infos,
+ IAccessibilityInteractionConnectionCallback callback) {
+ if (infos.size() > 0) {
+ try {
+ callback.setPrefetchAccessibilityNodeInfoResult(infos, interactionId);
+ } catch (RemoteException re) {
+ /* ignore - other side isn't too bothered if this doesn't arrive */
+ }
+ }
+ }
+
private void updateInfoForViewportAndReturnFindNodeResult(AccessibilityNodeInfo info,
IAccessibilityInteractionConnectionCallback callback, int interactionId,
MagnificationSpec spec, Region interactiveRegion) {
- try {
- mViewRootImpl.mAttachInfo.mAccessibilityFetchFlags = 0;
- associateLeashedParentIfNeeded(info);
- applyScreenMatrixIfNeeded(info);
- adjustBoundsInScreenIfNeeded(info);
- // To avoid applyAppScaleAndMagnificationSpecIfNeeded changing the bounds of node,
- // then impact the visibility result, we need to adjust visibility before apply scale.
- adjustIsVisibleToUserIfNeeded(info, interactiveRegion);
- applyAppScaleAndMagnificationSpecIfNeeded(info, spec);
- callback.setFindAccessibilityNodeInfoResult(info, interactionId);
- } catch (RemoteException re) {
- /* ignore - the other side will time out */
- }
+ updateInfoForViewPort(info, spec, interactiveRegion);
+ returnFindNodeResult(info, callback, interactionId);
}
private boolean handleClickableSpanActionUiThread(
@@ -1053,56 +1147,45 @@ public final class AccessibilityInteractionController {
private final ArrayList<View> mTempViewList = new ArrayList<View>();
- public void prefetchAccessibilityNodeInfos(View view, int virtualViewId, int fetchFlags,
- List<AccessibilityNodeInfo> outInfos, Bundle arguments) {
+ public void prefetchAccessibilityNodeInfos(View view, AccessibilityNodeInfo root,
+ int virtualViewId, int fetchFlags, List<AccessibilityNodeInfo> outInfos) {
+ if (root == null) {
+ return;
+ }
AccessibilityNodeProvider provider = view.getAccessibilityNodeProvider();
- // Determine if we'll be populating extra data
- final String extraDataRequested = (arguments == null) ? null
- : arguments.getString(EXTRA_DATA_REQUESTED_KEY);
if (provider == null) {
- AccessibilityNodeInfo root = view.createAccessibilityNodeInfo();
- if (root != null) {
- if (extraDataRequested != null) {
- view.addExtraDataToAccessibilityNodeInfo(
- root, extraDataRequested, arguments);
- }
- outInfos.add(root);
- if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
- prefetchPredecessorsOfRealNode(view, outInfos);
- }
- if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
- prefetchSiblingsOfRealNode(view, outInfos);
- }
- if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
- prefetchDescendantsOfRealNode(view, outInfos);
- }
+ if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
+ prefetchPredecessorsOfRealNode(view, outInfos);
+ }
+ if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
+ prefetchSiblingsOfRealNode(view, outInfos);
+ }
+ if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
+ prefetchDescendantsOfRealNode(view, outInfos);
}
} else {
- final AccessibilityNodeInfo root =
- provider.createAccessibilityNodeInfo(virtualViewId);
- if (root != null) {
- if (extraDataRequested != null) {
- provider.addExtraDataToAccessibilityNodeInfo(
- virtualViewId, root, extraDataRequested, arguments);
- }
- outInfos.add(root);
- if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
- prefetchPredecessorsOfVirtualNode(root, view, provider, outInfos);
- }
- if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
- prefetchSiblingsOfVirtualNode(root, view, provider, outInfos);
- }
- if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
- prefetchDescendantsOfVirtualNode(root, provider, outInfos);
- }
+ if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_PREDECESSORS) != 0) {
+ prefetchPredecessorsOfVirtualNode(root, view, provider, outInfos);
+ }
+ if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS) != 0) {
+ prefetchSiblingsOfVirtualNode(root, view, provider, outInfos);
+ }
+ if ((fetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS) != 0) {
+ prefetchDescendantsOfVirtualNode(root, provider, outInfos);
}
}
if (ENFORCE_NODE_TREE_CONSISTENT) {
- enforceNodeTreeConsistent(outInfos);
+ enforceNodeTreeConsistent(root, outInfos);
}
}
- private void enforceNodeTreeConsistent(List<AccessibilityNodeInfo> nodes) {
+ private boolean shouldStopPrefetching(List prefetchededInfos) {
+ return mHandler.hasUserInteractiveMessagesWaiting()
+ || prefetchededInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE;
+ }
+
+ private void enforceNodeTreeConsistent(
+ AccessibilityNodeInfo root, List<AccessibilityNodeInfo> nodes) {
LongSparseArray<AccessibilityNodeInfo> nodeMap =
new LongSparseArray<AccessibilityNodeInfo>();
final int nodeCount = nodes.size();
@@ -1113,7 +1196,6 @@ public final class AccessibilityInteractionController {
// If the nodes are a tree it does not matter from
// which node we start to search for the root.
- AccessibilityNodeInfo root = nodeMap.valueAt(0);
AccessibilityNodeInfo parent = root;
while (parent != null) {
root = parent;
@@ -1180,9 +1262,11 @@ public final class AccessibilityInteractionController {
private void prefetchPredecessorsOfRealNode(View view,
List<AccessibilityNodeInfo> outInfos) {
+ if (shouldStopPrefetching(outInfos)) {
+ return;
+ }
ViewParent parent = view.getParentForAccessibility();
- while (parent instanceof View
- && outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ while (parent instanceof View && !shouldStopPrefetching(outInfos)) {
View parentView = (View) parent;
AccessibilityNodeInfo info = parentView.createAccessibilityNodeInfo();
if (info != null) {
@@ -1194,6 +1278,9 @@ public final class AccessibilityInteractionController {
private void prefetchSiblingsOfRealNode(View current,
List<AccessibilityNodeInfo> outInfos) {
+ if (shouldStopPrefetching(outInfos)) {
+ return;
+ }
ViewParent parent = current.getParentForAccessibility();
if (parent instanceof ViewGroup) {
ViewGroup parentGroup = (ViewGroup) parent;
@@ -1203,7 +1290,7 @@ public final class AccessibilityInteractionController {
parentGroup.addChildrenForAccessibility(children);
final int childCount = children.size();
for (int i = 0; i < childCount; i++) {
- if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ if (shouldStopPrefetching(outInfos)) {
return;
}
View child = children.get(i);
@@ -1231,7 +1318,7 @@ public final class AccessibilityInteractionController {
private void prefetchDescendantsOfRealNode(View root,
List<AccessibilityNodeInfo> outInfos) {
- if (!(root instanceof ViewGroup)) {
+ if (shouldStopPrefetching(outInfos) || !(root instanceof ViewGroup)) {
return;
}
HashMap<View, AccessibilityNodeInfo> addedChildren =
@@ -1242,7 +1329,7 @@ public final class AccessibilityInteractionController {
root.addChildrenForAccessibility(children);
final int childCount = children.size();
for (int i = 0; i < childCount; i++) {
- if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ if (shouldStopPrefetching(outInfos)) {
return;
}
View child = children.get(i);
@@ -1267,7 +1354,7 @@ public final class AccessibilityInteractionController {
} finally {
children.clear();
}
- if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ if (!shouldStopPrefetching(outInfos)) {
for (Map.Entry<View, AccessibilityNodeInfo> entry : addedChildren.entrySet()) {
View addedChild = entry.getKey();
AccessibilityNodeInfo virtualRoot = entry.getValue();
@@ -1289,7 +1376,7 @@ public final class AccessibilityInteractionController {
long parentNodeId = root.getParentNodeId();
int accessibilityViewId = AccessibilityNodeInfo.getAccessibilityViewId(parentNodeId);
while (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED_ITEM_ID) {
- if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ if (shouldStopPrefetching(outInfos)) {
return;
}
final int virtualDescendantId =
@@ -1334,7 +1421,7 @@ public final class AccessibilityInteractionController {
if (parent != null) {
final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
- if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ if (shouldStopPrefetching(outInfos)) {
return;
}
final long childNodeId = parent.getChildId(i);
@@ -1359,7 +1446,7 @@ public final class AccessibilityInteractionController {
final int initialOutInfosSize = outInfos.size();
final int childCount = root.getChildCount();
for (int i = 0; i < childCount; i++) {
- if (outInfos.size() >= MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ if (shouldStopPrefetching(outInfos)) {
return;
}
final long childNodeId = root.getChildId(i);
@@ -1369,7 +1456,7 @@ public final class AccessibilityInteractionController {
outInfos.add(child);
}
}
- if (outInfos.size() < MAX_ACCESSIBILITY_NODE_INFO_BATCH_SIZE) {
+ if (!shouldStopPrefetching(outInfos)) {
final int addedChildCount = outInfos.size() - initialOutInfosSize;
for (int i = 0; i < addedChildCount; i++) {
AccessibilityNodeInfo child = outInfos.get(initialOutInfosSize + i);
@@ -1478,6 +1565,10 @@ public final class AccessibilityInteractionController {
boolean hasAccessibilityCallback(Message message) {
return message.what < FIRST_NO_ACCESSIBILITY_CALLBACK_MSG ? true : false;
}
+
+ boolean hasUserInteractiveMessagesWaiting() {
+ return hasMessagesOrCallbacks();
+ }
}
private final class AddNodeInfosForViewId implements Predicate<View> {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 0ba1dfee16f3..8117c963b959 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -34,6 +34,7 @@ import android.graphics.ColorSpace;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
+import android.hardware.display.DeviceProductInfo;
import android.hardware.display.DisplayManager;
import android.hardware.display.DisplayManagerGlobal;
import android.os.Build;
@@ -1181,6 +1182,18 @@ public final class Display {
}
/**
+ * Returns the product-specific information about the display or the directly connected
+ * device on the display chain.
+ * For example, if the display is transitively connected, this field may contain product
+ * information about the intermediate device.
+ * Returns {@code null} if product information is not available.
+ */
+ @Nullable
+ public DeviceProductInfo getDeviceProductInfo() {
+ return mDisplayInfo.deviceProductInfo;
+ }
+
+ /**
* Gets display metrics that describe the size and density of this display.
* The size returned by this method does not necessarily represent the
* actual raw size (native resolution) of the display.
diff --git a/core/java/android/view/OWNERS b/core/java/android/view/OWNERS
index e66b17aa4426..cbb86de4785f 100644
--- a/core/java/android/view/OWNERS
+++ b/core/java/android/view/OWNERS
@@ -57,6 +57,7 @@ per-file ViewRootImpl.java = file:/graphics/java/android/graphics/OWNERS
per-file ViewRootImpl.java = file:/services/core/java/com/android/server/input/OWNERS
per-file ViewRootImpl.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file ViewRootImpl.java = file:/core/java/android/view/inputmethod/OWNERS
+per-file AccessibilityInteractionController.java = file:/services/accessibility/OWNERS
# WindowManager
per-file DisplayCutout.aidl = file:/services/core/java/com/android/server/wm/OWNERS
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 2053826d91a9..1819da4a86a0 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -2782,6 +2782,15 @@ public interface WindowManager extends ViewManager {
public boolean hasManualSurfaceInsets;
/**
+ * Whether we should use global insets state when report insets to the window. When set to
+ * {@code true}, all the insets will be reported to the window regardless of the z-order.
+ * Otherwise, only the insets above the given window will be reported.
+ *
+ * @hide
+ */
+ public boolean receiveInsetsIgnoringZOrder;
+
+ /**
* Whether the previous surface insets should be used vs. what is currently set. When set
* to {@code true}, the view root will ignore surfaces insets in this object and use what
* it currently has.
@@ -3714,15 +3723,16 @@ public interface WindowManager extends ViewManager {
out.writeInt(preferredDisplayModeId);
out.writeInt(systemUiVisibility);
out.writeInt(subtreeSystemUiVisibility);
- out.writeInt(hasSystemUiListeners ? 1 : 0);
+ out.writeBoolean(hasSystemUiListeners);
out.writeInt(inputFeatures);
out.writeLong(userActivityTimeout);
out.writeInt(surfaceInsets.left);
out.writeInt(surfaceInsets.top);
out.writeInt(surfaceInsets.right);
out.writeInt(surfaceInsets.bottom);
- out.writeInt(hasManualSurfaceInsets ? 1 : 0);
- out.writeInt(preservePreviousSurfaceInsets ? 1 : 0);
+ out.writeBoolean(hasManualSurfaceInsets);
+ out.writeBoolean(receiveInsetsIgnoringZOrder);
+ out.writeBoolean(preservePreviousSurfaceInsets);
out.writeLong(accessibilityIdOfAnchor);
TextUtils.writeToParcel(accessibilityTitle, out, parcelableFlags);
out.writeInt(mColorMode);
@@ -3783,15 +3793,16 @@ public interface WindowManager extends ViewManager {
preferredDisplayModeId = in.readInt();
systemUiVisibility = in.readInt();
subtreeSystemUiVisibility = in.readInt();
- hasSystemUiListeners = in.readInt() != 0;
+ hasSystemUiListeners = in.readBoolean();
inputFeatures = in.readInt();
userActivityTimeout = in.readLong();
surfaceInsets.left = in.readInt();
surfaceInsets.top = in.readInt();
surfaceInsets.right = in.readInt();
surfaceInsets.bottom = in.readInt();
- hasManualSurfaceInsets = in.readInt() != 0;
- preservePreviousSurfaceInsets = in.readInt() != 0;
+ hasManualSurfaceInsets = in.readBoolean();
+ receiveInsetsIgnoringZOrder = in.readBoolean();
+ preservePreviousSurfaceInsets = in.readBoolean();
accessibilityIdOfAnchor = in.readLong();
accessibilityTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
mColorMode = in.readInt();
@@ -4020,6 +4031,11 @@ public interface WindowManager extends ViewManager {
changes |= SURFACE_INSETS_CHANGED;
}
+ if (receiveInsetsIgnoringZOrder != o.receiveInsetsIgnoringZOrder) {
+ receiveInsetsIgnoringZOrder = o.receiveInsetsIgnoringZOrder;
+ changes |= SURFACE_INSETS_CHANGED;
+ }
+
if (preservePreviousSurfaceInsets != o.preservePreviousSurfaceInsets) {
preservePreviousSurfaceInsets = o.preservePreviousSurfaceInsets;
changes |= SURFACE_INSETS_CHANGED;
@@ -4208,6 +4224,9 @@ public interface WindowManager extends ViewManager {
sb.append(" (!preservePreviousSurfaceInsets)");
}
}
+ if (receiveInsetsIgnoringZOrder) {
+ sb.append(" receive insets ignoring z-order");
+ }
if (mColorMode != COLOR_MODE_DEFAULT) {
sb.append(" colorMode=").append(ActivityInfo.colorModeToString(mColorMode));
}
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index f63749be6df2..9556c25575cd 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -23,7 +23,9 @@ import android.compat.annotation.UnsupportedAppUsage;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
+import android.os.Handler;
import android.os.IBinder;
+import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.os.RemoteException;
@@ -113,6 +115,8 @@ public final class AccessibilityInteractionClient
private final Object mInstanceLock = new Object();
+ private Handler mMainHandler;
+
private volatile int mInteractionId = -1;
private AccessibilityNodeInfo mFindAccessibilityNodeInfoResult;
@@ -123,6 +127,11 @@ public final class AccessibilityInteractionClient
private Message mSameThreadMessage;
+ private int mInteractionIdWaitingForPrefetchResult;
+ private int mConnectionIdWaitingForPrefetchResult;
+ private String[] mPackageNamesForNextPrefetchResult;
+ private Runnable mPrefetchResultRunnable;
+
/**
* @return The client for the current thread.
*/
@@ -197,6 +206,9 @@ public final class AccessibilityInteractionClient
private AccessibilityInteractionClient() {
/* reducing constructor visibility */
+ if (Looper.getMainLooper() != null) {
+ mMainHandler = new Handler(Looper.getMainLooper());
+ }
}
/**
@@ -451,16 +463,16 @@ public final class AccessibilityInteractionClient
Binder.restoreCallingIdentity(identityToken);
}
if (packageNames != null) {
- List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
- interactionId);
- finalizeAndCacheAccessibilityNodeInfos(infos, connectionId,
- bypassCache, packageNames);
- if (infos != null && !infos.isEmpty()) {
- for (int i = 1; i < infos.size(); i++) {
- infos.get(i).recycle();
- }
- return infos.get(0);
+ AccessibilityNodeInfo info =
+ getFindAccessibilityNodeInfoResultAndClear(interactionId);
+ if ((prefetchFlags & AccessibilityNodeInfo.FLAG_PREFETCH_MASK) != 0
+ && info != null) {
+ setInteractionWaitingForPrefetchResult(interactionId, connectionId,
+ packageNames);
}
+ finalizeAndCacheAccessibilityNodeInfo(info, connectionId,
+ bypassCache, packageNames);
+ return info;
}
} else {
if (DEBUG) {
@@ -474,6 +486,15 @@ public final class AccessibilityInteractionClient
return null;
}
+ private void setInteractionWaitingForPrefetchResult(int interactionId, int connectionId,
+ String[] packageNames) {
+ synchronized (mInstanceLock) {
+ mInteractionIdWaitingForPrefetchResult = interactionId;
+ mConnectionIdWaitingForPrefetchResult = connectionId;
+ mPackageNamesForNextPrefetchResult = packageNames;
+ }
+ }
+
private static String idToString(int accessibilityWindowId, long accessibilityNodeId) {
return accessibilityWindowId + "/"
+ AccessibilityNodeInfo.idToString(accessibilityNodeId);
@@ -829,6 +850,60 @@ public final class AccessibilityInteractionClient
}
/**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setPrefetchAccessibilityNodeInfoResult(@NonNull List<AccessibilityNodeInfo> infos,
+ int interactionId) {
+ List<AccessibilityNodeInfo> infosCopy = null;
+ int mConnectionIdWaitingForPrefetchResultCopy = -1;
+ String[] mPackageNamesForNextPrefetchResultCopy = null;
+
+ synchronized (mInstanceLock) {
+ if (!infos.isEmpty() && mInteractionIdWaitingForPrefetchResult == interactionId) {
+ if (mMainHandler != null) {
+ if (mPrefetchResultRunnable != null) {
+ mMainHandler.removeCallbacks(mPrefetchResultRunnable);
+ mPrefetchResultRunnable = null;
+ }
+ /**
+ * TODO(b/180957109): AccessibilityCache is prone to deadlocks
+ * We post caching the prefetched nodes in the main thread. Using the binder
+ * thread results in "Long monitor contention with owner main" logs where
+ * service response times may exceed 5 seconds. This is due to the cache calling
+ * out to the system when refreshing nodes with the lock held.
+ */
+ mPrefetchResultRunnable = () -> finalizeAndCacheAccessibilityNodeInfos(
+ infos, mConnectionIdWaitingForPrefetchResult, false,
+ mPackageNamesForNextPrefetchResult);
+ mMainHandler.post(mPrefetchResultRunnable);
+
+ } else {
+ for (AccessibilityNodeInfo info : infos) {
+ infosCopy.add(new AccessibilityNodeInfo(info));
+ }
+ mConnectionIdWaitingForPrefetchResultCopy =
+ mConnectionIdWaitingForPrefetchResult;
+ mPackageNamesForNextPrefetchResultCopy =
+ new String[mPackageNamesForNextPrefetchResult.length];
+ for (int i = 0; i < mPackageNamesForNextPrefetchResult.length; i++) {
+ mPackageNamesForNextPrefetchResultCopy[i] =
+ mPackageNamesForNextPrefetchResult[i];
+
+ }
+ }
+ }
+
+ }
+
+ if (infosCopy != null) {
+ finalizeAndCacheAccessibilityNodeInfos(
+ infosCopy, mConnectionIdWaitingForPrefetchResultCopy, false,
+ mPackageNamesForNextPrefetchResultCopy);
+ }
+ }
+
+ /**
* Gets the result of a request to perform an accessibility action.
*
* @param interactionId The interaction id to match the result with the request.
diff --git a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
index 049bb31adbb1..231e75a19a06 100644
--- a/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
+++ b/core/java/android/view/accessibility/IAccessibilityInteractionConnectionCallback.aidl
@@ -47,6 +47,15 @@ oneway interface IAccessibilityInteractionConnectionCallback {
int interactionId);
/**
+ * Sets the result of a prefetch request that returns {@link AccessibilityNodeInfo}s.
+ *
+ * @param root The {@link AccessibilityNodeInfo} for which the prefetching is based off of.
+ * @param infos The result {@link AccessibilityNodeInfo}s.
+ */
+ void setPrefetchAccessibilityNodeInfoResult(
+ in List<AccessibilityNodeInfo> infos, int interactionId);
+
+ /**
* Sets the result of a request to perform an accessibility action.
*
* @param Whether the action was performed.
diff --git a/core/java/android/view/translation/TranslationSpec.java b/core/java/android/view/translation/TranslationSpec.java
index ab1bc477e0fd..16418a78f2c1 100644
--- a/core/java/android/view/translation/TranslationSpec.java
+++ b/core/java/android/view/translation/TranslationSpec.java
@@ -28,7 +28,7 @@ import com.android.internal.util.DataClass;
* <p>This spec help specify information such as the language/locale for the translation, as well
* as the data format for the translation (text, audio, etc.)</p>
*/
-@DataClass(genEqualsHashCode = true, genHiddenConstDefs = true)
+@DataClass(genEqualsHashCode = true, genHiddenConstDefs = true, genToString = true)
public final class TranslationSpec implements Parcelable {
/** Data format for translation is text. */
@@ -99,6 +99,18 @@ public final class TranslationSpec implements Parcelable {
@Override
@DataClass.Generated.Member
+ public String toString() {
+ // You can override field toString logic by defining methods like:
+ // String fieldNameToString() { ... }
+
+ return "TranslationSpec { " +
+ "language = " + mLanguage + ", " +
+ "dataFormat = " + mDataFormat +
+ " }";
+ }
+
+ @Override
+ @DataClass.Generated.Member
public boolean equals(@android.annotation.Nullable Object o) {
// You can override field equality logic by defining either of the methods like:
// boolean fieldNameEquals(TranslationSpec other) { ... }
@@ -175,10 +187,10 @@ public final class TranslationSpec implements Parcelable {
};
@DataClass.Generated(
- time = 1609964630624L,
+ time = 1614326090637L,
codegenVersion = "1.0.22",
sourceFile = "frameworks/base/core/java/android/view/translation/TranslationSpec.java",
- inputSignatures = "public static final int DATA_FORMAT_TEXT\nprivate final @android.annotation.NonNull java.lang.String mLanguage\nprivate final @android.view.translation.TranslationSpec.DataFormat int mDataFormat\nclass TranslationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genHiddenConstDefs=true)")
+ inputSignatures = "public static final int DATA_FORMAT_TEXT\nprivate final @android.annotation.NonNull java.lang.String mLanguage\nprivate final @android.view.translation.TranslationSpec.DataFormat int mDataFormat\nclass TranslationSpec extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genHiddenConstDefs=true, genToString=true)")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/view/translation/Translator.java b/core/java/android/view/translation/Translator.java
index 22c3e57ecc95..163f832882c5 100644
--- a/core/java/android/view/translation/Translator.java
+++ b/core/java/android/view/translation/Translator.java
@@ -35,6 +35,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
import com.android.internal.util.SyncResultReceiver;
+import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -221,6 +222,12 @@ public class Translator {
return mId;
}
+ /** @hide */
+ public void dump(@NonNull String prefix, @NonNull PrintWriter pw) {
+ pw.print(prefix); pw.print("sourceSpec: "); pw.println(mSourceSpec);
+ pw.print(prefix); pw.print("destSpec: "); pw.println(mDestSpec);
+ }
+
/**
* Requests a translation for the provided {@link TranslationRequest} using the Translator's
* source spec and destination spec.
diff --git a/core/java/android/view/translation/UiTranslationController.java b/core/java/android/view/translation/UiTranslationController.java
index b1e45bbcd875..81006121bdef 100644
--- a/core/java/android/view/translation/UiTranslationController.java
+++ b/core/java/android/view/translation/UiTranslationController.java
@@ -40,6 +40,7 @@ import android.view.translation.UiTranslationManager.UiTranslationState;
import com.android.internal.util.function.pooled.PooledLambda;
+import java.io.PrintWriter;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
@@ -133,6 +134,23 @@ public class UiTranslationController {
}
/**
+ * Called to dump the translation information for Activity.
+ */
+ public void dump(String outerPrefix, PrintWriter pw) {
+ pw.print(outerPrefix); pw.println("UiTranslationController:");
+ final String pfx = outerPrefix + " ";
+ pw.print(pfx); pw.print("activity: "); pw.println(mActivity);
+ final int translatorSize = mTranslators.size();
+ pw.print(outerPrefix); pw.print("number translator: "); pw.println(translatorSize);
+ for (int i = 0; i < translatorSize; i++) {
+ pw.print(outerPrefix); pw.print("#"); pw.println(i);
+ final Translator translator = mTranslators.valueAt(i);
+ translator.dump(outerPrefix, pw);
+ pw.println();
+ }
+ }
+
+ /**
* The method is used by {@link Translator}, it will be called when the translation is done. The
* translation result can be get from here.
*/
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index e0b4ec71b0a0..2cf50bbc6793 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -705,6 +705,14 @@ public class RemoteViews implements Parcelable, Filter {
public String getPackageName() {
return mContextForResources.getPackageName();
}
+
+ @Override
+ public boolean isRestricted() {
+ // Override isRestricted and direct to resource's implementation. The isRestricted is
+ // used for determining the risky resources loading, e.g. fonts, thus direct to context
+ // for resource.
+ return mContextForResources.isRestricted();
+ }
}
private class SetEmptyView extends Action {
diff --git a/core/java/com/android/internal/net/NetworkUtilsInternal.java b/core/java/com/android/internal/net/NetworkUtilsInternal.java
index 571d7e721094..052959abff69 100644
--- a/core/java/com/android/internal/net/NetworkUtilsInternal.java
+++ b/core/java/com/android/internal/net/NetworkUtilsInternal.java
@@ -22,6 +22,8 @@ import static android.system.OsConstants.AF_INET6;
import android.annotation.NonNull;
import android.system.Os;
+import java.io.FileDescriptor;
+
/** @hide */
public class NetworkUtilsInternal {
@@ -36,6 +38,20 @@ public class NetworkUtilsInternal {
public static native void setAllowNetworkingForProcess(boolean allowNetworking);
/**
+ * Protect {@code fd} from VPN connections. After protecting, data sent through
+ * this socket will go directly to the underlying network, so its traffic will not be
+ * forwarded through the VPN.
+ */
+ public static native boolean protectFromVpn(FileDescriptor fd);
+
+ /**
+ * Protect {@code socketfd} from VPN connections. After protecting, data sent through
+ * this socket will go directly to the underlying network, so its traffic will not be
+ * forwarded through the VPN.
+ */
+ public static native boolean protectFromVpn(int socketfd);
+
+ /**
* Returns true if the hostname is weakly validated.
* @param hostname Name of host to validate.
* @return True if it's a valid-ish hostname.
diff --git a/core/java/com/android/server/SystemConfig.java b/core/java/com/android/server/SystemConfig.java
index 58df2be2b944..bac6bbe43c91 100644
--- a/core/java/com/android/server/SystemConfig.java
+++ b/core/java/com/android/server/SystemConfig.java
@@ -1234,8 +1234,7 @@ public class SystemConfig {
final int incrementalVersion = IncrementalManager.getVersion();
if (incrementalVersion > 0) {
- addFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY, 0);
- addFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY_VERSION, incrementalVersion);
+ addFeature(PackageManager.FEATURE_INCREMENTAL_DELIVERY, incrementalVersion);
}
if (PackageManager.APP_ENUMERATION_ENABLED_BY_DEFAULT) {
diff --git a/core/jni/Android.bp b/core/jni/Android.bp
index 2287900795a5..d6d33873adaa 100644
--- a/core/jni/Android.bp
+++ b/core/jni/Android.bp
@@ -51,6 +51,7 @@ cc_library_shared {
"android_util_XmlBlock.cpp",
"android_util_jar_StrictJarFile.cpp",
"com_android_internal_util_VirtualRefBasePtr.cpp",
+ ":deviceproductinfoconstants_aidl",
],
include_dirs: [
@@ -150,7 +151,7 @@ cc_library_shared {
"android_os_VintfRuntimeInfo.cpp",
"android_os_incremental_IncrementalManager.cpp",
"android_net_LocalSocketImpl.cpp",
- "android_net_NetUtils.cpp",
+ "android_net_NetworkUtils.cpp",
"android_service_DataLoaderService.cpp",
"android_util_AssetManager.cpp",
"android_util_Binder.cpp",
diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp
index c7439f1b32d4..b0c575162b56 100644
--- a/core/jni/android_content_res_ApkAssets.cpp
+++ b/core/jni/android_content_res_ApkAssets.cpp
@@ -83,6 +83,10 @@ class LoaderAssetsProvider : public AssetsProvider {
return true;
}
+ std::optional<std::string_view> GetPath() const override {
+ return {};
+ }
+
const std::string& GetDebugName() const override {
return debug_name_;
}
@@ -358,8 +362,16 @@ static jlong NativeGetFinalizer(JNIEnv* /*env*/, jclass /*clazz*/) {
}
static jstring NativeGetAssetPath(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
- const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
- return env->NewStringUTF(apk_assets->GetPath().c_str());
+ auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+ if (auto path = apk_assets->GetPath()) {
+ return env->NewStringUTF(path->data());
+ }
+ return nullptr;
+}
+
+static jstring NativeGetDebugName(JNIEnv* env, jclass /*clazz*/, jlong ptr) {
+ auto apk_assets = reinterpret_cast<const ApkAssets*>(ptr);
+ return env->NewStringUTF(apk_assets->GetDebugName().c_str());
}
static jlong NativeGetStringBlock(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) {
@@ -467,6 +479,7 @@ static const JNINativeMethod gApkAssetsMethods[] = {
(void*)NativeLoadFromFdOffset},
{"nativeGetFinalizer", "()J", (void*)NativeGetFinalizer},
{"nativeGetAssetPath", "(J)Ljava/lang/String;", (void*)NativeGetAssetPath},
+ {"nativeGetDebugName", "(J)Ljava/lang/String;", (void*)NativeGetDebugName},
{"nativeGetStringBlock", "(J)J", (void*)NativeGetStringBlock},
{"nativeIsUpToDate", "(J)Z", (void*)NativeIsUpToDate},
{"nativeOpenXml", "(JLjava/lang/String;)J", (void*)NativeOpenXml},
diff --git a/core/jni/android_net_NetUtils.cpp b/core/jni/android_net_NetworkUtils.cpp
index e2af87ee1adf..750810840bde 100644
--- a/core/jni/android_net_NetUtils.cpp
+++ b/core/jni/android_net_NetworkUtils.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#define LOG_TAG "NetUtils"
+#define LOG_TAG "NetworkUtils"
#include <vector>
@@ -123,15 +123,6 @@ static jint android_net_utils_bindSocketToNetwork(JNIEnv *env, jobject thiz, job
return setNetworkForSocket(netId, AFileDescriptor_getFD(env, javaFd));
}
-static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint socket)
-{
- return (jboolean) !protectFromVpn(socket);
-}
-
-static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jobject thiz, jobject javaFd) {
- return android_net_utils_protectFromVpn(env, thiz, AFileDescriptor_getFD(env, javaFd));
-}
-
static jboolean android_net_utils_queryUserAccess(JNIEnv *env, jobject thiz, jint uid, jint netId)
{
return (jboolean) !queryUserAccess(uid, netId);
@@ -276,8 +267,6 @@ static const JNINativeMethod gNetworkUtilMethods[] = {
{ "getBoundNetworkForProcess", "()I", (void*) android_net_utils_getBoundNetworkForProcess },
{ "bindProcessToNetworkForHostResolution", "(I)Z", (void*) android_net_utils_bindProcessToNetworkForHostResolution },
{ "bindSocketToNetwork", "(Ljava/io/FileDescriptor;I)I", (void*) android_net_utils_bindSocketToNetwork },
- { "protectFromVpn", "(I)Z", (void*) android_net_utils_protectFromVpn },
- { "protectFromVpn", "(Ljava/io/FileDescriptor;)Z", (void*) android_net_utils_protectFromVpnWithFd },
{ "queryUserAccess", "(II)Z", (void*)android_net_utils_queryUserAccess },
{ "attachDropAllBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_attachDropAllBPFFilter },
{ "detachBPFFilter", "(Ljava/io/FileDescriptor;)V", (void*) android_net_utils_detachBPFFilter },
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 451ea93349f7..cbf4481bd2f1 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -27,6 +27,7 @@
#include <android-base/chrono_utils.h>
#include <android/graphics/region.h>
#include <android/gui/BnScreenCaptureListener.h>
+#include <android/hardware/display/IDeviceProductInfoConstants.h>
#include <android/os/IInputConstants.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
@@ -1022,16 +1023,24 @@ static jobject convertDeviceProductInfoToJavaObject(
} else {
LOG_FATAL("Unknown alternative for variant DeviceProductInfo::ManufactureOrModelDate");
}
- auto relativeAddress = env->NewIntArray(info->relativeAddress.size());
- auto relativeAddressData = env->GetIntArrayElements(relativeAddress, nullptr);
- for (int i = 0; i < info->relativeAddress.size(); i++) {
- relativeAddressData[i] = info->relativeAddress[i];
+ jint connectionToSinkType;
+ // Relative address maps to HDMI physical address. All addresses are 4 digits long allowing
+ // for a 5–device-deep hierarchy. For more information, refer:
+ // Section 8.7 - Physical Address of HDMI Specification Version 1.3a
+ using android::hardware::display::IDeviceProductInfoConstants;
+ if (info->relativeAddress.size() != 4) {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_UNKNOWN;
+ } else if (info->relativeAddress[0] == 0) {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_BUILT_IN;
+ } else if (info->relativeAddress[1] == 0) {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_DIRECT;
+ } else {
+ connectionToSinkType = IDeviceProductInfoConstants::CONNECTION_TO_SINK_TRANSITIVE;
}
- env->ReleaseIntArrayElements(relativeAddress, relativeAddressData, 0);
return env->NewObject(gDeviceProductInfoClassInfo.clazz, gDeviceProductInfoClassInfo.ctor, name,
manufacturerPnpId, productId, modelYear, manufactureDate,
- relativeAddress);
+ connectionToSinkType);
}
static jobject nativeGetStaticDisplayInfo(JNIEnv* env, jclass clazz, jobject tokenObj) {
@@ -1970,7 +1979,7 @@ int register_android_view_SurfaceControl(JNIEnv* env)
"Ljava/lang/String;"
"Ljava/lang/Integer;"
"Landroid/hardware/display/DeviceProductInfo$ManufactureDate;"
- "[I)V");
+ "I)V");
jclass deviceProductInfoManufactureDateClazz =
FindClassOrDie(env, "android/hardware/display/DeviceProductInfo$ManufactureDate");
diff --git a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
index 10fc18dcd386..980e12d0bb40 100644
--- a/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
+++ b/core/jni/com_android_internal_net_NetworkUtilsInternal.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#include <android/file_descriptor_jni.h>
+
#include "NetdClient.h"
#include "core_jni_helpers.h"
#include "jni.h"
@@ -24,9 +26,20 @@ static void android_net_utils_setAllowNetworkingForProcess(JNIEnv *env, jobject
setAllowNetworkingForProcess(hasConnectivity == JNI_TRUE);
}
+static jboolean android_net_utils_protectFromVpn(JNIEnv *env, jobject thiz, jint socket) {
+ return (jboolean)!protectFromVpn(socket);
+}
+
+static jboolean android_net_utils_protectFromVpnWithFd(JNIEnv *env, jobject thiz, jobject javaFd) {
+ return android_net_utils_protectFromVpn(env, thiz, AFileDescriptor_getFD(env, javaFd));
+}
+
static const JNINativeMethod gNetworkUtilMethods[] = {
{"setAllowNetworkingForProcess", "(Z)V",
(void *)android_net_utils_setAllowNetworkingForProcess},
+ {"protectFromVpn", "(I)Z", (void *)android_net_utils_protectFromVpn},
+ {"protectFromVpn", "(Ljava/io/FileDescriptor;)Z",
+ (void *)android_net_utils_protectFromVpnWithFd},
};
int register_com_android_internal_net_NetworkUtilsInternal(JNIEnv *env) {
diff --git a/core/proto/OWNERS b/core/proto/OWNERS
index 99fd21592411..e62b5c102a59 100644
--- a/core/proto/OWNERS
+++ b/core/proto/OWNERS
@@ -15,6 +15,7 @@ per-file settings_enums.proto=tmfang@google.com
ogunwale@google.com
jjaggi@google.com
roosa@google.com
+per-file package_item_info.proto = toddke@google.com
per-file usagestatsservice.proto, usagestatsservice_v2.proto = mwachens@google.com
per-file apphibernationservice.proto = file:/core/java/android/apphibernation/OWNERS
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 12cb3980f785..359bb69a417e 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -848,6 +848,15 @@
<!-- y-intercept --> <item>1.000000000000000</item>
</string-array>
+ <!-- Default strength, in percentage, of bright color reduction when activated. -->
+ <integer name="config_reduceBrightColorsStrengthDefault">0</integer>
+
+ <!-- Minimum strength, in percentage, supported by bright color reduction. -->
+ <integer name="config_reduceBrightColorsStrengthMin">0</integer>
+
+ <!-- Maximum strength, in percentage, supported by bright color reduction. -->
+ <integer name="config_reduceBrightColorsStrengthMax">100</integer>
+
<!-- Boolean indicating whether display white balance is supported. -->
<bool name="config_displayWhiteBalanceAvailable">false</bool>
@@ -1783,7 +1792,7 @@
* SDK level 28 makes the following algorithms mandatory : "cbc(aes)", "hmac(md5)",
"hmac(sha1)", "hmac(sha256)", "hmac(sha384)", "hmac(sha512)", "rfc4106(gcm(aes))"
* SDK level 31 makes the following algorithms mandatory : "rfc3686(ctr(aes))",
- "xcbc(aes)", "rfc7539esp(chacha20,poly1305)"
+ "xcbc(aes)", "cmac(aes)", "rfc7539esp(chacha20,poly1305)"
-->
<string-array name="config_optionalIpSecAlgorithms" translatable="false">
<!-- Add algorithm here -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index dbb584dfe293..5d56eb760679 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3224,6 +3224,9 @@
<java-symbol type="bool" name="config_reduceBrightColorsAvailable" />
<java-symbol type="array" name="config_reduceBrightColorsCoefficients" />
<java-symbol type="array" name="config_reduceBrightColorsCoefficientsNonlinear" />
+ <java-symbol type="integer" name="config_reduceBrightColorsStrengthDefault" />
+ <java-symbol type="integer" name="config_reduceBrightColorsStrengthMin" />
+ <java-symbol type="integer" name="config_reduceBrightColorsStrengthMax" />
<java-symbol type="array" name="config_availableColorModes" />
<java-symbol type="array" name="config_mappedColorModes" />
<java-symbol type="string" name="config_vendorColorModesRestoreHint" />
diff --git a/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java b/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java
index ab24f89015c7..7e1e7f4bdd7f 100644
--- a/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java
+++ b/core/tests/coretests/src/android/view/accessibility/AccessibilityInteractionClientTest.java
@@ -33,9 +33,6 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
-import java.util.Arrays;
-import java.util.List;
-
/**
* Tests for AccessibilityInteractionClient
*/
@@ -65,7 +62,7 @@ public class AccessibilityInteractionClientTest {
final long accessibilityNodeId = 0x4321L;
AccessibilityNodeInfo nodeFromConnection = AccessibilityNodeInfo.obtain();
nodeFromConnection.setSourceNodeId(accessibilityNodeId, windowId);
- mMockConnection.mInfosToReturn = Arrays.asList(nodeFromConnection);
+ mMockConnection.mInfoToReturn = nodeFromConnection;
AccessibilityInteractionClient client = AccessibilityInteractionClient.getInstance();
AccessibilityNodeInfo node = client.findAccessibilityNodeInfoByAccessibilityId(
MOCK_CONNECTION_ID, windowId, accessibilityNodeId, true, 0, null);
@@ -75,7 +72,7 @@ public class AccessibilityInteractionClientTest {
}
private static class MockConnection extends AccessibilityServiceConnectionImpl {
- List<AccessibilityNodeInfo> mInfosToReturn;
+ AccessibilityNodeInfo mInfoToReturn;
@Override
public String[] findAccessibilityNodeInfoByAccessibilityId(int accessibilityWindowId,
@@ -83,7 +80,7 @@ public class AccessibilityInteractionClientTest {
IAccessibilityInteractionConnectionCallback callback, int flags, long threadId,
Bundle arguments) {
try {
- callback.setFindAccessibilityNodeInfosResult(mInfosToReturn, interactionId);
+ callback.setFindAccessibilityNodeInfoResult(mInfoToReturn, interactionId);
} catch (RemoteException e) {
throw new RuntimeException(e);
}
diff --git a/core/tests/coretests/src/android/view/accessibility/OWNERS b/core/tests/coretests/src/android/view/accessibility/OWNERS
new file mode 100644
index 000000000000..b74281edbf52
--- /dev/null
+++ b/core/tests/coretests/src/android/view/accessibility/OWNERS
@@ -0,0 +1 @@
+include /core/java/android/view/accessibility/OWNERS
diff --git a/data/etc/car/android.car.cluster.xml b/data/etc/car/android.car.cluster.xml
index d7f29da7a356..de3accafa2fa 100644
--- a/data/etc/car/android.car.cluster.xml
+++ b/data/etc/car/android.car.cluster.xml
@@ -20,5 +20,7 @@
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
+ <permission name="android.car.permission.CAR_ENGINE_DETAILED"/>
+ <permission name="android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/car/com.android.car.bugreport.xml b/data/etc/car/com.android.car.bugreport.xml
index c3642d886180..2ff98357f8bf 100644
--- a/data/etc/car/com.android.car.bugreport.xml
+++ b/data/etc/car/com.android.car.bugreport.xml
@@ -21,5 +21,6 @@
<permission name="android.permission.READ_LOGS"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.BROADCAST_CLOSE_SYSTEM_DIALOGS"/>
+ <permission name="android.car.permission.CAR_DRIVING_STATE"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/car/com.android.car.carlauncher.xml b/data/etc/car/com.android.car.carlauncher.xml
index 0e49284d106f..ac16af348471 100644
--- a/data/etc/car/com.android.car.carlauncher.xml
+++ b/data/etc/car/com.android.car.carlauncher.xml
@@ -17,9 +17,10 @@
<permissions>
<privapp-permissions package="com.android.car.carlauncher">
<permission name="android.permission.ACTIVITY_EMBEDDING"/>
- <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
+ <permission name="android.permission.CONTROL_INCALL_EXPERIENCE"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
<permission name="android.permission.PACKAGE_USAGE_STATS"/>
+ <permission name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/car/com.android.car.dialer.xml b/data/etc/car/com.android.car.dialer.xml
index d44f5a1704a2..61ae53a30209 100644
--- a/data/etc/car/com.android.car.dialer.xml
+++ b/data/etc/car/com.android.car.dialer.xml
@@ -18,5 +18,6 @@
<privapp-permissions package="com.android.car.dialer">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
+ <permission name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/car/com.android.car.hvac.xml b/data/etc/car/com.android.car.hvac.xml
index d3631e067f8b..534d44da9a7c 100644
--- a/data/etc/car/com.android.car.hvac.xml
+++ b/data/etc/car/com.android.car.hvac.xml
@@ -17,5 +17,6 @@
<permissions>
<privapp-permissions package="com.android.car.hvac">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
+ <permission name="android.car.permission.CONTROL_CAR_CLIMATE"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/car/com.android.car.radio.xml b/data/etc/car/com.android.car.radio.xml
index d7853aba2d90..ed8652c01647 100644
--- a/data/etc/car/com.android.car.radio.xml
+++ b/data/etc/car/com.android.car.radio.xml
@@ -18,5 +18,7 @@
<privapp-permissions package="com.android.car.radio">
<permission name="android.permission.ACCESS_BROADCAST_RADIO"/>
<permission name="android.permission.MEDIA_CONTENT_CONTROL"/>
+ <permission name="android.car.permission.CAR_CONTROL_AUDIO_SETTINGS"/>
+ <permission name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/car/com.google.android.car.kitchensink.xml b/data/etc/car/com.google.android.car.kitchensink.xml
index bd30d7a61517..e6196c296552 100644
--- a/data/etc/car/com.google.android.car.kitchensink.xml
+++ b/data/etc/car/com.google.android.car.kitchensink.xml
@@ -51,5 +51,41 @@
<!-- use for rotary fragment to enable/disable packages related to rotary -->
<permission name="android.permission.CHANGE_COMPONENT_ENABLED_STATE"/>
+
+ <!-- CarService permissions -->
+ <!-- TODO: Explain why so many permissions are required -->
+ <permission name="android.car.permission.ACCESS_CAR_PROJECTION_STATUS"/>
+ <permission name="android.car.permission.CAR_CONTROL_AUDIO_SETTINGS"/>
+ <permission name="android.car.permission.CAR_CONTROL_AUDIO_VOLUME"/>
+ <permission name="android.car.permission.CAR_DIAGNOSTICS"/>
+ <permission name="android.car.permission.CAR_DISPLAY_IN_CLUSTER"/>
+ <permission name="android.car.permission.CAR_DRIVING_STATE"/>
+ <permission name="android.car.permission.CAR_DYNAMICS_STATE"/>
+ <permission name="android.car.permission.CAR_EXTERIOR_LIGHTS"/>
+ <permission name="android.car.permission.CAR_IDENTIFICATION"/>
+ <permission name="android.car.permission.CAR_INSTRUMENT_CLUSTER_CONTROL"/>
+ <permission name="android.car.permission.CAR_MILEAGE"/>
+ <permission name="android.car.permission.CAR_MOCK_VEHICLE_HAL"/>
+ <permission name="android.car.permission.CAR_NAVIGATION_MANAGER"/>
+ <permission name="android.car.permission.CAR_POWER"/>
+ <permission name="android.car.permission.CAR_PROJECTION"/>
+ <permission name="android.car.permission.CAR_TIRES"/>
+ <permission name="android.car.permission.CAR_TEST_SERVICE"/>
+ <permission name="android.car.permission.CAR_UX_RESTRICTIONS_CONFIGURATION"/>
+ <permission name="android.car.permission.CAR_VENDOR_EXTENSION"/>
+ <permission name="android.car.permission.CONTROL_CAR_CLIMATE"/>
+ <permission name="android.car.permission.CONTROL_CAR_DOORS"/>
+ <permission name="android.car.permission.CONTROL_CAR_EXTERIOR_LIGHTS"/>
+ <permission name="android.car.permission.CONTROL_CAR_FEATURES"/>
+ <permission name="android.car.permission.CONTROL_CAR_MIRRORS"/>
+ <permission name="android.car.permission.CONTROL_CAR_SEATS"/>
+ <permission name="android.car.permission.CONTROL_CAR_WINDOWS"/>
+ <permission name="android.car.permission.GET_CAR_VENDOR_CATEGORY_INFO"/>
+ <permission name="android.car.permission.GET_CAR_VENDOR_CATEGORY_SEAT"/>
+ <permission name="android.car.permission.READ_CAR_STEERING"/>
+ <permission name="android.car.permission.SET_CAR_VENDOR_CATEGORY_INFO"/>
+ <permission name="android.car.permission.STORAGE_MONITORING"/>
+ <permission name="android.car.permission.VMS_PUBLISHER"/>
+ <permission name="android.car.permission.VMS_SUBSCRIBER"/>
</privapp-permissions>
</permissions>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 5d4d7c3c4aa4..fae89d65ddd1 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -256,6 +256,7 @@ applications that come with the platform
<!-- Permissions required for reading DeviceConfig -->
<permission name="android.permission.READ_DEVICE_CONFIG" />
<permission name="android.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND"/>
+ <permission name="android.permission.MODIFY_QUIET_MODE"/>
</privapp-permissions>
<privapp-permissions package="com.android.providers.telephony">
@@ -483,6 +484,8 @@ applications that come with the platform
<permission name="android.permission.SIGNAL_REBOOT_READINESS" />
<!-- Permission required for CTS test - PeopleManagerTest -->
<permission name="android.permission.READ_PEOPLE_DATA" />
+ <!-- Permission required for CTS test - UiTranslationManagerTest -->
+ <permission name="android.permission.MANAGE_UI_TRANSLATION" />
</privapp-permissions>
<privapp-permissions package="com.android.statementservice">
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUILayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUILayout.java
index 32f3648be19a..c6d994ecde8d 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUILayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/sizecompatui/SizeCompatUILayout.java
@@ -280,7 +280,7 @@ class SizeCompatUILayout {
: stableBounds.right - taskBounds.left - mButtonSize;
final int positionY = stableBounds.bottom - taskBounds.top - mButtonSize;
- mSyncQueue.runInSync(t -> t.setPosition(leash, positionX, positionY));
+ updateSurfacePosition(leash, positionX, positionY);
}
void updateHintSurfacePosition() {
@@ -303,7 +303,16 @@ class SizeCompatUILayout {
final int positionY =
stableBounds.bottom - taskBounds.top - mPopupOffsetY - mHint.getMeasuredHeight();
- mSyncQueue.runInSync(t -> t.setPosition(leash, positionX, positionY));
+ updateSurfacePosition(leash, positionX, positionY);
+ }
+
+ private void updateSurfacePosition(SurfaceControl leash, int positionX, int positionY) {
+ mSyncQueue.runInSync(t -> {
+ t.setPosition(leash, positionX, positionY);
+ // The size compat UI should be the topmost child of the Task in case there can be more
+ // than one children.
+ t.setLayer(leash, Integer.MAX_VALUE);
+ });
}
int getDisplayId() {
diff --git a/libs/androidfw/ApkAssets.cpp b/libs/androidfw/ApkAssets.cpp
index 9c743cea592a..76366fce2aea 100755
--- a/libs/androidfw/ApkAssets.cpp
+++ b/libs/androidfw/ApkAssets.cpp
@@ -156,7 +156,11 @@ std::unique_ptr<ApkAssets> ApkAssets::LoadImpl(std::unique_ptr<Asset> resources_
std::move(loaded_idmap)));
}
-const std::string& ApkAssets::GetPath() const {
+std::optional<std::string_view> ApkAssets::GetPath() const {
+ return assets_provider_->GetPath();
+}
+
+const std::string& ApkAssets::GetDebugName() const {
return assets_provider_->GetDebugName();
}
diff --git a/libs/androidfw/AssetManager2.cpp b/libs/androidfw/AssetManager2.cpp
index 36bde5ccf267..c0ef7be8b673 100644
--- a/libs/androidfw/AssetManager2.cpp
+++ b/libs/androidfw/AssetManager2.cpp
@@ -116,8 +116,10 @@ void AssetManager2::BuildDynamicRefTable() {
package_groups_.clear();
package_ids_.fill(0xff);
- // A mapping from apk assets path to the runtime package id of its first loaded package.
- std::unordered_map<std::string, uint8_t> apk_assets_package_ids;
+ // A mapping from path of apk assets that could be target packages of overlays to the runtime
+ // package id of its first loaded package. Overlays currently can only override resources in the
+ // first package in the target resource table.
+ std::unordered_map<std::string, uint8_t> target_assets_package_ids;
// Overlay resources are not directly referenced by an application so their resource ids
// can change throughout the application's lifetime. Assign overlay package ids last.
@@ -140,8 +142,8 @@ void AssetManager2::BuildDynamicRefTable() {
if (auto loaded_idmap = apk_assets->GetLoadedIdmap(); loaded_idmap != nullptr) {
// The target package must precede the overlay package in the apk assets paths in order
// to take effect.
- auto iter = apk_assets_package_ids.find(std::string(loaded_idmap->TargetApkPath()));
- if (iter == apk_assets_package_ids.end()) {
+ auto iter = target_assets_package_ids.find(std::string(loaded_idmap->TargetApkPath()));
+ if (iter == target_assets_package_ids.end()) {
LOG(INFO) << "failed to find target package for overlay "
<< loaded_idmap->OverlayApkPath();
} else {
@@ -205,7 +207,10 @@ void AssetManager2::BuildDynamicRefTable() {
package_name, static_cast<uint8_t>(entry.package_id));
}
- apk_assets_package_ids.insert(std::make_pair(apk_assets->GetPath(), package_id));
+ if (auto apk_assets_path = apk_assets->GetPath()) {
+ // Overlay target ApkAssets must have been created using path based load apis.
+ target_assets_package_ids.insert(std::make_pair(std::string(*apk_assets_path), package_id));
+ }
}
}
@@ -227,7 +232,7 @@ void AssetManager2::DumpToLog() const {
std::string list;
for (const auto& apk_assets : apk_assets_) {
- base::StringAppendF(&list, "%s,", apk_assets->GetPath().c_str());
+ base::StringAppendF(&list, "%s,", apk_assets->GetDebugName().c_str());
}
LOG(INFO) << "ApkAssets: " << list;
@@ -383,8 +388,8 @@ void AssetManager2::SetConfiguration(const ResTable_config& configuration) {
}
}
-std::set<std::string> AssetManager2::GetNonSystemOverlayPaths() const {
- std::set<std::string> non_system_overlays;
+std::set<const ApkAssets*> AssetManager2::GetNonSystemOverlays() const {
+ std::set<const ApkAssets*> non_system_overlays;
for (const PackageGroup& package_group : package_groups_) {
bool found_system_package = false;
for (const ConfiguredPackage& package : package_group.packages_) {
@@ -396,7 +401,7 @@ std::set<std::string> AssetManager2::GetNonSystemOverlayPaths() const {
if (!found_system_package) {
for (const ConfiguredOverlay& overlay : package_group.overlays_) {
- non_system_overlays.insert(apk_assets_[overlay.cookie]->GetPath());
+ non_system_overlays.insert(apk_assets_[overlay.cookie]);
}
}
}
@@ -408,7 +413,7 @@ base::expected<std::set<ResTable_config>, IOError> AssetManager2::GetResourceCon
bool exclude_system, bool exclude_mipmap) const {
ATRACE_NAME("AssetManager::GetResourceConfigurations");
const auto non_system_overlays =
- (exclude_system) ? GetNonSystemOverlayPaths() : std::set<std::string>();
+ (exclude_system) ? GetNonSystemOverlays() : std::set<const ApkAssets*>();
std::set<ResTable_config> configurations;
for (const PackageGroup& package_group : package_groups_) {
@@ -419,8 +424,8 @@ base::expected<std::set<ResTable_config>, IOError> AssetManager2::GetResourceCon
}
auto apk_assets = apk_assets_[package_group.cookies_[i]];
- if (exclude_system && apk_assets->IsOverlay()
- && non_system_overlays.find(apk_assets->GetPath()) == non_system_overlays.end()) {
+ if (exclude_system && apk_assets->IsOverlay() &&
+ non_system_overlays.find(apk_assets) == non_system_overlays.end()) {
// Exclude overlays that target system resources.
continue;
}
@@ -439,7 +444,7 @@ std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system,
ATRACE_NAME("AssetManager::GetResourceLocales");
std::set<std::string> locales;
const auto non_system_overlays =
- (exclude_system) ? GetNonSystemOverlayPaths() : std::set<std::string>();
+ (exclude_system) ? GetNonSystemOverlays() : std::set<const ApkAssets*>();
for (const PackageGroup& package_group : package_groups_) {
for (size_t i = 0; i < package_group.packages_.size(); i++) {
@@ -449,8 +454,8 @@ std::set<std::string> AssetManager2::GetResourceLocales(bool exclude_system,
}
auto apk_assets = apk_assets_[package_group.cookies_[i]];
- if (exclude_system && apk_assets->IsOverlay()
- && non_system_overlays.find(apk_assets->GetPath()) == non_system_overlays.end()) {
+ if (exclude_system && apk_assets->IsOverlay() &&
+ non_system_overlays.find(apk_assets) == non_system_overlays.end()) {
// Exclude overlays that target system resources.
continue;
}
@@ -491,7 +496,7 @@ std::unique_ptr<AssetDir> AssetManager2::OpenDir(const std::string& dirname) con
AssetDir::FileInfo info;
info.setFileName(String8(name.data(), name.size()));
info.setFileType(type);
- info.setSourceName(String8(apk_assets->GetPath().c_str()));
+ info.setSourceName(String8(apk_assets->GetDebugName().c_str()));
files->add(info);
};
@@ -846,7 +851,7 @@ std::string AssetManager2::GetLastResourceResolution() const {
}
log_stream << "\n\t" << prefix->second << ": " << *step.package_name << " ("
- << apk_assets_[step.cookie]->GetPath() << ")";
+ << apk_assets_[step.cookie]->GetDebugName() << ")";
if (!step.config_name.isEmpty()) {
log_stream << " -" << step.config_name;
}
@@ -1556,41 +1561,32 @@ base::expected<std::monostate, IOError> Theme::SetTo(const Theme& o) {
std::map<ApkAssetsCookie, SourceToDestinationRuntimePackageMap> src_asset_cookie_id_map;
// Determine which ApkAssets are loaded in both theme AssetManagers.
- std::vector<const ApkAssets*> src_assets = o.asset_manager_->GetApkAssets();
+ const auto src_assets = o.asset_manager_->GetApkAssets();
for (size_t i = 0; i < src_assets.size(); i++) {
const ApkAssets* src_asset = src_assets[i];
- std::vector<const ApkAssets*> dest_assets = asset_manager_->GetApkAssets();
+ const auto dest_assets = asset_manager_->GetApkAssets();
for (size_t j = 0; j < dest_assets.size(); j++) {
const ApkAssets* dest_asset = dest_assets[j];
+ if (src_asset != dest_asset) {
+ // ResourcesManager caches and reuses ApkAssets when the same apk must be present in
+ // multiple AssetManagers. Two ApkAssets point to the same version of the same resources
+ // if they are the same instance.
+ continue;
+ }
- // Map the runtime package of the source apk asset to the destination apk asset.
- if (src_asset->GetPath() == dest_asset->GetPath()) {
- const auto& src_packages = src_asset->GetLoadedArsc()->GetPackages();
- const auto& dest_packages = dest_asset->GetLoadedArsc()->GetPackages();
-
- SourceToDestinationRuntimePackageMap package_map;
-
- // The source and destination package should have the same number of packages loaded in
- // the same order.
- const size_t N = src_packages.size();
- CHECK(N == dest_packages.size())
- << " LoadedArsc " << src_asset->GetPath() << " differs number of packages.";
- for (size_t p = 0; p < N; p++) {
- auto& src_package = src_packages[p];
- auto& dest_package = dest_packages[p];
- CHECK(src_package->GetPackageName() == dest_package->GetPackageName())
- << " Package " << src_package->GetPackageName() << " differs in load order.";
-
- int src_package_id = o.asset_manager_->GetAssignedPackageId(src_package.get());
- int dest_package_id = asset_manager_->GetAssignedPackageId(dest_package.get());
- package_map[src_package_id] = dest_package_id;
- }
-
- src_to_dest_asset_cookies.insert(std::make_pair(i, j));
- src_asset_cookie_id_map.insert(std::make_pair(i, package_map));
- break;
+ // Map the package ids of the asset in the source AssetManager to the package ids of the
+ // asset in th destination AssetManager.
+ SourceToDestinationRuntimePackageMap package_map;
+ for (const auto& loaded_package : src_asset->GetLoadedArsc()->GetPackages()) {
+ const int src_package_id = o.asset_manager_->GetAssignedPackageId(loaded_package.get());
+ const int dest_package_id = asset_manager_->GetAssignedPackageId(loaded_package.get());
+ package_map[src_package_id] = dest_package_id;
}
+
+ src_to_dest_asset_cookies.insert(std::make_pair(i, j));
+ src_asset_cookie_id_map.insert(std::make_pair(i, package_map));
+ break;
}
}
diff --git a/libs/androidfw/AssetsProvider.cpp b/libs/androidfw/AssetsProvider.cpp
index f3c48f7f9fc8..0aaf0b359b60 100644
--- a/libs/androidfw/AssetsProvider.cpp
+++ b/libs/androidfw/AssetsProvider.cpp
@@ -261,6 +261,13 @@ std::optional<uint32_t> ZipAssetsProvider::GetCrc(std::string_view path) const {
return entry.crc32;
}
+std::optional<std::string_view> ZipAssetsProvider::GetPath() const {
+ if (name_.GetPath() != nullptr) {
+ return *name_.GetPath();
+ }
+ return {};
+}
+
const std::string& ZipAssetsProvider::GetDebugName() const {
return name_.GetDebugName();
}
@@ -318,6 +325,10 @@ bool DirectoryAssetsProvider::ForEachFile(
return true;
}
+std::optional<std::string_view> DirectoryAssetsProvider::GetPath() const {
+ return dir_;
+}
+
const std::string& DirectoryAssetsProvider::GetDebugName() const {
return dir_;
}
@@ -336,13 +347,9 @@ MultiAssetsProvider::MultiAssetsProvider(std::unique_ptr<AssetsProvider>&& prima
std::unique_ptr<AssetsProvider>&& secondary)
: primary_(std::forward<std::unique_ptr<AssetsProvider>>(primary)),
secondary_(std::forward<std::unique_ptr<AssetsProvider>>(secondary)) {
- if (primary_->GetDebugName() == kEmptyDebugString) {
- debug_name_ = secondary_->GetDebugName();
- } else if (secondary_->GetDebugName() == kEmptyDebugString) {
- debug_name_ = primary_->GetDebugName();
- } else {
- debug_name_ = primary_->GetDebugName() + " and " + secondary_->GetDebugName();
- }
+ debug_name_ = primary_->GetDebugName() + " and " + secondary_->GetDebugName();
+ path_ = (primary_->GetDebugName() != kEmptyDebugString) ? primary_->GetPath()
+ : secondary_->GetPath();
}
std::unique_ptr<AssetsProvider> MultiAssetsProvider::Create(
@@ -367,6 +374,10 @@ bool MultiAssetsProvider::ForEachFile(const std::string& root_path,
return primary_->ForEachFile(root_path, f) && secondary_->ForEachFile(root_path, f);
}
+std::optional<std::string_view> MultiAssetsProvider::GetPath() const {
+ return path_;
+}
+
const std::string& MultiAssetsProvider::GetDebugName() const {
return debug_name_;
}
@@ -394,6 +405,10 @@ bool EmptyAssetsProvider::ForEachFile(
return true;
}
+std::optional<std::string_view> EmptyAssetsProvider::GetPath() const {
+ return {};
+}
+
const std::string& EmptyAssetsProvider::GetDebugName() const {
const static std::string kEmpty = kEmptyDebugString;
return kEmpty;
diff --git a/libs/androidfw/include/androidfw/ApkAssets.h b/libs/androidfw/include/androidfw/ApkAssets.h
index d0019ed6be30..6f88f41976cd 100644
--- a/libs/androidfw/include/androidfw/ApkAssets.h
+++ b/libs/androidfw/include/androidfw/ApkAssets.h
@@ -34,7 +34,6 @@ namespace android {
// Holds an APK.
class ApkAssets {
public:
-
// Creates an ApkAssets from a path on device.
static std::unique_ptr<ApkAssets> Load(const std::string& path,
package_property_t flags = 0U);
@@ -61,12 +60,11 @@ class ApkAssets {
static std::unique_ptr<ApkAssets> LoadOverlay(const std::string& idmap_path,
package_property_t flags = 0U);
- // TODO(177101983): Remove all uses of GetPath for checking whether two ApkAssets are the same.
- // With the introduction of ResourcesProviders, not all ApkAssets have paths. This could cause
- // bugs when path is used for comparison because multiple ApkAssets could have the same "firendly
- // name". Use pointer equality instead. ResourceManager caches and reuses ApkAssets so the
- // same asset should have the same pointer.
- const std::string& GetPath() const;
+ // Path to the contents of the ApkAssets on disk. The path could represent an APk, a directory,
+ // or some other file type.
+ std::optional<std::string_view> GetPath() const;
+
+ const std::string& GetDebugName() const;
const AssetsProvider* GetAssetsProvider() const {
return assets_provider_.get();
diff --git a/libs/androidfw/include/androidfw/AssetManager2.h b/libs/androidfw/include/androidfw/AssetManager2.h
index 2255973f1039..119f531b8634 100644
--- a/libs/androidfw/include/androidfw/AssetManager2.h
+++ b/libs/androidfw/include/androidfw/AssetManager2.h
@@ -412,7 +412,7 @@ class AssetManager2 {
void RebuildFilterList();
// Retrieves the APK paths of overlays that overlay non-system packages.
- std::set<std::string> GetNonSystemOverlayPaths() const;
+ std::set<const ApkAssets*> GetNonSystemOverlays() const;
// AssetManager2::GetBag(resid) wraps this function to track which resource ids have already
// been seen while traversing bag parents.
diff --git a/libs/androidfw/include/androidfw/AssetsProvider.h b/libs/androidfw/include/androidfw/AssetsProvider.h
index 6f16ff453905..63bbdcc9698d 100644
--- a/libs/androidfw/include/androidfw/AssetsProvider.h
+++ b/libs/androidfw/include/androidfw/AssetsProvider.h
@@ -48,6 +48,10 @@ struct AssetsProvider {
virtual bool ForEachFile(const std::string& path,
const std::function<void(const StringPiece&, FileType)>& f) const = 0;
+ // Retrieves the path to the contents of the AssetsProvider on disk. The path could represent an
+ // APk, a directory, or some other file type.
+ WARN_UNUSED virtual std::optional<std::string_view> GetPath() const = 0;
+
// Retrieves a name that represents the interface. This may or may not be the path of the
// interface source.
WARN_UNUSED virtual const std::string& GetDebugName() const = 0;
@@ -85,9 +89,9 @@ struct ZipAssetsProvider : public AssetsProvider {
bool ForEachFile(const std::string& root_path,
const std::function<void(const StringPiece&, FileType)>& f) const override;
+ WARN_UNUSED std::optional<std::string_view> GetPath() const override;
WARN_UNUSED const std::string& GetDebugName() const override;
WARN_UNUSED bool IsUpToDate() const override;
-
WARN_UNUSED std::optional<uint32_t> GetCrc(std::string_view path) const;
~ZipAssetsProvider() override = default;
@@ -125,6 +129,7 @@ struct DirectoryAssetsProvider : public AssetsProvider {
bool ForEachFile(const std::string& path,
const std::function<void(const StringPiece&, FileType)>& f) const override;
+ WARN_UNUSED std::optional<std::string_view> GetPath() const override;
WARN_UNUSED const std::string& GetDebugName() const override;
WARN_UNUSED bool IsUpToDate() const override;
@@ -149,6 +154,7 @@ struct MultiAssetsProvider : public AssetsProvider {
bool ForEachFile(const std::string& root_path,
const std::function<void(const StringPiece&, FileType)>& f) const override;
+ WARN_UNUSED std::optional<std::string_view> GetPath() const override;
WARN_UNUSED const std::string& GetDebugName() const override;
WARN_UNUSED bool IsUpToDate() const override;
@@ -163,6 +169,7 @@ struct MultiAssetsProvider : public AssetsProvider {
std::unique_ptr<AssetsProvider> primary_;
std::unique_ptr<AssetsProvider> secondary_;
+ std::optional<std::string_view> path_;
std::string debug_name_;
};
@@ -173,6 +180,7 @@ struct EmptyAssetsProvider : public AssetsProvider {
bool ForEachFile(const std::string& path,
const std::function<void(const StringPiece&, FileType)>& f) const override;
+ WARN_UNUSED std::optional<std::string_view> GetPath() const override;
WARN_UNUSED const std::string& GetDebugName() const override;
WARN_UNUSED bool IsUpToDate() const override;
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
index e620dfbafa08..8b448877c15b 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceDiscoveryService.java
@@ -107,12 +107,10 @@ public class CompanionDeviceDiscoveryService extends Service {
String callingPackage,
IFindDeviceCallback findCallback,
AndroidFuture serviceCallback) {
- if (DEBUG) {
- Log.i(LOG_TAG,
- "startDiscovery() called with: filter = [" + request
- + "], findCallback = [" + findCallback + "]"
- + "], serviceCallback = [" + serviceCallback + "]");
- }
+ Log.i(LOG_TAG,
+ "startDiscovery() called with: filter = [" + request
+ + "], findCallback = [" + findCallback + "]"
+ + "], serviceCallback = [" + serviceCallback + "]");
mFindCallback = findCallback;
mServiceCallback = serviceCallback;
Handler.getMain().sendMessage(obtainMessage(
@@ -127,7 +125,7 @@ public class CompanionDeviceDiscoveryService extends Service {
@Override
public IBinder onBind(Intent intent) {
- if (DEBUG) Log.i(LOG_TAG, "onBind(" + intent + ")");
+ Log.i(LOG_TAG, "onBind(" + intent + ")");
return mBinder.asBinder();
}
@@ -135,7 +133,7 @@ public class CompanionDeviceDiscoveryService extends Service {
public void onCreate() {
super.onCreate();
- if (DEBUG) Log.i(LOG_TAG, "onCreate()");
+ Log.i(LOG_TAG, "onCreate()");
mBluetoothManager = getSystemService(BluetoothManager.class);
mBluetoothAdapter = mBluetoothManager.getAdapter();
@@ -160,7 +158,9 @@ public class CompanionDeviceDiscoveryService extends Service {
= CollectionUtils.map(mBLEFilters, BluetoothLeDeviceFilter::getScanFilter);
reset();
- } else if (DEBUG) Log.i(LOG_TAG, "startDiscovery: duplicate request: " + request);
+ } else {
+ Log.i(LOG_TAG, "startDiscovery: duplicate request: " + request);
+ }
if (!ArrayUtils.isEmpty(mDevicesFound)) {
onReadyToShowUI();
@@ -197,17 +197,20 @@ public class CompanionDeviceDiscoveryService extends Service {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
+ Log.i(LOG_TAG, "registerReceiver(BluetoothDevice.ACTION_FOUND)");
mBluetoothBroadcastReceiver = new BluetoothBroadcastReceiver();
registerReceiver(mBluetoothBroadcastReceiver, intentFilter);
mBluetoothAdapter.startDiscovery();
}
if (shouldScan(mBLEFilters) && mBLEScanner != null) {
+ Log.i(LOG_TAG, "BLEScanner.startScan");
mBLEScanCallback = new BLEScanCallback();
mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
}
if (shouldScan(mWifiFilters)) {
+ Log.i(LOG_TAG, "registerReceiver(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)");
mWifiBroadcastReceiver = new WifiBroadcastReceiver();
registerReceiver(mWifiBroadcastReceiver,
new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
@@ -225,7 +228,7 @@ public class CompanionDeviceDiscoveryService extends Service {
@MainThread
private void reset() {
- if (DEBUG) Log.i(LOG_TAG, "reset()");
+ Log.i(LOG_TAG, "reset()");
stopScan();
mDevicesFound.clear();
mSelectedDevice = null;
@@ -234,12 +237,13 @@ public class CompanionDeviceDiscoveryService extends Service {
@Override
public boolean onUnbind(Intent intent) {
+ Log.i(LOG_TAG, "onUnbind(intent = " + intent + ")");
stopScan();
return super.onUnbind(intent);
}
private void stopScan() {
- if (DEBUG) Log.i(LOG_TAG, "stopScan()");
+ Log.i(LOG_TAG, "stopScan()");
if (!mIsScanning) return;
mIsScanning = false;
diff --git a/core/java/android/net/QosFilterParcelable.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl
index 312d6352ee92..312d6352ee92 100644
--- a/core/java/android/net/QosFilterParcelable.aidl
+++ b/packages/Connectivity/framework/aidl-export/android/net/QosFilterParcelable.aidl
diff --git a/core/java/android/net/QosSession.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl
index c2cf36624b55..c2cf36624b55 100644
--- a/core/java/android/net/QosSession.aidl
+++ b/packages/Connectivity/framework/aidl-export/android/net/QosSession.aidl
diff --git a/core/java/android/net/QosSocketInfo.aidl b/packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl
index 476c0900e23e..476c0900e23e 100644
--- a/core/java/android/net/QosSocketInfo.aidl
+++ b/packages/Connectivity/framework/aidl-export/android/net/QosSocketInfo.aidl
diff --git a/packages/Connectivity/framework/api/current.txt b/packages/Connectivity/framework/api/current.txt
index 31b8fc8ae53a..a8f1a4d2a7f8 100644
--- a/packages/Connectivity/framework/api/current.txt
+++ b/packages/Connectivity/framework/api/current.txt
@@ -401,16 +401,6 @@ package android.net {
method public android.net.NetworkRequest.Builder setNetworkSpecifier(android.net.NetworkSpecifier);
}
- public final class Proxy {
- ctor public Proxy();
- method @Deprecated public static String getDefaultHost();
- method @Deprecated public static int getDefaultPort();
- method @Deprecated public static String getHost(android.content.Context);
- method @Deprecated public static int getPort(android.content.Context);
- field @Deprecated public static final String EXTRA_PROXY_INFO = "android.intent.extra.PROXY_INFO";
- field public static final String PROXY_CHANGE_ACTION = "android.intent.action.PROXY_CHANGE";
- }
-
public class ProxyInfo implements android.os.Parcelable {
ctor public ProxyInfo(@Nullable android.net.ProxyInfo);
method public static android.net.ProxyInfo buildDirectProxy(String, int);
diff --git a/packages/Connectivity/framework/api/module-lib-current.txt b/packages/Connectivity/framework/api/module-lib-current.txt
index 3af855ec1e11..a9fd6f248560 100644
--- a/packages/Connectivity/framework/api/module-lib-current.txt
+++ b/packages/Connectivity/framework/api/module-lib-current.txt
@@ -23,10 +23,6 @@ package android.net {
field public static final int TRANSPORT_TEST = 7; // 0x7
}
- public final class Proxy {
- method public static void setHttpProxyConfiguration(@Nullable android.net.ProxyInfo);
- }
-
public final class TcpRepairWindow {
ctor public TcpRepairWindow(int, int, int, int, int, int);
field public final int maxWindow;
diff --git a/packages/Connectivity/framework/api/system-current.txt b/packages/Connectivity/framework/api/system-current.txt
index 41ebc5774f3d..373fa3c24027 100644
--- a/packages/Connectivity/framework/api/system-current.txt
+++ b/packages/Connectivity/framework/api/system-current.txt
@@ -308,6 +308,9 @@ package android.net {
field public static final int ID_NONE = -1; // 0xffffffff
}
+ public class NetworkReleasedException extends java.lang.Exception {
+ }
+
public class NetworkRequest implements android.os.Parcelable {
method @Nullable public String getRequestorPackageName();
method public int getRequestorUid();
@@ -317,6 +320,47 @@ package android.net {
method @NonNull @RequiresPermission(android.Manifest.permission.NETWORK_SIGNAL_STRENGTH_WAKEUP) public android.net.NetworkRequest.Builder setSignalStrength(int);
}
+ public abstract class QosCallback {
+ ctor public QosCallback();
+ method public void onError(@NonNull android.net.QosCallbackException);
+ method public void onQosSessionAvailable(@NonNull android.net.QosSession, @NonNull android.net.QosSessionAttributes);
+ method public void onQosSessionLost(@NonNull android.net.QosSession);
+ }
+
+ public static class QosCallback.QosCallbackRegistrationException extends java.lang.RuntimeException {
+ }
+
+ public final class QosCallbackException extends java.lang.Exception {
+ }
+
+ public abstract class QosFilter {
+ method @NonNull public abstract android.net.Network getNetwork();
+ method public abstract boolean matchesLocalAddress(@NonNull java.net.InetAddress, int, int);
+ }
+
+ public final class QosSession implements android.os.Parcelable {
+ ctor public QosSession(int, int);
+ method public int describeContents();
+ method public int getSessionId();
+ method public int getSessionType();
+ method public long getUniqueId();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSession> CREATOR;
+ field public static final int TYPE_EPS_BEARER = 1; // 0x1
+ }
+
+ public interface QosSessionAttributes {
+ }
+
+ public final class QosSocketInfo implements android.os.Parcelable {
+ ctor public QosSocketInfo(@NonNull android.net.Network, @NonNull java.net.Socket) throws java.io.IOException;
+ method public int describeContents();
+ method @NonNull public java.net.InetSocketAddress getLocalSocketAddress();
+ method @NonNull public android.net.Network getNetwork();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
+ field @NonNull public static final android.os.Parcelable.Creator<android.net.QosSocketInfo> CREATOR;
+ }
+
public final class RouteInfo implements android.os.Parcelable {
ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int);
ctor public RouteInfo(@Nullable android.net.IpPrefix, @Nullable java.net.InetAddress, @Nullable String, int, int);
@@ -331,6 +375,12 @@ package android.net {
field public static final int SUCCESS = 0; // 0x0
}
+ public class SocketLocalAddressChangedException extends java.lang.Exception {
+ }
+
+ public class SocketNotBoundException extends java.lang.Exception {
+ }
+
public final class StaticIpConfiguration implements android.os.Parcelable {
ctor public StaticIpConfiguration();
ctor public StaticIpConfiguration(@Nullable android.net.StaticIpConfiguration);
@@ -392,16 +442,3 @@ package android.net.apf {
}
-package android.net.util {
-
- public final class SocketUtils {
- method public static void bindSocketToInterface(@NonNull java.io.FileDescriptor, @NonNull String) throws android.system.ErrnoException;
- method public static void closeSocket(@Nullable java.io.FileDescriptor) throws java.io.IOException;
- method @NonNull public static java.net.SocketAddress makeNetlinkSocketAddress(int, int);
- method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int);
- method @Deprecated @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, @NonNull byte[]);
- method @NonNull public static java.net.SocketAddress makePacketSocketAddress(int, int, @NonNull byte[]);
- }
-
-}
-
diff --git a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
index e7ab0a1c7ac8..39ec2edcea3f 100644
--- a/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
+++ b/packages/Connectivity/framework/src/android/net/ConnectivityManager.java
@@ -2245,31 +2245,6 @@ public class ConnectivityManager {
}
}
- /* TODO: These permissions checks don't belong in client-side code. Move them to
- * services.jar, possibly in com.android.server.net. */
-
- /** {@hide} */
- public static final void enforceChangePermission(Context context,
- String callingPkg, String callingAttributionTag) {
- int uid = Binder.getCallingUid();
- checkAndNoteChangeNetworkStateOperation(context, uid, callingPkg,
- callingAttributionTag, true /* throwException */);
- }
-
- /**
- * Check if the package is a allowed to change the network state. This also accounts that such
- * an access happened.
- *
- * @return {@code true} iff the package is allowed to change the network state.
- */
- // TODO: Remove method and replace with direct call once R code is pushed to AOSP
- private static boolean checkAndNoteChangeNetworkStateOperation(@NonNull Context context,
- int uid, @NonNull String callingPackage, @Nullable String callingAttributionTag,
- boolean throwException) {
- return Settings.checkAndNoteChangeNetworkStateOperation(context, uid, callingPackage,
- callingAttributionTag, throwException);
- }
-
/**
* Check if the package is a allowed to write settings. This also accounts that such an access
* happened.
diff --git a/core/java/android/net/IOnSetOemNetworkPreferenceListener.aidl b/packages/Connectivity/framework/src/android/net/IOnSetOemNetworkPreferenceListener.aidl
index 7979afc54f90..7979afc54f90 100644
--- a/core/java/android/net/IOnSetOemNetworkPreferenceListener.aidl
+++ b/packages/Connectivity/framework/src/android/net/IOnSetOemNetworkPreferenceListener.aidl
diff --git a/core/java/android/net/IQosCallback.aidl b/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
index 91c75759f85c..91c75759f85c 100644
--- a/core/java/android/net/IQosCallback.aidl
+++ b/packages/Connectivity/framework/src/android/net/IQosCallback.aidl
diff --git a/core/java/android/net/NetworkReleasedException.java b/packages/Connectivity/framework/src/android/net/NetworkReleasedException.java
index 0629b7563aea..0629b7563aea 100644
--- a/core/java/android/net/NetworkReleasedException.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkReleasedException.java
diff --git a/packages/Connectivity/framework/src/android/net/NetworkUtils.java b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
index b5e8a614b8ea..9e42bbecbe9d 100644
--- a/packages/Connectivity/framework/src/android/net/NetworkUtils.java
+++ b/packages/Connectivity/framework/src/android/net/NetworkUtils.java
@@ -87,22 +87,6 @@ public class NetworkUtils {
public static native int bindSocketToNetwork(FileDescriptor fd, int netId);
/**
- * Protect {@code fd} from VPN connections. After protecting, data sent through
- * this socket will go directly to the underlying network, so its traffic will not be
- * forwarded through the VPN.
- */
- @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553,
- publicAlternatives = "Use {@link android.net.VpnService#protect} instead.")
- public static native boolean protectFromVpn(FileDescriptor fd);
-
- /**
- * Protect {@code socketfd} from VPN connections. After protecting, data sent through
- * this socket will go directly to the underlying network, so its traffic will not be
- * forwarded through the VPN.
- */
- public native static boolean protectFromVpn(int socketfd);
-
- /**
* Determine if {@code uid} can access network designated by {@code netId}.
* @return {@code true} if {@code uid} can access network, {@code false} otherwise.
*/
diff --git a/core/java/android/net/QosCallback.java b/packages/Connectivity/framework/src/android/net/QosCallback.java
index 22f06bc0e690..22f06bc0e690 100644
--- a/core/java/android/net/QosCallback.java
+++ b/packages/Connectivity/framework/src/android/net/QosCallback.java
diff --git a/core/java/android/net/QosCallbackConnection.java b/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
index bdb4ad68cd7b..bdb4ad68cd7b 100644
--- a/core/java/android/net/QosCallbackConnection.java
+++ b/packages/Connectivity/framework/src/android/net/QosCallbackConnection.java
diff --git a/core/java/android/net/QosCallbackException.java b/packages/Connectivity/framework/src/android/net/QosCallbackException.java
index 7fd9a527e2ac..7fd9a527e2ac 100644
--- a/core/java/android/net/QosCallbackException.java
+++ b/packages/Connectivity/framework/src/android/net/QosCallbackException.java
diff --git a/core/java/android/net/QosFilter.java b/packages/Connectivity/framework/src/android/net/QosFilter.java
index ab55002e02b3..ab55002e02b3 100644
--- a/core/java/android/net/QosFilter.java
+++ b/packages/Connectivity/framework/src/android/net/QosFilter.java
diff --git a/core/java/android/net/QosFilterParcelable.java b/packages/Connectivity/framework/src/android/net/QosFilterParcelable.java
index da3b2cf8ff7a..da3b2cf8ff7a 100644
--- a/core/java/android/net/QosFilterParcelable.java
+++ b/packages/Connectivity/framework/src/android/net/QosFilterParcelable.java
diff --git a/core/java/android/net/QosSession.java b/packages/Connectivity/framework/src/android/net/QosSession.java
index 4f3bb77c5877..4f3bb77c5877 100644
--- a/core/java/android/net/QosSession.java
+++ b/packages/Connectivity/framework/src/android/net/QosSession.java
diff --git a/core/java/android/net/QosSessionAttributes.java b/packages/Connectivity/framework/src/android/net/QosSessionAttributes.java
index 7a885942d1b5..7a885942d1b5 100644
--- a/core/java/android/net/QosSessionAttributes.java
+++ b/packages/Connectivity/framework/src/android/net/QosSessionAttributes.java
diff --git a/core/java/android/net/QosSocketFilter.java b/packages/Connectivity/framework/src/android/net/QosSocketFilter.java
index 2080e68f5fba..2080e68f5fba 100644
--- a/core/java/android/net/QosSocketFilter.java
+++ b/packages/Connectivity/framework/src/android/net/QosSocketFilter.java
diff --git a/core/java/android/net/QosSocketInfo.java b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
index d37c4691ddde..d37c4691ddde 100644
--- a/core/java/android/net/QosSocketInfo.java
+++ b/packages/Connectivity/framework/src/android/net/QosSocketInfo.java
diff --git a/core/java/android/net/SocketLocalAddressChangedException.java b/packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java
index 9daad83fd13e..9daad83fd13e 100644
--- a/core/java/android/net/SocketLocalAddressChangedException.java
+++ b/packages/Connectivity/framework/src/android/net/SocketLocalAddressChangedException.java
diff --git a/core/java/android/net/SocketNotBoundException.java b/packages/Connectivity/framework/src/android/net/SocketNotBoundException.java
index b1d7026ac981..b1d7026ac981 100644
--- a/core/java/android/net/SocketNotBoundException.java
+++ b/packages/Connectivity/framework/src/android/net/SocketNotBoundException.java
diff --git a/core/java/android/net/UidRange.aidl b/packages/Connectivity/framework/src/android/net/UidRange.aidl
index f70fc8e2fefd..f70fc8e2fefd 100644
--- a/core/java/android/net/UidRange.aidl
+++ b/packages/Connectivity/framework/src/android/net/UidRange.aidl
diff --git a/core/java/android/net/UidRange.java b/packages/Connectivity/framework/src/android/net/UidRange.java
index f0e7da78d669..26518d32edcb 100644
--- a/core/java/android/net/UidRange.java
+++ b/packages/Connectivity/framework/src/android/net/UidRange.java
@@ -16,8 +16,6 @@
package android.net;
-import static android.os.UserHandle.PER_USER_RANGE;
-
import android.annotation.Nullable;
import android.os.Parcel;
import android.os.Parcelable;
@@ -52,14 +50,15 @@ public final class UidRange implements Parcelable {
/** Returns the smallest user Id which is contained in this UidRange */
public int getStartUser() {
- return start / PER_USER_RANGE;
+ return UserHandle.getUserHandleForUid(start).getIdentifier();
}
/** Returns the largest user Id which is contained in this UidRange */
public int getEndUser() {
- return stop / PER_USER_RANGE;
+ return UserHandle.getUserHandleForUid(stop).getIdentifier();
}
+ /** Returns whether the UidRange contains the specified UID. */
public boolean contains(int uid) {
return start <= uid && uid <= stop;
}
@@ -72,7 +71,7 @@ public final class UidRange implements Parcelable {
}
/**
- * @return {@code true} if this range contains every UID contained by the {@param other} range.
+ * @return {@code true} if this range contains every UID contained by the {@code other} range.
*/
public boolean containsRange(UidRange other) {
return start <= other.start && other.stop <= stop;
@@ -118,18 +117,18 @@ public final class UidRange implements Parcelable {
}
public static final @android.annotation.NonNull Creator<UidRange> CREATOR =
- new Creator<UidRange>() {
- @Override
- public UidRange createFromParcel(Parcel in) {
- int start = in.readInt();
- int stop = in.readInt();
+ new Creator<UidRange>() {
+ @Override
+ public UidRange createFromParcel(Parcel in) {
+ int start = in.readInt();
+ int stop = in.readInt();
- return new UidRange(start, stop);
- }
- @Override
- public UidRange[] newArray(int size) {
- return new UidRange[size];
- }
+ return new UidRange(start, stop);
+ }
+ @Override
+ public UidRange[] newArray(int size) {
+ return new UidRange[size];
+ }
};
/**
diff --git a/packages/Connectivity/service/Android.bp b/packages/Connectivity/service/Android.bp
index f20b89fb842c..e65b7b423bdc 100644
--- a/packages/Connectivity/service/Android.bp
+++ b/packages/Connectivity/service/Android.bp
@@ -63,6 +63,7 @@ java_library {
"unsupportedappusage",
],
static_libs: [
+ "modules-utils-os",
"net-utils-device-common",
"net-utils-framework-common",
"netd-client",
diff --git a/packages/Connectivity/service/jarjar-rules.txt b/packages/Connectivity/service/jarjar-rules.txt
index ef53ebb43c40..d8205bf780fd 100644
--- a/packages/Connectivity/service/jarjar-rules.txt
+++ b/packages/Connectivity/service/jarjar-rules.txt
@@ -1 +1,2 @@
-rule com.android.net.module.util.** com.android.connectivity.util.@1 \ No newline at end of file
+rule com.android.net.module.util.** com.android.connectivity.net-utils.@1
+rule com.android.modules.utils.** com.android.connectivity.modules-utils.@1 \ No newline at end of file
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
index ecd40667843e..f9584a3e15e9 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/EditUserPhotoController.java
@@ -38,6 +38,7 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.ContactsContract.DisplayPhoto;
import android.provider.MediaStore;
+import android.util.EventLog;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
@@ -126,6 +127,14 @@ public class EditUserPhotoController {
}
final Uri pictureUri = data != null && data.getData() != null
? data.getData() : mTakePictureUri;
+
+ // Check if the result is a content uri
+ if (!ContentResolver.SCHEME_CONTENT.equals(pictureUri.getScheme())) {
+ Log.e(TAG, "Invalid pictureUri scheme: " + pictureUri.getScheme());
+ EventLog.writeEvent(0x534e4554, "172939189", -1, pictureUri.getPath());
+ return false;
+ }
+
switch (requestCode) {
case REQUEST_CODE_CROP_PHOTO:
onPhotoCropped(pictureUri);
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 71e09106368b..1393116a814e 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -164,6 +164,7 @@
<uses-permission android:name="android.permission.MANAGE_APP_PREDICTIONS" />
<uses-permission android:name="android.permission.MANAGE_SEARCH_UI" />
<uses-permission android:name="android.permission.MANAGE_SMARTSPACE" />
+ <uses-permission android:name="android.permission.MANAGE_UI_TRANSLATION" />
<uses-permission android:name="android.permission.NETWORK_SETTINGS" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.SET_TIME" />
diff --git a/packages/SystemUI/README.md b/packages/SystemUI/README.md
index 60994d892b6e..ee8d02301d5d 100644
--- a/packages/SystemUI/README.md
+++ b/packages/SystemUI/README.md
@@ -144,10 +144,6 @@ Biometric UI.
Delegates SysUI events to WM Shell controllers.
-### [com.android.systemui.people.widget.PeopleSpaceWidgetEnabler](/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java)
-
-Enables People Space widgets.
-
---
* [Plugins](/packages/SystemUI/docs/plugins.md)
diff --git a/packages/SystemUI/docs/media-controls-pipeline.png b/packages/SystemUI/docs/media-controls-pipeline.png
new file mode 100644
index 000000000000..e7408ad9fd4a
--- /dev/null
+++ b/packages/SystemUI/docs/media-controls-pipeline.png
Binary files differ
diff --git a/packages/SystemUI/docs/media-controls.md b/packages/SystemUI/docs/media-controls.md
new file mode 100644
index 000000000000..579f453a3a92
--- /dev/null
+++ b/packages/SystemUI/docs/media-controls.md
@@ -0,0 +1,94 @@
+# SysUI Media Controls Pipeline
+
+[TOC]
+
+## Purpose
+
+Describe how events flow through the media controls pipeline, and provide a high level overview of what the different components do.
+
+## Pipeline Diagram
+
+![media controls pipeline](media-controls-pipeline.png)
+
+* Orange: External inputs
+* Blue: Internal listeners; all except `MediaDataManager` and `ResumeMediaBrowser` implement [`MediaDataManager.Listener`](/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt#711) and receive `onMediaDataLoaded` and `onMediaDataRemoved` events
+
+## Classes
+
+Files under [`systemui/media/`](/packages/SystemUI/src/com/android/systemui/media/):
+
+* UI
+ * `dialog/`
+ * Output switcher dialog (maintained by Settings team)
+ * IlluminationDrawable.kt
+ * LightSourceDrawable.kt
+ * These create the glow animation when you tap on a button (see [`qs_media_light_source`](/packages/SystemUI/res/drawable/qs_media_light_source.xml)). Should be reusable in other layouts.
+ * Carousel:
+ * MediaCarouselController.kt
+ * Keeps the carousel view up to date and handles state changes (e.g. expansion)
+ * Handles settings gear and page indicator
+ * MediaCarouselScrollHandler.kt
+ * Handles scrolling between players in the carousel
+ * MediaScrollView.kt
+ * Scrollview used in the carousel layout, has some custom measurement code
+ * Individual players:
+ * KeyguardMediaController.kt
+ * Lockscreen media controls have a special wrapper in order to work with the existing lockscreen notification layout
+ * MediaControlPanel.java
+ * Main class for media control UI
+ * SeekBarObserver.kt
+ * Updates seekbar state
+ * SeekBarViewModel.kt
+ * Implements its own `computePosition()` for the seekbar (to avoid continually polling the `PlaybackState`, which involves binder calls)
+ * Does some touch falsing (ignore flings, require drags to start near the thumb - otherwise users would often accidentally trigger the seekbar when they meant to move the carousel or shade)
+ * PlayerViewHolder.kt
+ * Holds references to the UI elements in the panel
+* Animation support:
+ * MediaHierarchyManager.kt
+ * Responsible for placement of media view and animation between hosts
+ * MediaHost.kt
+ * Every location that a media player could be located needs a `MediaHost`
+ * Tracks configuration (if it should show inactive media, needs falsing, etc.)
+ * MediaHostStatesManager.kt
+ * Manages the various media host states and coordinates heights between different players
+ * Has the most up to date state for any location
+ * MediaViewController.kt
+ * Controls a single instance of a media player, keeps the media view states up to date
+* Backend
+ * MediaData.kt
+ * Holds all the media data (track info, active/resume state, etc.)
+ * MediaDataCombineLatest.kt
+ * Combines update events from `MediaDataManager` and `MediaDeviceManager`, so that downstream listeners will have device info
+ * MediaDataFilter.kt
+ * Filters media data based on the current user
+ * Exit point for the pipeline: "external listeners" (currently `MediaHost` and `MediaCarouselController`), while they should be added via `MediaDataManager.addListener()`, will actually be listening to this output
+ * MediaDataManager.kt
+ * Entry point for the pipeline; initializes listener connections and assigns external listeners to the correct exit point
+ * Converts media notifications and resumable media info into `MediaData`
+ * MediaDeviceManager.kt
+ * Handles device updates
+ * MediaFeatureFlag.kt
+ * Utility to check whether media controls are enabled
+ * MediaSessionBasedFilter.kt
+ * Filters media events based on media session. This prevents duplicate controls in situations like casting where we might get both a local and remote object for the same media session.
+ * MediaTimeoutListener.kt
+ * Listens to `PlaybackState` and marks controls inactive after the media has been paused/stopped for 10 minutes (value can be adjusted locally with `adb shell setprop debug.sysui.media_timeout [ms]`)
+ * MediaResumeListener.kt
+ * Listens for new media data and attempts to find a valid `MediaBrowserService` for the app. If successful, sends the information back to the `MediaDataManager`
+ * Saves up to 5 valid `MediaBrowserService` components found this way, and queries them for recent media on boot or user change
+ * Note: the user can disable this feature completely (or block certain apps from being resumable) in [Settings](https://source.corp.google.com/android/packages/apps/Settings/src/com/android/settings/sound/ResumableMediaAppsController.java), in which case this listener will do nothing (or ignore updates from the blocked apps).
+ * ResumeMediaBrowser.java
+ * Connects to an app's [`MediaBrowser`](https://developer.android.com/reference/android/media/browse/MediaBrowser) to determine whether SystemUI is able to connect and find a recent [`MediaItem`](https://developer.android.com/reference/android/media/browse/MediaBrowser.MediaItem)
+* Factory classes (for unit testing):
+ * LocalMediaManagerFactory.kt
+ * MediaBrowserFactory.java
+ * MediaControllerFactory.java
+ * ResumeMediaBrowserFactory.java
+
+## Miscellaneous
+
+Other useful documents:
+
+* [go/sysui-media-resumption-requirements](https://goto.google.com/sysui-media-resumption-requirements) - Internal documentation for app developers about how to work with media resumption
+* [Playing nicely with media controls](https://android-developers.googleblog.com/2020/08/playing-nicely-with-media-controls.html) - blog post on the Android 11 updates
+* [Media Controls developer guide](https://developer.android.com/guide/topics/media/media-controls)
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml
index 79868093fb12..71cdaf5c7091 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_bouncer.xml
@@ -24,7 +24,7 @@
<include
style="@style/BouncerSecurityContainer"
layout="@layout/keyguard_host_view"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content" />
</FrameLayout>
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml
index 04e645bd0a32..1e142eaeef86 100644
--- a/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml
+++ b/packages/SystemUI/res-keyguard/layout/keyguard_host_view.xml
@@ -41,13 +41,14 @@
android:layout_gravity="center">
<com.android.keyguard.KeyguardSecurityViewFlipper
android:id="@+id/view_flipper"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="match_parent"
android:clipChildren="false"
android:clipToPadding="false"
android:paddingTop="@dimen/keyguard_security_view_top_margin"
android:paddingStart="@dimen/keyguard_security_view_lateral_margin"
android:paddingEnd="@dimen/keyguard_security_view_lateral_margin"
+ android:layout_gravity="center"
android:gravity="center">
</com.android.keyguard.KeyguardSecurityViewFlipper>
</com.android.keyguard.KeyguardSecurityContainer>
diff --git a/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml b/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml
new file mode 100644
index 000000000000..e09bf7e37ed0
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/values-sw600dp-land/bools.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2021 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>
+ <bool name="can_use_one_handed_bouncer">true</bool>
+</resources>
diff --git a/packages/SystemUI/res-keyguard/values/config.xml b/packages/SystemUI/res-keyguard/values/config.xml
index 8d9d6ee68c67..6176f7c1dd0a 100644
--- a/packages/SystemUI/res-keyguard/values/config.xml
+++ b/packages/SystemUI/res-keyguard/values/config.xml
@@ -22,4 +22,5 @@
<!-- Allow the menu hard key to be disabled in LockScreen on some devices [DO NOT TRANSLATE] -->
<bool name="config_disableMenuKeyInLockScreen">false</bool>
+ <bool name="can_use_one_handed_bouncer">false</bool>
</resources>
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 187ae58c2f2c..cf9de5e7e226 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -85,10 +85,10 @@
android:tint="?attr/wallpaperTextColor" />
<ImageView
- android:id="@+id/alt_left_button"
+ android:id="@+id/wallet_button"
android:layout_height="@dimen/keyguard_affordance_height"
android:layout_width="@dimen/keyguard_affordance_width"
- android:layout_gravity="bottom|start"
+ android:layout_gravity="bottom|end"
android:scaleType="center"
android:tint="?attr/wallpaperTextColor"
android:layout_marginStart="24dp"
diff --git a/packages/SystemUI/res/layout/long_screenshot.xml b/packages/SystemUI/res/layout/long_screenshot.xml
index e2f3e2a306e3..7ba28a8483c3 100644
--- a/packages/SystemUI/res/layout/long_screenshot.xml
+++ b/packages/SystemUI/res/layout/long_screenshot.xml
@@ -76,7 +76,6 @@
android:layout_height="wrap_content"
android:layout_marginBottom="42dp"
android:layout_marginHorizontal="48dp"
- android:adjustViewBounds="true"
app:layout_constrainedHeight="true"
app:layout_constrainedWidth="true"
app:layout_constraintTop_toBottomOf="@id/guideline"
@@ -110,6 +109,7 @@
android:visibility="invisible"
android:layout_width="200dp"
android:layout_height="200dp"
+ android:elevation="2dp"
app:layout_constraintTop_toBottomOf="@id/guideline"
app:layout_constraintLeft_toLeftOf="parent"
app:handleThickness="@dimen/screenshot_crop_handle_thickness"
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 0893c1488005..761512ce3d14 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -315,7 +315,6 @@
<item>com.android.systemui.accessibility.SystemActions</item>
<item>com.android.systemui.toast.ToastUI</item>
<item>com.android.systemui.wmshell.WMShell</item>
- <item>com.android.systemui.people.widget.PeopleSpaceWidgetEnabler</item>
</string-array>
<!-- QS tile shape store width. negative implies fill configuration instead of stroke-->
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index 5f6fd30ffa1b..a2d7707a1569 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -29,12 +29,17 @@ import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Insets;
import android.graphics.Rect;
+import android.provider.Settings;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.util.TypedValue;
+import android.view.Gravity;
import android.view.MotionEvent;
+import android.view.OrientationEventListener;
import android.view.VelocityTracker;
+import android.view.View;
import android.view.ViewConfiguration;
+import android.view.ViewPropertyAnimator;
import android.view.WindowInsets;
import android.view.WindowInsetsAnimation;
import android.view.WindowInsetsAnimationControlListener;
@@ -55,6 +60,7 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
+import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import java.util.List;
@@ -99,6 +105,12 @@ public class KeyguardSecurityContainer extends FrameLayout {
private boolean mDisappearAnimRunning;
private SwipeListener mSwipeListener;
+ private boolean mIsSecurityViewLeftAligned = true;
+ private boolean mOneHandedMode = false;
+ private SecurityMode mSecurityMode = SecurityMode.Invalid;
+ private ViewPropertyAnimator mRunningOneHandedAnimator;
+ private final OrientationEventListener mOrientationEventListener;
+
private final WindowInsetsAnimation.Callback mWindowInsetsAnimationCallback =
new WindowInsetsAnimation.Callback(DISPATCH_MODE_STOP) {
@@ -157,16 +169,20 @@ public class KeyguardSecurityContainer extends FrameLayout {
// Used to notify the container when something interesting happens.
public interface SecurityCallback {
boolean dismiss(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen);
+
void userActivity();
+
void onSecurityModeChanged(SecurityMode securityMode, boolean needsInput);
/**
- * @param strongAuth wheher the user has authenticated with strong authentication like
- * pattern, password or PIN but not by trust agents or fingerprint
+ * @param strongAuth wheher the user has authenticated with strong authentication like
+ * pattern, password or PIN but not by trust agents or fingerprint
* @param targetUserId a user that needs to be the foreground user at the finish completion.
*/
void finish(boolean strongAuth, int targetUserId);
+
void reset();
+
void onCancelClicked();
}
@@ -224,12 +240,136 @@ public class KeyguardSecurityContainer extends FrameLayout {
super(context, attrs, defStyle);
mSpringAnimation = new SpringAnimation(this, DynamicAnimation.Y);
mViewConfiguration = ViewConfiguration.get(context);
+
+ mOrientationEventListener = new OrientationEventListener(context) {
+ @Override
+ public void onOrientationChanged(int orientation) {
+ updateLayoutForSecurityMode(mSecurityMode);
+ }
+ };
}
void onResume(SecurityMode securityMode, boolean faceAuthEnabled) {
+ mSecurityMode = securityMode;
mSecurityViewFlipper.setWindowInsetsAnimationCallback(mWindowInsetsAnimationCallback);
updateBiometricRetry(securityMode, faceAuthEnabled);
+ updateLayoutForSecurityMode(securityMode);
+ mOrientationEventListener.enable();
+ }
+
+ void updateLayoutForSecurityMode(SecurityMode securityMode) {
+ mSecurityMode = securityMode;
+ mOneHandedMode = canUseOneHandedBouncer();
+
+ if (mOneHandedMode) {
+ mIsSecurityViewLeftAligned = isOneHandedKeyguardLeftAligned(mContext);
+ }
+
+ updateSecurityViewGravity();
+ updateSecurityViewLocation(false);
+ }
+
+ /** Return whether the one-handed keyguard should be enabled. */
+ private boolean canUseOneHandedBouncer() {
+ // Is it enabled?
+ if (!getResources().getBoolean(
+ com.android.internal.R.bool.config_enableOneHandedKeyguard)) {
+ return false;
+ }
+
+ if (!KeyguardSecurityModel.isSecurityViewOneHanded(mSecurityMode)) {
+ return false;
+ }
+
+ return getResources().getBoolean(R.bool.can_use_one_handed_bouncer);
+ }
+
+ /** Read whether the one-handed keyguard should be on the left/right from settings. */
+ private boolean isOneHandedKeyguardLeftAligned(Context context) {
+ try {
+ return Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.ONE_HANDED_KEYGUARD_SIDE)
+ == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT;
+ } catch (Settings.SettingNotFoundException ex) {
+ return true;
+ }
+ }
+
+ private void updateSecurityViewGravity() {
+ View securityView = findKeyguardSecurityView();
+
+ if (securityView == null) {
+ return;
+ }
+
+ FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) securityView.getLayoutParams();
+
+ if (mOneHandedMode) {
+ lp.gravity = Gravity.LEFT | Gravity.BOTTOM;
+ } else {
+ lp.gravity = Gravity.CENTER_HORIZONTAL;
+ }
+
+ securityView.setLayoutParams(lp);
+ }
+
+ /**
+ * Moves the inner security view to the correct location (in one handed mode) with animation.
+ * This is triggered when the user taps on the side of the screen that is not currently occupied
+ * by the security view .
+ */
+ private void updateSecurityViewLocation(boolean animate) {
+ View securityView = findKeyguardSecurityView();
+
+ if (securityView == null) {
+ return;
+ }
+
+ if (!mOneHandedMode) {
+ securityView.setTranslationX(0);
+ return;
+ }
+
+ if (mRunningOneHandedAnimator != null) {
+ mRunningOneHandedAnimator.cancel();
+ mRunningOneHandedAnimator = null;
+ }
+
+ int targetTranslation = mIsSecurityViewLeftAligned ? 0 : (int) (getMeasuredWidth() / 2f);
+
+ if (animate) {
+ mRunningOneHandedAnimator = securityView.animate().translationX(targetTranslation);
+ mRunningOneHandedAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
+ mRunningOneHandedAnimator.setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mRunningOneHandedAnimator = null;
+ }
+ });
+
+ mRunningOneHandedAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
+ mRunningOneHandedAnimator.start();
+ } else {
+ securityView.setTranslationX(targetTranslation);
+ }
+ }
+
+ @Nullable
+ private KeyguardSecurityViewFlipper findKeyguardSecurityView() {
+ for (int i = 0; i < getChildCount(); i++) {
+ View child = getChildAt(i);
+
+ if (isKeyguardSecurityView(child)) {
+ return (KeyguardSecurityViewFlipper) child;
+ }
+ }
+
+ return null;
+ }
+
+ private boolean isKeyguardSecurityView(View view) {
+ return view instanceof KeyguardSecurityViewFlipper;
}
public void onPause() {
@@ -238,6 +378,7 @@ public class KeyguardSecurityContainer extends FrameLayout {
mAlertDialog = null;
}
mSecurityViewFlipper.setWindowInsetsAnimationCallback(null);
+ mOrientationEventListener.disable();
}
@Override
@@ -319,19 +460,44 @@ public class KeyguardSecurityContainer extends FrameLayout {
if (mSwipeListener != null) {
mSwipeListener.onSwipeUp();
}
+ } else {
+ if (!mIsDragging) {
+ handleTap(event);
+ }
}
}
return true;
}
+ private void handleTap(MotionEvent event) {
+ // If we're using a fullscreen security mode, skip
+ if (!mOneHandedMode) {
+ return;
+ }
+
+ // Did the tap hit the "other" side of the bouncer?
+ if ((mIsSecurityViewLeftAligned && (event.getX() > getWidth() / 2f))
+ || (!mIsSecurityViewLeftAligned && (event.getX() < getWidth() / 2f))) {
+ mIsSecurityViewLeftAligned = !mIsSecurityViewLeftAligned;
+
+ Settings.Global.putInt(
+ mContext.getContentResolver(),
+ Settings.Global.ONE_HANDED_KEYGUARD_SIDE,
+ mIsSecurityViewLeftAligned ? Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT
+ : Settings.Global.ONE_HANDED_KEYGUARD_SIDE_RIGHT);
+
+ updateSecurityViewLocation(true);
+ }
+ }
+
void setSwipeListener(SwipeListener swipeListener) {
mSwipeListener = swipeListener;
}
private void startSpringAnimation(float startVelocity) {
mSpringAnimation
- .setStartVelocity(startVelocity)
- .animateToFinalPosition(0);
+ .setStartVelocity(startVelocity)
+ .animateToFinalPosition(0);
}
public void startDisappearAnimation(SecurityMode securitySelection) {
@@ -441,18 +607,17 @@ public class KeyguardSecurityContainer extends FrameLayout {
return insets.inset(0, 0, 0, inset);
}
-
private void showDialog(String title, String message) {
if (mAlertDialog != null) {
mAlertDialog.dismiss();
}
mAlertDialog = new AlertDialog.Builder(mContext)
- .setTitle(title)
- .setMessage(message)
- .setCancelable(false)
- .setNeutralButton(R.string.ok, null)
- .create();
+ .setTitle(title)
+ .setMessage(message)
+ .setCancelable(false)
+ .setNeutralButton(R.string.ok, null)
+ .create();
if (!(mContext instanceof Activity)) {
mAlertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_KEYGUARD_DIALOG);
}
@@ -490,6 +655,47 @@ public class KeyguardSecurityContainer extends FrameLayout {
}
}
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ int maxHeight = 0;
+ int maxWidth = 0;
+ int childState = 0;
+
+ int halfWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ MeasureSpec.getSize(widthMeasureSpec) / 2,
+ MeasureSpec.getMode(widthMeasureSpec));
+
+ for (int i = 0; i < getChildCount(); i++) {
+ final View view = getChildAt(i);
+ if (view.getVisibility() != GONE) {
+ if (mOneHandedMode && isKeyguardSecurityView(view)) {
+ measureChildWithMargins(view, halfWidthMeasureSpec, 0,
+ heightMeasureSpec, 0);
+ } else {
+ measureChildWithMargins(view, widthMeasureSpec, 0,
+ heightMeasureSpec, 0);
+ }
+ final LayoutParams lp = (LayoutParams) view.getLayoutParams();
+ maxWidth = Math.max(maxWidth,
+ view.getMeasuredWidth() + lp.leftMargin + lp.rightMargin);
+ maxHeight = Math.max(maxHeight,
+ view.getMeasuredHeight() + lp.topMargin + lp.bottomMargin);
+ childState = combineMeasuredStates(childState, view.getMeasuredState());
+ }
+ }
+
+ maxWidth += getPaddingLeft() + getPaddingRight();
+ maxHeight += getPaddingTop() + getPaddingBottom();
+
+ // Check against our minimum height and width
+ maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
+ maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
+
+ setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
+ resolveSizeAndState(maxHeight, heightMeasureSpec,
+ childState << MEASURED_HEIGHT_STATE_SHIFT));
+ }
+
void showAlmostAtWipeDialog(int attempts, int remaining, int userType) {
String message = null;
switch (userType) {
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 1a8d420fb394..fdab8db67431 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -404,6 +404,7 @@ public class KeyguardSecurityContainerController extends ViewController<Keyguard
if (newView != null) {
newView.onResume(KeyguardSecurityView.VIEW_REVEALED);
mSecurityViewFlipperController.show(newView);
+ mView.updateLayoutForSecurityMode(securityMode);
}
mSecurityCallback.onSecurityModeChanged(
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
index c77c86711abf..631c24844417 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityModel.java
@@ -92,4 +92,13 @@ public class KeyguardSecurityModel {
throw new IllegalStateException("Unknown security quality:" + security);
}
}
+
+ /**
+ * Returns whether the given security view should be used in a "one handed" way. This can be
+ * used to change how the security view is drawn (e.g. take up less of the screen, and align to
+ * one side).
+ */
+ public static boolean isSecurityViewOneHanded(SecurityMode securityMode) {
+ return securityMode == SecurityMode.Pattern || securityMode == SecurityMode.PIN;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index fe0ae33d17f1..ae4c8e5a3327 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -59,6 +59,7 @@ import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.power.EnhancedEstimates;
import com.android.systemui.power.PowerUI;
import com.android.systemui.privacy.PrivacyItemController;
+import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.screenrecord.RecordingController;
@@ -246,6 +247,7 @@ public class Dependency {
@Inject Lazy<KeyguardUpdateMonitor> mKeyguardUpdateMonitor;
@Inject Lazy<BatteryController> mBatteryController;
@Inject Lazy<NightDisplayListener> mNightDisplayListener;
+ @Inject Lazy<ReduceBrightColorsController> mReduceBrightColorsController;
@Inject Lazy<ManagedProfileController> mManagedProfileController;
@Inject Lazy<NextAlarmController> mNextAlarmController;
@Inject Lazy<DataSaverController> mDataSaverController;
@@ -393,6 +395,8 @@ public class Dependency {
mProviders.put(NightDisplayListener.class, mNightDisplayListener::get);
+ mProviders.put(ReduceBrightColorsController.class, mReduceBrightColorsController::get);
+
mProviders.put(ManagedProfileController.class, mManagedProfileController::get);
mProviders.put(NextAlarmController.class, mNextAlarmController::get);
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index 865ca40b1f4c..59c0fb816a96 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -19,15 +19,18 @@ package com.android.systemui;
import android.app.ActivityThread;
import android.app.Application;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.os.Process;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.UserHandle;
+import android.provider.Settings;
import android.util.Log;
import android.util.TimingsTraceLog;
import android.view.SurfaceControl;
@@ -37,6 +40,8 @@ import com.android.systemui.dagger.ContextComponentHelper;
import com.android.systemui.dagger.GlobalRootComponent;
import com.android.systemui.dagger.SysUIComponent;
import com.android.systemui.dump.DumpManager;
+import com.android.systemui.people.PeopleSpaceActivity;
+import com.android.systemui.people.widget.PeopleSpaceWidgetProvider;
import com.android.systemui.shared.system.ThreadedRendererCompat;
import com.android.systemui.util.NotificationChannels;
@@ -121,6 +126,26 @@ public class SystemUIApplication extends Application implements
mServices[i].onBootCompleted();
}
}
+ // If SHOW_PEOPLE_SPACE is true, enable People Space widget provider.
+ // TODO(b/170396074): Migrate to new feature flag (go/silk-flags-howto)
+ try {
+ int showPeopleSpace = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.SHOW_PEOPLE_SPACE, 1);
+ context.getPackageManager().setComponentEnabledSetting(
+ new ComponentName(context, PeopleSpaceWidgetProvider.class),
+ showPeopleSpace == 1
+ ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ context.getPackageManager().setComponentEnabledSetting(
+ new ComponentName(context, PeopleSpaceActivity.class),
+ showPeopleSpace == 1
+ ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+ : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
+ PackageManager.DONT_KILL_APP);
+ } catch (Exception e) {
+ Log.w(TAG, "Error enabling People Space widget:", e);
+ }
}
}, bootCompletedFilter);
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 726e2d06bf90..a2f96bbad203 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -25,6 +25,7 @@ import android.content.Context;
import android.content.SharedPreferences;
import android.content.om.OverlayManager;
import android.hardware.display.AmbientDisplayConfiguration;
+import android.hardware.display.ColorDisplayManager;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
@@ -60,6 +61,7 @@ import com.android.systemui.navigationbar.NavigationBarOverlayController;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.PluginInitializerImpl;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.recents.OverviewProxyService;
import com.android.systemui.recents.Recents;
import com.android.systemui.settings.UserTracker;
@@ -82,6 +84,7 @@ import com.android.systemui.statusbar.policy.DeviceProvisionedController;
import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.theme.ThemeOverlayApplier;
import com.android.systemui.util.leak.LeakDetector;
+import com.android.systemui.util.settings.SecureSettings;
import com.android.wm.shell.legacysplitscreen.LegacySplitScreen;
import com.android.wm.shell.pip.Pip;
@@ -266,6 +269,15 @@ public class DependencyProvider {
}
/** */
+ @SysUISingleton
+ @Provides
+ public ReduceBrightColorsController provideReduceBrightColorsListener(
+ @Background Handler bgHandler, UserTracker userTracker,
+ ColorDisplayManager colorDisplayManager, SecureSettings secureSettings) {
+ return new ReduceBrightColorsController(userTracker, bgHandler,
+ colorDisplayManager, secureSettings);
+ }
+
@Provides
@SysUISingleton
public ActivityManagerWrapper provideActivityManagerWrapper() {
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
index 5d226d562c29..1ed881993800 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemUIBinder.java
@@ -27,7 +27,6 @@ import com.android.systemui.globalactions.GlobalActionsComponent;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.dagger.KeyguardModule;
import com.android.systemui.media.systemsounds.HomeSoundEffectController;
-import com.android.systemui.people.widget.PeopleSpaceWidgetEnabler;
import com.android.systemui.power.PowerUI;
import com.android.systemui.privacy.television.TvOngoingPrivacyChip;
import com.android.systemui.recents.Recents;
@@ -185,10 +184,4 @@ public abstract class SystemUIBinder {
@IntoMap
@ClassKey(HomeSoundEffectController.class)
public abstract SystemUI bindHomeSoundEffectController(HomeSoundEffectController sysui);
-
- /** Inject into PeopleSpaceWidgetEnabler. */
- @Binds
- @IntoMap
- @ClassKey(PeopleSpaceWidgetEnabler.class)
- public abstract SystemUI bindPeopleSpaceWidgetEnabler(PeopleSpaceWidgetEnabler sysui);
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java
index 870e3bed2b7a..422ffd524aa8 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/NavigationModeController.java
@@ -200,7 +200,7 @@ public class NavigationModeController implements Dumpable {
Log.d(TAG, " assetPaths=");
ApkAssets[] assets = context.getResources().getAssets().getApkAssets();
for (ApkAssets a : assets) {
- Log.d(TAG, " " + a.getAssetPath());
+ Log.d(TAG, " " + a.getDebugName());
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java
deleted file mode 100644
index 3df264421d75..000000000000
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetEnabler.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2021 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.people.widget;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.util.Log;
-
-import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.SysUISingleton;
-import com.android.systemui.people.PeopleSpaceActivity;
-import com.android.systemui.statusbar.FeatureFlags;
-
-import javax.inject.Inject;
-
-/**
- * Enables People Space widgets.
- */
-@SysUISingleton
-public class PeopleSpaceWidgetEnabler extends SystemUI {
- private static final String TAG = "PeopleSpaceWdgtEnabler";
- private Context mContext;
- private FeatureFlags mFeatureFlags;
-
- @Inject
- public PeopleSpaceWidgetEnabler(Context context, FeatureFlags featureFlags) {
- super(context);
- mContext = context;
- mFeatureFlags = featureFlags;
- }
-
- @Override
- public void start() {
- Log.d(TAG, "Starting service");
- try {
- boolean showPeopleSpace = mFeatureFlags.isPeopleTileEnabled();
- mContext.getPackageManager().setComponentEnabledSetting(
- new ComponentName(mContext, PeopleSpaceWidgetProvider.class),
- showPeopleSpace
- ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
- : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- mContext.getPackageManager().setComponentEnabledSetting(
- new ComponentName(mContext, PeopleSpaceActivity.class),
- showPeopleSpace
- ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
- : PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
- PackageManager.DONT_KILL_APP);
- } catch (Exception e) {
- Log.w(TAG, "Error enabling People Space widget:", e);
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
new file mode 100644
index 000000000000..42d603ec5051
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/ReduceBrightColorsController.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 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.qs;
+
+import android.content.Context;
+import android.database.ContentObserver;
+import android.hardware.display.ColorDisplayManager;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.provider.Settings;
+
+import androidx.annotation.NonNull;
+
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.settings.UserTracker;
+import com.android.systemui.statusbar.policy.CallbackController;
+import com.android.systemui.util.settings.SecureSettings;
+
+import java.util.ArrayList;
+
+import javax.inject.Inject;
+
+/**
+ * @hide
+ */
+public class ReduceBrightColorsController implements
+ CallbackController<ReduceBrightColorsController.Listener> {
+ private final ColorDisplayManager mManager;
+ private final UserTracker mUserTracker;
+ private UserTracker.Callback mCurrentUserTrackerCallback;
+ private final Handler mHandler;
+ private final ContentObserver mContentObserver;
+ private final SecureSettings mSecureSettings;
+ private final ArrayList<ReduceBrightColorsController.Listener> mListeners = new ArrayList<>();
+
+ @Inject
+ public ReduceBrightColorsController(UserTracker userTracker,
+ @Background Handler handler,
+ ColorDisplayManager colorDisplayManager,
+ SecureSettings secureSettings) {
+ mManager = colorDisplayManager;
+ mUserTracker = userTracker;
+ mHandler = handler;
+ mSecureSettings = secureSettings;
+ mContentObserver = new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ super.onChange(selfChange, uri);
+ final String setting = uri == null ? null : uri.getLastPathSegment();
+ synchronized (mListeners) {
+ if (setting != null && mListeners.size() != 0) {
+ if (setting.equals(Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED)) {
+ for (Listener listener : mListeners) {
+ listener.onActivated(mManager.isReduceBrightColorsActivated());
+ }
+ }
+ }
+ }
+ }
+ };
+
+ mCurrentUserTrackerCallback = new UserTracker.Callback() {
+ @Override
+ public void onUserChanged(int newUser, Context userContext) {
+ synchronized (mListeners) {
+ if (mListeners.size() > 0) {
+ mSecureSettings.unregisterContentObserver(mContentObserver);
+ mSecureSettings.registerContentObserverForUser(
+ Settings.Secure.getUriFor(
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED),
+ false, mContentObserver, newUser);
+ }
+ }
+ }
+ };
+ mUserTracker.addCallback(mCurrentUserTrackerCallback, new HandlerExecutor(handler));
+ }
+
+ @Override
+ public void addCallback(@NonNull Listener listener) {
+ synchronized (mListeners) {
+ if (!mListeners.contains(listener)) {
+ mListeners.add(listener);
+ if (mListeners.size() == 1) {
+ mSecureSettings.registerContentObserverForUser(
+ Settings.Secure.getUriFor(
+ Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED),
+ false, mContentObserver, mUserTracker.getUserId());
+ }
+ }
+ }
+ }
+
+ @Override
+ public void removeCallback(@androidx.annotation.NonNull Listener listener) {
+ synchronized (mListeners) {
+ if (mListeners.remove(listener) && mListeners.size() == 0) {
+ mSecureSettings.unregisterContentObserver(mContentObserver);
+ }
+ }
+ }
+
+ /** Returns {@code true} if Reduce Bright Colors is activated */
+ public boolean isReduceBrightColorsActivated() {
+ return mManager.isReduceBrightColorsActivated();
+ }
+
+ /** Sets the activation state of Reduce Bright Colors */
+ public void setReduceBrightColorsActivated(boolean activated) {
+ mManager.setReduceBrightColorsActivated(activated);
+ }
+
+ /**
+ * Listener invoked whenever the Reduce Bright Colors settings are changed.
+ */
+ public interface Listener {
+ /**
+ * Listener invoked when the activated state changes.
+ *
+ * @param activated {@code true} if Reduce Bright Colors is activated.
+ */
+ default void onActivated(boolean activated) {
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 33713f3724c7..d41bd7ad4d3c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -16,6 +16,8 @@
package com.android.systemui.qs.dagger;
+import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE;
+
import android.content.Context;
import android.hardware.display.NightDisplayListener;
import android.os.Handler;
@@ -25,6 +27,7 @@ import com.android.systemui.media.dagger.MediaModule;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.statusbar.phone.AutoTileManager;
import com.android.systemui.statusbar.phone.ManagedProfileController;
import com.android.systemui.statusbar.policy.CastController;
@@ -32,6 +35,8 @@ import com.android.systemui.statusbar.policy.DataSaverController;
import com.android.systemui.statusbar.policy.HotspotController;
import com.android.systemui.util.settings.SecureSettings;
+import javax.inject.Named;
+
import dagger.Binds;
import dagger.Module;
import dagger.Provides;
@@ -54,7 +59,9 @@ public interface QSModule {
DataSaverController dataSaverController,
ManagedProfileController managedProfileController,
NightDisplayListener nightDisplayListener,
- CastController castController) {
+ CastController castController,
+ ReduceBrightColorsController reduceBrightColorsController,
+ @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
AutoTileManager manager = new AutoTileManager(
context,
autoAddTrackerBuilder,
@@ -65,7 +72,9 @@ public interface QSModule {
dataSaverController,
managedProfileController,
nightDisplayListener,
- castController
+ castController,
+ reduceBrightColorsController,
+ isReduceBrightColorsAvailable
);
manager.init();
return manager;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
index f94cabcee297..aec7b9a4b6b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ReduceBrightColorsTile.java
@@ -33,46 +33,39 @@ import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.SecureSetting;
+import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.qs.tileimpl.QSTileImpl;
-import com.android.systemui.settings.UserTracker;
-import com.android.systemui.util.settings.SecureSettings;
import javax.inject.Inject;
import javax.inject.Named;
/** Quick settings tile: Reduce Bright Colors **/
-public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> {
+public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState>
+ implements ReduceBrightColorsController.Listener{
//TODO(b/170973645): get icon drawable
private final Icon mIcon = null;
- private final SecureSetting mActivatedSetting;
private final boolean mIsAvailable;
+ private final ReduceBrightColorsController mReduceBrightColorsController;
+ private boolean mIsListening;
@Inject
public ReduceBrightColorsTile(
@Named(RBC_AVAILABLE) boolean isAvailable,
+ ReduceBrightColorsController reduceBrightColorsController,
QSHost host,
@Background Looper backgroundLooper,
@Main Handler mainHandler,
MetricsLogger metricsLogger,
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
- QSLogger qsLogger,
- UserTracker userTracker,
- SecureSettings secureSettings
+ QSLogger qsLogger
) {
super(host, backgroundLooper, mainHandler, metricsLogger, statusBarStateController,
activityStarter, qsLogger);
-
- mActivatedSetting = new SecureSetting(secureSettings, mainHandler,
- Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED, userTracker.getUserId()) {
- @Override
- protected void handleValueChanged(int value, boolean observedChange) {
- refreshState();
- }
- };
+ mReduceBrightColorsController = reduceBrightColorsController;
+ mReduceBrightColorsController.observe(getLifecycle(), this);
mIsAvailable = isAvailable;
}
@@ -84,7 +77,6 @@ public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> {
@Override
protected void handleDestroy() {
super.handleDestroy();
- mActivatedSetting.setListening(false);
}
@Override
@@ -93,25 +85,13 @@ public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> {
}
@Override
- public void handleSetListening(boolean listening) {
- super.handleSetListening(listening);
- mActivatedSetting.setListening(listening);
- }
-
- @Override
- protected void handleUserSwitch(int newUserId) {
- mActivatedSetting.setUserId(newUserId);
- refreshState();
- }
-
- @Override
public Intent getLongClickIntent() {
return new Intent(Settings.ACTION_REDUCE_BRIGHT_COLORS_SETTINGS);
}
@Override
protected void handleClick() {
- mActivatedSetting.setValue(mState.value ? 0 : 1);
+ mReduceBrightColorsController.setReduceBrightColorsActivated(!mState.value);
}
@Override
@@ -121,7 +101,7 @@ public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> {
@Override
protected void handleUpdateState(BooleanState state, Object arg) {
- state.value = mActivatedSetting.getValue() == 1;
+ state.value = mReduceBrightColorsController.isReduceBrightColorsActivated();
state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
state.label = mContext.getString(R.string.quick_settings_reduce_bright_colors_label);
state.expandedAccessibilityClassName = Switch.class.getName();
@@ -132,4 +112,9 @@ public class ReduceBrightColorsTile extends QSTileImpl<QSTile.BooleanState> {
public int getMetricsCategory() {
return 0;
}
+
+ @Override
+ public void onActivated(boolean activated) {
+ refreshState();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
index 5b55864eed8a..c066619d049a 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/CropView.java
@@ -65,6 +65,9 @@ public class CropView extends View {
private float mTopDelta = 0f;
private float mBottomDelta = 0f;
+ private int mExtraTopPadding;
+ private int mExtraBottomPadding;
+
private CropBoundary mCurrentDraggingBoundary = CropBoundary.NONE;
private float mStartingY; // y coordinate of ACTION_DOWN
private CropInteractionListener mCropInteractionListener;
@@ -117,12 +120,13 @@ public class CropView extends View {
if (mCurrentDraggingBoundary != CropBoundary.NONE) {
float delta = event.getY() - mStartingY;
if (mCurrentDraggingBoundary == CropBoundary.TOP) {
- mTopDelta = pixelsToFraction((int) MathUtils.constrain(delta, -topPx,
+ mTopDelta = pixelDistanceToFraction((int) MathUtils.constrain(delta,
+ -topPx + mExtraTopPadding,
bottomPx - 2 * mCropTouchMargin - topPx));
} else { // Bottom
- mBottomDelta = pixelsToFraction((int) MathUtils.constrain(delta,
+ mBottomDelta = pixelDistanceToFraction((int) MathUtils.constrain(delta,
topPx + 2 * mCropTouchMargin - bottomPx,
- getHeight() - bottomPx));
+ getHeight() - bottomPx - mExtraBottomPadding));
}
updateListener(event);
invalidate();
@@ -195,6 +199,16 @@ public class CropView extends View {
}
/**
+ * Set additional top and bottom padding for the image being cropped (used when the
+ * corresponding ImageView doesn't take the full height).
+ */
+ public void setExtraPadding(int top, int bottom) {
+ mExtraTopPadding = top;
+ mExtraBottomPadding = bottom;
+ invalidate();
+ }
+
+ /**
* @return value [0,1] representing the position of the top crop boundary. Does not reflect
* changes from any in-progress touch input.
*/
@@ -244,12 +258,22 @@ public class CropView extends View {
true, mHandlePaint);
}
+ /**
+ * Convert the given fraction position to pixel position within the View.
+ */
private int fractionToPixels(float frac) {
- return (int) (frac * getHeight());
+ return (int) (mExtraTopPadding + frac * getImageHeight());
+ }
+
+ private int getImageHeight() {
+ return getHeight() - mExtraTopPadding - mExtraBottomPadding;
}
- private float pixelsToFraction(int px) {
- return px / (float) getHeight();
+ /**
+ * Convert the given pixel distance to fraction of the image.
+ */
+ private float pixelDistanceToFraction(int px) {
+ return px / (float) getImageHeight();
}
private CropBoundary nearestBoundary(MotionEvent event, int topPx, int bottomPx) {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
index 5a13ea55222d..4dc846e0e95d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/LongScreenshotActivity.java
@@ -157,6 +157,9 @@ public class LongScreenshotActivity extends Activity {
});
}
}
+ mPreview.addOnLayoutChangeListener(
+ (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) ->
+ updateCropLocation());
}
@Override
@@ -305,6 +308,27 @@ public class LongScreenshotActivity extends Activity {
}
}
+ private void updateCropLocation() {
+ Drawable drawable = mPreview.getDrawable();
+ if (drawable == null) {
+ return;
+ }
+
+ float imageRatio = drawable.getBounds().width() / (float) drawable.getBounds().height();
+ float viewRatio = mPreview.getWidth() / (float) mPreview.getHeight();
+
+ if (imageRatio > viewRatio) {
+ // Image is full width and height is constrained, compute extra padding to inform
+ // CropView
+ float imageHeight = mPreview.getHeight() * viewRatio / imageRatio;
+ int extraPadding = (int) (mPreview.getHeight() - imageHeight) / 2;
+ mCropView.setExtraPadding(extraPadding, extraPadding);
+ } else {
+ // Image is full height
+ mCropView.setExtraPadding(0, 0);
+ }
+ }
+
private void doCapture() {
mScrollCaptureController.start(mConnection,
new ScrollCaptureController.ScrollCaptureCallback() {
@@ -319,6 +343,7 @@ public class LongScreenshotActivity extends Activity {
Log.i(TAG, "Got tiles " + imageTileSet.getWidth() + " x "
+ imageTileSet.getHeight());
mPreview.setImageDrawable(imageTileSet.getDrawable());
+ updateCropLocation();
mMagnifierView.setDrawable(imageTileSet.getDrawable(),
imageTileSet.getWidth(), imageTileSet.getHeight());
mCropView.animateBoundaryTo(CropView.CropBoundary.BOTTOM, 0.5f);
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
index 7a0ec4c520b2..90f304262ea1 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/MagnifierView.java
@@ -16,6 +16,8 @@
package com.android.systemui.screenshot;
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.annotation.NonNull;
import android.content.Context;
import android.content.res.TypedArray;
@@ -28,6 +30,7 @@ import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
+import android.view.ViewPropertyAnimator;
import androidx.annotation.Nullable;
@@ -35,7 +38,7 @@ import com.android.systemui.R;
/**
* MagnifierView shows a full-res cropped circular display of a given ImageTileSet, contents and
- * positioning dereived from events from a CropView to which it listens.
+ * positioning derived from events from a CropView to which it listens.
*
* Not meant to be a general-purpose magnifier!
*/
@@ -57,6 +60,20 @@ public class MagnifierView extends View implements CropView.CropInteractionListe
private float mLastCropPosition;
private CropView.CropBoundary mCropBoundary;
+ private ViewPropertyAnimator mTranslationAnimator;
+ private final Animator.AnimatorListener mTranslationAnimatorListener =
+ new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mTranslationAnimator = null;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mTranslationAnimator = null;
+ }
+ };
+
public MagnifierView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
@@ -133,6 +150,8 @@ public class MagnifierView extends View implements CropView.CropInteractionListe
public void onCropMotionEvent(MotionEvent event, CropView.CropBoundary boundary,
float cropPosition, int cropPositionPx) {
mCropBoundary = boundary;
+ boolean touchOnRight = event.getX() > getParentWidth() / 2;
+ float translateXTarget = touchOnRight ? 0 : getParentWidth() - getWidth();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mLastCropPosition = cropPosition;
@@ -144,11 +163,22 @@ public class MagnifierView extends View implements CropView.CropInteractionListe
setAlpha(0f);
setTranslationX((getParentWidth() - getWidth()) / 2);
setVisibility(View.VISIBLE);
- boolean touchOnRight = event.getX() > getParentWidth() / 2;
- float translateXTarget = touchOnRight ? 0 : getParentWidth() - getWidth();
- animate().alpha(1f).translationX(translateXTarget).scaleX(1f).scaleY(1f).start();
+ mTranslationAnimator =
+ animate().alpha(1f).translationX(translateXTarget).scaleX(1f).scaleY(1f);
+ mTranslationAnimator.setListener(mTranslationAnimatorListener);
+ mTranslationAnimator.start();
break;
case MotionEvent.ACTION_MOVE:
+ // The touch is near the middle if it's within 10% of the center point.
+ // We don't want to animate horizontally if the touch is near the middle.
+ boolean nearMiddle = Math.abs(event.getX() - getParentWidth() / 2)
+ < getParentWidth() / 10f;
+ boolean viewOnLeft = getTranslationX() < (getParentWidth() - getWidth()) / 2;
+ if (!nearMiddle && viewOnLeft != touchOnRight && mTranslationAnimator == null) {
+ mTranslationAnimator = animate().translationX(translateXTarget);
+ mTranslationAnimator.setListener(mTranslationAnimatorListener);
+ mTranslationAnimator.start();
+ }
mLastCropPosition = cropPosition;
setTranslationY(cropPositionPx - getHeight() / 2);
invalidate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 0ad6507fb01e..dff97a679164 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.notification.init
+import android.content.Context
+import android.provider.Settings
import android.service.notification.StatusBarNotification
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.people.widget.PeopleSpaceWidgetManager
@@ -58,6 +60,7 @@ import javax.inject.Inject
*/
@SysUISingleton
class NotificationsControllerImpl @Inject constructor(
+ private val context: Context,
private val featureFlags: FeatureFlags,
private val notificationListener: NotificationListener,
private val entryManager: NotificationEntryManager,
@@ -129,7 +132,9 @@ class NotificationsControllerImpl @Inject constructor(
entryManager.attach(notificationListener)
}
- if (featureFlags.isPeopleTileEnabled) {
+ val showPeopleSpace = Settings.Global.getInt(context.contentResolver,
+ Settings.Global.SHOW_PEOPLE_SPACE, 1)
+ if (showPeopleSpace == 1) {
peopleSpaceWidgetManager.attach(notificationListener)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index e40c262765ea..204dd9f5e58c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -14,6 +14,8 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE;
+
import android.content.Context;
import android.content.res.Resources;
import android.hardware.display.ColorDisplayManager;
@@ -27,6 +29,7 @@ import com.android.systemui.R;
import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.qs.SecureSetting;
import com.android.systemui.qs.external.CustomTile;
import com.android.systemui.statusbar.policy.CastController;
@@ -41,6 +44,8 @@ import com.android.systemui.util.settings.SecureSettings;
import java.util.ArrayList;
import java.util.Objects;
+import javax.inject.Named;
+
/**
* Manages which tiles should be automatically added to QS.
*/
@@ -69,6 +74,8 @@ public class AutoTileManager implements UserAwareController {
private final ManagedProfileController mManagedProfileController;
private final NightDisplayListener mNightDisplayListener;
private final CastController mCastController;
+ private final ReduceBrightColorsController mReduceBrightColorsController;
+ private final boolean mIsReduceBrightColorsAvailable;
private final ArrayList<AutoAddSetting> mAutoAddSettingList = new ArrayList<>();
public AutoTileManager(Context context, AutoAddTracker.Builder autoAddTrackerBuilder,
@@ -79,7 +86,9 @@ public class AutoTileManager implements UserAwareController {
DataSaverController dataSaverController,
ManagedProfileController managedProfileController,
NightDisplayListener nightDisplayListener,
- CastController castController) {
+ CastController castController,
+ ReduceBrightColorsController reduceBrightColorsController,
+ @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
mContext = context;
mHost = host;
mSecureSettings = secureSettings;
@@ -91,6 +100,8 @@ public class AutoTileManager implements UserAwareController {
mManagedProfileController = managedProfileController;
mNightDisplayListener = nightDisplayListener;
mCastController = castController;
+ mReduceBrightColorsController = reduceBrightColorsController;
+ mIsReduceBrightColorsAvailable = isReduceBrightColorsAvailable;
}
/**
@@ -124,9 +135,9 @@ public class AutoTileManager implements UserAwareController {
if (!mAutoTracker.isAdded(CAST)) {
mCastController.addCallback(mCastCallback);
}
-
- // TODO(b/170970675): Set a listener/controller and callback for Reduce Bright Colors
- // state changes. Call into ColorDisplayService to get availability/config status
+ if (!mAutoTracker.isAdded(BRIGHTNESS) && mIsReduceBrightColorsAvailable) {
+ mReduceBrightColorsController.addCallback(mReduceBrightColorsCallback);
+ }
int settingsN = mAutoAddSettingList.size();
for (int i = 0; i < settingsN; i++) {
@@ -143,6 +154,9 @@ public class AutoTileManager implements UserAwareController {
if (ColorDisplayManager.isNightDisplayAvailable(mContext)) {
mNightDisplayListener.setCallback(null);
}
+ if (mIsReduceBrightColorsAvailable) {
+ mReduceBrightColorsController.removeCallback(mReduceBrightColorsCallback);
+ }
mCastController.removeCallback(mCastCallback);
int settingsN = mAutoAddSettingList.size();
for (int i = 0; i < settingsN; i++) {
@@ -287,6 +301,24 @@ public class AutoTileManager implements UserAwareController {
};
@VisibleForTesting
+ final ReduceBrightColorsController.Listener mReduceBrightColorsCallback =
+ new ReduceBrightColorsController.Listener() {
+ @Override
+ public void onActivated(boolean activated) {
+ if (activated) {
+ addReduceBrightColorsTile();
+ }
+ }
+
+ private void addReduceBrightColorsTile() {
+ if (mAutoTracker.isAdded(BRIGHTNESS)) return;
+ mHost.addTile(BRIGHTNESS);
+ mAutoTracker.setTileAdded(BRIGHTNESS);
+ mHandler.post(() -> mReduceBrightColorsController.removeCallback(this));
+ }
+ };
+
+ @VisibleForTesting
final CastController.Callback mCastCallback = new CastController.Callback() {
@Override
public void onCastDevicesChanged() {
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 986333ce5010..80109cb7a06c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -19,7 +19,6 @@ package com.android.systemui.statusbar.phone;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.AccessibilityAction;
-import static com.android.systemui.controls.dagger.ControlsComponent.Visibility.AVAILABLE;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_BUTTON;
import static com.android.systemui.tuner.LockscreenFragment.LOCKSCREEN_LEFT_UNLOCK;
@@ -74,10 +73,6 @@ import com.android.systemui.Dependency;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.assist.AssistManager;
-import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.controls.dagger.ControlsComponent;
-import com.android.systemui.controls.ui.ControlsDialog;
-import com.android.systemui.controls.ui.ControlsUiController;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.IntentButtonProvider;
import com.android.systemui.plugins.IntentButtonProvider.IntentButton;
@@ -130,7 +125,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private KeyguardAffordanceView mRightAffordanceView;
private KeyguardAffordanceView mLeftAffordanceView;
- private ImageView mAltLeftButton;
+ private ImageView mWalletButton;
private ViewGroup mIndicationArea;
private TextView mIndicationText;
private TextView mIndicationTextBottom;
@@ -179,11 +174,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
private int mBurnInXOffset;
private int mBurnInYOffset;
private ActivityIntentHelper mActivityIntentHelper;
-
- private ControlsDialog mControlsDialog;
- private ControlsComponent mControlsComponent;
private int mLockScreenMode;
- private BroadcastDispatcher mBroadcastDispatcher;
private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
public KeyguardBottomAreaView(Context context) {
@@ -251,7 +242,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mOverlayContainer = findViewById(R.id.overlay_container);
mRightAffordanceView = findViewById(R.id.camera_button);
mLeftAffordanceView = findViewById(R.id.left_button);
- mAltLeftButton = findViewById(R.id.alt_left_button);
+ mWalletButton = findViewById(R.id.wallet_button);
mIndicationArea = findViewById(R.id.keyguard_indication_area);
mIndicationText = findViewById(R.id.keyguard_indication_text);
mIndicationTextBottom = findViewById(R.id.keyguard_indication_text_bottom);
@@ -351,10 +342,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mLeftAffordanceView.setLayoutParams(lp);
updateLeftAffordanceIcon();
- lp = mAltLeftButton.getLayoutParams();
+ lp = mWalletButton.getLayoutParams();
lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
- mAltLeftButton.setLayoutParams(lp);
+ mWalletButton.setLayoutParams(lp);
}
private void updateRightAffordanceIcon() {
@@ -427,11 +418,11 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mLeftAffordanceView.setContentDescription(state.contentDescription);
}
- private void updateControlsVisibility() {
- if (mDozing || mControlsComponent.getVisibility() != AVAILABLE) {
- mAltLeftButton.setVisibility(GONE);
+ private void updateWalletVisibility() {
+ if (mDozing) {
+ mWalletButton.setVisibility(GONE);
} else {
- mAltLeftButton.setVisibility(VISIBLE);
+ mWalletButton.setVisibility(VISIBLE);
}
}
@@ -699,8 +690,8 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
public void startFinishDozeAnimation() {
long delay = 0;
- if (mAltLeftButton.getVisibility() == View.VISIBLE) {
- startFinishDozeAnimationElement(mAltLeftButton, delay);
+ if (mWalletButton.getVisibility() == View.VISIBLE) {
+ startFinishDozeAnimationElement(mWalletButton, delay);
}
if (mLeftAffordanceView.getVisibility() == View.VISIBLE) {
startFinishDozeAnimationElement(mLeftAffordanceView, delay);
@@ -774,14 +765,10 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
updateCameraVisibility();
updateLeftAffordanceIcon();
- updateControlsVisibility();
+ updateWalletVisibility();
if (dozing) {
mOverlayContainer.setVisibility(INVISIBLE);
- if (mControlsDialog != null) {
- mControlsDialog.dismiss();
- mControlsDialog = null;
- }
} else {
mOverlayContainer.setVisibility(VISIBLE);
if (animate) {
@@ -811,7 +798,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
mLeftAffordanceView.setAlpha(alpha);
mRightAffordanceView.setAlpha(alpha);
mIndicationArea.setAlpha(alpha);
- mAltLeftButton.setAlpha(alpha);
+ mWalletButton.setAlpha(alpha);
}
private class DefaultLeftButton implements IntentButton {
@@ -884,38 +871,18 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
return insets;
}
- /**
- * Show or hide controls, depending on the lock screen mode and controls
- * availability.
- */
- public void setupControls(ControlsComponent component, BroadcastDispatcher dispatcher) {
- mControlsComponent = component;
- mBroadcastDispatcher = dispatcher;
- setupControls();
- }
-
- private void setupControls() {
+ private void setupWallet() {
boolean inNewLayout = mLockScreenMode != KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
boolean settingEnabled = Settings.Global.getInt(mContext.getContentResolver(),
"controls_lockscreen", 0) == 1;
- if (!inNewLayout || !settingEnabled || !mControlsComponent.isEnabled()) {
- mAltLeftButton.setVisibility(View.GONE);
+ if (!inNewLayout || !settingEnabled) {
+ mWalletButton.setVisibility(View.GONE);
return;
}
- mControlsComponent.getControlsListingController().get()
- .addCallback(list -> {
- if (!list.isEmpty()) {
- mAltLeftButton.setImageDrawable(list.get(0).loadIcon());
- mAltLeftButton.setOnClickListener((v) -> {
- ControlsUiController ui = mControlsComponent
- .getControlsUiController().get();
- mControlsDialog = new ControlsDialog(mContext, mBroadcastDispatcher)
- .show(ui);
- });
- }
- updateControlsVisibility();
- });
+ // TODO: add image
+ // mWalletButton.setImageDrawable(list.get(0).loadIcon());
+ updateWalletVisibility();
}
/**
@@ -923,6 +890,6 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL
*/
public void onLockScreenModeChanged(int mode) {
mLockScreenMode = mode;
- setupControls();
+ setupWallet();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
index 83c347b05012..ae14fa943a4b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelViewController.java
@@ -89,10 +89,8 @@ import com.android.systemui.DejankUtils;
import com.android.systemui.Interpolators;
import com.android.systemui.R;
import com.android.systemui.biometrics.AuthController;
-import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.Classifier;
import com.android.systemui.classifier.FalsingCollector;
-import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.dagger.qualifiers.DisplayId;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.DozeLog;
@@ -245,7 +243,6 @@ public class NotificationPanelViewController extends PanelViewController {
public void onLockScreenModeChanged(int mode) {
mLockScreenMode = mode;
mClockPositionAlgorithm.onLockScreenModeChanged(mode);
- mKeyguardBottomArea.onLockScreenModeChanged(mode);
}
@Override
@@ -304,7 +301,6 @@ public class NotificationPanelViewController extends PanelViewController {
private final QSDetailDisplayer mQSDetailDisplayer;
private final FeatureFlags mFeatureFlags;
private final ScrimController mScrimController;
- private final ControlsComponent mControlsComponent;
// Maximum # notifications to show on Keyguard; extras will be collapsed in an overflow card.
// If there are exactly 1 + mMaxKeyguardNotifications, then still shows all notifications
@@ -520,7 +516,6 @@ public class NotificationPanelViewController extends PanelViewController {
private NotificationShelfController mNotificationShelfController;
private int mLockScreenMode = KeyguardUpdateMonitor.LOCK_SCREEN_MODE_NORMAL;
- private BroadcastDispatcher mBroadcastDispatcher;
private View.AccessibilityDelegate mAccessibilityDelegate = new View.AccessibilityDelegate() {
@Override
@@ -578,9 +573,7 @@ public class NotificationPanelViewController extends PanelViewController {
UserManager userManager,
MediaDataManager mediaDataManager,
AmbientState ambientState,
- FeatureFlags featureFlags,
- ControlsComponent controlsComponent,
- BroadcastDispatcher broadcastDispatcher) {
+ FeatureFlags featureFlags) {
super(view, falsingManager, dozeLog, keyguardStateController,
(SysuiStatusBarStateController) statusBarStateController, vibratorHelper,
latencyTracker, flingAnimationUtilsBuilder.get(), statusBarTouchableRegionManager,
@@ -623,7 +616,6 @@ public class NotificationPanelViewController extends PanelViewController {
mScrimController = scrimController;
mUserManager = userManager;
mMediaDataManager = mediaDataManager;
- mControlsComponent = controlsComponent;
pulseExpansionHandler.setPulseExpandAbortListener(() -> {
if (mQs != null) {
mQs.animateHeaderSlidingOut();
@@ -662,7 +654,6 @@ public class NotificationPanelViewController extends PanelViewController {
mEntryManager = notificationEntryManager;
mConversationNotificationManager = conversationNotificationManager;
mAuthController = authController;
- mBroadcastDispatcher = broadcastDispatcher;
mView.setBackgroundColor(Color.TRANSPARENT);
OnAttachStateChangeListener onAttachStateChangeListener = new OnAttachStateChangeListener();
@@ -972,7 +963,6 @@ public class NotificationPanelViewController extends PanelViewController {
mKeyguardBottomArea.setAffordanceHelper(mAffordanceHelper);
mKeyguardBottomArea.setStatusBar(mStatusBar);
mKeyguardBottomArea.setUserSetupComplete(mUserSetupComplete);
- mKeyguardBottomArea.setupControls(mControlsComponent, mBroadcastDispatcher);
}
private void updateMaxDisplayedNotifications(boolean recompute) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
index 55744f94f2b0..b6ed3e50ed7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelViewController.java
@@ -27,7 +27,6 @@ import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
-import android.annotation.Nullable;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.os.SystemClock;
@@ -1243,7 +1242,10 @@ public abstract class PanelViewController {
mVelocityTracker.clear();
break;
}
- return false;
+
+ // Finally, if none of the above cases applies, ensure that touches do not get handled
+ // by the contents of a panel that is not showing (a bit of a hack to avoid b/178277858)
+ return (mView.getVisibility() != View.VISIBLE);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 6c097bdb08d3..044f52fd689e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -383,8 +383,15 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
int qsTypeIcon = 0;
IconState qsIcon = null;
CharSequence description = null;
+ // Mobile icon will only be shown in the statusbar in 2 scenarios
+ // 1. Mobile is the default network, and it is validated
+ // 2. Mobile is the default network, it is not validated and there is no other
+ // non-Carrier WiFi networks available.
+ boolean maybeShowIcons = (mCurrentState.inetCondition == 1)
+ || (mCurrentState.inetCondition == 0
+ && !mNetworkController.isNonCarrierWifiNetworkAvailable());
// Only send data sim callbacks to QS.
- if (mCurrentState.dataSim && mCurrentState.isDefault) {
+ if (mCurrentState.dataSim && mCurrentState.isDefault && maybeShowIcons) {
qsTypeIcon =
(showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.qsDataType : 0;
qsIcon = new IconState(mCurrentState.enabled
@@ -397,7 +404,7 @@ public class MobileSignalController extends SignalController<MobileState, Mobile
boolean activityOut = mCurrentState.dataConnected
&& !mCurrentState.carrierNetworkChangeMode
&& mCurrentState.activityOut;
- showDataIcon &= mCurrentState.dataSim && mCurrentState.isDefault;
+ showDataIcon &= mCurrentState.dataSim && mCurrentState.isDefault && maybeShowIcons;
boolean showTriangle = showDataIcon && !mCurrentState.airplaneMode;
int typeIcon = (showDataIcon || mConfig.alwaysShowDataRatIcon) ? icons.dataType : 0;
showDataIcon |= mCurrentState.roaming;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 8eb1e6487046..fbdaf9cdae20 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -547,6 +547,10 @@ public class NetworkControllerImpl extends BroadcastReceiver
return mWifiSignalController.isCarrierMergedWifi(subId);
}
+ boolean isNonCarrierWifiNetworkAvailable() {
+ return !mNoNetworksAvailable;
+ }
+
boolean isEthernetDefault() {
return mConnectedTransports.get(NetworkCapabilities.TRANSPORT_ETHERNET);
}
@@ -908,6 +912,11 @@ public class NetworkControllerImpl extends BroadcastReceiver
return true;
}
+ @VisibleForTesting
+ void setNoNetworksAvailable(boolean noNetworksAvailable) {
+ mNoNetworksAvailable = noNetworksAvailable;
+ }
+
private void updateAirplaneMode(boolean force) {
boolean airplaneMode = (Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.AIRPLANE_MODE_ON, 0) == 1);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
index 8d72c9c8810e..b9b62b415c00 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/WifiSignalController.java
@@ -106,10 +106,18 @@ public class WifiSignalController extends
if (mCurrentState.inetCondition == 0) {
contentDescription += ("," + mContext.getString(R.string.data_connection_no_internet));
}
- IconState statusIcon = new IconState(wifiVisible, getCurrentIconId(), contentDescription);
if (mProviderModel) {
+ // WiFi icon will only be shown in the statusbar in 2 scenarios
+ // 1. WiFi is the default network, and it is validated
+ // 2. WiFi is the default network, it is not validated and there is no other
+ // non-Carrier WiFi networks available.
+ boolean maybeShowIcons = (mCurrentState.inetCondition == 1)
+ || (mCurrentState.inetCondition == 0
+ && !mNetworkController.isNonCarrierWifiNetworkAvailable());
+ IconState statusIcon = new IconState(
+ wifiVisible && maybeShowIcons, getCurrentIconId(), contentDescription);
IconState qsIcon = null;
- if (mCurrentState.isDefault || (!mNetworkController.isRadioOn()
+ if ((mCurrentState.isDefault && maybeShowIcons) || (!mNetworkController.isRadioOn()
&& !mNetworkController.isEthernetDefault())) {
qsIcon = new IconState(mCurrentState.connected,
mWifiTracker.isCaptivePortal ? R.drawable.ic_qs_wifi_disconnected
@@ -123,6 +131,8 @@ public class WifiSignalController extends
);
callback.setWifiIndicators(wifiIndicators);
} else {
+ IconState statusIcon = new IconState(
+ wifiVisible, getCurrentIconId(), contentDescription);
IconState qsIcon = new IconState(mCurrentState.connected,
mWifiTracker.isCaptivePortal ? R.drawable.ic_qs_wifi_disconnected
: getQsCurrentIconId(), contentDescription);
@@ -146,15 +156,25 @@ public class WifiSignalController extends
if (mCurrentState.inetCondition == 0) {
dataContentDescription = mContext.getString(R.string.data_connection_no_internet);
}
- boolean qsVisible = mCurrentState.enabled
- && (mCurrentState.connected && mCurrentState.inetCondition == 1);
-
+ // Mobile icon will only be shown in the statusbar in 2 scenarios
+ // 1. Mobile is the default network, and it is validated
+ // 2. Mobile is the default network, it is not validated and there is no other
+ // non-Carrier WiFi networks available.
+ boolean maybeShowIcons = (mCurrentState.inetCondition == 1)
+ || (mCurrentState.inetCondition == 0
+ && !mNetworkController.isNonCarrierWifiNetworkAvailable());
+ boolean sbVisible = mCurrentState.enabled && mCurrentState.connected
+ && maybeShowIcons && mCurrentState.isDefault;
IconState statusIcon =
- new IconState(qsVisible, getCurrentIconIdForCarrierWifi(), contentDescription);
- int qsTypeIcon = mCurrentState.connected ? icons.qsDataType : 0;
- int typeIcon = mCurrentState.connected ? icons.dataType : 0;
- IconState qsIcon = new IconState(
- mCurrentState.connected, getQsCurrentIconIdForCarrierWifi(), contentDescription);
+ new IconState(sbVisible, getCurrentIconIdForCarrierWifi(), contentDescription);
+ int typeIcon = sbVisible ? icons.dataType : 0;
+ int qsTypeIcon = 0;
+ IconState qsIcon = null;
+ if (sbVisible) {
+ qsTypeIcon = icons.qsDataType;
+ qsIcon = new IconState(mCurrentState.connected, getQsCurrentIconIdForCarrierWifi(),
+ contentDescription);
+ }
CharSequence description =
mNetworkController.getNetworkNameForCarrierWiFi(mCurrentState.subId);
MobileDataIndicators mobileDataIndicators = new MobileDataIndicators(
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
index 854be1f76722..1783fa4112b8 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerTest.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import static android.view.WindowInsets.Type.ime;
+import static android.view.WindowInsets.Type.systemBars;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
@@ -24,13 +25,20 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.graphics.Insets;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
+import android.testing.TestableResources;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.WindowInsets;
import android.view.WindowInsetsController;
+import android.widget.FrameLayout;
import androidx.test.filters.SmallTest;
import com.android.keyguard.KeyguardSecurityModel.SecurityMode;
+import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import org.junit.Before;
@@ -45,12 +53,21 @@ import org.mockito.junit.MockitoRule;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper()
public class KeyguardSecurityContainerTest extends SysuiTestCase {
+ private static final int SCREEN_WIDTH = 1600;
+ private static final int FAKE_MEASURE_SPEC =
+ View.MeasureSpec.makeMeasureSpec(SCREEN_WIDTH, View.MeasureSpec.EXACTLY);
+
+ private static final SecurityMode ONE_HANDED_SECURITY_MODE = SecurityMode.PIN;
+ private static final SecurityMode TWO_HANDED_SECURITY_MODE = SecurityMode.Password;
+
+
@Rule
public MockitoRule mRule = MockitoJUnit.rule();
@Mock
private WindowInsetsController mWindowInsetsController;
+
@Mock
private KeyguardSecurityViewFlipper mSecurityViewFlipper;
@@ -58,9 +75,18 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
@Before
public void setup() {
+ // Needed here, otherwise when mKeyguardSecurityContainer is created below, it'll cache
+ // the real references (rather than the TestableResources that this call creates).
+ mContext.ensureTestableResources();
+ FrameLayout.LayoutParams securityViewFlipperLayoutParams = new FrameLayout.LayoutParams(
+ ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
+
when(mSecurityViewFlipper.getWindowInsetsController()).thenReturn(mWindowInsetsController);
+ when(mSecurityViewFlipper.getLayoutParams()).thenReturn(securityViewFlipperLayoutParams);
mKeyguardSecurityContainer = new KeyguardSecurityContainer(getContext());
mKeyguardSecurityContainer.mSecurityViewFlipper = mSecurityViewFlipper;
+ mKeyguardSecurityContainer.addView(mSecurityViewFlipper, new ViewGroup.LayoutParams(
+ ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
}
@Test
@@ -69,4 +95,128 @@ public class KeyguardSecurityContainerTest extends SysuiTestCase {
verify(mWindowInsetsController).controlWindowInsetsAnimation(eq(ime()), anyLong(), any(),
any(), any());
}
-} \ No newline at end of file
+
+ @Test
+ public void onMeasure_usesFullWidthWithoutOneHandedMode() {
+ setUpKeyguard(
+ /* deviceConfigCanUseOneHandedKeyguard= */false,
+ /* sysuiResourceCanUseOneHandedKeyguard= */ false,
+ ONE_HANDED_SECURITY_MODE);
+
+ mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+
+ verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ }
+
+ @Test
+ public void onMeasure_usesFullWidthWithDeviceFlagDisabled() {
+ setUpKeyguard(
+ /* deviceConfigCanUseOneHandedKeyguard= */false,
+ /* sysuiResourceCanUseOneHandedKeyguard= */ true,
+ ONE_HANDED_SECURITY_MODE);
+
+ mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ }
+
+ @Test
+ public void onMeasure_usesFullWidthWithSysUIFlagDisabled() {
+ setUpKeyguard(
+ /* deviceConfigCanUseOneHandedKeyguard= */true,
+ /* sysuiResourceCanUseOneHandedKeyguard= */ false,
+ ONE_HANDED_SECURITY_MODE);
+
+ mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ }
+
+ @Test
+ public void onMeasure_usesHalfWidthWithFlagsEnabled() {
+ setUpKeyguard(
+ /* deviceConfigCanUseOneHandedKeyguard= */true,
+ /* sysuiResourceCanUseOneHandedKeyguard= */ true,
+ ONE_HANDED_SECURITY_MODE);
+
+ int halfWidthMeasureSpec =
+ View.MeasureSpec.makeMeasureSpec(SCREEN_WIDTH / 2, View.MeasureSpec.EXACTLY);
+ mKeyguardSecurityContainer.onMeasure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+
+ verify(mSecurityViewFlipper).measure(halfWidthMeasureSpec, FAKE_MEASURE_SPEC);
+ }
+
+ @Test
+ public void onMeasure_usesFullWidthForFullScreenIme() {
+ setUpKeyguard(
+ /* deviceConfigCanUseOneHandedKeyguard= */true,
+ /* sysuiResourceCanUseOneHandedKeyguard= */ true,
+ TWO_HANDED_SECURITY_MODE);
+
+ mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ }
+
+ @Test
+ public void onMeasure_respectsViewInsets() {
+ int imeInsetAmount = 100;
+ int systemBarInsetAmount = 10;
+
+ setUpKeyguard(
+ /* deviceConfigCanUseOneHandedKeyguard= */false,
+ /* sysuiResourceCanUseOneHandedKeyguard= */ false,
+ ONE_HANDED_SECURITY_MODE);
+
+ Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
+ Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
+
+ WindowInsets insets = new WindowInsets.Builder()
+ .setInsets(ime(), imeInset)
+ .setInsetsIgnoringVisibility(systemBars(), systemBarInset)
+ .build();
+
+ // It's reduced by the max of the systembar and IME, so just subtract IME inset.
+ int expectedHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
+ SCREEN_WIDTH - imeInsetAmount, View.MeasureSpec.EXACTLY);
+
+ mKeyguardSecurityContainer.onApplyWindowInsets(insets);
+ mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, expectedHeightMeasureSpec);
+ }
+
+ @Test
+ public void onMeasure_respectsViewInsets_largerSystembar() {
+ int imeInsetAmount = 0;
+ int systemBarInsetAmount = 10;
+
+ setUpKeyguard(
+ /* deviceConfigCanUseOneHandedKeyguard= */false,
+ /* sysuiResourceCanUseOneHandedKeyguard= */ false,
+ ONE_HANDED_SECURITY_MODE);
+
+ Insets imeInset = Insets.of(0, 0, 0, imeInsetAmount);
+ Insets systemBarInset = Insets.of(0, 0, 0, systemBarInsetAmount);
+
+ WindowInsets insets = new WindowInsets.Builder()
+ .setInsets(ime(), imeInset)
+ .setInsetsIgnoringVisibility(systemBars(), systemBarInset)
+ .build();
+
+ int expectedHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(
+ SCREEN_WIDTH - systemBarInsetAmount, View.MeasureSpec.EXACTLY);
+
+ mKeyguardSecurityContainer.onApplyWindowInsets(insets);
+ mKeyguardSecurityContainer.measure(FAKE_MEASURE_SPEC, FAKE_MEASURE_SPEC);
+ verify(mSecurityViewFlipper).measure(FAKE_MEASURE_SPEC, expectedHeightMeasureSpec);
+ }
+
+ private void setUpKeyguard(
+ boolean deviceConfigCanUseOneHandedKeyguard,
+ boolean sysuiResourceCanUseOneHandedKeyguard,
+ SecurityMode securityMode) {
+ TestableResources testableResources = mContext.getOrCreateTestableResources();
+ testableResources.addOverride(com.android.internal.R.bool.config_enableOneHandedKeyguard,
+ deviceConfigCanUseOneHandedKeyguard);
+ testableResources.addOverride(R.bool.can_use_one_handed_bouncer,
+ sysuiResourceCanUseOneHandedKeyguard);
+ mKeyguardSecurityContainer.updateLayoutForSecurityMode(securityMode);
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
index ffd747e09e23..880c290802df 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ReduceBrightColorsTileTest.java
@@ -18,10 +18,12 @@ package com.android.systemui.qs.tiles;
import static junit.framework.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.os.Handler;
-import android.provider.Settings;
import android.service.quicksettings.Tile;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -34,9 +36,9 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.qs.logging.QSLogger;
import com.android.systemui.settings.UserTracker;
-import com.android.systemui.util.settings.FakeSettings;
import org.junit.Before;
import org.junit.Test;
@@ -60,8 +62,9 @@ public class ReduceBrightColorsTileTest extends SysuiTestCase {
private QSLogger mQSLogger;
@Mock
private UserTracker mUserTracker;
+ @Mock
+ private ReduceBrightColorsController mReduceBrightColorsController;
- private FakeSettings mFakeSettings;
private TestableLooper mTestableLooper;
private ReduceBrightColorsTile mTile;
@@ -72,24 +75,23 @@ public class ReduceBrightColorsTileTest extends SysuiTestCase {
mTestableLooper = TestableLooper.get(this);
when(mHost.getContext()).thenReturn(mContext);
- mFakeSettings = new FakeSettings();
mTile = new ReduceBrightColorsTile(
true,
+ mReduceBrightColorsController,
mHost,
mTestableLooper.getLooper(),
new Handler(mTestableLooper.getLooper()),
mMetricsLogger,
mStatusBarStateController,
mActivityStarter,
- mQSLogger,
- mUserTracker,
- mFakeSettings
+ mQSLogger
);
}
@Test
public void testNotActive() {
+ when(mReduceBrightColorsController.isReduceBrightColorsActivated()).thenReturn(false);
mTile.refreshState();
mTestableLooper.processAllMessages();
@@ -100,33 +102,27 @@ public class ReduceBrightColorsTileTest extends SysuiTestCase {
@Test
public void testActive() {
- mFakeSettings.putIntForUser(
- Settings.Secure.REDUCE_BRIGHT_COLORS_ACTIVATED,
- 1,
- mUserTracker.getUserId());
+ when(mReduceBrightColorsController.isReduceBrightColorsActivated()).thenReturn(true);
mTile.refreshState();
mTestableLooper.processAllMessages();
- assertActiveState();
+ assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
+ assertEquals(mTile.getState().label.toString(),
+ mContext.getString(R.string.quick_settings_reduce_bright_colors_label));
}
@Test
- public void testActive_clicked_isActive() {
+ public void testActive_clicked_featureIsActivated() {
+ when(mReduceBrightColorsController.isReduceBrightColorsActivated()).thenReturn(false);
mTile.refreshState();
mTestableLooper.processAllMessages();
// Validity check
assertEquals(Tile.STATE_INACTIVE, mTile.getState().state);
mTile.handleClick();
- mTile.refreshState();
- mTestableLooper.processAllMessages();
- assertActiveState();
+ verify(mReduceBrightColorsController, times(1))
+ .setReduceBrightColorsActivated(eq(true));
}
- private void assertActiveState() {
- assertEquals(Tile.STATE_ACTIVE, mTile.getState().state);
- assertEquals(mTile.getState().label.toString(),
- mContext.getString(R.string.quick_settings_reduce_bright_colors_label));
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
index 82d1f43e5e4e..094a70e24572 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/AutoTileManagerTest.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.phone;
+import static com.android.systemui.qs.dagger.QSFlagsModule.RBC_AVAILABLE;
+
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
@@ -47,6 +49,7 @@ import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSTileHost;
+import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.qs.SecureSetting;
import com.android.systemui.statusbar.policy.CastController;
import com.android.systemui.statusbar.policy.CastController.CastDevice;
@@ -67,6 +70,8 @@ import org.mockito.MockitoAnnotations;
import java.util.Collections;
import java.util.List;
+import javax.inject.Named;
+
@RunWith(AndroidTestingRunner.class)
@RunWithLooper
@SmallTest
@@ -88,9 +93,11 @@ public class AutoTileManagerTest extends SysuiTestCase {
@Mock private DataSaverController mDataSaverController;
@Mock private ManagedProfileController mManagedProfileController;
@Mock private NightDisplayListener mNightDisplayListener;
+ @Mock private ReduceBrightColorsController mReduceBrightColorsController;
@Mock(answer = Answers.RETURNS_SELF)
private AutoAddTracker.Builder mAutoAddTrackerBuilder;
@Mock private Context mUserContext;
+ private final boolean mIsReduceBrightColorsAvailable = true;
private AutoTileManager mAutoTileManager;
private SecureSettings mSecureSettings;
@@ -130,7 +137,9 @@ public class AutoTileManagerTest extends SysuiTestCase {
DataSaverController dataSaverController,
ManagedProfileController managedProfileController,
NightDisplayListener nightDisplayListener,
- CastController castController) {
+ CastController castController,
+ ReduceBrightColorsController reduceBrightColorsController,
+ @Named(RBC_AVAILABLE) boolean isReduceBrightColorsAvailable) {
return new AutoTileManager(context, autoAddTrackerBuilder, mQsTileHost,
Handler.createAsync(TestableLooper.get(this).getLooper()),
mSecureSettings,
@@ -138,13 +147,15 @@ public class AutoTileManagerTest extends SysuiTestCase {
dataSaverController,
managedProfileController,
nightDisplayListener,
- castController);
+ castController,
+ reduceBrightColorsController,
+ isReduceBrightColorsAvailable);
}
private AutoTileManager createAutoTileManager(Context context) {
return createAutoTileManager(context, mAutoAddTrackerBuilder, mHotspotController,
mDataSaverController, mManagedProfileController, mNightDisplayListener,
- mCastController);
+ mCastController, mReduceBrightColorsController, mIsReduceBrightColorsAvailable);
}
@Test
@@ -157,9 +168,11 @@ public class AutoTileManagerTest extends SysuiTestCase {
ManagedProfileController mPC = mock(ManagedProfileController.class);
NightDisplayListener nDS = mock(NightDisplayListener.class);
CastController cC = mock(CastController.class);
+ ReduceBrightColorsController rBC = mock(ReduceBrightColorsController.class);
AutoTileManager manager =
- createAutoTileManager(mock(Context.class), builder, hC, dSC, mPC, nDS, cC);
+ createAutoTileManager(mock(Context.class), builder, hC, dSC, mPC, nDS, cC, rBC,
+ true);
verify(tracker, never()).initialize();
verify(hC, never()).addCallback(any());
@@ -167,6 +180,7 @@ public class AutoTileManagerTest extends SysuiTestCase {
verify(mPC, never()).addCallback(any());
verify(nDS, never()).setCallback(any());
verify(cC, never()).addCallback(any());
+ verify(rBC, never()).addCallback(any());
assertNull(manager.getSecureSettingForKey(TEST_SETTING));
assertNull(manager.getSecureSettingForKey(TEST_SETTING_COMPONENT));
}
@@ -207,6 +221,10 @@ public class AutoTileManagerTest extends SysuiTestCase {
inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
}
+ InOrder inOrderReduceBrightColors = inOrder(mReduceBrightColorsController);
+ inOrderReduceBrightColors.verify(mReduceBrightColorsController).removeCallback(any());
+ inOrderReduceBrightColors.verify(mReduceBrightColorsController).addCallback(any());
+
InOrder inOrderCast = inOrder(mCastController);
inOrderCast.verify(mCastController).removeCallback(any());
inOrderCast.verify(mCastController).addCallback(any());
@@ -247,6 +265,10 @@ public class AutoTileManagerTest extends SysuiTestCase {
inOrderNightDisplay.verify(mNightDisplayListener).setCallback(isNotNull());
}
+ InOrder inOrderReduceBrightColors = inOrder(mReduceBrightColorsController);
+ inOrderReduceBrightColors.verify(mReduceBrightColorsController).removeCallback(any());
+ inOrderReduceBrightColors.verify(mReduceBrightColorsController).addCallback(any());
+
InOrder inOrderCast = inOrder(mCastController);
inOrderCast.verify(mCastController).removeCallback(any());
inOrderCast.verify(mCastController, never()).addCallback(any());
@@ -315,6 +337,18 @@ public class AutoTileManagerTest extends SysuiTestCase {
verify(mQsTileHost, never()).addTile("night");
}
+ @Test
+ public void reduceBrightColorsTileAdded_whenActivated() {
+ mAutoTileManager.mReduceBrightColorsCallback.onActivated(true);
+ verify(mQsTileHost).addTile("reduce_brightness");
+ }
+
+ @Test
+ public void reduceBrightColorsTileNotAdded_whenDeactivated() {
+ mAutoTileManager.mReduceBrightColorsCallback.onActivated(false);
+ verify(mQsTileHost, never()).addTile("reduce_brightness");
+ }
+
private static List<CastDevice> buildFakeCastDevice(boolean isCasting) {
CastDevice cd = new CastDevice();
cd.state = isCasting ? CastDevice.STATE_CONNECTED : CastDevice.STATE_DISCONNECTED;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
index dd31f522b94d..ec5114e181e8 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationPanelViewTest.java
@@ -71,10 +71,8 @@ import com.android.keyguard.dagger.KeyguardUserSwitcherComponent;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.biometrics.AuthController;
-import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.classifier.FalsingCollectorFake;
import com.android.systemui.classifier.FalsingManagerFake;
-import com.android.systemui.controls.dagger.ControlsComponent;
import com.android.systemui.doze.DozeLog;
import com.android.systemui.media.MediaDataManager;
import com.android.systemui.media.MediaHierarchyManager;
@@ -222,10 +220,6 @@ public class NotificationPanelViewTest extends SysuiTestCase {
@Mock
private FeatureFlags mFeatureFlags;
@Mock
- private ControlsComponent mControlsComponent;
- @Mock
- private BroadcastDispatcher mBroadcastDispatcher;
- @Mock
private AmbientState mAmbientState;
@Mock
private UserManager mUserManager;
@@ -328,9 +322,7 @@ public class NotificationPanelViewTest extends SysuiTestCase {
mUserManager,
mMediaDataManager,
mAmbientState,
- mFeatureFlags,
- mControlsComponent,
- mBroadcastDispatcher);
+ mFeatureFlags);
mNotificationPanelViewController.initDependencies(
mStatusBar,
mNotificationShelfController);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index e52b92648670..b1b71ccba8ce 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -372,6 +372,8 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
new NetworkCapabilities(mNetCapabilities), new LinkProperties(), false);
mNetworkCallback.onCapabilitiesChanged(
mock(Network.class), new NetworkCapabilities(mNetCapabilities));
+ mDefaultCallbackInWifiTracker.onCapabilitiesChanged(
+ mock(Network.class), new NetworkCapabilities(mNetCapabilities));
} else {
mNetworkCallback.onLost(mock(Network.class));
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
index c6812a26c20b..847030e83115 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerWifiTest.java
@@ -223,13 +223,14 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
setWifiEnabled(true);
verifyLastWifiIcon(false, WifiIcons.WIFI_NO_NETWORK);
+ mNetworkController.setNoNetworksAvailable(false);
setWifiStateForVcn(true, testSsid);
setWifiLevelForVcn(0);
-
// Connected, but still not validated - does not show
//verifyLastWifiIcon(false, WifiIcons.WIFI_SIGNAL_STRENGTH[0][0]);
- verifyLastMobileDataIndicatorsForVcn(false, 0, TelephonyIcons.ICON_CWF, false);
+ verifyLastMobileDataIndicatorsForVcn(false, 0, 0, false);
+ mNetworkController.setNoNetworksAvailable(true);
for (int testLevel = 0; testLevel < WifiIcons.WIFI_LEVEL_COUNT; testLevel++) {
setWifiLevelForVcn(testLevel);
@@ -239,7 +240,7 @@ public class NetworkControllerWifiTest extends NetworkControllerBaseTest {
setConnectivityViaBroadcastForVcn(
NetworkCapabilities.TRANSPORT_CELLULAR, false, true, mVcnTransportInfo);
- verifyLastMobileDataIndicatorsForVcn(false, testLevel, TelephonyIcons.ICON_CWF, false);
+ verifyLastMobileDataIndicatorsForVcn(true, testLevel, TelephonyIcons.ICON_CWF, false);
}
}
diff --git a/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
index bafb641dcc9e..6828dd916701 100644
--- a/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
+++ b/services/accessibility/java/com/android/server/accessibility/ActionReplacingCallback.java
@@ -40,29 +40,34 @@ public class ActionReplacingCallback extends IAccessibilityInteractionConnection
private final IAccessibilityInteractionConnectionCallback mServiceCallback;
private final IAccessibilityInteractionConnection mConnectionWithReplacementActions;
private final int mInteractionId;
+ private final int mNodeWithReplacementActionsInteractionId;
private final Object mLock = new Object();
@GuardedBy("mLock")
- List<AccessibilityNodeInfo> mNodesWithReplacementActions;
+ private boolean mReplacementNodeIsReadyOrFailed;
+
+ @GuardedBy("mLock")
+ AccessibilityNodeInfo mNodeWithReplacementActions;
@GuardedBy("mLock")
List<AccessibilityNodeInfo> mNodesFromOriginalWindow;
@GuardedBy("mLock")
+ boolean mSetFindNodeFromOriginalWindowCalled = false;
+
+ @GuardedBy("mLock")
AccessibilityNodeInfo mNodeFromOriginalWindow;
- // Keep track of whether or not we've been called back for a single node
@GuardedBy("mLock")
- boolean mSingleNodeCallbackHappened;
+ boolean mSetFindNodesFromOriginalWindowCalled = false;
+
- // Keep track of whether or not we've been called back for multiple node
@GuardedBy("mLock")
- boolean mMultiNodeCallbackHappened;
+ List<AccessibilityNodeInfo> mPrefetchedNodesFromOriginalWindow;
- // We shouldn't get any more callbacks after we've called back the original service, but
- // keep track to make sure we catch such strange things
@GuardedBy("mLock")
- boolean mDone;
+ boolean mSetPrefetchFromOriginalWindowCalled = false;
+
public ActionReplacingCallback(IAccessibilityInteractionConnectionCallback serviceCallback,
IAccessibilityInteractionConnection connectionWithReplacementActions,
@@ -70,19 +75,20 @@ public class ActionReplacingCallback extends IAccessibilityInteractionConnection
mServiceCallback = serviceCallback;
mConnectionWithReplacementActions = connectionWithReplacementActions;
mInteractionId = interactionId;
+ mNodeWithReplacementActionsInteractionId = interactionId + 1;
// Request the root node of the replacing window
final long identityToken = Binder.clearCallingIdentity();
try {
mConnectionWithReplacementActions.findAccessibilityNodeInfoByAccessibilityId(
- AccessibilityNodeInfo.ROOT_NODE_ID, null, interactionId + 1, this, 0,
+ AccessibilityNodeInfo.ROOT_NODE_ID, null,
+ mNodeWithReplacementActionsInteractionId, this, 0,
interrogatingPid, interrogatingTid, null, null);
} catch (RemoteException re) {
if (DEBUG) {
Slog.e(LOG_TAG, "Error calling findAccessibilityNodeInfoByAccessibilityId()");
}
- // Pretend we already got a (null) list of replacement nodes
- mMultiNodeCallbackHappened = true;
+ mReplacementNodeIsReadyOrFailed = true;
} finally {
Binder.restoreCallingIdentity(identityToken);
}
@@ -90,46 +96,67 @@ public class ActionReplacingCallback extends IAccessibilityInteractionConnection
@Override
public void setFindAccessibilityNodeInfoResult(AccessibilityNodeInfo info, int interactionId) {
- boolean readyForCallback;
- synchronized(mLock) {
+ synchronized (mLock) {
if (interactionId == mInteractionId) {
mNodeFromOriginalWindow = info;
+ mSetFindNodeFromOriginalWindowCalled = true;
+ } else if (interactionId == mNodeWithReplacementActionsInteractionId) {
+ mNodeWithReplacementActions = info;
+ mReplacementNodeIsReadyOrFailed = true;
} else {
Slog.e(LOG_TAG, "Callback with unexpected interactionId");
return;
}
-
- mSingleNodeCallbackHappened = true;
- readyForCallback = mMultiNodeCallbackHappened;
- }
- if (readyForCallback) {
- replaceInfoActionsAndCallService();
}
+ replaceInfoActionsAndCallServiceIfReady();
}
@Override
public void setFindAccessibilityNodeInfosResult(List<AccessibilityNodeInfo> infos,
int interactionId) {
- boolean callbackForSingleNode;
- boolean callbackForMultipleNodes;
- synchronized(mLock) {
+ synchronized (mLock) {
if (interactionId == mInteractionId) {
mNodesFromOriginalWindow = infos;
- } else if (interactionId == mInteractionId + 1) {
- mNodesWithReplacementActions = infos;
+ mSetFindNodesFromOriginalWindowCalled = true;
+ } else if (interactionId == mNodeWithReplacementActionsInteractionId) {
+ setNodeWithReplacementActionsFromList(infos);
+ mReplacementNodeIsReadyOrFailed = true;
} else {
Slog.e(LOG_TAG, "Callback with unexpected interactionId");
return;
}
- callbackForSingleNode = mSingleNodeCallbackHappened;
- callbackForMultipleNodes = mMultiNodeCallbackHappened;
- mMultiNodeCallbackHappened = true;
}
- if (callbackForSingleNode) {
- replaceInfoActionsAndCallService();
+ replaceInfoActionsAndCallServiceIfReady();
+ }
+
+ @Override
+ public void setPrefetchAccessibilityNodeInfoResult(List<AccessibilityNodeInfo> infos,
+ int interactionId)
+ throws RemoteException {
+ synchronized (mLock) {
+ if (interactionId == mInteractionId) {
+ mPrefetchedNodesFromOriginalWindow = infos;
+ mSetPrefetchFromOriginalWindowCalled = true;
+ } else {
+ Slog.e(LOG_TAG, "Callback with unexpected interactionId");
+ return;
+ }
}
- if (callbackForMultipleNodes) {
- replaceInfosActionsAndCallService();
+ replaceInfoActionsAndCallServiceIfReady();
+ }
+
+ private void replaceInfoActionsAndCallServiceIfReady() {
+ replaceInfoActionsAndCallService();
+ replaceInfosActionsAndCallService();
+ replacePrefetchInfosActionsAndCallService();
+ }
+
+ private void setNodeWithReplacementActionsFromList(List<AccessibilityNodeInfo> infos) {
+ for (int i = 0; i < infos.size(); i++) {
+ AccessibilityNodeInfo info = infos.get(i);
+ if (info.getSourceNodeId() == AccessibilityNodeInfo.ROOT_NODE_ID) {
+ mNodeWithReplacementActions = info;
+ }
}
}
@@ -142,55 +169,81 @@ public class ActionReplacingCallback extends IAccessibilityInteractionConnection
private void replaceInfoActionsAndCallService() {
final AccessibilityNodeInfo nodeToReturn;
+ boolean doCallback = false;
synchronized (mLock) {
- if (mDone) {
- if (DEBUG) {
- Slog.e(LOG_TAG, "Extra callback");
- }
- return;
- }
- if (mNodeFromOriginalWindow != null) {
+ doCallback = mReplacementNodeIsReadyOrFailed
+ && mSetFindNodeFromOriginalWindowCalled;
+ if (doCallback && mNodeFromOriginalWindow != null) {
replaceActionsOnInfoLocked(mNodeFromOriginalWindow);
+ mSetFindNodeFromOriginalWindowCalled = false;
}
- recycleReplaceActionNodesLocked();
nodeToReturn = mNodeFromOriginalWindow;
- mDone = true;
}
- try {
- mServiceCallback.setFindAccessibilityNodeInfoResult(nodeToReturn, mInteractionId);
- } catch (RemoteException re) {
- if (DEBUG) {
- Slog.e(LOG_TAG, "Failed to setFindAccessibilityNodeInfoResult");
+ if (doCallback) {
+ try {
+ mServiceCallback.setFindAccessibilityNodeInfoResult(nodeToReturn, mInteractionId);
+ } catch (RemoteException re) {
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "Failed to setFindAccessibilityNodeInfoResult");
+ }
}
}
}
private void replaceInfosActionsAndCallService() {
- final List<AccessibilityNodeInfo> nodesToReturn;
+ List<AccessibilityNodeInfo> nodesToReturn = null;
+ boolean doCallback = false;
synchronized (mLock) {
- if (mDone) {
+ doCallback = mReplacementNodeIsReadyOrFailed
+ && mSetFindNodesFromOriginalWindowCalled;
+ if (doCallback) {
+ nodesToReturn = replaceActionsLocked(mNodesFromOriginalWindow);
+ mSetFindNodesFromOriginalWindowCalled = false;
+ }
+ }
+ if (doCallback) {
+ try {
+ mServiceCallback.setFindAccessibilityNodeInfosResult(nodesToReturn, mInteractionId);
+ } catch (RemoteException re) {
if (DEBUG) {
- Slog.e(LOG_TAG, "Extra callback");
+ Slog.e(LOG_TAG, "Failed to setFindAccessibilityNodeInfosResult");
}
- return;
}
- if (mNodesFromOriginalWindow != null) {
- for (int i = 0; i < mNodesFromOriginalWindow.size(); i++) {
- replaceActionsOnInfoLocked(mNodesFromOriginalWindow.get(i));
+ }
+ }
+
+ private void replacePrefetchInfosActionsAndCallService() {
+ List<AccessibilityNodeInfo> nodesToReturn = null;
+ boolean doCallback = false;
+ synchronized (mLock) {
+ doCallback = mReplacementNodeIsReadyOrFailed
+ && mSetPrefetchFromOriginalWindowCalled;
+ if (doCallback) {
+ nodesToReturn = replaceActionsLocked(mPrefetchedNodesFromOriginalWindow);
+ mSetPrefetchFromOriginalWindowCalled = false;
+ }
+ }
+ if (doCallback) {
+ try {
+ mServiceCallback.setPrefetchAccessibilityNodeInfoResult(
+ nodesToReturn, mInteractionId);
+ } catch (RemoteException re) {
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "Failed to setFindAccessibilityNodeInfosResult");
}
}
- recycleReplaceActionNodesLocked();
- nodesToReturn = (mNodesFromOriginalWindow == null)
- ? null : new ArrayList<>(mNodesFromOriginalWindow);
- mDone = true;
}
- try {
- mServiceCallback.setFindAccessibilityNodeInfosResult(nodesToReturn, mInteractionId);
- } catch (RemoteException re) {
- if (DEBUG) {
- Slog.e(LOG_TAG, "Failed to setFindAccessibilityNodeInfosResult");
+ }
+
+ @GuardedBy("mLock")
+ private List<AccessibilityNodeInfo> replaceActionsLocked(List<AccessibilityNodeInfo> infos) {
+ if (infos != null) {
+ for (int i = 0; i < infos.size(); i++) {
+ replaceActionsOnInfoLocked(infos.get(i));
}
}
+ return (infos == null)
+ ? null : new ArrayList<>(infos);
}
@GuardedBy("mLock")
@@ -204,40 +257,22 @@ public class ActionReplacingCallback extends IAccessibilityInteractionConnection
info.setDismissable(false);
// We currently only replace actions for the root node
if ((info.getSourceNodeId() == AccessibilityNodeInfo.ROOT_NODE_ID)
- && mNodesWithReplacementActions != null) {
- // This list should always contain a single node with the root ID
- for (int i = 0; i < mNodesWithReplacementActions.size(); i++) {
- AccessibilityNodeInfo nodeWithReplacementActions =
- mNodesWithReplacementActions.get(i);
- if (nodeWithReplacementActions.getSourceNodeId()
- == AccessibilityNodeInfo.ROOT_NODE_ID) {
- List<AccessibilityAction> actions = nodeWithReplacementActions.getActionList();
- if (actions != null) {
- for (int j = 0; j < actions.size(); j++) {
- info.addAction(actions.get(j));
- }
- // The PIP needs to be able to take accessibility focus
- info.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
- info.addAction(AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
- }
- info.setClickable(nodeWithReplacementActions.isClickable());
- info.setFocusable(nodeWithReplacementActions.isFocusable());
- info.setContextClickable(nodeWithReplacementActions.isContextClickable());
- info.setScrollable(nodeWithReplacementActions.isScrollable());
- info.setLongClickable(nodeWithReplacementActions.isLongClickable());
- info.setDismissable(nodeWithReplacementActions.isDismissable());
+ && mNodeWithReplacementActions != null) {
+ List<AccessibilityAction> actions = mNodeWithReplacementActions.getActionList();
+ if (actions != null) {
+ for (int j = 0; j < actions.size(); j++) {
+ info.addAction(actions.get(j));
}
+ // The PIP needs to be able to take accessibility focus
+ info.addAction(AccessibilityAction.ACTION_ACCESSIBILITY_FOCUS);
+ info.addAction(AccessibilityAction.ACTION_CLEAR_ACCESSIBILITY_FOCUS);
}
+ info.setClickable(mNodeWithReplacementActions.isClickable());
+ info.setFocusable(mNodeWithReplacementActions.isFocusable());
+ info.setContextClickable(mNodeWithReplacementActions.isContextClickable());
+ info.setScrollable(mNodeWithReplacementActions.isScrollable());
+ info.setLongClickable(mNodeWithReplacementActions.isLongClickable());
+ info.setDismissable(mNodeWithReplacementActions.isDismissable());
}
}
-
- @GuardedBy("mLock")
- private void recycleReplaceActionNodesLocked() {
- if (mNodesWithReplacementActions == null) return;
- for (int i = mNodesWithReplacementActions.size() - 1; i >= 0; i--) {
- AccessibilityNodeInfo nodeWithReplacementAction = mNodesWithReplacementActions.get(i);
- nodeWithReplacementAction.recycle();
- }
- mNodesWithReplacementActions = null;
- }
}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 50ad6617b1fe..e251700498ee 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -19,6 +19,7 @@ package com.android.server.appwidget;
import static android.content.Context.KEYGUARD_SERVICE;
import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
+import static android.content.res.Resources.ID_NULL;
import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
@@ -2578,9 +2579,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
info.updatePeriodMillis = sa.getInt(
com.android.internal.R.styleable.AppWidgetProviderInfo_updatePeriodMillis, 0);
info.initialLayout = sa.getResourceId(
- com.android.internal.R.styleable.AppWidgetProviderInfo_initialLayout, 0);
+ com.android.internal.R.styleable.AppWidgetProviderInfo_initialLayout, ID_NULL);
info.initialKeyguardLayout = sa.getResourceId(com.android.internal.R.styleable.
- AppWidgetProviderInfo_initialKeyguardLayout, 0);
+ AppWidgetProviderInfo_initialKeyguardLayout, ID_NULL);
String className = sa
.getString(com.android.internal.R.styleable.AppWidgetProviderInfo_configure);
@@ -2591,11 +2592,12 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
info.label = activityInfo.loadLabel(pm).toString();
info.icon = activityInfo.getIconResource();
info.previewImage = sa.getResourceId(
- com.android.internal.R.styleable.AppWidgetProviderInfo_previewImage, 0);
+ com.android.internal.R.styleable.AppWidgetProviderInfo_previewImage, ID_NULL);
info.previewLayout = sa.getResourceId(
- com.android.internal.R.styleable.AppWidgetProviderInfo_previewLayout, 0);
+ com.android.internal.R.styleable.AppWidgetProviderInfo_previewLayout, ID_NULL);
info.autoAdvanceViewId = sa.getResourceId(
- com.android.internal.R.styleable.AppWidgetProviderInfo_autoAdvanceViewId, -1);
+ com.android.internal.R.styleable.AppWidgetProviderInfo_autoAdvanceViewId,
+ View.NO_ID);
info.resizeMode = sa.getInt(
com.android.internal.R.styleable.AppWidgetProviderInfo_resizeMode,
AppWidgetProviderInfo.RESIZE_NONE);
@@ -2605,8 +2607,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
info.widgetFeatures = sa.getInt(
com.android.internal.R.styleable.AppWidgetProviderInfo_widgetFeatures, 0);
info.descriptionRes = sa.getResourceId(
- com.android.internal.R.styleable.AppWidgetProviderInfo_description,
- Resources.ID_NULL);
+ com.android.internal.R.styleable.AppWidgetProviderInfo_description, ID_NULL);
sa.recycle();
return info;
} catch (IOException | PackageManager.NameNotFoundException | XmlPullParserException e) {
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 542d527177a1..ff3d0162a2f8 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -120,6 +120,7 @@ import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
import android.net.NetworkTestResultParcelable;
import android.net.NetworkUtils;
import android.net.NetworkWatchlistManager;
@@ -155,7 +156,6 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
-import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
@@ -324,7 +324,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
// 0 is full bad, 100 is full good
private int mDefaultInetConditionPublished = 0;
- private INetworkManagementService mNMS;
@VisibleForTesting
protected IDnsResolver mDnsResolver;
@VisibleForTesting
@@ -1040,15 +1039,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
}
- public ConnectivityService(Context context, INetworkManagementService netManager,
- INetworkStatsService statsService) {
- this(context, netManager, statsService, getDnsResolver(context), new IpConnectivityLog(),
+ public ConnectivityService(Context context, INetworkStatsService statsService) {
+ this(context, statsService, getDnsResolver(context), new IpConnectivityLog(),
NetdService.getInstance(), new Dependencies());
}
@VisibleForTesting
- protected ConnectivityService(Context context, INetworkManagementService netManager,
- INetworkStatsService statsService, IDnsResolver dnsresolver, IpConnectivityLog logger,
+ protected ConnectivityService(Context context, INetworkStatsService statsService,
+ IDnsResolver dnsresolver, IpConnectivityLog logger,
INetd netd, Dependencies deps) {
if (DBG) log("ConnectivityService starting up");
@@ -1095,7 +1093,6 @@ public class ConnectivityService extends IConnectivityManager.Stub
// TODO: Consider making the timer customizable.
mNascentDelayMs = DEFAULT_NASCENT_DELAY_MS;
- mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
mStatsService = Objects.requireNonNull(statsService, "missing INetworkStatsService");
mPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
mPolicyManagerInternal = Objects.requireNonNull(
@@ -1203,7 +1200,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
mUserAllContext.registerReceiver(mIntentReceiver, intentFilter,
null /* broadcastPermission */, mHandler);
- mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNMS, mNetd);
+ mNetworkActivityTracker = new LegacyNetworkActivityTracker(mContext, mHandler, mNetd);
mNetdCallback = new NetdCallback();
try {
@@ -1237,12 +1234,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
mDnsManager = new DnsManager(mContext, mDnsResolver);
registerPrivateDnsSettingsCallbacks();
- mNoServiceNetwork = new NetworkAgentInfo(null,
+ mNoServiceNetwork = new NetworkAgentInfo(null,
new Network(NO_SERVICE_NET_ID),
new NetworkInfo(TYPE_NONE, 0, "", ""),
new LinkProperties(), new NetworkCapabilities(), 0, mContext,
null, new NetworkAgentConfig(), this, null,
- null, null, 0, INVALID_UID,
+ null, 0, INVALID_UID,
mQosCallbackTracker);
}
@@ -2201,8 +2198,45 @@ public class ConnectivityService extends IConnectivityManager.Stub
"ConnectivityService");
}
+ /**
+ * Performs a strict and comprehensive check of whether a calling package is allowed to
+ * change the state of network, as the condition differs for pre-M, M+, and
+ * privileged/preinstalled apps. The caller is expected to have either the
+ * CHANGE_NETWORK_STATE or the WRITE_SETTINGS permission declared. Either of these
+ * permissions allow changing network state; WRITE_SETTINGS is a runtime permission and
+ * can be revoked, but (except in M, excluding M MRs), CHANGE_NETWORK_STATE is a normal
+ * permission and cannot be revoked. See http://b/23597341
+ *
+ * Note: if the check succeeds because the application holds WRITE_SETTINGS, the operation
+ * of this app will be updated to the current time.
+ */
private void enforceChangePermission(String callingPkg, String callingAttributionTag) {
- ConnectivityManager.enforceChangePermission(mContext, callingPkg, callingAttributionTag);
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.CHANGE_NETWORK_STATE)
+ == PackageManager.PERMISSION_GRANTED) {
+ return;
+ }
+
+ if (callingPkg == null) {
+ throw new SecurityException("Calling package name is null.");
+ }
+
+ final AppOpsManager appOpsMgr = mContext.getSystemService(AppOpsManager.class);
+ final int uid = mDeps.getCallingUid();
+ final int mode = appOpsMgr.noteOpNoThrow(AppOpsManager.OPSTR_WRITE_SETTINGS, uid,
+ callingPkg, callingAttributionTag, null /* message */);
+
+ if (mode == AppOpsManager.MODE_ALLOWED) {
+ return;
+ }
+
+ if ((mode == AppOpsManager.MODE_DEFAULT) && (mContext.checkCallingOrSelfPermission(
+ android.Manifest.permission.WRITE_SETTINGS) == PackageManager.PERMISSION_GRANTED)) {
+ return;
+ }
+
+ throw new SecurityException(callingPkg + " was not granted either of these permissions:"
+ + android.Manifest.permission.CHANGE_NETWORK_STATE + ","
+ + android.Manifest.permission.WRITE_SETTINGS + ".");
}
private void enforceSettingsPermission() {
@@ -6030,7 +6064,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
final NetworkAgentInfo nai = new NetworkAgentInfo(na,
new Network(mNetIdManager.reserveNetId()), new NetworkInfo(networkInfo), lp, nc,
currentScore, mContext, mTrackerHandler, new NetworkAgentConfig(networkAgentConfig),
- this, mNetd, mDnsResolver, mNMS, providerId, uid, mQosCallbackTracker);
+ this, mNetd, mDnsResolver, providerId, uid, mQosCallbackTracker);
// Make sure the LinkProperties and NetworkCapabilities reflect what the agent info says.
processCapabilitiesFromAgent(nai, nc);
@@ -7952,8 +7986,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
final UnderlyingNetworkInfo[] underlyingNetworkInfos = getAllVpnInfo();
try {
- mStatsService.forceUpdateIfaces(getDefaultNetworks(), getAllNetworkState(), activeIface,
- underlyingNetworkInfos);
+ final ArrayList<NetworkStateSnapshot> snapshots = new ArrayList<>();
+ // TODO: Directly use NetworkStateSnapshot when feasible.
+ for (final NetworkState state : getAllNetworkState()) {
+ final NetworkStateSnapshot snapshot = new NetworkStateSnapshot(state.network,
+ state.networkCapabilities, state.linkProperties, state.subscriberId,
+ state.legacyNetworkType);
+ snapshots.add(snapshot);
+ }
+ mStatsService.forceUpdateIfaces(getDefaultNetworks(), snapshots.toArray(
+ new NetworkStateSnapshot[0]), activeIface, underlyingNetworkInfos);
} catch (Exception ignored) {
}
}
@@ -8186,7 +8228,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
TestNetworkService.enforceTestNetworkPermissions(mContext);
if (mTNS == null) {
- mTNS = new TestNetworkService(mContext, mNMS);
+ mTNS = new TestNetworkService(mContext);
}
return mTNS;
@@ -8661,9 +8703,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
private class NetdCallback extends BaseNetdUnsolicitedEventListener {
@Override
- public void onInterfaceClassActivityChanged(boolean isActive, int timerLabel,
+ public void onInterfaceClassActivityChanged(boolean isActive, int transportType,
long timestampNs, int uid) {
- mNetworkActivityTracker.setAndReportNetworkActive(isActive, timerLabel, timestampNs);
+ mNetworkActivityTracker.setAndReportNetworkActive(isActive, transportType, timestampNs);
+ }
+
+ @Override
+ public void onInterfaceLinkStateChanged(String iface, boolean up) {
+ for (NetworkAgentInfo nai : mNetworkAgentInfos) {
+ nai.clatd.interfaceLinkStateChanged(iface, up);
+ }
+ }
+
+ @Override
+ public void onInterfaceRemoved(String iface) {
+ for (NetworkAgentInfo nai : mNetworkAgentInfos) {
+ nai.clatd.interfaceRemoved(iface);
+ }
}
}
@@ -8697,7 +8753,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
LegacyNetworkActivityTracker(@NonNull Context context, @NonNull Handler handler,
- @NonNull INetworkManagementService nms, @NonNull INetd netd) {
+ @NonNull INetd netd) {
mContext = context;
mNetd = netd;
mHandler = handler;
diff --git a/services/core/java/com/android/server/ConnectivityServiceInitializer.java b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
index 0779f7117d82..097441f706e6 100644
--- a/services/core/java/com/android/server/ConnectivityServiceInitializer.java
+++ b/services/core/java/com/android/server/ConnectivityServiceInitializer.java
@@ -21,7 +21,6 @@ import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import android.content.Context;
import android.net.INetworkStatsService;
-import android.os.INetworkManagementService;
import android.os.ServiceManager;
import android.util.Log;
@@ -38,8 +37,7 @@ public final class ConnectivityServiceInitializer extends SystemService {
// Load JNI libraries used by ConnectivityService and its dependencies
System.loadLibrary("service-connectivity");
// TODO: Define formal APIs to get the needed services.
- mConnectivity = new ConnectivityService(context, getNetworkManagementService(),
- getNetworkStatsService());
+ mConnectivity = new ConnectivityService(context, getNetworkStatsService());
}
@Override
@@ -49,11 +47,6 @@ public final class ConnectivityServiceInitializer extends SystemService {
/* allowIsolated= */ false, DUMP_FLAG_PRIORITY_HIGH | DUMP_FLAG_PRIORITY_NORMAL);
}
- private INetworkManagementService getNetworkManagementService() {
- return INetworkManagementService.Stub.asInterface(
- ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE));
- }
-
private INetworkStatsService getNetworkStatsService() {
return INetworkStatsService.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 44054088d937..10d6570929ed 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -44,7 +44,6 @@ import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENAB
import android.annotation.NonNull;
import android.app.ActivityManager;
import android.content.Context;
-import android.net.ConnectivityManager;
import android.net.INetd;
import android.net.INetdUnsolicitedEventListener;
import android.net.INetworkManagementEventObserver;
@@ -54,7 +53,6 @@ import android.net.InterfaceConfiguration;
import android.net.InterfaceConfigurationParcel;
import android.net.IpPrefix;
import android.net.LinkAddress;
-import android.net.Network;
import android.net.NetworkPolicyManager;
import android.net.NetworkStack;
import android.net.NetworkStats;
@@ -974,19 +972,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
@Override
- public void setDnsForwarders(Network network, String[] dns) {
- NetworkStack.checkNetworkStackPermission(mContext);
-
- int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
-
- try {
- mNetdService.tetherDnsSet(netId, dns);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
public String[] getDnsForwarders() {
NetworkStack.checkNetworkStackPermission(mContext);
try {
@@ -1775,27 +1760,6 @@ public class NetworkManagementService extends INetworkManagementService.Stub {
}
@Override
- public void addLegacyRouteForNetId(int netId, RouteInfo routeInfo, int uid) {
- NetworkStack.checkNetworkStackPermission(mContext);
-
- final LinkAddress la = routeInfo.getDestinationLinkAddress();
- final String ifName = routeInfo.getInterface();
- final String dst = la.toString();
- final String nextHop;
-
- if (routeInfo.hasGateway()) {
- nextHop = routeInfo.getGateway().getHostAddress();
- } else {
- nextHop = "";
- }
- try {
- mNetdService.networkAddLegacyRoute(netId, ifName, dst, nextHop, uid);
- } catch (RemoteException | ServiceSpecificException e) {
- throw new IllegalStateException(e);
- }
- }
-
- @Override
public void allowProtect(int uid) {
NetworkStack.checkNetworkStackPermission(mContext);
diff --git a/services/core/java/com/android/server/TestNetworkService.java b/services/core/java/com/android/server/TestNetworkService.java
index 96f832d26816..55408ea61566 100644
--- a/services/core/java/com/android/server/TestNetworkService.java
+++ b/services/core/java/com/android/server/TestNetworkService.java
@@ -32,7 +32,6 @@ import android.net.NetworkAgent;
import android.net.NetworkAgentConfig;
import android.net.NetworkCapabilities;
import android.net.NetworkProvider;
-import android.net.NetworkStack;
import android.net.RouteInfo;
import android.net.StringNetworkSpecifier;
import android.net.TestNetworkInterface;
@@ -41,7 +40,6 @@ import android.os.Binder;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.IBinder;
-import android.os.INetworkManagementService;
import android.os.Looper;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
@@ -51,6 +49,7 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.NetdUtils;
import com.android.net.module.util.NetworkStackConstants;
+import com.android.net.module.util.PermissionUtils;
import java.io.UncheckedIOException;
import java.net.Inet4Address;
@@ -69,7 +68,6 @@ class TestNetworkService extends ITestNetworkManager.Stub {
@NonNull private static final AtomicInteger sTestTunIndex = new AtomicInteger();
@NonNull private final Context mContext;
- @NonNull private final INetworkManagementService mNMS;
@NonNull private final INetd mNetd;
@NonNull private final HandlerThread mHandlerThread;
@@ -82,14 +80,12 @@ class TestNetworkService extends ITestNetworkManager.Stub {
private static native int jniCreateTunTap(boolean isTun, @NonNull String iface);
@VisibleForTesting
- protected TestNetworkService(
- @NonNull Context context, @NonNull INetworkManagementService netManager) {
+ protected TestNetworkService(@NonNull Context context) {
mHandlerThread = new HandlerThread("TestNetworkServiceThread");
mHandlerThread.start();
mHandler = new Handler(mHandlerThread.getLooper());
mContext = Objects.requireNonNull(context, "missing Context");
- mNMS = Objects.requireNonNull(netManager, "missing INetworkManagementService");
mNetd = Objects.requireNonNull(NetdService.getInstance(), "could not get netd instance");
mCm = mContext.getSystemService(ConnectivityManager.class);
mNetworkProvider = new NetworkProvider(mContext, mHandler.getLooper(),
@@ -324,7 +320,7 @@ class TestNetworkService extends ITestNetworkManager.Stub {
try {
final long token = Binder.clearCallingIdentity();
try {
- NetworkStack.checkNetworkStackPermission(mContext);
+ PermissionUtils.enforceNetworkStackPermission(mContext);
NetdUtils.setInterfaceUp(mNetd, iface);
} finally {
Binder.restoreCallingIdentity(token);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 7cd494976c94..e8a4fa20cd30 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -15179,8 +15179,8 @@ public class ActivityManagerService extends IActivityManager.Stub
mFgsStartTempAllowList.add(changingUid, durationMs, reasonCode, reason,
callingUid);
}
- setAppIdTempAllowlistStateLSP(changingUid, adding);
}
+ setAppIdTempAllowlistStateLSP(changingUid, adding);
}
}
}
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index 2de709ebe71d..42fcd4460386 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -880,8 +880,8 @@ public class ClipboardService extends SystemService {
CharSequence sourceAppLabel = null;
if (clipboard.mPrimaryClipPackage != null) {
try {
- sourceAppLabel = mPm.getApplicationLabel(
- mPm.getApplicationInfo(clipboard.mPrimaryClipPackage, 0));
+ sourceAppLabel = mPm.getApplicationLabel(mPm.getApplicationInfoAsUser(
+ clipboard.mPrimaryClipPackage, 0, userId));
} catch (PackageManager.NameNotFoundException e) {
// leave label as null
}
@@ -889,7 +889,7 @@ public class ClipboardService extends SystemService {
try {
CharSequence callingAppLabel = mPm.getApplicationLabel(
- mPm.getApplicationInfo(callingPackage, 0));
+ mPm.getApplicationInfoAsUser(callingPackage, 0, userId));
String message;
if (sourceAppLabel != null) {
message = callingAppLabel + " pasted from " + sourceAppLabel;
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index df83df9a73fb..5cf478a3ef1f 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -80,6 +80,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
}
/**
+ * @param change an object generated by services/core/xsd/platform-compat-config.xsd
+ */
+ public CompatChange(Change change) {
+ this(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
+ change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
+ change.getDescription(), change.getOverridable());
+ }
+
+ /**
* @param changeId Unique ID for the change. See {@link android.compat.Compatibility}.
* @param name Short descriptive name.
* @param enableAfterTargetSdk {@code targetSdkVersion} restriction. See {@link EnabledAfter};
@@ -93,15 +102,10 @@ public final class CompatChange extends CompatibilityChangeInfo {
boolean overridable) {
super(changeId, name, enableAfterTargetSdk, enableSinceTargetSdk, disabled, loggingOnly,
description, overridable);
- }
- /**
- * @param change an object generated by services/core/xsd/platform-compat-config.xsd
- */
- public CompatChange(Change change) {
- super(change.getId(), change.getName(), change.getEnableAfterTargetSdk(),
- change.getEnableSinceTargetSdk(), change.getDisabled(), change.getLoggingOnly(),
- change.getDescription(), change.getOverridable());
+ // Initialize override maps.
+ mEvaluatedOverrides = new HashMap<>();
+ mRawOverrides = new HashMap<>();
}
void registerListener(ChangeListener listener) {
@@ -127,18 +131,13 @@ public final class CompatChange extends CompatibilityChangeInfo {
throw new IllegalArgumentException(
"Can't add overrides for a logging only change " + toString());
}
- if (mEvaluatedOverrides == null) {
- mEvaluatedOverrides = new HashMap<>();
- }
mEvaluatedOverrides.put(pname, enabled);
notifyListener(pname);
}
private void removePackageOverrideInternal(String pname) {
- if (mEvaluatedOverrides != null) {
- if (mEvaluatedOverrides.remove(pname) != null) {
- notifyListener(pname);
- }
+ if (mEvaluatedOverrides.remove(pname) != null) {
+ notifyListener(pname);
}
}
@@ -157,9 +156,6 @@ public final class CompatChange extends CompatibilityChangeInfo {
throw new IllegalArgumentException(
"Can't add overrides for a logging only change " + toString());
}
- if (mRawOverrides == null) {
- mRawOverrides = new HashMap<>();
- }
mRawOverrides.put(packageName, override);
recheckOverride(packageName, allowedState, context);
}
@@ -212,7 +208,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
}
boolean hasPackageOverride(String pname) {
- return mRawOverrides != null && mRawOverrides.containsKey(pname);
+ return mRawOverrides.containsKey(pname);
}
/**
* Remove any package override for the given package name, restoring the default behaviour.
@@ -223,7 +219,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
*/
boolean removePackageOverride(String pname, OverrideAllowedState allowedState,
Context context) {
- if (mRawOverrides != null && (mRawOverrides.remove(pname) != null)) {
+ if (mRawOverrides.remove(pname) != null) {
recheckOverride(pname, allowedState, context);
return true;
}
@@ -241,7 +237,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
if (app == null) {
return defaultValue();
}
- if (mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(app.packageName)) {
+ if (mEvaluatedOverrides.containsKey(app.packageName)) {
return mEvaluatedOverrides.get(app.packageName);
}
if (getDisabled()) {
@@ -289,7 +285,7 @@ public final class CompatChange extends CompatibilityChangeInfo {
* @return true if there is such override
*/
private boolean hasOverride(String packageName) {
- return mEvaluatedOverrides != null && mEvaluatedOverrides.containsKey(packageName);
+ return mEvaluatedOverrides.containsKey(packageName);
}
/**
@@ -298,20 +294,15 @@ public final class CompatChange extends CompatibilityChangeInfo {
* @return true if there is such a deferred override
*/
private boolean hasRawOverride(String packageName) {
- return mRawOverrides != null && mRawOverrides.containsKey(packageName);
+ return mRawOverrides.containsKey(packageName);
}
- void loadOverrides(ChangeOverrides changeOverrides) {
- if (mRawOverrides == null) {
- mRawOverrides = new HashMap<>();
- }
+ void clearOverrides() {
mRawOverrides.clear();
-
- if (mEvaluatedOverrides == null) {
- mEvaluatedOverrides = new HashMap<>();
- }
mEvaluatedOverrides.clear();
+ }
+ void loadOverrides(ChangeOverrides changeOverrides) {
// Load deferred overrides for backwards compatibility
if (changeOverrides.getDeferred() != null) {
for (OverrideValue override : changeOverrides.getDeferred().getOverrideValue()) {
@@ -345,34 +336,30 @@ public final class CompatChange extends CompatibilityChangeInfo {
}
ChangeOverrides saveOverrides() {
- if (mRawOverrides == null || mRawOverrides.isEmpty()) {
+ if (mRawOverrides.isEmpty()) {
return null;
}
ChangeOverrides changeOverrides = new ChangeOverrides();
changeOverrides.setChangeId(getId());
ChangeOverrides.Raw rawOverrides = new ChangeOverrides.Raw();
List<RawOverrideValue> rawList = rawOverrides.getRawOverrideValue();
- if (mRawOverrides != null) {
- for (Map.Entry<String, PackageOverride> entry : mRawOverrides.entrySet()) {
- RawOverrideValue override = new RawOverrideValue();
- override.setPackageName(entry.getKey());
- override.setMinVersionCode(entry.getValue().getMinVersionCode());
- override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
- override.setEnabled(entry.getValue().getEnabled());
- rawList.add(override);
- }
+ for (Map.Entry<String, PackageOverride> entry : mRawOverrides.entrySet()) {
+ RawOverrideValue override = new RawOverrideValue();
+ override.setPackageName(entry.getKey());
+ override.setMinVersionCode(entry.getValue().getMinVersionCode());
+ override.setMaxVersionCode(entry.getValue().getMaxVersionCode());
+ override.setEnabled(entry.getValue().getEnabled());
+ rawList.add(override);
}
changeOverrides.setRaw(rawOverrides);
ChangeOverrides.Validated validatedOverrides = new ChangeOverrides.Validated();
List<OverrideValue> validatedList = validatedOverrides.getOverrideValue();
- if (mEvaluatedOverrides != null) {
- for (Map.Entry<String, Boolean> entry : mEvaluatedOverrides.entrySet()) {
- OverrideValue override = new OverrideValue();
- override.setPackageName(entry.getKey());
- override.setEnabled(entry.getValue());
- validatedList.add(override);
- }
+ for (Map.Entry<String, Boolean> entry : mEvaluatedOverrides.entrySet()) {
+ OverrideValue override = new OverrideValue();
+ override.setPackageName(entry.getKey());
+ override.setEnabled(entry.getValue());
+ validatedList.add(override);
}
changeOverrides.setValidated(validatedOverrides);
return changeOverrides;
@@ -394,10 +381,10 @@ public final class CompatChange extends CompatibilityChangeInfo {
if (getLoggingOnly()) {
sb.append("; loggingOnly");
}
- if (mEvaluatedOverrides != null && mEvaluatedOverrides.size() > 0) {
+ if (!mEvaluatedOverrides.isEmpty()) {
sb.append("; packageOverrides=").append(mEvaluatedOverrides);
}
- if (mRawOverrides != null && mRawOverrides.size() > 0) {
+ if (!mRawOverrides.isEmpty()) {
sb.append("; rawOverrides=").append(mRawOverrides);
}
if (getOverridable()) {
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 66a652053857..2c053b421904 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -67,6 +67,7 @@ final class CompatConfig {
private static final String TAG = "CompatConfig";
private static final String APP_COMPAT_DATA_DIR = "/data/misc/appcompat";
+ private static final String STATIC_OVERRIDES_PRODUCT_DIR = "/product/etc/appcompat";
private static final String OVERRIDES_FILE = "compat_framework_overrides.xml";
@GuardedBy("mChanges")
@@ -94,8 +95,7 @@ final class CompatConfig {
config.initConfigFromLib(Environment.buildPath(
apex.apexDirectory, "etc", "compatconfig"));
}
- File overridesFile = new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE);
- config.initOverrides(overridesFile);
+ config.initOverrides();
config.invalidateCache();
return config;
}
@@ -525,10 +525,34 @@ final class CompatConfig {
}
}
- void initOverrides(File overridesFile) {
+ private void initOverrides() {
+ initOverrides(new File(APP_COMPAT_DATA_DIR, OVERRIDES_FILE),
+ new File(STATIC_OVERRIDES_PRODUCT_DIR, OVERRIDES_FILE));
+ }
+
+ @VisibleForTesting
+ void initOverrides(File dynamicOverridesFile, File staticOverridesFile) {
+ // Clear overrides from all changes before loading.
+ synchronized (mChanges) {
+ for (int i = 0; i < mChanges.size(); ++i) {
+ mChanges.valueAt(i).clearOverrides();
+ }
+ }
+
+ loadOverrides(staticOverridesFile);
+
+ mOverridesFile = dynamicOverridesFile;
+ loadOverrides(dynamicOverridesFile);
+
+ if (staticOverridesFile.exists()) {
+ // Only save overrides if there is a static overrides file.
+ saveOverrides();
+ }
+ }
+
+ private void loadOverrides(File overridesFile) {
if (!overridesFile.exists()) {
- mOverridesFile = overridesFile;
- // There have not been any overrides added yet.
+ // Overrides file doesn't exist.
return;
}
@@ -548,7 +572,6 @@ final class CompatConfig {
Slog.w(TAG, "Error processing " + overridesFile + " " + e.toString());
return;
}
- mOverridesFile = overridesFile;
}
/**
diff --git a/services/core/java/com/android/server/connectivity/DataConnectionStats.java b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
index fbd089c1f0ee..15f43a0481bd 100644
--- a/services/core/java/com/android/server/connectivity/DataConnectionStats.java
+++ b/services/core/java/com/android/server/connectivity/DataConnectionStats.java
@@ -52,6 +52,7 @@ public class DataConnectionStats extends BroadcastReceiver {
private SignalStrength mSignalStrength;
private ServiceState mServiceState;
private int mDataState = TelephonyManager.DATA_DISCONNECTED;
+ private int mNrState = NetworkRegistrationInfo.NR_STATE_NONE;
public DataConnectionStats(Context context, Handler listenerHandler) {
mContext = context;
@@ -99,7 +100,7 @@ public class DataConnectionStats extends BroadcastReceiver {
: regInfo.getAccessNetworkTechnology();
// If the device is in NSA NR connection the networkType will report as LTE.
// For cell dwell rate metrics, this should report NR instead.
- if (regInfo != null && regInfo.getNrState() == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
+ if (mNrState == NetworkRegistrationInfo.NR_STATE_CONNECTED) {
networkType = TelephonyManager.NETWORK_TYPE_NR;
}
if (DEBUG) Log.d(TAG, String.format("Noting data connection for network type %s: %svisible",
@@ -171,6 +172,7 @@ public class DataConnectionStats extends BroadcastReceiver {
@Override
public void onServiceStateChanged(ServiceState state) {
mServiceState = state;
+ mNrState = state.getNrState();
notePhoneDataConnectionState();
}
diff --git a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
index 34d9ccc15dba..7b20ded19205 100644
--- a/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
+++ b/services/core/java/com/android/server/connectivity/KeepaliveTracker.java
@@ -57,8 +57,8 @@ import android.util.Log;
import android.util.Pair;
import com.android.internal.R;
-import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.net.module.util.HexDump;
import com.android.net.module.util.IpUtils;
import java.io.FileDescriptor;
diff --git a/services/core/java/com/android/server/connectivity/Nat464Xlat.java b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
index 641287f0f435..fa80b25f9026 100644
--- a/services/core/java/com/android/server/connectivity/Nat464Xlat.java
+++ b/services/core/java/com/android/server/connectivity/Nat464Xlat.java
@@ -29,14 +29,12 @@ import android.net.LinkAddress;
import android.net.LinkProperties;
import android.net.NetworkInfo;
import android.net.RouteInfo;
-import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.net.module.util.NetworkStackConstants;
-import com.android.server.net.BaseNetworkObserver;
import java.net.Inet6Address;
import java.util.Objects;
@@ -48,7 +46,7 @@ import java.util.Objects;
*
* @hide
*/
-public class Nat464Xlat extends BaseNetworkObserver {
+public class Nat464Xlat {
private static final String TAG = Nat464Xlat.class.getSimpleName();
// This must match the interface prefix in clatd.c.
@@ -70,7 +68,6 @@ public class Nat464Xlat extends BaseNetworkObserver {
private final IDnsResolver mDnsResolver;
private final INetd mNetd;
- private final INetworkManagementService mNMService;
// The network we're running on, and its type.
private final NetworkAgentInfo mNetwork;
@@ -99,11 +96,9 @@ public class Nat464Xlat extends BaseNetworkObserver {
private boolean mPrefixDiscoveryRunning;
- public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver,
- INetworkManagementService nmService) {
+ public Nat464Xlat(NetworkAgentInfo nai, INetd netd, IDnsResolver dnsResolver) {
mDnsResolver = dnsResolver;
mNetd = netd;
- mNMService = nmService;
mNetwork = nai;
}
@@ -174,13 +169,6 @@ public class Nat464Xlat extends BaseNetworkObserver {
* and set internal state.
*/
private void enterStartingState(String baseIface) {
- try {
- mNMService.registerObserver(this);
- } catch (RemoteException e) {
- Log.e(TAG, "Can't register iface observer for clat on " + mNetwork.toShortString());
- return;
- }
-
mNat64PrefixInUse = selectNat64Prefix();
String addrStr = null;
try {
@@ -216,11 +204,6 @@ public class Nat464Xlat extends BaseNetworkObserver {
* Unregister as a base observer for the stacked interface, and clear internal state.
*/
private void leaveStartedState() {
- try {
- mNMService.unregisterObserver(this);
- } catch (RemoteException | IllegalStateException e) {
- Log.e(TAG, "Error unregistering clatd observer on " + mBaseIface + ": " + e);
- }
mNat64PrefixInUse = null;
mIface = null;
mBaseIface = null;
@@ -507,12 +490,10 @@ public class Nat464Xlat extends BaseNetworkObserver {
stop();
}
- @Override
public void interfaceLinkStateChanged(String iface, boolean up) {
mNetwork.handler().post(() -> { handleInterfaceLinkStateChanged(iface, up); });
}
- @Override
public void interfaceRemoved(String iface) {
mNetwork.handler().post(() -> handleInterfaceRemoved(iface));
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 4cf527415d7e..cac6cab7074e 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -43,7 +43,6 @@ import android.net.QosSession;
import android.net.TcpKeepalivePacketData;
import android.os.Handler;
import android.os.IBinder;
-import android.os.INetworkManagementService;
import android.os.RemoteException;
import android.os.SystemClock;
import android.telephony.data.EpsBearerQosSessionAttributes;
@@ -341,8 +340,8 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
public NetworkAgentInfo(INetworkAgent na, Network net, NetworkInfo info,
@NonNull LinkProperties lp, @NonNull NetworkCapabilities nc, int score, Context context,
Handler handler, NetworkAgentConfig config, ConnectivityService connService, INetd netd,
- IDnsResolver dnsResolver, INetworkManagementService nms, int factorySerialNumber,
- int creatorUid, QosCallbackTracker qosCallbackTracker) {
+ IDnsResolver dnsResolver, int factorySerialNumber, int creatorUid,
+ QosCallbackTracker qosCallbackTracker) {
Objects.requireNonNull(net);
Objects.requireNonNull(info);
Objects.requireNonNull(lp);
@@ -356,7 +355,7 @@ public class NetworkAgentInfo implements Comparable<NetworkAgentInfo> {
linkProperties = lp;
networkCapabilities = nc;
mScore = score;
- clatd = new Nat464Xlat(this, netd, dnsResolver, nms);
+ clatd = new Nat464Xlat(this, netd, dnsResolver);
mConnService = connService;
mContext = context;
mHandler = handler;
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 835b4688dd4e..658d27f43313 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -425,7 +425,13 @@ public final class DeviceStateManagerService extends SystemService {
if (!mRequestRecords.isEmpty()) {
final OverrideRequestRecord topRequest =
mRequestRecords.get(mRequestRecords.size() - 1);
- topRequest.setStatusLocked(OverrideRequestRecord.STATUS_ACTIVE);
+ if (topRequest.mRequestedState.getIdentifier() == mCommittedState.getIdentifier()) {
+ // The top request could have come in while the service was awaiting callback
+ // from the policy. In that case we only set it to active if it matches the
+ // current committed state, otherwise it will be set to active when its
+ // requested state is committed.
+ topRequest.setStatusLocked(OverrideRequestRecord.STATUS_ACTIVE);
+ }
}
mPendingState = Optional.empty();
@@ -563,10 +569,13 @@ public final class DeviceStateManagerService extends SystemService {
new OverrideRequestRecord(processRecord, token, deviceState.get(), flags);
mRequestRecords.add(request);
processRecord.mRequestRecords.put(request.mToken, request);
- // We don't set the status of the new request to ACTIVE here as it will be set in
- // commitPendingState().
- updatePendingStateLocked();
+ final boolean updatedPendingState = updatePendingStateLocked();
+ if (!updatedPendingState && !mPendingState.isPresent()) {
+ // We don't set the status of the new request to ACTIVE if the request updated the
+ // pending state as it will be set in commitPendingState().
+ request.setStatusLocked(OverrideRequestRecord.STATUS_ACTIVE, true /* markDirty */);
+ }
}
notifyRequestsOfStatusChangeIfNeeded();
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index dce6bd849953..645ca7ac33e0 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -31,7 +31,6 @@ import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
-import android.os.PowerManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.DeviceConfig;
@@ -80,6 +79,8 @@ public class DisplayModeDirector {
// specific display.
private static final int GLOBAL_ID = -1;
+ private static final int INVALID_DISPLAY_MODE_ID = -1;
+
// The tolerance within which we consider something approximately equals.
private static final float FLOAT_TOLERANCE = 0.01f;
@@ -322,12 +323,30 @@ public class DisplayModeDirector {
appRequestSummary.maxRefreshRate));
}
- // If the application requests a given mode with preferredModeId function, it will be
- // stored as baseModeId.
- int baseModeId = defaultMode.getModeId();
- if (availableModes.length > 0) {
+ int baseModeId = INVALID_DISPLAY_MODE_ID;
+
+ // Select the default mode if available. This is important because SurfaceFlinger
+ // can do only seamless switches by default. Some devices (e.g. TV) don't support
+ // seamless switching so the mode we select here won't be changed.
+ for (int availableMode : availableModes) {
+ if (availableMode == defaultMode.getModeId()) {
+ baseModeId = defaultMode.getModeId();
+ break;
+ }
+ }
+
+ // If the application requests a display mode by setting
+ // LayoutParams.preferredDisplayModeId, it will be the only available mode and it'll
+ // be stored as baseModeId.
+ if (baseModeId == INVALID_DISPLAY_MODE_ID && availableModes.length > 0) {
baseModeId = availableModes[0];
}
+
+ if (baseModeId == INVALID_DISPLAY_MODE_ID) {
+ throw new IllegalStateException("Can't select a base display mode for display "
+ + displayId + ". The votes are " + mVotesByDisplay.valueAt(displayId));
+ }
+
if (mModeSwitchingType == DisplayManager.SWITCHING_TYPE_NONE) {
Display.Mode baseMode = null;
for (Display.Mode mode : modes) {
@@ -351,6 +370,7 @@ public class DisplayModeDirector {
boolean allowGroupSwitching =
mModeSwitchingType == DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS;
+
return new DesiredDisplayModeSpecs(baseModeId,
allowGroupSwitching,
new RefreshRateRange(
diff --git a/services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java b/services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java
deleted file mode 100644
index b082b25aea02..000000000000
--- a/services/core/java/com/android/server/graphics/fonts/FontCrashDetector.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * Copyright (C) 2021 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.graphics.fonts;
-
-import android.annotation.NonNull;
-import android.util.Slog;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * A class to detect font-related native crash.
- *
- * <p>If a fs-verity protected file is accessed through mmap and corrupted file block is detected,
- * SIGBUG signal is generated and the process will crash. To find corrupted files and remove them,
- * we use a marker file to detect crash.
- * <ol>
- * <li>Create a marker file before reading fs-verity protected font files.
- * <li>Delete the marker file after reading font files successfully.
- * <li>If the marker file is found in the next process startup, it means that the process
- * crashed before. We will delete font files to prevent crash loop.
- * </ol>
- *
- * <p>Example usage:
- * <pre>
- * FontCrashDetector detector = new FontCrashDetector(new File("/path/to/marker_file"));
- * if (detector.hasCrashed()) {
- * // Do cleanup
- * }
- * try (FontCrashDetector.MonitoredBlock b = detector.start()) {
- * // Read files
- * }
- * </pre>
- *
- * <p>This class DOES NOT detect Java exceptions. If a Java exception is thrown while monitoring
- * crash, the marker file will be deleted. Creating and deleting marker files are not lightweight.
- * Please use this class sparingly with caution.
- */
-/* package */ final class FontCrashDetector {
-
- private static final String TAG = "FontCrashDetector";
-
- @NonNull
- private final File mMarkerFile;
-
- /* package */ FontCrashDetector(@NonNull File markerFile) {
- mMarkerFile = markerFile;
- }
-
- /* package */ boolean hasCrashed() {
- return mMarkerFile.exists();
- }
-
- /* package */ void clear() {
- if (!mMarkerFile.delete()) {
- Slog.e(TAG, "Could not delete marker file: " + mMarkerFile);
- }
- }
-
- /** Starts crash monitoring. */
- /* package */ MonitoredBlock start() {
- try {
- mMarkerFile.createNewFile();
- } catch (IOException e) {
- Slog.e(TAG, "Could not create marker file: " + mMarkerFile, e);
- }
- return new MonitoredBlock();
- }
-
- /** A helper class to monitor crash with try-with-resources syntax. */
- /* package */ class MonitoredBlock implements AutoCloseable {
- /** Ends crash monitoring. */
- @Override
- public void close() {
- clear();
- }
- }
-}
diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
index 01e839dae07a..900ec905609f 100644
--- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
+++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java
@@ -63,7 +63,6 @@ public final class FontManagerService extends IFontManager.Stub {
private static final String TAG = "FontManagerService";
private static final String FONT_FILES_DIR = "/data/fonts/files";
- private static final String CRASH_MARKER_FILE = "/data/fonts/config/crash.txt";
@Override
public FontConfig getFontConfig() {
@@ -200,10 +199,6 @@ public final class FontManagerService extends IFontManager.Stub {
private final Object mUpdatableFontDirLock = new Object();
@GuardedBy("mUpdatableFontDirLock")
- @NonNull
- private final FontCrashDetector mFontCrashDetector;
-
- @GuardedBy("mUpdatableFontDirLock")
@Nullable
private final UpdatableFontDir mUpdatableFontDir;
@@ -217,7 +212,6 @@ public final class FontManagerService extends IFontManager.Stub {
private FontManagerService(Context context) {
mContext = context;
- mFontCrashDetector = new FontCrashDetector(new File(CRASH_MARKER_FILE));
mUpdatableFontDir = createUpdatableFontDir();
initialize();
}
@@ -244,19 +238,8 @@ public final class FontManagerService extends IFontManager.Stub {
}
return;
}
- if (mFontCrashDetector.hasCrashed()) {
- Slog.i(TAG, "Crash detected. Clearing font updates.");
- try {
- mUpdatableFontDir.clearUpdates();
- } catch (SystemFontException e) {
- Slog.e(TAG, "Failed to clear updates.", e);
- }
- mFontCrashDetector.clear();
- }
- try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) {
- mUpdatableFontDir.loadFontFileMap();
- updateSerializedFontMap();
- }
+ mUpdatableFontDir.loadFontFileMap();
+ updateSerializedFontMap();
}
}
@@ -286,10 +269,8 @@ public final class FontManagerService extends IFontManager.Stub {
FontManager.RESULT_ERROR_VERSION_MISMATCH,
"The base config version is older than current.");
}
- try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) {
- mUpdatableFontDir.update(requests);
- updateSerializedFontMap();
- }
+ mUpdatableFontDir.update(requests);
+ updateSerializedFontMap();
}
}
@@ -300,10 +281,8 @@ public final class FontManagerService extends IFontManager.Stub {
"The font updater is disabled.");
}
synchronized (mUpdatableFontDirLock) {
- try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) {
- mUpdatableFontDir.clearUpdates();
- updateSerializedFontMap();
- }
+ mUpdatableFontDir.clearUpdates();
+ updateSerializedFontMap();
}
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index b4d9b01f716f..115cafedca93 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -221,7 +221,7 @@ public class HdmiControlService extends SystemService {
private int mHdmiCecVolumeControl;
// Make sure HdmiCecConfig is instantiated and the XMLs are read.
- private final HdmiCecConfig mHdmiCecConfig;
+ private HdmiCecConfig mHdmiCecConfig;
/**
* Interface to report send result.
@@ -580,6 +580,11 @@ public class HdmiControlService extends SystemService {
mHdmiCecNetwork = hdmiCecNetwork;
}
+ @VisibleForTesting
+ void setHdmiCecConfig(HdmiCecConfig hdmiCecConfig) {
+ mHdmiCecConfig = hdmiCecConfig;
+ }
+
public HdmiCecNetwork getHdmiCecNetwork() {
return mHdmiCecNetwork;
}
diff --git a/services/core/java/com/android/server/location/GeocoderProxy.java b/services/core/java/com/android/server/location/GeocoderProxy.java
index 3ac148ddab1b..c93c4b1f21b7 100644
--- a/services/core/java/com/android/server/location/GeocoderProxy.java
+++ b/services/core/java/com/android/server/location/GeocoderProxy.java
@@ -24,7 +24,7 @@ import android.location.IGeocodeProvider;
import android.os.IBinder;
import android.os.RemoteException;
-import com.android.server.ServiceWatcher;
+import com.android.server.servicewatcher.ServiceWatcher;
import java.util.Collections;
diff --git a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
index 6ea4bd2b1d6d..e1c87000ea89 100644
--- a/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
+++ b/services/core/java/com/android/server/location/HardwareActivityRecognitionProxy.java
@@ -25,8 +25,8 @@ import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
-import com.android.server.ServiceWatcher;
-import com.android.server.ServiceWatcher.BoundService;
+import com.android.server.servicewatcher.ServiceWatcher;
+import com.android.server.servicewatcher.ServiceWatcher.BoundService;
/**
* Proxy class to bind GmsCore to the ActivityRecognitionHardware.
diff --git a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
index bdfa6d7aa67e..c70714932792 100644
--- a/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
+++ b/services/core/java/com/android/server/location/geofence/GeofenceProxy.java
@@ -29,7 +29,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
-import com.android.server.ServiceWatcher;
+import com.android.server.servicewatcher.ServiceWatcher;
import java.util.Objects;
diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
index 44b62b3659dc..c86e49bc7948 100644
--- a/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
+++ b/services/core/java/com/android/server/location/provider/proxy/ProxyLocationProvider.java
@@ -36,9 +36,9 @@ import android.util.ArraySet;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
-import com.android.server.ServiceWatcher;
-import com.android.server.ServiceWatcher.BoundService;
import com.android.server.location.provider.AbstractLocationProvider;
+import com.android.server.servicewatcher.ServiceWatcher;
+import com.android.server.servicewatcher.ServiceWatcher.BoundService;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/net/NetworkStatsService.java b/services/core/java/com/android/server/net/NetworkStatsService.java
index 5b9a11bc5a31..3a5e10ed951a 100644
--- a/services/core/java/com/android/server/net/NetworkStatsService.java
+++ b/services/core/java/com/android/server/net/NetworkStatsService.java
@@ -97,7 +97,7 @@ import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkIdentity;
import android.net.NetworkStack;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
import android.net.NetworkStats;
import android.net.NetworkStats.NonMonotonicObserver;
import android.net.NetworkStatsHistory;
@@ -296,7 +296,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
/** Last states of all networks sent from ConnectivityService. */
@GuardedBy("mStatsLock")
@Nullable
- private NetworkState[] mLastNetworkStates = null;
+ private NetworkStateSnapshot[] mLastNetworkStateSnapshots = null;
private final DropBoxNonMonotonicObserver mNonMonotonicObserver =
new DropBoxNonMonotonicObserver();
@@ -378,8 +378,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
case MSG_UPDATE_IFACES: {
// If no cached states, ignore.
- if (mLastNetworkStates == null) break;
- updateIfaces(mDefaultNetworks, mLastNetworkStates, mActiveIface);
+ if (mLastNetworkStateSnapshots == null) break;
+ updateIfaces(mDefaultNetworks, mLastNetworkStateSnapshots, mActiveIface);
break;
}
case MSG_PERFORM_POLL_REGISTER_ALERT: {
@@ -967,10 +967,9 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
}
- @Override
public void forceUpdateIfaces(
Network[] defaultNetworks,
- NetworkState[] networkStates,
+ NetworkStateSnapshot[] networkStates,
String activeIface,
UnderlyingNetworkInfo[] underlyingNetworkInfos) {
checkNetworkStackPermission(mContext);
@@ -1248,13 +1247,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
private void updateIfaces(
Network[] defaultNetworks,
- NetworkState[] networkStates,
+ NetworkStateSnapshot[] snapshots,
String activeIface) {
synchronized (mStatsLock) {
mWakeLock.acquire();
try {
mActiveIface = activeIface;
- updateIfacesLocked(defaultNetworks, networkStates);
+ updateIfacesLocked(defaultNetworks, snapshots);
} finally {
mWakeLock.release();
}
@@ -1262,13 +1261,13 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
}
/**
- * Inspect all current {@link NetworkState} to derive mapping from {@code iface} to {@link
- * NetworkStatsHistory}. When multiple networks are active on a single {@code iface},
+ * Inspect all current {@link NetworkStateSnapshot}s to derive mapping from {@code iface} to
+ * {@link NetworkStatsHistory}. When multiple networks are active on a single {@code iface},
* they are combined under a single {@link NetworkIdentitySet}.
*/
@GuardedBy("mStatsLock")
private void updateIfacesLocked(@Nullable Network[] defaultNetworks,
- @NonNull NetworkState[] states) {
+ @NonNull NetworkStateSnapshot[] snapshots) {
if (!mSystemReady) return;
if (LOGV) Slog.v(TAG, "updateIfacesLocked()");
@@ -1288,21 +1287,21 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
mDefaultNetworks = defaultNetworks;
}
- mLastNetworkStates = states;
+ mLastNetworkStateSnapshots = snapshots;
final boolean combineSubtypeEnabled = mSettings.getCombineSubtypeEnabled();
final ArraySet<String> mobileIfaces = new ArraySet<>();
- for (NetworkState state : states) {
- final boolean isMobile = isNetworkTypeMobile(state.legacyNetworkType);
- final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, state.network);
+ for (NetworkStateSnapshot snapshot : snapshots) {
+ final boolean isMobile = isNetworkTypeMobile(snapshot.legacyType);
+ final boolean isDefault = ArrayUtils.contains(mDefaultNetworks, snapshot.network);
final int subType = combineSubtypeEnabled ? SUBTYPE_COMBINED
- : getSubTypeForState(state);
- final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, state,
+ : getSubTypeForStateSnapshot(snapshot);
+ final NetworkIdentity ident = NetworkIdentity.buildNetworkIdentity(mContext, snapshot,
isDefault, subType);
// Traffic occurring on the base interface is always counted for
// both total usage and UID details.
- final String baseIface = state.linkProperties.getInterfaceName();
+ final String baseIface = snapshot.linkProperties.getInterfaceName();
if (baseIface != null) {
findOrCreateNetworkIdentitySet(mActiveIfaces, baseIface).add(ident);
findOrCreateNetworkIdentitySet(mActiveUidIfaces, baseIface).add(ident);
@@ -1312,7 +1311,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// If IMS is metered, then the IMS network usage has already included VT usage.
// VT is considered always metered in framework's layer. If VT is not metered
// per carrier's policy, modem will report 0 usage for VT calls.
- if (state.networkCapabilities.hasCapability(
+ if (snapshot.networkCapabilities.hasCapability(
NetworkCapabilities.NET_CAPABILITY_IMS) && !ident.getMetered()) {
// Copy the identify from IMS one but mark it as metered.
@@ -1358,7 +1357,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
// (or non eBPF offloaded) TX they would appear on both, however egress interface
// accounting is explicitly bypassed for traffic from the clat uid.
//
- final List<LinkProperties> stackedLinks = state.linkProperties.getStackedLinks();
+ final List<LinkProperties> stackedLinks = snapshot.linkProperties.getStackedLinks();
for (LinkProperties stackedLink : stackedLinks) {
final String stackedIface = stackedLink.getInterfaceName();
if (stackedIface != null) {
@@ -1381,7 +1380,7 @@ public class NetworkStatsService extends INetworkStatsService.Stub {
* {@link PhoneStateListener}. Otherwise, return 0 given that other networks with different
* transport types do not actually fill this value.
*/
- private int getSubTypeForState(@NonNull NetworkState state) {
+ private int getSubTypeForStateSnapshot(@NonNull NetworkStateSnapshot state) {
if (!state.networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
return 0;
}
diff --git a/services/core/java/com/android/server/pm/DataLoaderManagerService.java b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
index 9a9b14c31314..b34611b9cd6f 100644
--- a/services/core/java/com/android/server/pm/DataLoaderManagerService.java
+++ b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
@@ -207,35 +207,37 @@ public class DataLoaderManagerService extends SystemService {
@Override
public void onServiceDisconnected(ComponentName arg0) {
Slog.i(TAG, "DataLoader " + mId + " disconnected, but will try to recover");
- callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
- destroy();
+ unbindAndReportDestroyed();
}
@Override
public void onBindingDied(ComponentName name) {
Slog.i(TAG, "DataLoader " + mId + " died");
- callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
- destroy();
+ unbindAndReportDestroyed();
}
@Override
public void onNullBinding(ComponentName name) {
Slog.i(TAG, "DataLoader " + mId + " failed to start");
- callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
- destroy();
+ unbindAndReportDestroyed();
}
@Override
public void binderDied() {
Slog.i(TAG, "DataLoader " + mId + " died");
- callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
- destroy();
+ unbindAndReportDestroyed();
}
IDataLoader getDataLoader() {
return mDataLoader;
}
+ private void unbindAndReportDestroyed() {
+ if (unbind()) {
+ callListener(IDataLoaderStatusListener.DATA_LOADER_DESTROYED);
+ }
+ }
+
void destroy() {
if (mDataLoader != null) {
try {
@@ -244,11 +246,15 @@ public class DataLoaderManagerService extends SystemService {
}
mDataLoader = null;
}
+ unbind();
+ }
+
+ boolean unbind() {
try {
mContext.unbindService(this);
} catch (Exception ignored) {
}
- remove();
+ return remove();
}
private boolean append() {
@@ -266,12 +272,14 @@ public class DataLoaderManagerService extends SystemService {
}
}
- private void remove() {
+ private boolean remove() {
synchronized (mServiceConnections) {
if (mServiceConnections.get(mId) == this) {
mServiceConnections.remove(mId);
+ return true;
}
}
+ return false;
}
private void callListener(int status) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index e3f925a97dda..06b85cfbd404 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -11634,9 +11634,17 @@ public class PackageManagerService extends IPackageManager.Stub
healthCheckParams.unhealthyTimeoutMs = INCREMENTAL_STORAGE_UNHEALTHY_TIMEOUT_MS;
healthCheckParams.unhealthyMonitoringMs =
INCREMENTAL_STORAGE_UNHEALTHY_MONITORING_MS;
+ // Continue monitoring health and loading progress of active incremental packages
mIncrementalManager.registerHealthListener(parsedPackage.getPath(),
healthCheckParams,
new IncrementalHealthListener(parsedPackage.getPackageName()));
+ final IncrementalStatesCallback incrementalStatesCallback =
+ new IncrementalStatesCallback(parsedPackage.getPackageName(),
+ UserHandle.getUid(UserHandle.ALL, pkgSetting.appId),
+ getInstalledUsers(pkgSetting, UserHandle.USER_ALL));
+ pkgSetting.setIncrementalStatesCallback(incrementalStatesCallback);
+ mIncrementalManager.registerLoadingProgressCallback(parsedPackage.getPath(),
+ new IncrementalProgressListener(parsedPackage.getPackageName()));
}
}
return scanResult.pkgSetting.pkg;
@@ -19420,6 +19428,8 @@ public class PackageManagerService extends IPackageManager.Stub
mIncrementalManager.unregisterLoadingProgressCallbacks(codePath);
// Unregister health listener as it will always be healthy from now
mIncrementalManager.unregisterHealthListener(codePath);
+ // Make sure the information is preserved
+ scheduleWriteSettingsLocked();
}
@Override
@@ -19482,11 +19492,11 @@ public class PackageManagerService extends IPackageManager.Stub
final PackageSetting ps;
synchronized (mLock) {
ps = mSettings.getPackageLPr(mPackageName);
+ if (ps == null) {
+ return;
+ }
+ ps.setLoadingProgress(progress);
}
- if (ps == null) {
- return;
- }
- ps.setLoadingProgress(progress);
}
}
@@ -20090,7 +20100,7 @@ public class PackageManagerService extends IPackageManager.Stub
} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
- "Error deriving application ABI");
+ "Error deriving application ABI: " + pme.getMessage());
}
}
diff --git a/services/core/java/com/android/server/servicewatcher/OWNERS b/services/core/java/com/android/server/servicewatcher/OWNERS
new file mode 100644
index 000000000000..ced619f05f1d
--- /dev/null
+++ b/services/core/java/com/android/server/servicewatcher/OWNERS
@@ -0,0 +1,5 @@
+# Bug component: 25692
+
+sooniln@google.com
+wyattriley@google.com
+
diff --git a/services/core/java/com/android/server/ServiceWatcher.java b/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
index 8a2894c84cc4..5d49663209b7 100644
--- a/services/core/java/com/android/server/ServiceWatcher.java
+++ b/services/core/java/com/android/server/servicewatcher/ServiceWatcher.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.server;
+package com.android.server.servicewatcher;
import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_NOT_FOREGROUND;
@@ -52,6 +52,7 @@ import com.android.internal.annotations.Immutable;
import com.android.internal.content.PackageMonitor;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.server.FgThread;
import java.io.FileDescriptor;
import java.io.PrintWriter;
diff --git a/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java b/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java
index 531c62c5b4e9..0b51488280e0 100644
--- a/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java
+++ b/services/core/java/com/android/server/timezonedetector/location/RealLocationTimeZoneProviderProxy.java
@@ -39,8 +39,8 @@ import android.service.timezone.TimeZoneProviderSuggestion;
import android.util.IndentingPrintWriter;
import com.android.internal.annotations.GuardedBy;
-import com.android.server.ServiceWatcher;
-import com.android.server.ServiceWatcher.BoundService;
+import com.android.server.servicewatcher.ServiceWatcher;
+import com.android.server.servicewatcher.ServiceWatcher.BoundService;
import java.util.Objects;
import java.util.function.Predicate;
diff --git a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
index 685dce4683d7..96f84dc65e1d 100644
--- a/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
+++ b/services/core/java/com/android/server/vibrator/InputDeviceDelegate.java
@@ -16,6 +16,7 @@
package com.android.server.vibrator;
+import android.annotation.Nullable;
import android.content.Context;
import android.hardware.input.InputManager;
import android.os.CombinedVibrationEffect;
@@ -33,7 +34,11 @@ final class InputDeviceDelegate implements InputManager.InputDeviceListener {
private final Object mLock = new Object();
private final Handler mHandler;
- private final InputManager mInputManager;
+ private final Context mContext;
+
+ @GuardedBy("mLock")
+ @Nullable
+ private InputManager mInputManager;
@GuardedBy("mLock")
private final SparseArray<VibratorManager> mInputDeviceVibrators = new SparseArray<>();
@@ -47,7 +52,13 @@ final class InputDeviceDelegate implements InputManager.InputDeviceListener {
InputDeviceDelegate(Context context, Handler handler) {
mHandler = handler;
- mInputManager = context.getSystemService(InputManager.class);
+ mContext = context;
+ }
+
+ public void onSystemReady() {
+ synchronized (mLock) {
+ mInputManager = mContext.getSystemService(InputManager.class);
+ }
}
@Override
@@ -116,6 +127,10 @@ final class InputDeviceDelegate implements InputManager.InputDeviceListener {
*/
public boolean updateInputDeviceVibrators(boolean vibrateInputDevices) {
synchronized (mLock) {
+ if (mInputManager == null) {
+ // Ignore update, service not loaded yet so change cannot be applied.
+ return false;
+ }
if (vibrateInputDevices == mShouldVibrateInputDevices) {
// No need to update if settings haven't changed.
return false;
@@ -150,6 +165,10 @@ final class InputDeviceDelegate implements InputManager.InputDeviceListener {
private void updateInputDevice(int deviceId) {
synchronized (mLock) {
+ if (mInputManager == null) {
+ // Ignore update, service not loaded yet so change cannot be applied.
+ return;
+ }
if (!mShouldVibrateInputDevices) {
// No need to keep this device vibrator if setting is off.
return;
diff --git a/services/core/java/com/android/server/vibrator/VibrationSettings.java b/services/core/java/com/android/server/vibrator/VibrationSettings.java
index 334129d6bde9..4a07c1ac1e39 100644
--- a/services/core/java/com/android/server/vibrator/VibrationSettings.java
+++ b/services/core/java/com/android/server/vibrator/VibrationSettings.java
@@ -16,6 +16,7 @@
package com.android.server.vibrator;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IUidObserver;
import android.content.Context;
@@ -57,8 +58,6 @@ final class VibrationSettings {
private final Object mLock = new Object();
private final Context mContext;
- private final Vibrator mVibrator;
- private final AudioManager mAudioManager;
private final SettingsObserver mSettingObserver;
@VisibleForTesting
final UidObserver mUidObserver;
@@ -68,6 +67,13 @@ final class VibrationSettings {
private final SparseArray<VibrationEffect> mFallbackEffects;
@GuardedBy("mLock")
+ @Nullable
+ private Vibrator mVibrator;
+ @GuardedBy("mLock")
+ @Nullable
+ private AudioManager mAudioManager;
+
+ @GuardedBy("mLock")
private boolean mVibrateInputDevices;
@GuardedBy("mLock")
private boolean mVibrateWhenRinging;
@@ -86,22 +92,9 @@ final class VibrationSettings {
VibrationSettings(Context context, Handler handler) {
mContext = context;
- mVibrator = context.getSystemService(Vibrator.class);
- mAudioManager = context.getSystemService(AudioManager.class);
mSettingObserver = new SettingsObserver(handler);
mUidObserver = new UidObserver();
- registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
- registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING));
- registerSettingsObserver(Settings.Global.getUriFor(Settings.Global.APPLY_RAMPING_RINGER));
- registerSettingsObserver(Settings.Global.getUriFor(Settings.Global.ZEN_MODE));
- registerSettingsObserver(
- Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_INTENSITY));
- registerSettingsObserver(
- Settings.System.getUriFor(Settings.System.NOTIFICATION_VIBRATION_INTENSITY));
- registerSettingsObserver(
- Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY));
-
VibrationEffect clickEffect = createEffectFromResource(
com.android.internal.R.array.config_virtualKeyVibePattern);
VibrationEffect doubleClickEffect = VibrationEffect.createWaveform(
@@ -119,6 +112,15 @@ final class VibrationSettings {
mFallbackEffects.put(VibrationEffect.EFFECT_TEXTURE_TICK,
VibrationEffect.get(VibrationEffect.EFFECT_TICK, false));
+ // Update with current values from settings.
+ updateSettings();
+ }
+
+ public void onSystemReady() {
+ synchronized (mLock) {
+ mVibrator = mContext.getSystemService(Vibrator.class);
+ mAudioManager = mContext.getSystemService(AudioManager.class);
+ }
try {
ActivityManager.getService().registerUidObserver(mUidObserver,
ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
@@ -148,7 +150,18 @@ final class VibrationSettings {
}
});
- // Update with current values from settings.
+ registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_INPUT_DEVICES));
+ registerSettingsObserver(Settings.System.getUriFor(Settings.System.VIBRATE_WHEN_RINGING));
+ registerSettingsObserver(Settings.Global.getUriFor(Settings.Global.APPLY_RAMPING_RINGER));
+ registerSettingsObserver(Settings.Global.getUriFor(Settings.Global.ZEN_MODE));
+ registerSettingsObserver(
+ Settings.System.getUriFor(Settings.System.HAPTIC_FEEDBACK_INTENSITY));
+ registerSettingsObserver(
+ Settings.System.getUriFor(Settings.System.NOTIFICATION_VIBRATION_INTENSITY));
+ registerSettingsObserver(
+ Settings.System.getUriFor(Settings.System.RING_VIBRATION_INTENSITY));
+
+ // Update with newly loaded services.
updateSettings();
}
@@ -178,17 +191,21 @@ final class VibrationSettings {
* @return The vibration intensity, one of Vibrator.VIBRATION_INTENSITY_*
*/
public int getDefaultIntensity(int usageHint) {
- if (isRingtone(usageHint)) {
- return mVibrator.getDefaultRingVibrationIntensity();
- } else if (isNotification(usageHint)) {
- return mVibrator.getDefaultNotificationVibrationIntensity();
- } else if (isHapticFeedback(usageHint)) {
- return mVibrator.getDefaultHapticFeedbackIntensity();
- } else if (isAlarm(usageHint)) {
+ if (isAlarm(usageHint)) {
return Vibrator.VIBRATION_INTENSITY_HIGH;
- } else {
- return Vibrator.VIBRATION_INTENSITY_MEDIUM;
}
+ synchronized (mLock) {
+ if (mVibrator != null) {
+ if (isRingtone(usageHint)) {
+ return mVibrator.getDefaultRingVibrationIntensity();
+ } else if (isNotification(usageHint)) {
+ return mVibrator.getDefaultNotificationVibrationIntensity();
+ } else if (isHapticFeedback(usageHint)) {
+ return mVibrator.getDefaultHapticFeedbackIntensity();
+ }
+ }
+ }
+ return Vibrator.VIBRATION_INTENSITY_MEDIUM;
}
/**
@@ -234,8 +251,11 @@ final class VibrationSettings {
if (!isRingtone(usageHint)) {
return true;
}
- int ringerMode = mAudioManager.getRingerModeInternal();
synchronized (mLock) {
+ if (mAudioManager == null) {
+ return false;
+ }
+ int ringerMode = mAudioManager.getRingerModeInternal();
if (mVibrateWhenRinging) {
return ringerMode != AudioManager.RINGER_MODE_SILENT;
} else if (mApplyRampingRinger) {
@@ -304,12 +324,12 @@ final class VibrationSettings {
mVibrateWhenRinging = getSystemSetting(Settings.System.VIBRATE_WHEN_RINGING, 0) != 0;
mApplyRampingRinger = getGlobalSetting(Settings.Global.APPLY_RAMPING_RINGER, 0) != 0;
mHapticFeedbackIntensity = getSystemSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
- mVibrator.getDefaultHapticFeedbackIntensity());
+ getDefaultIntensity(VibrationAttributes.USAGE_TOUCH));
mNotificationIntensity = getSystemSetting(
Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
- mVibrator.getDefaultNotificationVibrationIntensity());
+ getDefaultIntensity(VibrationAttributes.USAGE_NOTIFICATION));
mRingIntensity = getSystemSetting(Settings.System.RING_VIBRATION_INTENSITY,
- mVibrator.getDefaultRingVibrationIntensity());
+ getDefaultIntensity(VibrationAttributes.USAGE_RINGTONE));
mVibrateInputDevices = getSystemSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0) > 0;
mZenMode = getGlobalSetting(Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
}
@@ -346,15 +366,15 @@ final class VibrationSettings {
proto.write(VibratorManagerServiceDumpProto.HAPTIC_FEEDBACK_INTENSITY,
mHapticFeedbackIntensity);
proto.write(VibratorManagerServiceDumpProto.HAPTIC_FEEDBACK_DEFAULT_INTENSITY,
- mVibrator.getDefaultHapticFeedbackIntensity());
+ getDefaultIntensity(VibrationAttributes.USAGE_TOUCH));
proto.write(VibratorManagerServiceDumpProto.NOTIFICATION_INTENSITY,
mNotificationIntensity);
proto.write(VibratorManagerServiceDumpProto.NOTIFICATION_DEFAULT_INTENSITY,
- mVibrator.getDefaultNotificationVibrationIntensity());
+ getDefaultIntensity(VibrationAttributes.USAGE_NOTIFICATION));
proto.write(VibratorManagerServiceDumpProto.RING_INTENSITY,
mRingIntensity);
proto.write(VibratorManagerServiceDumpProto.RING_DEFAULT_INTENSITY,
- mVibrator.getDefaultRingVibrationIntensity());
+ getDefaultIntensity(VibrationAttributes.USAGE_RINGTONE));
}
}
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index 175085475b6c..90a763c260f6 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -127,9 +127,9 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
@GuardedBy("mLock")
private ExternalVibrationHolder mCurrentExternalVibration;
- private VibrationSettings mVibrationSettings;
- private VibrationScaler mVibrationScaler;
- private InputDeviceDelegate mInputDeviceDelegate;
+ private final VibrationSettings mVibrationSettings;
+ private final VibrationScaler mVibrationScaler;
+ private final InputDeviceDelegate mInputDeviceDelegate;
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
@@ -170,6 +170,10 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
mContext = context;
mHandler = injector.createHandler(Looper.myLooper());
+ mVibrationSettings = new VibrationSettings(mContext, mHandler);
+ mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings);
+ mInputDeviceDelegate = new InputDeviceDelegate(mContext, mHandler);
+
VibrationCompleteListener listener = new VibrationCompleteListener(this);
mNativeWrapper = injector.getNativeWrapper();
mNativeWrapper.init(listener);
@@ -224,12 +228,12 @@ public class VibratorManagerService extends IVibratorManagerService.Stub {
Slog.v(TAG, "Initializing VibratorManager service...");
Trace.traceBegin(Trace.TRACE_TAG_VIBRATOR, "systemReady");
try {
- mVibrationSettings = new VibrationSettings(mContext, mHandler);
- mVibrationScaler = new VibrationScaler(mContext, mVibrationSettings);
- mInputDeviceDelegate = new InputDeviceDelegate(mContext, mHandler);
+ mVibrationSettings.onSystemReady();
+ mInputDeviceDelegate.onSystemReady();
mVibrationSettings.addListener(this::updateServiceState);
+ // Will update settings and input devices.
updateServiceState();
} finally {
Slog.v(TAG, "VibratorManager service initialized");
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 32152ec85493..af9cdeb52fe3 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -69,6 +69,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_INPUT_METHOD;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL;
import static android.view.WindowManager.LayoutParams.TYPE_NOTIFICATION_SHADE;
+import static android.view.WindowManager.LayoutParams.TYPE_POINTER;
import static android.view.WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR;
import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_ADDITIONAL;
@@ -242,7 +243,7 @@ public class DisplayPolicy {
}
}
- private final SystemGesturesPointerEventListener mSystemGestures;
+ private SystemGesturesPointerEventListener mSystemGestures;
private volatile int mLidState = LID_ABSENT;
private volatile int mDockMode = Intent.EXTRA_DOCK_STATE_UNDOCKED;
@@ -384,7 +385,7 @@ public class DisplayPolicy {
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS = 0;
private static final int MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION = 1;
- private final GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
+ private GestureNavigationSettingsObserver mGestureNavigationSettingsObserver;
private final WindowManagerInternal.AppTransitionListener mAppTransitionListener;
@@ -448,119 +449,6 @@ public class DisplayPolicy {
final Looper looper = UiThread.getHandler().getLooper();
mHandler = new PolicyHandler(looper);
- mSystemGestures = new SystemGesturesPointerEventListener(mContext, mHandler,
- new SystemGesturesPointerEventListener.Callbacks() {
- @Override
- public void onSwipeFromTop() {
- synchronized (mLock) {
- if (mStatusBar != null) {
- requestTransientBars(mStatusBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_TOP);
- }
- }
-
- @Override
- public void onSwipeFromBottom() {
- synchronized (mLock) {
- if (mNavigationBar != null
- && mNavigationBarPosition == NAV_BAR_BOTTOM) {
- requestTransientBars(mNavigationBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM);
- }
- }
-
- @Override
- public void onSwipeFromRight() {
- final Region excludedRegion = Region.obtain();
- synchronized (mLock) {
- mDisplayContent.calculateSystemGestureExclusion(
- excludedRegion, null /* outUnrestricted */);
- final boolean excluded =
- mSystemGestures.currentGestureStartedInRegion(excludedRegion);
- if (mNavigationBar != null && (mNavigationBarPosition == NAV_BAR_RIGHT
- || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
- requestTransientBars(mNavigationBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_RIGHT);
- }
- excludedRegion.recycle();
- }
-
- @Override
- public void onSwipeFromLeft() {
- final Region excludedRegion = Region.obtain();
- synchronized (mLock) {
- mDisplayContent.calculateSystemGestureExclusion(
- excludedRegion, null /* outUnrestricted */);
- final boolean excluded =
- mSystemGestures.currentGestureStartedInRegion(excludedRegion);
- if (mNavigationBar != null && (mNavigationBarPosition == NAV_BAR_LEFT
- || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
- requestTransientBars(mNavigationBar);
- }
- checkAltBarSwipeForTransientBars(ALT_BAR_LEFT);
- }
- excludedRegion.recycle();
- }
-
- @Override
- public void onFling(int duration) {
- if (mService.mPowerManagerInternal != null) {
- mService.mPowerManagerInternal.setPowerBoost(
- Boost.INTERACTION, duration);
- }
- }
-
- @Override
- public void onDebug() {
- // no-op
- }
-
- private WindowOrientationListener getOrientationListener() {
- final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
- return rotation != null ? rotation.getOrientationListener() : null;
- }
-
- @Override
- public void onDown() {
- final WindowOrientationListener listener = getOrientationListener();
- if (listener != null) {
- listener.onTouchStart();
- }
- }
-
- @Override
- public void onUpOrCancel() {
- final WindowOrientationListener listener = getOrientationListener();
- if (listener != null) {
- listener.onTouchEnd();
- }
- }
-
- @Override
- public void onMouseHoverAtTop() {
- mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
- Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
- msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
- mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
- }
-
- @Override
- public void onMouseHoverAtBottom() {
- mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
- Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
- msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
- mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
- }
-
- @Override
- public void onMouseLeaveFromEdge() {
- mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
- }
- });
- displayContent.registerPointerEventListener(mSystemGestures);
mAppTransitionListener = new WindowManagerInternal.AppTransitionListener() {
private Runnable mAppTransitionPending = () -> {
@@ -616,7 +504,7 @@ public class DisplayPolicy {
mImmersiveModeConfirmation = new ImmersiveModeConfirmation(mContext, looper,
mService.mVrModeEnabled);
- // TODO: Make it can take screenshot on external display
+ // TODO(b/180986447): Make it can take screenshot on external display
mScreenshotHelper = displayContent.isDefaultDisplay
? new ScreenshotHelper(mContext) : null;
@@ -640,16 +528,6 @@ public class DisplayPolicy {
mRefreshRatePolicy = new RefreshRatePolicy(mService,
mDisplayContent.getDisplayInfo(),
mService.mHighRefreshRateDenylist);
-
- mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(mHandler,
- mContext, () -> {
- synchronized (mLock) {
- onConfigurationChanged();
- mSystemGestures.onConfigurationChanged();
- mDisplayContent.updateSystemGestureExclusion();
- }
- });
- mHandler.post(mGestureNavigationSettingsObserver::register);
}
private void checkAltBarSwipeForTransientBars(@WindowManagerPolicy.AltBarPosition int pos) {
@@ -668,12 +546,154 @@ public class DisplayPolicy {
}
void systemReady() {
- mSystemGestures.systemReady();
if (mService.mPointerLocationEnabled) {
setPointerLocationEnabled(true);
}
}
+ @NonNull
+ private GestureNavigationSettingsObserver getGestureNavigationSettingsObserver() {
+ if (mGestureNavigationSettingsObserver == null) {
+ mGestureNavigationSettingsObserver = new GestureNavigationSettingsObserver(mHandler,
+ mContext, () -> {
+ synchronized (mLock) {
+ onConfigurationChanged();
+ getSystemGestures().onConfigurationChanged();
+ mDisplayContent.updateSystemGestureExclusion();
+ }
+ });
+ mHandler.post(mGestureNavigationSettingsObserver::register);
+ }
+ return mGestureNavigationSettingsObserver;
+ }
+
+ @NonNull
+ private SystemGesturesPointerEventListener getSystemGestures() {
+ if (mSystemGestures == null) {
+ final Context gestureContext = mUiContext.createWindowContext(
+ mDisplayContent.getDisplay(), TYPE_POINTER, null /* options */);
+ mSystemGestures = new SystemGesturesPointerEventListener(gestureContext, mHandler,
+ new SystemGesturesPointerEventListener.Callbacks() {
+ @Override
+ public void onSwipeFromTop() {
+ synchronized (mLock) {
+ if (mStatusBar != null) {
+ requestTransientBars(mStatusBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_TOP);
+ }
+ }
+
+ @Override
+ public void onSwipeFromBottom() {
+ synchronized (mLock) {
+ if (mNavigationBar != null
+ && mNavigationBarPosition == NAV_BAR_BOTTOM) {
+ requestTransientBars(mNavigationBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_BOTTOM);
+ }
+ }
+
+ @Override
+ public void onSwipeFromRight() {
+ final Region excludedRegion = Region.obtain();
+ synchronized (mLock) {
+ mDisplayContent.calculateSystemGestureExclusion(
+ excludedRegion, null /* outUnrestricted */);
+ final boolean excluded = mSystemGestures
+ .currentGestureStartedInRegion(excludedRegion);
+ if (mNavigationBar != null
+ && (mNavigationBarPosition == NAV_BAR_RIGHT
+ || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
+ requestTransientBars(mNavigationBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_RIGHT);
+ }
+ excludedRegion.recycle();
+ }
+
+ @Override
+ public void onSwipeFromLeft() {
+ final Region excludedRegion = Region.obtain();
+ synchronized (mLock) {
+ mDisplayContent.calculateSystemGestureExclusion(
+ excludedRegion, null /* outUnrestricted */);
+ final boolean excluded = mSystemGestures
+ .currentGestureStartedInRegion(excludedRegion);
+ if (mNavigationBar != null
+ && (mNavigationBarPosition == NAV_BAR_LEFT
+ || !excluded && mNavigationBarAlwaysShowOnSideGesture)) {
+ requestTransientBars(mNavigationBar);
+ }
+ checkAltBarSwipeForTransientBars(ALT_BAR_LEFT);
+ }
+ excludedRegion.recycle();
+ }
+
+ @Override
+ public void onFling(int duration) {
+ if (mService.mPowerManagerInternal != null) {
+ mService.mPowerManagerInternal.setPowerBoost(
+ Boost.INTERACTION, duration);
+ }
+ }
+
+ @Override
+ public void onDebug() {
+ // no-op
+ }
+
+ private WindowOrientationListener getOrientationListener() {
+ final DisplayRotation rotation = mDisplayContent.getDisplayRotation();
+ return rotation != null ? rotation.getOrientationListener() : null;
+ }
+
+ @Override
+ public void onDown() {
+ final WindowOrientationListener listener = getOrientationListener();
+ if (listener != null) {
+ listener.onTouchStart();
+ }
+ }
+
+ @Override
+ public void onUpOrCancel() {
+ final WindowOrientationListener listener = getOrientationListener();
+ if (listener != null) {
+ listener.onTouchEnd();
+ }
+ }
+
+ @Override
+ public void onMouseHoverAtTop() {
+ mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
+ Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
+ msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_STATUS;
+ mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
+ }
+
+ @Override
+ public void onMouseHoverAtBottom() {
+ mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
+ Message msg = mHandler.obtainMessage(MSG_REQUEST_TRANSIENT_BARS);
+ msg.arg1 = MSG_REQUEST_TRANSIENT_BARS_ARG_NAVIGATION;
+ mHandler.sendMessageDelayed(msg, 500 /* delayMillis */);
+ }
+
+ @Override
+ public void onMouseLeaveFromEdge() {
+ mHandler.removeMessages(MSG_REQUEST_TRANSIENT_BARS);
+ }
+ });
+ mDisplayContent.registerPointerEventListener(getSystemGestures());
+ if (mService.mSystemReady) {
+ mSystemGestures.systemReady();
+ }
+ }
+ return mSystemGestures;
+ }
+
private int getDisplayId() {
return mDisplayContent.getDisplayId();
}
@@ -1455,8 +1475,7 @@ public class DisplayPolicy {
}
void onDisplayInfoChanged(DisplayInfo info) {
- mSystemGestures.screenWidth = info.logicalWidth;
- mSystemGestures.screenHeight = info.logicalHeight;
+ getSystemGestures().onDisplayInfoChanged(info);
}
private void layoutStatusBar(DisplayFrames displayFrames, Rect contentFrame) {
@@ -1969,7 +1988,7 @@ public class DisplayPolicy {
public void onOverlayChangedLw() {
updateCurrentUserResources();
onConfigurationChanged();
- mSystemGestures.onConfigurationChanged();
+ getSystemGestures().onConfigurationChanged();
}
/**
@@ -2040,10 +2059,10 @@ public class DisplayPolicy {
}
mNavBarOpacityMode = res.getInteger(R.integer.config_navBarOpacityMode);
- mLeftGestureInset = mGestureNavigationSettingsObserver.getLeftSensitivity(res);
- mRightGestureInset = mGestureNavigationSettingsObserver.getRightSensitivity(res);
- mNavButtonForcedVisible =
- mGestureNavigationSettingsObserver.areNavigationButtonForcedVisible();
+ final GestureNavigationSettingsObserver observer = getGestureNavigationSettingsObserver();
+ mLeftGestureInset = observer.getLeftSensitivity(res);
+ mRightGestureInset = observer.getRightSensitivity(res);
+ mNavButtonForcedVisible = observer.areNavigationButtonForcedVisible();
mNavigationBarLetsThroughTaps = res.getBoolean(R.bool.config_navBarTapThrough);
mNavigationBarAlwaysShowOnSideGesture =
res.getBoolean(R.bool.config_navBarAlwaysShowOnSideEdgeGesture);
@@ -3056,7 +3075,7 @@ public class DisplayPolicy {
}
void release() {
- mHandler.post(mGestureNavigationSettingsObserver::unregister);
+ mHandler.post(getGestureNavigationSettingsObserver()::unregister);
}
@VisibleForTesting
diff --git a/services/core/java/com/android/server/wm/InsetsStateController.java b/services/core/java/com/android/server/wm/InsetsStateController.java
index 75176df6aaf7..a971794dc97d 100644
--- a/services/core/java/com/android/server/wm/InsetsStateController.java
+++ b/services/core/java/com/android/server/wm/InsetsStateController.java
@@ -124,7 +124,8 @@ class InsetsStateController {
? provider.getSource().getType() : ITYPE_INVALID;
return getInsetsForTarget(type, target.getWindowingMode(), target.isAlwaysOnTop(),
target.getFrozenInsetsState() != null ? target.getFrozenInsetsState() :
- target.mAboveInsetsState);
+ (target.mAttrs.receiveInsetsIgnoringZOrder ? mState :
+ target.mAboveInsetsState));
}
InsetsState getInsetsForWindowMetrics(@NonNull WindowManager.LayoutParams attrs) {
diff --git a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
index f3859b41b6fd..a98a47802914 100644
--- a/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
+++ b/services/core/java/com/android/server/wm/SystemGesturesPointerEventListener.java
@@ -126,11 +126,17 @@ class SystemGesturesPointerEventListener implements PointerEventListener {
Slog.w(TAG, "Cannot create GestureDetector, display removed:" + displayId);
return;
}
+ onDisplayInfoChanged(info);
mGestureDetector = new GestureDetector(mContext, new FlingGestureDetector(), mHandler) {
};
});
}
+ void onDisplayInfoChanged(DisplayInfo info) {
+ screenWidth = info.logicalWidth;
+ screenHeight = info.logicalHeight;
+ }
+
@Override
public void onPointerEvent(MotionEvent event) {
if (mGestureDetector != null && event.isTouchEvent()) {
diff --git a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
index f3b69e30b40a..0be43ab8d26c 100644
--- a/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
+++ b/services/core/java/com/android/server/wm/TaskLaunchParamsModifier.java
@@ -180,6 +180,7 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
} else if (launchMode == WINDOWING_MODE_FULLSCREEN) {
if (DEBUG) appendLog("activity-options-fullscreen=" + outParams.mBounds);
} else if (layout != null && canApplyFreeformPolicy) {
+ mTmpBounds.set(currentParams.mBounds);
getLayoutBounds(display, root, layout, mTmpBounds);
if (!mTmpBounds.isEmpty()) {
launchMode = WINDOWING_MODE_FREEFORM;
@@ -500,11 +501,11 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
}
private void getLayoutBounds(@NonNull DisplayContent display, @NonNull ActivityRecord root,
- @NonNull ActivityInfo.WindowLayout windowLayout, @NonNull Rect outBounds) {
+ @NonNull ActivityInfo.WindowLayout windowLayout, @NonNull Rect inOutBounds) {
final int verticalGravity = windowLayout.gravity & Gravity.VERTICAL_GRAVITY_MASK;
final int horizontalGravity = windowLayout.gravity & Gravity.HORIZONTAL_GRAVITY_MASK;
if (!windowLayout.hasSpecifiedSize() && verticalGravity == 0 && horizontalGravity == 0) {
- outBounds.setEmpty();
+ inOutBounds.setEmpty();
return;
}
@@ -518,11 +519,17 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
int width;
int height;
if (!windowLayout.hasSpecifiedSize()) {
- outBounds.setEmpty();
- getTaskBounds(root, display, windowLayout, WINDOWING_MODE_FREEFORM,
- /* hasInitialBounds */ false, outBounds);
- width = outBounds.width();
- height = outBounds.height();
+ if (!inOutBounds.isEmpty()) {
+ // If the bounds is resolved already and WindowLayout doesn't have any opinion on
+ // its size, use the already resolved size and apply the gravity to it.
+ width = inOutBounds.width();
+ height = inOutBounds.height();
+ } else {
+ getTaskBounds(root, display, windowLayout, WINDOWING_MODE_FREEFORM,
+ /* hasInitialBounds */ false, inOutBounds);
+ width = inOutBounds.width();
+ height = inOutBounds.height();
+ }
} else {
width = defaultWidth;
if (windowLayout.width > 0 && windowLayout.width < defaultWidth) {
@@ -563,11 +570,11 @@ class TaskLaunchParamsModifier implements LaunchParamsModifier {
fractionOfVerticalOffset = 0.5f;
}
- outBounds.set(0, 0, width, height);
- outBounds.offset(displayStableBounds.left, displayStableBounds.top);
+ inOutBounds.set(0, 0, width, height);
+ inOutBounds.offset(displayStableBounds.left, displayStableBounds.top);
final int xOffset = (int) (fractionOfHorizontalOffset * (defaultWidth - width));
final int yOffset = (int) (fractionOfVerticalOffset * (defaultHeight - height));
- outBounds.offset(xOffset, yOffset);
+ inOutBounds.offset(xOffset, yOffset);
}
private boolean shouldLaunchUnresizableAppInFreeform(ActivityRecord activity,
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
index 18184b0a82af..f1d8e6c167d7 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/LocalDisplayAdapterTest.java
@@ -592,6 +592,7 @@ public class LocalDisplayAdapterTest {
new DisplayModeDirector.RefreshRateRange(60f, 60f),
new DisplayModeDirector.RefreshRateRange(60f, 60f)
));
+ waitForHandlerToComplete(mHandler, HANDLER_WAIT_MS);
verify(mSurfaceControlProxy).setDesiredDisplayModeSpecs(display.token,
new SurfaceControl.DesiredDisplayModeSpecs(
/* baseModeId */ 0,
diff --git a/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java
new file mode 100644
index 000000000000..170f561aa2da
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/accessibility/AccessibilityInteractionControllerNodeRequestsTest.java
@@ -0,0 +1,581 @@
+/*
+ * Copyright (C) 2021 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.accessibility;
+
+
+import static android.view.accessibility.AccessibilityNodeInfo.FLAG_INCLUDE_NOT_IMPORTANT_VIEWS;
+import static android.view.accessibility.AccessibilityNodeInfo.FLAG_PREFETCH_DESCENDANTS;
+import static android.view.accessibility.AccessibilityNodeInfo.FLAG_PREFETCH_SIBLINGS;
+import static android.view.accessibility.AccessibilityNodeInfo.ROOT_NODE_ID;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyList;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.app.Instrumentation;
+import android.content.Context;
+import android.os.RemoteException;
+import android.view.AccessibilityInteractionController;
+import android.view.View;
+import android.view.ViewRootImpl;
+import android.view.WindowManager;
+import android.view.accessibility.AccessibilityNodeIdManager;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
+import android.view.accessibility.IAccessibilityInteractionConnectionCallback;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Captor;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Tests that verify expected node and prefetched node results when finding a view by node id. We
+ * send some requests to the controller via View methods to control message timing.
+ */
+@RunWith(AndroidJUnit4.class)
+public class AccessibilityInteractionControllerNodeRequestsTest {
+ private AccessibilityInteractionController mAccessibilityInteractionController;
+ @Mock
+ private IAccessibilityInteractionConnectionCallback mMockClientCallback1;
+ @Mock
+ private IAccessibilityInteractionConnectionCallback mMockClientCallback2;
+
+ @Captor
+ private ArgumentCaptor<AccessibilityNodeInfo> mFindInfoCaptor;
+ @Captor private ArgumentCaptor<List<AccessibilityNodeInfo>> mPrefetchInfoListCaptor;
+
+ private final Instrumentation mInstrumentation = InstrumentationRegistry.getInstrumentation();
+ private static final int MOCK_CLIENT_1_THREAD_AND_PROCESS_ID = 1;
+ private static final int MOCK_CLIENT_2_THREAD_AND_PROCESS_ID = 2;
+
+ private static final String FRAME_LAYOUT_DESCRIPTION = "frameLayout";
+ private static final String TEXT_VIEW_1_DESCRIPTION = "textView1";
+ private static final String TEXT_VIEW_2_DESCRIPTION = "textView2";
+
+ private TestFrameLayout mFrameLayout;
+ private TestTextView mTextView1;
+ private TestTextView2 mTextView2;
+
+ private boolean mSendClient1RequestForTextAfterTextPrefetched;
+ private boolean mSendClient2RequestForTextAfterTextPrefetched;
+ private boolean mSendRequestForTextAndIncludeUnImportantViews;
+ private int mMockClient1InteractionId;
+ private int mMockClient2InteractionId;
+
+ @Before
+ public void setUp() throws Throwable {
+ MockitoAnnotations.initMocks(this);
+
+ mInstrumentation.runOnMainSync(() -> {
+ final Context context = mInstrumentation.getTargetContext();
+ final ViewRootImpl viewRootImpl = new ViewRootImpl(context, context.getDisplay());
+
+ mFrameLayout = new TestFrameLayout(context);
+ mTextView1 = new TestTextView(context);
+ mTextView2 = new TestTextView2(context);
+
+ mFrameLayout.addView(mTextView1);
+ mFrameLayout.addView(mTextView2);
+
+ // The controller retrieves views through this manager, and registration happens on
+ // when attached to a window, which we don't have. We can simply reference FrameLayout
+ // with ROOT_NODE_ID
+ AccessibilityNodeIdManager.getInstance().registerViewWithId(
+ mTextView1, mTextView1.getAccessibilityViewId());
+ AccessibilityNodeIdManager.getInstance().registerViewWithId(
+ mTextView2, mTextView2.getAccessibilityViewId());
+
+ try {
+ viewRootImpl.setView(mFrameLayout, new WindowManager.LayoutParams(), null);
+
+ } catch (WindowManager.BadTokenException e) {
+ // activity isn't running, we will ignore BadTokenException.
+ }
+
+ mAccessibilityInteractionController =
+ new AccessibilityInteractionController(viewRootImpl);
+ });
+
+ }
+
+ @After
+ public void tearDown() throws Throwable {
+ AccessibilityNodeIdManager.getInstance().unregisterViewWithId(
+ mTextView1.getAccessibilityViewId());
+ AccessibilityNodeIdManager.getInstance().unregisterViewWithId(
+ mTextView2.getAccessibilityViewId());
+ }
+
+ /**
+ * Tests a basic request for the root node with prefetch flag
+ * {@link AccessibilityNodeInfo#FLAG_PREFETCH_DESCENDANTS}
+ *
+ * @throws RemoteException
+ */
+ @Test
+ public void testFindRootView_withOneClient_shouldReturnRootNodeAndPrefetchDescendants()
+ throws RemoteException {
+ // Request for our FrameLayout
+ sendNodeRequestToController(ROOT_NODE_ID, mMockClientCallback1,
+ mMockClient1InteractionId, FLAG_PREFETCH_DESCENDANTS);
+ mInstrumentation.waitForIdleSync();
+
+ // Verify we get FrameLayout
+ verify(mMockClientCallback1).setFindAccessibilityNodeInfoResult(
+ mFindInfoCaptor.capture(), eq(mMockClient1InteractionId));
+ AccessibilityNodeInfo infoSentToService = mFindInfoCaptor.getValue();
+ assertEquals(FRAME_LAYOUT_DESCRIPTION, infoSentToService.getContentDescription());
+
+ verify(mMockClientCallback1).setPrefetchAccessibilityNodeInfoResult(
+ mPrefetchInfoListCaptor.capture(), eq(mMockClient1InteractionId));
+ // The descendants are our two TextViews
+ List<AccessibilityNodeInfo> prefetchedNodes = mPrefetchInfoListCaptor.getValue();
+ assertEquals(2, prefetchedNodes.size());
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, prefetchedNodes.get(0).getContentDescription());
+ assertEquals(TEXT_VIEW_2_DESCRIPTION, prefetchedNodes.get(1).getContentDescription());
+
+ }
+
+ /**
+ * Tests a basic request for TestTextView1's node with prefetch flag
+ * {@link AccessibilityNodeInfo#FLAG_PREFETCH_SIBLINGS}
+ *
+ * @throws RemoteException
+ */
+ @Test
+ public void testFindTextView_withOneClient_shouldReturnNodeAndPrefetchedSiblings()
+ throws RemoteException {
+ // Request for TextView1
+ sendNodeRequestToController(AccessibilityNodeInfo.makeNodeId(
+ mTextView1.getAccessibilityViewId(), AccessibilityNodeProvider.HOST_VIEW_ID),
+ mMockClientCallback1, mMockClient1InteractionId, FLAG_PREFETCH_SIBLINGS);
+ mInstrumentation.waitForIdleSync();
+
+ // Verify we get TextView1
+ verify(mMockClientCallback1).setFindAccessibilityNodeInfoResult(
+ mFindInfoCaptor.capture(), eq(mMockClient1InteractionId));
+ AccessibilityNodeInfo infoSentToService = mFindInfoCaptor.getValue();
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, infoSentToService.getContentDescription());
+
+ // Verify the prefetched sibling of TextView1 is TextView2
+ verify(mMockClientCallback1).setPrefetchAccessibilityNodeInfoResult(
+ mPrefetchInfoListCaptor.capture(), eq(mMockClient1InteractionId));
+ // TextView2 is the prefetched sibling
+ List<AccessibilityNodeInfo> prefetchedNodes = mPrefetchInfoListCaptor.getValue();
+ assertEquals(1, prefetchedNodes.size());
+ assertEquals(TEXT_VIEW_2_DESCRIPTION, prefetchedNodes.get(0).getContentDescription());
+ }
+
+ /**
+ * Tests a series of controller requests to prevent prefetching.
+ * Request 1: Client 1 requests the root node
+ * Request 2: When the root node is initialized in
+ * {@link TestFrameLayout#onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo)},
+ * Client 2 requests TestTextView1's node
+ *
+ * Request 2 on the queue prevents prefetching for Request 1.
+ *
+ * @throws RemoteException
+ */
+ @Test
+ public void testFindRootAndTextNodes_withTwoClients_shouldPreventClient1Prefetch()
+ throws RemoteException {
+ mFrameLayout.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ final long nodeId = AccessibilityNodeInfo.makeNodeId(
+ mTextView1.getAccessibilityViewId(),
+ AccessibilityNodeProvider.HOST_VIEW_ID);
+
+ // Enqueue a request when this node is found from a different service for
+ // TextView1
+ sendNodeRequestToController(nodeId, mMockClientCallback2,
+ mMockClient2InteractionId, FLAG_PREFETCH_SIBLINGS);
+ }
+ });
+ // Client 1 request for FrameLayout
+ sendNodeRequestToController(ROOT_NODE_ID, mMockClientCallback1,
+ mMockClient1InteractionId, FLAG_PREFETCH_DESCENDANTS);
+
+ mInstrumentation.waitForIdleSync();
+
+ // Verify client 1 gets FrameLayout
+ verify(mMockClientCallback1).setFindAccessibilityNodeInfoResult(
+ mFindInfoCaptor.capture(), eq(mMockClient1InteractionId));
+ AccessibilityNodeInfo infoSentToService = mFindInfoCaptor.getValue();
+ assertEquals(FRAME_LAYOUT_DESCRIPTION, infoSentToService.getContentDescription());
+
+ // The second request is put in the queue in the FrameLayout's onInitializeA11yNodeInfo,
+ // meaning prefetching is interrupted and does not even begin for the first request
+ verify(mMockClientCallback1, never())
+ .setPrefetchAccessibilityNodeInfoResult(anyList(), anyInt());
+
+ // Verify client 2 gets TextView1
+ verify(mMockClientCallback2).setFindAccessibilityNodeInfoResult(
+ mFindInfoCaptor.capture(), eq(mMockClient2InteractionId));
+ infoSentToService = mFindInfoCaptor.getValue();
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, infoSentToService.getContentDescription());
+
+ // Verify the prefetched sibling of TextView1 is TextView2 (FLAG_PREFETCH_SIBLINGS)
+ verify(mMockClientCallback2).setPrefetchAccessibilityNodeInfoResult(
+ mPrefetchInfoListCaptor.capture(), eq(mMockClient2InteractionId));
+ List<AccessibilityNodeInfo> prefetchedNodes = mPrefetchInfoListCaptor.getValue();
+ assertEquals(1, prefetchedNodes.size());
+ assertEquals(TEXT_VIEW_2_DESCRIPTION, prefetchedNodes.get(0).getContentDescription());
+ }
+
+ /**
+ * Tests a series of controller same-service requests to interrupt prefetching and satisfy a
+ * pending node request.
+ * Request 1: Request the root node
+ * Request 2: When TextTextView1's node is initialized as part of Request 1's prefetching,
+ * request TestTextView1's node
+ *
+ * Request 1 prefetches TestTextView1's node, is interrupted by a pending request, and checks
+ * if its prefetched nodes satisfy any pending requests. It satisfies Request 2's request for
+ * TestTextView1's node. Request 2 is fulfilled, so it is removed from queue and does not
+ * prefetch.
+ *
+ * @throws RemoteException
+ */
+ @Test
+ public void testFindRootAndTextNode_withOneClient_shouldInterruptPrefetchAndSatisfyPendingMsg()
+ throws RemoteException {
+ mSendClient1RequestForTextAfterTextPrefetched = true;
+
+ mTextView1.setAccessibilityDelegate(new View.AccessibilityDelegate(){
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ info.setContentDescription(TEXT_VIEW_1_DESCRIPTION);
+ final long nodeId = AccessibilityNodeInfo.makeNodeId(
+ mTextView1.getAccessibilityViewId(),
+ AccessibilityNodeProvider.HOST_VIEW_ID);
+
+ if (mSendClient1RequestForTextAfterTextPrefetched) {
+ // Prevent a loop when processing second request
+ mSendClient1RequestForTextAfterTextPrefetched = false;
+ // TextView1 is prefetched here after the FrameLayout is found. Now enqueue a
+ // same-client request for TextView1
+ sendNodeRequestToController(nodeId, mMockClientCallback1,
+ ++mMockClient1InteractionId, FLAG_PREFETCH_SIBLINGS);
+
+ }
+ }
+ });
+ // Client 1 requests FrameLayout
+ sendNodeRequestToController(ROOT_NODE_ID, mMockClientCallback1,
+ mMockClient1InteractionId, FLAG_PREFETCH_DESCENDANTS);
+
+ // Flush out all messages
+ mInstrumentation.waitForIdleSync();
+
+ // When TextView1 is prefetched for FrameLayout, we put a message on the queue in
+ // TextView1's onInitializeA11yNodeInfo that requests for TextView1. The service thus get
+ // two node results for FrameLayout and TextView1.
+ verify(mMockClientCallback1, times(2))
+ .setFindAccessibilityNodeInfoResult(mFindInfoCaptor.capture(), anyInt());
+
+ List<AccessibilityNodeInfo> foundNodes = mFindInfoCaptor.getAllValues();
+ assertEquals(FRAME_LAYOUT_DESCRIPTION, foundNodes.get(0).getContentDescription());
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, foundNodes.get(1).getContentDescription());
+
+ // The controller will look at FrameLayout's prefetched nodes and find matching nodes in
+ // pending requests. The prefetched TextView1 matches the second request. The second
+ // request was removed from queue and prefetching for this request never occurred.
+ verify(mMockClientCallback1, times(1))
+ .setPrefetchAccessibilityNodeInfoResult(mPrefetchInfoListCaptor.capture(),
+ eq(mMockClient1InteractionId - 1));
+ List<AccessibilityNodeInfo> prefetchedNodes = mPrefetchInfoListCaptor.getValue();
+ assertEquals(1, prefetchedNodes.size());
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, prefetchedNodes.get(0).getContentDescription());
+ }
+
+ /**
+ * Like above, but tests a series of controller requests from different services to interrupt
+ * prefetching and satisfy a pending node request.
+ *
+ * @throws RemoteException
+ */
+ @Test
+ public void testFindRootAndTextNode_withTwoClients_shouldInterruptPrefetchAndSatisfyPendingMsg()
+ throws RemoteException {
+ mSendClient2RequestForTextAfterTextPrefetched = true;
+ mTextView1.setAccessibilityDelegate(new View.AccessibilityDelegate(){
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ info.setContentDescription(TEXT_VIEW_1_DESCRIPTION);
+ final long nodeId = AccessibilityNodeInfo.makeNodeId(
+ mTextView1.getAccessibilityViewId(),
+ AccessibilityNodeProvider.HOST_VIEW_ID);
+
+ if (mSendClient2RequestForTextAfterTextPrefetched) {
+ mSendClient2RequestForTextAfterTextPrefetched = false;
+ // TextView1 is prefetched here. Now enqueue client 2's request for
+ // TextView1
+ sendNodeRequestToController(nodeId, mMockClientCallback2,
+ mMockClient2InteractionId, FLAG_PREFETCH_SIBLINGS);
+ }
+ }
+ });
+ // Client 1 requests FrameLayout
+ sendNodeRequestToController(ROOT_NODE_ID, mMockClientCallback1,
+ mMockClient1InteractionId, FLAG_PREFETCH_DESCENDANTS);
+
+ mInstrumentation.waitForIdleSync();
+
+ // Verify client 1 gets FrameLayout
+ verify(mMockClientCallback1, times(1))
+ .setFindAccessibilityNodeInfoResult(mFindInfoCaptor.capture(), anyInt());
+ assertEquals(FRAME_LAYOUT_DESCRIPTION,
+ mFindInfoCaptor.getValue().getContentDescription());
+
+ // Verify client 1 has prefetched nodes
+ verify(mMockClientCallback1, times(1))
+ .setPrefetchAccessibilityNodeInfoResult(mPrefetchInfoListCaptor.capture(),
+ eq(mMockClient1InteractionId));
+
+ // Verify client 1's only prefetched node is TextView1
+ List<AccessibilityNodeInfo> prefetchedNodes = mPrefetchInfoListCaptor.getValue();
+ assertEquals(1, prefetchedNodes.size());
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, prefetchedNodes.get(0).getContentDescription());
+
+ // Verify client 2 gets TextView1
+ verify(mMockClientCallback2, times(1))
+ .setFindAccessibilityNodeInfoResult(mFindInfoCaptor.capture(), anyInt());
+
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, mFindInfoCaptor.getValue().getContentDescription());
+
+ // The second request was removed from queue and prefetching for this client request never
+ // occurred as it was satisfied.
+ verify(mMockClientCallback2, never())
+ .setPrefetchAccessibilityNodeInfoResult(anyList(), anyInt());
+
+ }
+
+ @Test
+ public void testFindNodeById_withTwoDifferentPrefetchFlags_shouldNotSatisfyPendingRequest()
+ throws RemoteException {
+ mSendRequestForTextAndIncludeUnImportantViews = true;
+ mTextView1.setAccessibilityDelegate(new View.AccessibilityDelegate(){
+ @Override
+ public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ info.setContentDescription(TEXT_VIEW_1_DESCRIPTION);
+ final long nodeId = AccessibilityNodeInfo.makeNodeId(
+ mTextView1.getAccessibilityViewId(),
+ AccessibilityNodeProvider.HOST_VIEW_ID);
+
+ if (mSendRequestForTextAndIncludeUnImportantViews) {
+ mSendRequestForTextAndIncludeUnImportantViews = false;
+ // TextView1 is prefetched here for client 1. Now enqueue a request from a
+ // different client that holds different fetch flags for TextView1
+ sendNodeRequestToController(nodeId, mMockClientCallback2,
+ mMockClient2InteractionId,
+ FLAG_PREFETCH_SIBLINGS | FLAG_INCLUDE_NOT_IMPORTANT_VIEWS);
+ }
+ }
+ });
+
+ // Mockito does not make copies of objects when called. It holds references, so
+ // the captor would point to client 2's results after all requests are processed. Verify
+ // prefetched node immediately
+ doAnswer(invocation -> {
+ List<AccessibilityNodeInfo> prefetched = invocation.getArgument(0);
+ assertEquals(TEXT_VIEW_1_DESCRIPTION, prefetched.get(0).getContentDescription());
+ return null;
+ }).when(mMockClientCallback1).setPrefetchAccessibilityNodeInfoResult(anyList(),
+ eq(mMockClient1InteractionId));
+
+ // Client 1 requests FrameLayout
+ sendNodeRequestToController(ROOT_NODE_ID, mMockClientCallback1,
+ mMockClient1InteractionId, FLAG_PREFETCH_DESCENDANTS);
+
+ mInstrumentation.waitForIdleSync();
+
+ // Verify client 1 gets FrameLayout
+ verify(mMockClientCallback1, times(1))
+ .setFindAccessibilityNodeInfoResult(mFindInfoCaptor.capture(),
+ eq(mMockClient1InteractionId));
+
+ assertEquals(FRAME_LAYOUT_DESCRIPTION,
+ mFindInfoCaptor.getValue().getContentDescription());
+
+ // Verify client 1 has prefetched results. The only prefetched node is TextView1
+ // (from above doAnswer)
+ verify(mMockClientCallback1, times(1))
+ .setPrefetchAccessibilityNodeInfoResult(mPrefetchInfoListCaptor.capture(),
+ eq(mMockClient1InteractionId));
+
+ // Verify client 2 gets TextView1
+ verify(mMockClientCallback2, times(1))
+ .setFindAccessibilityNodeInfoResult(mFindInfoCaptor.capture(),
+ eq(mMockClient2InteractionId));
+ assertEquals(TEXT_VIEW_1_DESCRIPTION,
+ mFindInfoCaptor.getValue().getContentDescription());
+ // Verify client 2 has TextView2 as a prefetched node
+ verify(mMockClientCallback2, times(1))
+ .setPrefetchAccessibilityNodeInfoResult(mPrefetchInfoListCaptor.capture(),
+ eq(mMockClient2InteractionId));
+ List<AccessibilityNodeInfo> prefetchedNode = mPrefetchInfoListCaptor.getValue();
+ assertEquals(1, prefetchedNode.size());
+ assertEquals(TEXT_VIEW_2_DESCRIPTION, prefetchedNode.get(0).getContentDescription());
+ }
+
+ private void sendNodeRequestToController(long requestedNodeId,
+ IAccessibilityInteractionConnectionCallback callback, int interactionId,
+ int prefetchFlags) {
+ final int processAndThreadId = callback == mMockClientCallback1
+ ? MOCK_CLIENT_1_THREAD_AND_PROCESS_ID
+ : MOCK_CLIENT_2_THREAD_AND_PROCESS_ID;
+
+ mAccessibilityInteractionController.findAccessibilityNodeInfoByAccessibilityIdClientThread(
+ requestedNodeId,
+ null, interactionId,
+ callback, prefetchFlags,
+ processAndThreadId,
+ processAndThreadId, null, null);
+
+ }
+
+ private class TestFrameLayout extends FrameLayout {
+
+ TestFrameLayout(Context context) {
+ super(context);
+ }
+
+ @Override
+ public int getWindowVisibility() {
+ // We aren't attached to a window so let's pretend
+ return VISIBLE;
+ }
+
+ @Override
+ public boolean isShown() {
+ // Controller check
+ return true;
+ }
+
+ @Override
+ public int getAccessibilityViewId() {
+ // static id doesn't reset after tests so return the same one
+ return 0;
+ }
+
+ @Override
+ public void addChildrenForAccessibility(ArrayList<View> outChildren) {
+ // ViewGroup#addChildrenForAccessbility sorting logic will switch these two
+ outChildren.add(mTextView1);
+ outChildren.add(mTextView2);
+ }
+
+ @Override
+ public boolean includeForAccessibility() {
+ return true;
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setContentDescription(FRAME_LAYOUT_DESCRIPTION);
+ }
+ }
+
+ private class TestTextView extends TextView {
+ TestTextView(Context context) {
+ super(context);
+ }
+
+ @Override
+ public int getWindowVisibility() {
+ return VISIBLE;
+ }
+
+ @Override
+ public boolean isShown() {
+ return true;
+ }
+
+ @Override
+ public int getAccessibilityViewId() {
+ return 1;
+ }
+
+ @Override
+ public boolean includeForAccessibility() {
+ return true;
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setContentDescription(TEXT_VIEW_1_DESCRIPTION);
+ }
+ }
+
+ private class TestTextView2 extends TextView {
+ TestTextView2(Context context) {
+ super(context);
+ }
+
+ @Override
+ public int getWindowVisibility() {
+ return VISIBLE;
+ }
+
+ @Override
+ public boolean isShown() {
+ return true;
+ }
+
+ @Override
+ public int getAccessibilityViewId() {
+ return 2;
+ }
+
+ @Override
+ public boolean includeForAccessibility() {
+ return true;
+ }
+
+ @Override
+ public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+ super.onInitializeAccessibilityNodeInfo(info);
+ info.setContentDescription(TEXT_VIEW_2_DESCRIPTION);
+ }
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index 8b0e948579fb..b6b6932c4a93 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -602,12 +602,12 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
when(mPackageManager.getApplicationInfo(eq("foo.bar"), anyInt()))
.thenReturn(ApplicationInfoBuilder.create()
- .withPackageName("foo.bar")
- .debuggable()
- .build());
+ .withPackageName("foo.bar")
+ .debuggable()
+ .build());
when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
.thenThrow(new NameNotFoundException());
@@ -649,7 +649,7 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
compatConfig.addOverrides(new CompatibilityOverrideConfig(Collections.singletonMap(1L,
new PackageOverride.Builder()
@@ -673,11 +673,11 @@ public class CompatConfigTest {
}
@Test
- public void testLoadOverridesRaw() throws Exception {
+ public void testInitOverridesRaw() throws Exception {
File tempDir = createTempDir();
File overridesFile = new File(tempDir, "overrides.xml");
// Change 1 is enabled for foo.bar (validated)
- // Change 2 is disabled for bar.baz (deferred)
+ // Change 2 is disabled for bar.baz (raw)
String xmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ "<overrides>\n"
+ " <change-overrides changeId=\"1\">\n"
@@ -709,7 +709,7 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
.withPackageName("foo.bar")
.withVersionCode(100L)
@@ -728,7 +728,7 @@ public class CompatConfigTest {
}
@Test
- public void testLoadOverridesDeferred() throws Exception {
+ public void testInitOverridesDeferred() throws Exception {
File tempDir = createTempDir();
File overridesFile = new File(tempDir, "overrides.xml");
// Change 1 is enabled for foo.bar (validated)
@@ -754,7 +754,7 @@ public class CompatConfigTest {
.addEnableSinceSdkChangeWithId(2, 2L)
.build();
compatConfig.forceNonDebuggableFinalForTest(true);
- compatConfig.initOverrides(overridesFile);
+ compatConfig.initOverrides(overridesFile, new File(""));
ApplicationInfo applicationInfo = ApplicationInfoBuilder.create()
.withPackageName("foo.bar")
.debuggable()
@@ -767,4 +767,115 @@ public class CompatConfigTest {
assertThat(compatConfig.isChangeEnabled(1L, applicationInfo)).isTrue();
assertThat(compatConfig.willChangeBeEnabled(2L, "bar.baz")).isFalse();
}
+
+ @Test
+ public void testInitOverridesWithStaticFile() throws Exception {
+ File tempDir = createTempDir();
+ File dynamicOverridesFile = new File(tempDir, "dynamic_overrides.xml");
+ File staticOverridesFile = new File(tempDir, "static_overrides.xml");
+ // Change 1 is enabled for foo.bar (raw)
+ // Change 2 is disabled for bar.baz (raw)
+ String dynamicXmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<overrides>"
+ + "<change-overrides changeId=\"1\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "<change-overrides changeId=\"2\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"false\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "</overrides>";
+ writeToFile(tempDir, "dynamic_overrides.xml", dynamicXmlData);
+ // Change 2 is enabled for foo.bar and bar.baz (raw)
+ // Change 3 is enabled for bar.baz (raw)
+ String staticXmlData = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"
+ + "<overrides>"
+ + "<change-overrides changeId=\"2\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "<change-overrides changeId=\"3\">"
+ + "<raw>"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + "</raw>"
+ + "</change-overrides>"
+ + "</overrides>";
+ writeToFile(tempDir, "static_overrides.xml", staticXmlData);
+ CompatConfig compatConfig = CompatConfigBuilder.create(mBuildClassifier, mContext)
+ .addDisabledChangeWithId(1L)
+ .addDisabledChangeWithId(2L)
+ .addDisabledChangeWithId(3L)
+ .build();
+ compatConfig.forceNonDebuggableFinalForTest(true);
+ // Adding an override that will be cleared after initOverrides is called.
+ compatConfig.addOverride(1L, "bar.baz", true);
+ compatConfig.initOverrides(dynamicOverridesFile, staticOverridesFile);
+ when(mPackageManager.getApplicationInfo(eq("foo.bar"), anyInt()))
+ .thenThrow(new NameNotFoundException());
+ when(mPackageManager.getApplicationInfo(eq("bar.baz"), anyInt()))
+ .thenThrow(new NameNotFoundException());
+
+ assertThat(compatConfig.willChangeBeEnabled(1L, "foo.bar")).isTrue();
+ assertThat(compatConfig.willChangeBeEnabled(2L, "foo.bar")).isTrue();
+ assertThat(compatConfig.willChangeBeEnabled(2L, "bar.baz")).isFalse();
+ assertThat(compatConfig.willChangeBeEnabled(3L, "bar.baz")).isTrue();
+ assertThat(readFile(dynamicOverridesFile))
+ .isEqualTo("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
+ + "<overrides>\n"
+ + " <change-overrides changeId=\"1\">\n"
+ + " <validated>\n"
+ + " </validated>\n"
+ + " <raw>\n"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " </raw>\n"
+ + " </change-overrides>\n"
+ + " <change-overrides changeId=\"2\">\n"
+ + " <validated>\n"
+ + " </validated>\n"
+ + " <raw>\n"
+ + " <raw-override-value packageName=\"foo.bar\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"false\">\n"
+ + " </raw-override-value>\n"
+ + " </raw>\n"
+ + " </change-overrides>\n"
+ + " <change-overrides changeId=\"3\">\n"
+ + " <validated>\n"
+ + " </validated>\n"
+ + " <raw>\n"
+ + " <raw-override-value packageName=\"bar.baz\" "
+ + "minVersionCode=\"-9223372036854775808\" "
+ + "maxVersionCode=\"9223372036854775807\" enabled=\"true\">\n"
+ + " </raw-override-value>\n"
+ + " </raw>\n"
+ + " </change-overrides>\n"
+ + "</overrides>\n");
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
index 26a549d77664..a97ea268b1c8 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java
@@ -274,6 +274,87 @@ public final class DeviceStateManagerServiceTest {
}
@Test
+ public void requestState_pendingStateAtRequest() throws RemoteException {
+ TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
+ mService.getBinderService().registerCallback(callback);
+
+ mPolicy.blockConfigure();
+
+ final IBinder firstRequestToken = new Binder();
+ final IBinder secondRequestToken = new Binder();
+ assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
+ TestDeviceStateManagerCallback.STATUS_UNKNOWN);
+ assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
+ TestDeviceStateManagerCallback.STATUS_UNKNOWN);
+
+ mService.getBinderService().requestState(firstRequestToken,
+ OTHER_DEVICE_STATE.getIdentifier(), 0 /* flags */);
+
+ assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
+ assertEquals(mService.getPendingState().get(), OTHER_DEVICE_STATE);
+ assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE);
+ assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
+ OTHER_DEVICE_STATE.getIdentifier());
+
+ mService.getBinderService().requestState(secondRequestToken,
+ DEFAULT_DEVICE_STATE.getIdentifier(), 0 /* flags */);
+
+ mPolicy.resumeConfigureOnce();
+
+ // First request status is now suspended as there is another pending request.
+ assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
+ TestDeviceStateManagerCallback.STATUS_SUSPENDED);
+ // Second request status still unknown because the service is still awaiting policy
+ // callback.
+ assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
+ TestDeviceStateManagerCallback.STATUS_UNKNOWN);
+
+ assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE);
+ assertEquals(mService.getPendingState().get(), DEFAULT_DEVICE_STATE);
+ assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE);
+ assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
+ DEFAULT_DEVICE_STATE.getIdentifier());
+
+ mPolicy.resumeConfigure();
+
+ assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
+ assertEquals(mService.getPendingState(), Optional.empty());
+ assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE);
+ assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
+ DEFAULT_DEVICE_STATE.getIdentifier());
+
+ // Now cancel the second request to make the first request active.
+ mService.getBinderService().cancelRequest(secondRequestToken);
+
+ assertEquals(callback.getLastNotifiedStatus(firstRequestToken),
+ TestDeviceStateManagerCallback.STATUS_ACTIVE);
+ assertEquals(callback.getLastNotifiedStatus(secondRequestToken),
+ TestDeviceStateManagerCallback.STATUS_CANCELED);
+
+ assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE);
+ assertEquals(mService.getPendingState(), Optional.empty());
+ assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE);
+ assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
+ OTHER_DEVICE_STATE.getIdentifier());
+ }
+
+ @Test
+ public void requestState_sameAsBaseState() throws RemoteException {
+ TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
+ mService.getBinderService().registerCallback(callback);
+
+ final IBinder token = new Binder();
+ assertEquals(callback.getLastNotifiedStatus(token),
+ TestDeviceStateManagerCallback.STATUS_UNKNOWN);
+
+ mService.getBinderService().requestState(token, DEFAULT_DEVICE_STATE.getIdentifier(),
+ 0 /* flags */);
+
+ assertEquals(callback.getLastNotifiedStatus(token),
+ TestDeviceStateManagerCallback.STATUS_ACTIVE);
+ }
+
+ @Test
public void requestState_flagCancelWhenBaseChanges() throws RemoteException {
TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
mService.getBinderService().registerCallback(callback);
@@ -407,6 +488,14 @@ public final class DeviceStateManagerServiceTest {
}
}
+ public void resumeConfigureOnce() {
+ if (mPendingConfigureCompleteRunnable != null) {
+ Runnable onComplete = mPendingConfigureCompleteRunnable;
+ mPendingConfigureCompleteRunnable = null;
+ onComplete.run();
+ }
+ }
+
public int getMostRecentRequestedStateToConfigure() {
return mLastDeviceStateRequestedToConfigure;
}
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
index 81b2381cd629..15ada896512b 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayModeDirectorTest.java
@@ -88,6 +88,7 @@ public class DisplayModeDirectorTest {
private static final String TAG = "DisplayModeDirectorTest";
private static final boolean DEBUG = false;
private static final float FLOAT_TOLERANCE = 0.01f;
+ private static final int DISPLAY_ID = 0;
private Context mContext;
private FakesInjector mInjector;
@@ -107,19 +108,29 @@ public class DisplayModeDirectorTest {
private DisplayModeDirector createDirectorFromRefreshRateArray(
float[] refreshRates, int baseModeId) {
+ return createDirectorFromRefreshRateArray(refreshRates, baseModeId, refreshRates[0]);
+ }
+
+ private DisplayModeDirector createDirectorFromRefreshRateArray(
+ float[] refreshRates, int baseModeId, float defaultRefreshRate) {
DisplayModeDirector director =
new DisplayModeDirector(mContext, mHandler, mInjector);
- int displayId = 0;
Display.Mode[] modes = new Display.Mode[refreshRates.length];
+ Display.Mode defaultMode = null;
for (int i = 0; i < refreshRates.length; i++) {
modes[i] = new Display.Mode(
/*modeId=*/baseModeId + i, /*width=*/1000, /*height=*/1000, refreshRates[i]);
+ if (refreshRates[i] == defaultRefreshRate) {
+ defaultMode = modes[i];
+ }
}
+ assertThat(defaultMode).isNotNull();
+
SparseArray<Display.Mode[]> supportedModesByDisplay = new SparseArray<>();
- supportedModesByDisplay.put(displayId, modes);
+ supportedModesByDisplay.put(DISPLAY_ID, modes);
director.injectSupportedModesByDisplay(supportedModesByDisplay);
SparseArray<Display.Mode> defaultModesByDisplay = new SparseArray<>();
- defaultModesByDisplay.put(displayId, modes[0]);
+ defaultModesByDisplay.put(DISPLAY_ID, defaultMode);
director.injectDefaultModeByDisplay(defaultModesByDisplay);
return director;
}
@@ -130,16 +141,15 @@ public class DisplayModeDirectorTest {
for (int i = 0; i < numRefreshRates; i++) {
refreshRates[i] = minFps + i;
}
- return createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/minFps);
+ return createDirectorFromRefreshRateArray(refreshRates, /*baseModeId=*/minFps,
+ /*defaultRefreshRate=*/minFps);
}
@Test
public void testDisplayModeVoting() {
- int displayId = 0;
-
// With no votes present, DisplayModeDirector should allow any refresh rate.
DesiredDisplayModeSpecs modeSpecs =
- createDirectorFromFpsRange(60, 90).getDesiredDisplayModeSpecs(displayId);
+ createDirectorFromFpsRange(60, 90).getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(modeSpecs.baseModeId).isEqualTo(60);
assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(0f);
assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(Float.POSITIVE_INFINITY);
@@ -156,12 +166,12 @@ public class DisplayModeDirectorTest {
assertTrue(2 * numPriorities < maxFps - minFps + 1);
SparseArray<Vote> votes = new SparseArray<>();
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
- votesByDisplay.put(displayId, votes);
+ votesByDisplay.put(DISPLAY_ID, votes);
for (int i = 0; i < numPriorities; i++) {
int priority = Vote.MIN_PRIORITY + i;
votes.put(priority, Vote.forRefreshRates(minFps + i, maxFps - i));
director.injectVotesByDisplay(votesByDisplay);
- modeSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ modeSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(modeSpecs.baseModeId).isEqualTo(minFps + i);
assertThat(modeSpecs.primaryRefreshRateRange.min)
.isEqualTo((float) (minFps + i));
@@ -177,11 +187,11 @@ public class DisplayModeDirectorTest {
DisplayModeDirector director = createDirectorFromFpsRange(60, 90);
SparseArray<Vote> votes = new SparseArray<>();
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
- votesByDisplay.put(displayId, votes);
+ votesByDisplay.put(DISPLAY_ID, votes);
votes.put(Vote.MAX_PRIORITY, Vote.forRefreshRates(65, 85));
votes.put(Vote.MIN_PRIORITY, Vote.forRefreshRates(70, 80));
director.injectVotesByDisplay(votesByDisplay);
- modeSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ modeSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(modeSpecs.baseModeId).isEqualTo(70);
assertThat(modeSpecs.primaryRefreshRateRange.min).isEqualTo(70f);
assertThat(modeSpecs.primaryRefreshRateRange.max).isEqualTo(80f);
@@ -190,18 +200,17 @@ public class DisplayModeDirectorTest {
@Test
public void testVotingWithFloatingPointErrors() {
- int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(50, 90);
SparseArray<Vote> votes = new SparseArray<>();
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
- votesByDisplay.put(displayId, votes);
+ votesByDisplay.put(DISPLAY_ID, votes);
float error = FLOAT_TOLERANCE / 4;
votes.put(Vote.PRIORITY_USER_SETTING_PEAK_REFRESH_RATE, Vote.forRefreshRates(0, 60));
votes.put(Vote.PRIORITY_APP_REQUEST_SIZE, Vote.forRefreshRates(60 + error, 60 + error));
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE,
Vote.forRefreshRates(60 - error, 60 - error));
director.injectVotesByDisplay(votesByDisplay);
- DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
@@ -213,15 +222,14 @@ public class DisplayModeDirectorTest {
assertTrue(PRIORITY_FLICKER < Vote.PRIORITY_APP_REQUEST_REFRESH_RATE);
assertTrue(PRIORITY_FLICKER < Vote.PRIORITY_APP_REQUEST_SIZE);
- int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(60, 90);
SparseArray<Vote> votes = new SparseArray<>();
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
- votesByDisplay.put(displayId, votes);
+ votesByDisplay.put(DISPLAY_ID, votes);
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90));
votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60));
director.injectVotesByDisplay(votesByDisplay);
- DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
@@ -229,7 +237,7 @@ public class DisplayModeDirectorTest {
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 90));
votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(90, 90));
director.injectVotesByDisplay(votesByDisplay);
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90);
@@ -237,7 +245,7 @@ public class DisplayModeDirectorTest {
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90));
votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60));
director.injectVotesByDisplay(votesByDisplay);
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90);
@@ -245,7 +253,7 @@ public class DisplayModeDirectorTest {
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(60, 60));
votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(90, 90));
director.injectVotesByDisplay(votesByDisplay);
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
}
@@ -261,14 +269,13 @@ public class DisplayModeDirectorTest {
assertTrue(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE
>= Vote.APP_REQUEST_REFRESH_RATE_RANGE_PRIORITY_CUTOFF);
- int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(60, 90);
SparseArray<Vote> votes = new SparseArray<>();
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
- votesByDisplay.put(displayId, votes);
+ votesByDisplay.put(DISPLAY_ID, votes);
votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(60, 60));
director.injectVotesByDisplay(votesByDisplay);
- DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f);
@@ -277,7 +284,7 @@ public class DisplayModeDirectorTest {
votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE,
Vote.forRefreshRates(90, Float.POSITIVE_INFINITY));
director.injectVotesByDisplay(votesByDisplay);
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isAtLeast(90f);
assertThat(desiredSpecs.appRequestRefreshRateRange.min).isAtMost(60f);
@@ -285,7 +292,7 @@ public class DisplayModeDirectorTest {
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(75, 75));
director.injectVotesByDisplay(votesByDisplay);
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(75);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(75);
assertThat(desiredSpecs.appRequestRefreshRateRange.min)
@@ -355,11 +362,10 @@ public class DisplayModeDirectorTest {
@Test
public void testVotingWithAlwaysRespectAppRequest() {
- final int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(50, 90);
SparseArray<Vote> votes = new SparseArray<>();
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
- votesByDisplay.put(displayId, votes);
+ votesByDisplay.put(DISPLAY_ID, votes);
votes.put(PRIORITY_FLICKER, Vote.forRefreshRates(0, 60));
votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, Vote.forRefreshRates(60, 90));
votes.put(Vote.PRIORITY_APP_REQUEST_REFRESH_RATE, Vote.forRefreshRates(90, 90));
@@ -369,7 +375,7 @@ public class DisplayModeDirectorTest {
director.injectVotesByDisplay(votesByDisplay);
assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse();
- DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
@@ -377,7 +383,7 @@ public class DisplayModeDirectorTest {
director.setShouldAlwaysRespectAppRequestedMode(true);
assertThat(director.shouldAlwaysRespectAppRequestedMode()).isTrue();
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(90);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(90);
assertThat(desiredSpecs.baseModeId).isEqualTo(90);
@@ -385,7 +391,7 @@ public class DisplayModeDirectorTest {
director.setShouldAlwaysRespectAppRequestedMode(false);
assertThat(director.shouldAlwaysRespectAppRequestedMode()).isFalse();
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
assertThat(desiredSpecs.baseModeId).isEqualTo(60);
@@ -393,11 +399,10 @@ public class DisplayModeDirectorTest {
@Test
public void testVotingWithSwitchingTypeNone() {
- final int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(0, 90);
SparseArray<Vote> votes = new SparseArray<>();
SparseArray<SparseArray<Vote>> votesByDisplay = new SparseArray<>();
- votesByDisplay.put(displayId, votes);
+ votesByDisplay.put(DISPLAY_ID, votes);
votes.put(Vote.PRIORITY_USER_SETTING_MIN_REFRESH_RATE, Vote.forRefreshRates(30, 90));
votes.put(Vote.PRIORITY_LOW_POWER_MODE, Vote.forRefreshRates(0, 60));
@@ -405,7 +410,7 @@ public class DisplayModeDirectorTest {
director.injectVotesByDisplay(votesByDisplay);
assertThat(director.getModeSwitchingType())
.isNotEqualTo(DisplayManager.SWITCHING_TYPE_NONE);
- DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(60);
@@ -417,7 +422,7 @@ public class DisplayModeDirectorTest {
assertThat(director.getModeSwitchingType())
.isEqualTo(DisplayManager.SWITCHING_TYPE_NONE);
- desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.primaryRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30);
assertThat(desiredSpecs.primaryRefreshRateRange.max).isWithin(FLOAT_TOLERANCE).of(30);
assertThat(desiredSpecs.appRequestRefreshRateRange.min).isWithin(FLOAT_TOLERANCE).of(30);
@@ -427,29 +432,38 @@ public class DisplayModeDirectorTest {
@Test
public void testVotingWithSwitchingTypeWithinGroups() {
- final int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(0, 90);
director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS);
assertThat(director.getModeSwitchingType())
.isEqualTo(DisplayManager.SWITCHING_TYPE_WITHIN_GROUPS);
- DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.allowGroupSwitching).isFalse();
}
@Test
public void testVotingWithSwitchingTypeWithinAndAcrossGroups() {
- final int displayId = 0;
DisplayModeDirector director = createDirectorFromFpsRange(0, 90);
director.setModeSwitchingType(DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
assertThat(director.getModeSwitchingType())
.isEqualTo(DisplayManager.SWITCHING_TYPE_ACROSS_AND_WITHIN_GROUPS);
- DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(displayId);
+ DesiredDisplayModeSpecs desiredSpecs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
assertThat(desiredSpecs.allowGroupSwitching).isTrue();
}
@Test
+ public void testDefaultDisplayModeIsSelectedIfAvailable() {
+ final float[] refreshRates = new float[]{24f, 25f, 30f, 60f, 90f};
+ final int defaultModeId = 3;
+ DisplayModeDirector director = createDirectorFromRefreshRateArray(
+ refreshRates, /*baseModeId=*/0, refreshRates[defaultModeId]);
+
+ DesiredDisplayModeSpecs specs = director.getDesiredDisplayModeSpecs(DISPLAY_ID);
+ assertThat(specs.baseModeId).isEqualTo(defaultModeId);
+ }
+
+ @Test
public void testBrightnessObserverGetsUpdatedRefreshRatesForZone() {
DisplayModeDirector director =
createDirectorFromRefreshRateArray(new float[] {60.f, 90.f}, /* baseModeId= */ 0);
diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java
deleted file mode 100644
index 275e7c7fec04..000000000000
--- a/services/tests/servicestests/src/com/android/server/graphics/fonts/FontCrashDetectorTest.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2021 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.graphics.fonts;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.Context;
-import android.os.FileUtils;
-import android.platform.test.annotations.Presubmit;
-
-import androidx.test.InstrumentationRegistry;
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import java.io.File;
-
-@Presubmit
-@SmallTest
-@RunWith(AndroidJUnit4.class)
-public final class FontCrashDetectorTest {
-
- private File mCacheDir;
-
- @SuppressWarnings("ResultOfMethodCallIgnored")
- @Before
- public void setUp() {
- Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
- mCacheDir = new File(context.getCacheDir(), "UpdatableFontDirTest");
- FileUtils.deleteContentsAndDir(mCacheDir);
- mCacheDir.mkdirs();
- }
-
- @Test
- public void detectCrash() throws Exception {
- // Prepare a marker file.
- File file = new File(mCacheDir, "detectCrash");
- assertThat(file.createNewFile()).isTrue();
-
- FontCrashDetector detector = new FontCrashDetector(file);
- assertThat(detector.hasCrashed()).isTrue();
-
- detector.clear();
- assertThat(detector.hasCrashed()).isFalse();
- assertThat(file.exists()).isFalse();
- }
-
- @Test
- public void monitorCrash() {
- File file = new File(mCacheDir, "monitorCrash");
- FontCrashDetector detector = new FontCrashDetector(file);
- assertThat(detector.hasCrashed()).isFalse();
-
- FontCrashDetector.MonitoredBlock block = detector.start();
- assertThat(file.exists()).isTrue();
-
- block.close();
- assertThat(file.exists()).isFalse();
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
index f2254a98a70e..c08857ca9bdc 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ActiveSourceActionTest.java
@@ -74,8 +74,6 @@ public class ActiveSourceActionTest {
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
-
mHdmiControlService = new HdmiControlService(mContextSpy) {
@Override
AudioManager getAudioManager() {
@@ -106,15 +104,11 @@ public class ActiveSourceActionTest {
protected void writeStringSystemProperty(String key, String value) {
// do nothing
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
Looper looper = mTestLooper.getLooper();
mHdmiControlService.setIoLooper(looper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
index 44418ce1e9c4..50ba761cef10 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcInitiationActionFromAvrTest.java
@@ -76,8 +76,6 @@ public class ArcInitiationActionFromAvrTest {
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
-
HdmiControlService hdmiControlService =
new HdmiControlService(mContextSpy) {
@Override
@@ -112,11 +110,6 @@ public class ArcInitiationActionFromAvrTest {
Looper getServiceLooper() {
return mTestLooper.getLooper();
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(hdmiControlService) {
@@ -128,6 +121,7 @@ public class ArcInitiationActionFromAvrTest {
mHdmiCecLocalDeviceAudioSystem.init();
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
+ hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
hdmiControlService, mNativeWrapper, hdmiControlService.getAtomWriter());
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 d454d8771e15..aa5bc933002d 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/ArcTerminationActionFromAvrTest.java
@@ -77,8 +77,6 @@ public class ArcTerminationActionFromAvrTest {
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
-
HdmiControlService hdmiControlService =
new HdmiControlService(mContextSpy) {
@Override
@@ -113,15 +111,11 @@ public class ArcTerminationActionFromAvrTest {
Looper getServiceLooper() {
return mTestLooper.getLooper();
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
+ hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
hdmiControlService, mNativeWrapper, hdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
index 7cb72c414e52..ef7b274eeb83 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DevicePowerStatusActionTest.java
@@ -86,8 +86,6 @@ public class DevicePowerStatusActionTest {
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
-
mHdmiControlService = new HdmiControlService(mContextSpy) {
@Override
AudioManager getAudioManager() {
@@ -118,15 +116,11 @@ public class DevicePowerStatusActionTest {
protected void writeStringSystemProperty(String key, String value) {
// do nothing
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
Looper looper = mTestLooper.getLooper();
mHdmiControlService.setIoLooper(looper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java
index 9bf95c0edcdb..678f8b219e28 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/DeviceSelectActionTest.java
@@ -106,8 +106,6 @@ public class DeviceSelectActionTest {
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
mIThermalServiceMock, new Handler(mMyLooper));
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
-
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
@Override
@@ -133,16 +131,12 @@ public class DeviceSelectActionTest {
protected PowerManager getPowerManager() {
return powerManager;
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
mHdmiCecLocalDeviceTv.init();
mHdmiControlService.setIoLooper(mMyLooper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
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 eedbc958dcd5..6bb148d43a57 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystemTest.java
@@ -98,8 +98,6 @@ public class HdmiCecLocalDeviceAudioSystemTest {
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
mIThermalServiceMock, new Handler(mMyLooper));
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
-
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
@Override
@@ -188,17 +186,13 @@ public class HdmiCecLocalDeviceAudioSystemTest {
protected PowerManager getPowerManager() {
return powerManager;
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mHdmiControlService.getHdmiCecConfig().setIntValue(
HdmiControlManager.CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
HdmiControlManager.VOLUME_CONTROL_ENABLED);
mMyLooper = mTestLooper.getLooper();
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
mHdmiCecLocalDeviceAudioSystem = new HdmiCecLocalDeviceAudioSystem(mHdmiControlService);
mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService) {
@Override
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 b11ac24b9a29..915392e6eb80 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -87,7 +87,6 @@ public class HdmiCecLocalDevicePlaybackTest {
mMyLooper = mTestLooper.getLooper();
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
mIThermalServiceMock, new Handler(mMyLooper));
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
@@ -136,15 +135,11 @@ public class HdmiCecLocalDevicePlaybackTest {
protected PowerManager getPowerManager() {
return powerManager;
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(mHdmiControlService);
mHdmiCecLocalDevicePlayback.init();
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
mHdmiControlService.setIoLooper(mMyLooper);
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
index 0717112da12c..b3f008598dc8 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTest.java
@@ -128,8 +128,6 @@ public class HdmiCecLocalDeviceTest {
Context context = InstrumentationRegistry.getTargetContext();
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
-
mHdmiControlService =
new HdmiControlService(context) {
@Override
@@ -163,13 +161,9 @@ public class HdmiCecLocalDeviceTest {
void wakeUp() {
mWakeupMessageReceived = true;
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mHdmiControlService.setIoLooper(mTestLooper.getLooper());
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
index 4623eb5b7d4b..4b3ef2f2cfd1 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDeviceTvTest.java
@@ -81,8 +81,6 @@ public class HdmiCecLocalDeviceTvTest {
PowerManager powerManager = new PowerManager(context, mIPowerManagerMock,
mIThermalServiceMock, new Handler(mMyLooper));
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
-
mHdmiControlService =
new HdmiControlService(InstrumentationRegistry.getTargetContext()) {
@Override
@@ -119,16 +117,12 @@ public class HdmiCecLocalDeviceTvTest {
AudioManager getAudioManager() {
return mAudioManager;
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mHdmiCecLocalDeviceTv = new HdmiCecLocalDeviceTv(mHdmiControlService);
mHdmiCecLocalDeviceTv.init();
mHdmiControlService.setIoLooper(mMyLooper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
index 06373c2284b2..1c7ff421fe92 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecPowerStatusControllerTest.java
@@ -62,12 +62,12 @@ public class HdmiCecPowerStatusControllerTest {
private FakeNativeWrapper mNativeWrapper;
private TestLooper mTestLooper = new TestLooper();
private ArrayList<HdmiCecLocalDevice> mLocalDevices = new ArrayList<>();
- private int mHdmiCecVersion = HdmiControlManager.HDMI_CEC_VERSION_1_4_B;
@Mock
private IPowerManager mIPowerManagerMock;
@Mock
private IThermalService mIThermalServiceMock;
private HdmiControlService mHdmiControlService;
+ private HdmiCecLocalDevicePlayback mHdmiCecLocalDevicePlayback;
@Before
public void setUp() throws Exception {
@@ -81,8 +81,6 @@ public class HdmiCecPowerStatusControllerTest {
when(contextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(contextSpy);
-
mHdmiControlService = new HdmiControlService(contextSpy) {
@Override
boolean isControlEnabled() {
@@ -100,33 +98,24 @@ public class HdmiCecPowerStatusControllerTest {
}
@Override
- int getCecVersion() {
- return mHdmiCecVersion;
- }
-
- @Override
boolean isPowerStandby() {
return false;
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mHdmiControlService.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
- HdmiCecLocalDevicePlayback hdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(
+ mHdmiCecLocalDevicePlayback = new HdmiCecLocalDevicePlayback(
mHdmiControlService);
- hdmiCecLocalDevicePlayback.init();
+ mHdmiCecLocalDevicePlayback.init();
mHdmiControlService.setIoLooper(myLooper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(contextSpy));
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
mHdmiControlService.setCecController(hdmiCecController);
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
- mLocalDevices.add(hdmiCecLocalDevicePlayback);
+ mLocalDevices.add(mHdmiCecLocalDevicePlayback);
HdmiPortInfo[] hdmiPortInfos = new HdmiPortInfo[1];
hdmiPortInfos[0] =
new HdmiPortInfo(1, HdmiPortInfo.PORT_OUTPUT, 0x0000, true, false, false);
@@ -188,77 +177,84 @@ public class HdmiCecPowerStatusControllerTest {
@Test
public void setPowerStatus_doesntSendBroadcast_1_4() {
+ setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
mHdmiCecPowerStatusController.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
mTestLooper.dispatchAll();
HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
- Constants.ADDR_PLAYBACK_1, Constants.ADDR_BROADCAST,
+ mHdmiCecLocalDevicePlayback.mAddress, Constants.ADDR_BROADCAST,
HdmiControlManager.POWER_STATUS_ON);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportPowerStatus);
}
@Test
public void setPowerStatus_transient_doesntSendBroadcast_1_4() {
+ setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
mHdmiCecPowerStatusController.setPowerStatus(
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
mTestLooper.dispatchAll();
HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
- Constants.ADDR_PLAYBACK_1, Constants.ADDR_BROADCAST,
+ mHdmiCecLocalDevicePlayback.mAddress, Constants.ADDR_BROADCAST,
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportPowerStatus);
}
@Test
public void setPowerStatus_fast_transient_doesntSendBroadcast_1_4() {
+ setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
mHdmiCecPowerStatusController.setPowerStatus(
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON, false);
mTestLooper.dispatchAll();
HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
- Constants.ADDR_PLAYBACK_1, Constants.ADDR_BROADCAST,
+ mHdmiCecLocalDevicePlayback.mAddress, Constants.ADDR_BROADCAST,
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportPowerStatus);
}
@Test
public void setPowerStatus_sendsBroadcast_2_0() {
- mHdmiCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
-
+ setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0);
mHdmiCecPowerStatusController.setPowerStatus(HdmiControlManager.POWER_STATUS_ON);
mTestLooper.dispatchAll();
HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
- Constants.ADDR_PLAYBACK_1, Constants.ADDR_BROADCAST,
+ mHdmiCecLocalDevicePlayback.mAddress, Constants.ADDR_BROADCAST,
HdmiControlManager.POWER_STATUS_ON);
assertThat(mNativeWrapper.getResultMessages()).contains(reportPowerStatus);
}
@Test
public void setPowerStatus_transient_sendsBroadcast_2_0() {
- mHdmiCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
-
+ setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0);
mHdmiCecPowerStatusController.setPowerStatus(
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
mTestLooper.dispatchAll();
HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
- Constants.ADDR_PLAYBACK_1, Constants.ADDR_BROADCAST,
+ mHdmiCecLocalDevicePlayback.mAddress, Constants.ADDR_BROADCAST,
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
assertThat(mNativeWrapper.getResultMessages()).contains(reportPowerStatus);
}
@Test
public void setPowerStatus_fast_transient_doesntSendBroadcast_2_0() {
- mHdmiCecVersion = HdmiControlManager.HDMI_CEC_VERSION_2_0;
-
+ setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0);
mHdmiCecPowerStatusController.setPowerStatus(
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON, false);
mTestLooper.dispatchAll();
HdmiCecMessage reportPowerStatus = HdmiCecMessageBuilder.buildReportPowerStatus(
- Constants.ADDR_PLAYBACK_1, Constants.ADDR_BROADCAST,
+ mHdmiCecLocalDevicePlayback.mAddress, Constants.ADDR_BROADCAST,
HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON);
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportPowerStatus);
}
+
+ private void setCecVersion(int version) {
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION, version);
+ mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
+ mTestLooper.dispatchAll();
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
index 32a70480c39e..47f3bf9daba7 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiControlServiceTest.java
@@ -19,6 +19,7 @@ import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM;
import static android.hardware.hdmi.HdmiDeviceInfo.DEVICE_PLAYBACK;
import static com.android.server.SystemService.PHASE_BOOT_COMPLETED;
+import static com.android.server.SystemService.PHASE_SYSTEM_SERVICES_READY;
import static com.android.server.hdmi.HdmiControlService.INITIATED_BY_ENABLE_CEC;
import static com.google.common.truth.Truth.assertThat;
@@ -44,12 +45,12 @@ import android.os.RemoteException;
import android.os.test.TestLooper;
import android.platform.test.annotations.Presubmit;
import android.provider.Settings;
+import android.util.Log;
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;
@@ -68,14 +69,64 @@ import java.util.Optional;
@RunWith(JUnit4.class)
public class HdmiControlServiceTest {
- private class HdmiCecLocalDeviceMyDevice extends HdmiCecLocalDeviceSource {
+ private class MockPlaybackDevice extends HdmiCecLocalDevicePlayback {
private boolean mCanGoToStandby;
private boolean mIsStandby;
private boolean mIsDisabled;
- protected HdmiCecLocalDeviceMyDevice(HdmiControlService service, int deviceType) {
- super(service, deviceType);
+ MockPlaybackDevice(HdmiControlService service) {
+ super(service);
+ }
+
+ @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 class MockAudioSystemDevice extends HdmiCecLocalDeviceAudioSystem {
+
+ private boolean mCanGoToStandby;
+ private boolean mIsStandby;
+ private boolean mIsDisabled;
+
+ MockAudioSystemDevice(HdmiControlService service) {
+ super(service);
}
@Override
@@ -123,8 +174,8 @@ public class HdmiControlServiceTest {
private Context mContextSpy;
private HdmiControlService mHdmiControlService;
private HdmiCecController mHdmiCecController;
- private HdmiCecLocalDeviceMyDevice mMyAudioSystemDevice;
- private HdmiCecLocalDeviceMyDevice mMyPlaybackDevice;
+ private MockAudioSystemDevice mAudioSystemDevice;
+ private MockPlaybackDevice mPlaybackDevice;
private FakeNativeWrapper mNativeWrapper;
private Looper mMyLooper;
private TestLooper mTestLooper = new TestLooper();
@@ -144,6 +195,7 @@ public class HdmiControlServiceTest {
PowerManager powerManager = new PowerManager(mContextSpy, mIPowerManagerMock,
mIThermalServiceMock, null);
when(mContextSpy.getSystemService(Context.POWER_SERVICE)).thenReturn(powerManager);
+ when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
@@ -157,21 +209,17 @@ public class HdmiControlServiceTest {
@Override
protected void writeStringSystemProperty(String key, String value) {
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
mMyLooper = mTestLooper.getLooper();
- mMyAudioSystemDevice =
- new HdmiCecLocalDeviceMyDevice(mHdmiControlService, DEVICE_AUDIO_SYSTEM);
- mMyPlaybackDevice = new HdmiCecLocalDeviceMyDevice(mHdmiControlService, DEVICE_PLAYBACK);
- mMyAudioSystemDevice.init();
- mMyPlaybackDevice.init();
+ mAudioSystemDevice = new MockAudioSystemDevice(mHdmiControlService);
+ mPlaybackDevice = new MockPlaybackDevice(mHdmiControlService);
+ mAudioSystemDevice.init();
+ mPlaybackDevice.init();
mHdmiControlService.setIoLooper(mMyLooper);
+ mHdmiControlService.setHdmiCecConfig(hdmiCecConfig);
+ mHdmiControlService.onBootPhase(PHASE_SYSTEM_SERVICES_READY);
mNativeWrapper = new FakeNativeWrapper();
mHdmiCecController = HdmiCecController.createWithNativeWrapper(
@@ -180,8 +228,8 @@ public class HdmiControlServiceTest {
mHdmiControlService.setHdmiMhlController(HdmiMhlControllerStub.create(mHdmiControlService));
mHdmiControlService.setMessageValidator(new HdmiCecMessageValidator(mHdmiControlService));
- mLocalDevices.add(mMyAudioSystemDevice);
- mLocalDevices.add(mMyPlaybackDevice);
+ mLocalDevices.add(mAudioSystemDevice);
+ mLocalDevices.add(mPlaybackDevice);
mHdmiPortInfo = new HdmiPortInfo[4];
mHdmiPortInfo[0] =
new HdmiPortInfo(1, HdmiPortInfo.PORT_INPUT, 0x2100, true, false, false);
@@ -192,6 +240,9 @@ public class HdmiControlServiceTest {
mHdmiPortInfo[3] =
new HdmiPortInfo(4, HdmiPortInfo.PORT_INPUT, 0x3000, true, false, false);
mNativeWrapper.setPortInfo(mHdmiPortInfo);
+ mHdmiControlService.getHdmiCecConfig().setIntValue(
+ HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_ENABLED,
+ HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
mHdmiControlService.initService();
mHdmiControlService.allocateLogicalAddress(mLocalDevices, INITIATED_BY_ENABLE_CEC);
@@ -201,13 +252,13 @@ public class HdmiControlServiceTest {
@Test
public void onStandby_notByCec_cannotGoToStandby() {
mStandbyMessageReceived = false;
- mMyPlaybackDevice.setCanGoToStandby(false);
+ mPlaybackDevice.setCanGoToStandby(false);
mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
- assertTrue(mMyPlaybackDevice.isStandby());
- assertTrue(mMyAudioSystemDevice.isStandby());
- assertFalse(mMyPlaybackDevice.isDisabled());
- assertFalse(mMyAudioSystemDevice.isDisabled());
+ assertTrue(mPlaybackDevice.isStandby());
+ assertTrue(mAudioSystemDevice.isStandby());
+ assertFalse(mPlaybackDevice.isDisabled());
+ assertFalse(mAudioSystemDevice.isDisabled());
}
@Test
@@ -215,10 +266,10 @@ public class HdmiControlServiceTest {
mStandbyMessageReceived = true;
mHdmiControlService.onStandby(HdmiControlService.STANDBY_SCREEN_OFF);
- assertTrue(mMyPlaybackDevice.isStandby());
- assertTrue(mMyAudioSystemDevice.isStandby());
- assertTrue(mMyPlaybackDevice.isDisabled());
- assertTrue(mMyAudioSystemDevice.isDisabled());
+ assertTrue(mPlaybackDevice.isStandby());
+ assertTrue(mAudioSystemDevice.isStandby());
+ assertTrue(mPlaybackDevice.isDisabled());
+ assertTrue(mAudioSystemDevice.isDisabled());
}
@Test
@@ -275,6 +326,7 @@ public class HdmiControlServiceTest {
mHdmiControlService.getHdmiCecConfig().setIntValue(
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.HDMI_CEC_VERSION_2_0);
+ mTestLooper.dispatchAll();
mHdmiControlService.setControlEnabled(HdmiControlManager.HDMI_CEC_CONTROL_ENABLED);
mNativeWrapper.clearResultMessages();
@@ -555,8 +607,8 @@ public class HdmiControlServiceTest {
HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
- mMyPlaybackDevice.getRcProfile(), mMyPlaybackDevice.getRcFeatures(),
- mMyPlaybackDevice.getDeviceFeatures());
+ mPlaybackDevice.getRcProfile(), mPlaybackDevice.getRcFeatures(),
+ mPlaybackDevice.getDeviceFeatures());
assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures);
}
@@ -573,8 +625,8 @@ public class HdmiControlServiceTest {
HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
- mMyPlaybackDevice.getRcProfile(), mMyPlaybackDevice.getRcFeatures(),
- mMyPlaybackDevice.getDeviceFeatures());
+ mPlaybackDevice.getRcProfile(), mPlaybackDevice.getRcFeatures(),
+ mPlaybackDevice.getDeviceFeatures());
assertThat(mNativeWrapper.getResultMessages()).doesNotContain(reportFeatures);
}
@@ -590,8 +642,8 @@ public class HdmiControlServiceTest {
HdmiCecMessage reportFeatures = HdmiCecMessageBuilder.buildReportFeatures(
Constants.ADDR_PLAYBACK_1, HdmiControlManager.HDMI_CEC_VERSION_2_0,
Arrays.asList(DEVICE_PLAYBACK, DEVICE_AUDIO_SYSTEM),
- mMyPlaybackDevice.getRcProfile(), mMyPlaybackDevice.getRcFeatures(),
- mMyPlaybackDevice.getDeviceFeatures());
+ mPlaybackDevice.getRcProfile(), mPlaybackDevice.getRcFeatures(),
+ mPlaybackDevice.getDeviceFeatures());
assertThat(mNativeWrapper.getResultMessages()).contains(reportFeatures);
}
@@ -612,41 +664,42 @@ public class HdmiControlServiceTest {
assertEquals(runnerUid, Binder.getCallingWorkSourceUid());
}
- @Ignore("b/180499471")
@Test
public void initCecVersion_limitToMinimumSupportedVersion() {
+ mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
+ Log.e("MARVIN", "set setting CEC");
mHdmiControlService.getHdmiCecConfig().setIntValue(
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.HDMI_CEC_VERSION_2_0);
- mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
- mHdmiControlService.initService();
+ mTestLooper.dispatchAll();
assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
}
- @Ignore("b/180499471")
@Test
public void initCecVersion_limitToAtLeast1_4() {
+ Log.e("MARVIN", "set HAL CEC to 0");
+ mNativeWrapper.setCecVersion(0x0);
+ Log.e("MARVIN", "set setting CEC to 2");
mHdmiControlService.getHdmiCecConfig().setIntValue(
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.HDMI_CEC_VERSION_2_0);
- mNativeWrapper.setCecVersion(0x0);
- mHdmiControlService.initService();
+ mTestLooper.dispatchAll();
assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
HdmiControlManager.HDMI_CEC_VERSION_1_4_B);
}
- @Ignore("b/180499471")
@Test
public void initCecVersion_useHighestMatchingVersion() {
+ mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0);
+ Log.e("MARVIN", "set setting CEC");
mHdmiControlService.getHdmiCecConfig().setIntValue(
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.HDMI_CEC_VERSION_2_0);
- mNativeWrapper.setCecVersion(HdmiControlManager.HDMI_CEC_VERSION_2_0);
- mHdmiControlService.initService();
+ mTestLooper.dispatchAll();
assertThat(mHdmiControlService.getCecVersion()).isEqualTo(
HdmiControlManager.HDMI_CEC_VERSION_2_0);
}
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
index b8dfd5672056..605f781b23df 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/PowerStatusMonitorActionTest.java
@@ -84,8 +84,6 @@ public class PowerStatusMonitorActionTest {
when(mContextSpy.getSystemService(PowerManager.class)).thenReturn(powerManager);
when(mIPowerManagerMock.isInteractive()).thenReturn(true);
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(mContextSpy);
-
mHdmiControlService = new HdmiControlService(mContextSpy) {
@Override
AudioManager getAudioManager() {
@@ -116,15 +114,11 @@ public class PowerStatusMonitorActionTest {
protected void writeStringSystemProperty(String key, String value) {
// do nothing
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
Looper looper = mTestLooper.getLooper();
mHdmiControlService.setIoLooper(looper);
+ mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(mContextSpy));
mNativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
this.mHdmiControlService, mNativeWrapper, mHdmiControlService.getAtomWriter());
@@ -185,6 +179,7 @@ public class PowerStatusMonitorActionTest {
mHdmiControlService.getHdmiCecConfig().setIntValue(
HdmiControlManager.CEC_SETTING_NAME_HDMI_CEC_VERSION,
HdmiControlManager.HDMI_CEC_VERSION_2_0);
+ mTestLooper.dispatchAll();
sendMessageFromPlaybackDevice(ADDR_PLAYBACK_1, 0x1000);
reportPowerStatus(ADDR_PLAYBACK_1, true, HdmiControlManager.POWER_STATUS_ON);
mTestLooper.dispatchAll();
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 f9160abcbfbf..e82c788020ed 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/SystemAudioInitiationActionFromAvrTest.java
@@ -65,8 +65,6 @@ public class SystemAudioInitiationActionFromAvrTest {
Context context = InstrumentationRegistry.getTargetContext();
- HdmiCecConfig hdmiCecConfig = new FakeHdmiCecConfig(context);
-
HdmiControlService hdmiControlService = new HdmiControlService(context) {
@Override
void sendCecCommand(
@@ -164,15 +162,11 @@ public class SystemAudioInitiationActionFromAvrTest {
int pathToPortId(int path) {
return -1;
}
-
- @Override
- protected HdmiCecConfig getHdmiCecConfig() {
- return hdmiCecConfig;
- }
};
Looper looper = mTestLooper.getLooper();
hdmiControlService.setIoLooper(looper);
+ hdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
HdmiCecController.NativeWrapper nativeWrapper = new FakeNativeWrapper();
HdmiCecController hdmiCecController = HdmiCecController.createWithNativeWrapper(
hdmiControlService, nativeWrapper, hdmiControlService.getAtomWriter());
diff --git a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
index 74bf4f5da70d..13c3919cefc5 100644
--- a/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/net/NetworkPolicyManagerServiceTest.java
@@ -2041,7 +2041,8 @@ public class NetworkPolicyManagerServiceTest {
final NetworkCapabilities networkCapabilities = new NetworkCapabilities();
networkCapabilities.addTransportType(TRANSPORT_WIFI);
networkCapabilities.setSSID(TEST_SSID);
- return new NetworkState(TYPE_WIFI, prop, networkCapabilities, null, null);
+ return new NetworkState(TYPE_WIFI, prop, networkCapabilities, new Network(TEST_NET_ID),
+ null);
}
private void expectHasInternetPermission(int uid, boolean hasIt) throws Exception {
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
index 8c62b7fe235e..3ca90603e9d2 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/InputDeviceDelegateTest.java
@@ -91,6 +91,7 @@ public class InputDeviceDelegateTest {
mInputDeviceDelegate = new InputDeviceDelegate(
mContextSpy, new Handler(mTestLooper.getLooper()));
+ mInputDeviceDelegate.onSystemReady();
}
@After
@@ -99,6 +100,24 @@ public class InputDeviceDelegateTest {
}
@Test
+ public void beforeSystemReady_ignoresAnyUpdate() throws Exception {
+ when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
+ InputDeviceDelegate inputDeviceDelegate = new InputDeviceDelegate(
+ mContextSpy, new Handler(mTestLooper.getLooper()));
+
+ inputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ true);
+ assertFalse(inputDeviceDelegate.isAvailable());
+
+ inputDeviceDelegate.onInputDeviceAdded(1);
+ assertFalse(inputDeviceDelegate.isAvailable());
+
+ updateInputDevices(new int[]{1});
+ assertFalse(inputDeviceDelegate.isAvailable());
+
+ verify(mIInputManagerMock, never()).getInputDevice(anyInt());
+ }
+
+ @Test
public void onInputDeviceAdded_withSettingsDisabled_ignoresNewDevice() throws Exception {
when(mIInputManagerMock.getInputDeviceIds()).thenReturn(new int[0]);
mInputDeviceDelegate.updateInputDeviceVibrators(/* vibrateInputDevices= */ false);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
index 1e6ef9137686..b6c11fe62ff6 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationScalerTest.java
@@ -88,6 +88,7 @@ public class VibrationScalerTest {
mVibrationSettings = new VibrationSettings(
mContextSpy, new Handler(mTestLooper.getLooper()));
mVibrationScaler = new VibrationScaler(mContextSpy, mVibrationSettings);
+ mVibrationSettings.onSystemReady();
}
@After
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
index d8679876965c..855012459bd6 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibrationSettingsTest.java
@@ -106,6 +106,7 @@ public class VibrationSettingsTest {
mAudioManager = mContextSpy.getSystemService(AudioManager.class);
mVibrationSettings = new VibrationSettings(mContextSpy,
new Handler(mTestLooper.getLooper()));
+ mVibrationSettings.onSystemReady();
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 0);
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
@@ -162,6 +163,23 @@ public class VibrationSettingsTest {
}
@Test
+ public void shouldVibrateForRingerMode_beforeSystemReady_returnsFalseOnlyForRingtone() {
+ setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
+ setRingerMode(AudioManager.RINGER_MODE_MAX);
+ VibrationSettings vibrationSettings = new VibrationSettings(mContextSpy,
+ new Handler(mTestLooper.getLooper()));
+
+ assertFalse(vibrationSettings.shouldVibrateForRingerMode(
+ VibrationAttributes.USAGE_RINGTONE));
+ assertTrue(mVibrationSettings.shouldVibrateForRingerMode(VibrationAttributes.USAGE_ALARM));
+ assertTrue(mVibrationSettings.shouldVibrateForRingerMode(VibrationAttributes.USAGE_TOUCH));
+ assertTrue(mVibrationSettings.shouldVibrateForRingerMode(
+ VibrationAttributes.USAGE_NOTIFICATION));
+ assertTrue(mVibrationSettings.shouldVibrateForRingerMode(
+ VibrationAttributes.USAGE_COMMUNICATION_REQUEST));
+ }
+
+ @Test
public void shouldVibrateForRingerMode_withoutRingtoneUsage_returnsTrue() {
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(VibrationAttributes.USAGE_ALARM));
assertTrue(mVibrationSettings.shouldVibrateForRingerMode(VibrationAttributes.USAGE_TOUCH));
@@ -303,6 +321,37 @@ public class VibrationSettingsTest {
}
@Test
+ public void getDefaultIntensity_beforeSystemReady_returnsMediumToAllExceptAlarm() {
+ mFakeVibrator.setDefaultHapticFeedbackIntensity(Vibrator.VIBRATION_INTENSITY_HIGH);
+ mFakeVibrator.setDefaultNotificationVibrationIntensity(Vibrator.VIBRATION_INTENSITY_HIGH);
+ mFakeVibrator.setDefaultRingVibrationIntensity(Vibrator.VIBRATION_INTENSITY_HIGH);
+
+ setUserSetting(Settings.System.NOTIFICATION_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_OFF);
+ setUserSetting(Settings.System.RING_VIBRATION_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_OFF);
+ setUserSetting(Settings.System.HAPTIC_FEEDBACK_INTENSITY,
+ Vibrator.VIBRATION_INTENSITY_OFF);
+
+ VibrationSettings vibrationSettings = new VibrationSettings(mContextSpy,
+ new Handler(mTestLooper.getLooper()));
+
+ assertEquals(Vibrator.VIBRATION_INTENSITY_HIGH,
+ vibrationSettings.getDefaultIntensity(VibrationAttributes.USAGE_ALARM));
+ assertEquals(Vibrator.VIBRATION_INTENSITY_MEDIUM,
+ vibrationSettings.getDefaultIntensity(VibrationAttributes.USAGE_TOUCH));
+ assertEquals(Vibrator.VIBRATION_INTENSITY_MEDIUM,
+ vibrationSettings.getDefaultIntensity(VibrationAttributes.USAGE_NOTIFICATION));
+ assertEquals(Vibrator.VIBRATION_INTENSITY_MEDIUM,
+ vibrationSettings.getDefaultIntensity(VibrationAttributes.USAGE_UNKNOWN));
+ assertEquals(Vibrator.VIBRATION_INTENSITY_MEDIUM,
+ vibrationSettings.getDefaultIntensity(
+ VibrationAttributes.USAGE_PHYSICAL_EMULATION));
+ assertEquals(Vibrator.VIBRATION_INTENSITY_MEDIUM,
+ vibrationSettings.getDefaultIntensity(VibrationAttributes.USAGE_RINGTONE));
+ }
+
+ @Test
public void getDefaultIntensity_returnsIntensityFromVibratorService() {
mFakeVibrator.setDefaultHapticFeedbackIntensity(Vibrator.VIBRATION_INTENSITY_HIGH);
mFakeVibrator.setDefaultNotificationVibrationIntensity(Vibrator.VIBRATION_INTENSITY_MEDIUM);
diff --git a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
index ba0a472c80dd..a28d18fb74d3 100644
--- a/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/vibrator/VibratorManagerServiceTest.java
@@ -176,8 +176,14 @@ public class VibratorManagerServiceTest {
LocalServices.removeServiceForTest(PowerManagerInternal.class);
}
+ private VibratorManagerService createSystemReadyService() {
+ VibratorManagerService service = createService();
+ service.systemReady();
+ return service;
+ }
+
private VibratorManagerService createService() {
- VibratorManagerService service = new VibratorManagerService(
+ return new VibratorManagerService(
mContextSpy,
new VibratorManagerService.Injector() {
@Override
@@ -201,8 +207,6 @@ public class VibratorManagerServiceTest {
void addService(String name, IBinder service) {
}
});
- service.systemReady();
- return service;
}
@Test
@@ -215,21 +219,44 @@ public class VibratorManagerServiceTest {
}
@Test
+ public void createService_doNotCrashIfUsedBeforeSystemReady() {
+ mockVibrators(1, 2);
+ mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+ mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_ALWAYS_ON_CONTROL);
+ VibratorManagerService service = createService();
+
+ assertNotNull(service.getVibratorIds());
+ assertNotNull(service.getVibratorInfo(1));
+ assertFalse(service.isVibrating(1));
+
+ CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
+ VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
+ vibrate(service, effect, HAPTIC_FEEDBACK_ATTRS);
+ service.cancelVibrate(service);
+
+ assertTrue(service.setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
+
+ IVibratorStateListener listener = mockVibratorStateListener();
+ assertTrue(service.registerVibratorStateListener(1, listener));
+ assertTrue(service.unregisterVibratorStateListener(1, listener));
+ }
+
+ @Test
public void getVibratorIds_withNullResultFromNative_returnsEmptyArray() {
when(mNativeWrapperMock.getVibratorIds()).thenReturn(null);
- assertArrayEquals(new int[0], createService().getVibratorIds());
+ assertArrayEquals(new int[0], createSystemReadyService().getVibratorIds());
}
@Test
public void getVibratorIds_withNonEmptyResultFromNative_returnsSameArray() {
mockVibrators(2, 1);
- assertArrayEquals(new int[]{2, 1}, createService().getVibratorIds());
+ assertArrayEquals(new int[]{2, 1}, createSystemReadyService().getVibratorIds());
}
@Test
public void getVibratorInfo_withMissingVibratorId_returnsNull() {
mockVibrators(1);
- assertNull(createService().getVibratorInfo(2));
+ assertNull(createSystemReadyService().getVibratorInfo(2));
}
@Test
@@ -239,7 +266,7 @@ public class VibratorManagerServiceTest {
vibrator.setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS, IVibrator.CAP_AMPLITUDE_CONTROL);
vibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
vibrator.setSupportedPrimitives(VibrationEffect.Composition.PRIMITIVE_CLICK);
- VibratorInfo info = createService().getVibratorInfo(1);
+ VibratorInfo info = createSystemReadyService().getVibratorInfo(1);
assertNotNull(info);
assertEquals(1, info.getId());
@@ -257,7 +284,7 @@ public class VibratorManagerServiceTest {
@Test
public void registerVibratorStateListener_callbacksAreTriggered() throws Exception {
mockVibrators(1);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
IVibratorStateListener listenerMock = mockVibratorStateListener();
service.registerVibratorStateListener(1, listenerMock);
@@ -278,7 +305,7 @@ public class VibratorManagerServiceTest {
@Test
public void unregisterVibratorStateListener_callbackNotTriggeredAfter() throws Exception {
mockVibrators(1);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
IVibratorStateListener listenerMock = mockVibratorStateListener();
service.registerVibratorStateListener(1, listenerMock);
@@ -303,7 +330,7 @@ public class VibratorManagerServiceTest {
@Test
public void registerVibratorStateListener_multipleVibratorsAreTriggered() throws Exception {
mockVibrators(0, 1, 2);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
IVibratorStateListener[] listeners = new IVibratorStateListener[3];
for (int i = 0; i < 3; i++) {
listeners[i] = mockVibratorStateListener();
@@ -330,7 +357,8 @@ public class VibratorManagerServiceTest {
CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
- assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
+ assertTrue(createSystemReadyService().setAlwaysOnEffect(
+ UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
VibrationEffect.Prebaked expectedEffect = new VibrationEffect.Prebaked(
VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
@@ -353,7 +381,8 @@ public class VibratorManagerServiceTest {
.addVibrator(2, VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK))
.addVibrator(3, VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK))
.combine();
- assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
+ assertTrue(createSystemReadyService().setAlwaysOnEffect(
+ UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
VibrationEffect.Prebaked expectedClick = new VibrationEffect.Prebaked(
VibrationEffect.EFFECT_CLICK, false, VibrationEffect.EFFECT_STRENGTH_STRONG);
@@ -376,9 +405,11 @@ public class VibratorManagerServiceTest {
CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
- assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
+ assertTrue(createSystemReadyService().setAlwaysOnEffect(
+ UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
- assertTrue(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, null, ALARM_ATTRS));
+ assertTrue(createSystemReadyService().setAlwaysOnEffect(
+ UID, PACKAGE_NAME, 1, null, ALARM_ATTRS));
assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1));
assertNull(mVibratorProviders.get(2).getAlwaysOnEffect(1));
@@ -392,7 +423,8 @@ public class VibratorManagerServiceTest {
CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
VibrationEffect.createOneShot(100, VibrationEffect.DEFAULT_AMPLITUDE));
- assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
+ assertFalse(createSystemReadyService().setAlwaysOnEffect(
+ UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1));
}
@@ -405,7 +437,8 @@ public class VibratorManagerServiceTest {
CombinedVibrationEffect effect = CombinedVibrationEffect.startSequential()
.addNext(0, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
.combine();
- assertFalse(createService().setAlwaysOnEffect(UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
+ assertFalse(createSystemReadyService().setAlwaysOnEffect(
+ UID, PACKAGE_NAME, 1, effect, ALARM_ATTRS));
assertNull(mVibratorProviders.get(1).getAlwaysOnEffect(1));
}
@@ -413,7 +446,7 @@ public class VibratorManagerServiceTest {
@Test
public void setAlwaysOnEffect_withNoVibratorWithCapability_ignoresEffect() {
mockVibrators(1);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
CombinedVibrationEffect mono = CombinedVibrationEffect.createSynced(
VibrationEffect.createPredefined(VibrationEffect.EFFECT_CLICK));
@@ -435,18 +468,18 @@ public class VibratorManagerServiceTest {
setRingerMode(AudioManager.RINGER_MODE_NORMAL);
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
setGlobalSetting(Settings.Global.APPLY_RAMPING_RINGER, 0);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
vibrate(service, VibrationEffect.createOneShot(40, 1), RINGTONE_ATTRS);
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 0);
setGlobalSetting(Settings.Global.APPLY_RAMPING_RINGER, 1);
- service = createService();
+ service = createSystemReadyService();
vibrate(service, VibrationEffect.createOneShot(40, 10), RINGTONE_ATTRS);
assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
setUserSetting(Settings.System.VIBRATE_WHEN_RINGING, 1);
setGlobalSetting(Settings.Global.APPLY_RAMPING_RINGER, 0);
- service = createService();
+ service = createSystemReadyService();
vibrate(service, VibrationEffect.createOneShot(40, 100), RINGTONE_ATTRS);
assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
@@ -459,7 +492,7 @@ public class VibratorManagerServiceTest {
mockVibrators(1);
FakeVibratorControllerProvider fakeVibrator = mVibratorProviders.get(1);
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
mRegisteredPowerModeListener.onLowPowerModeChanged(LOW_POWER_STATE);
vibrate(service, VibrationEffect.createOneShot(1, 1), HAPTIC_FEEDBACK_ATTRS);
vibrate(service, VibrationEffect.createOneShot(2, 2), RINGTONE_ATTRS);
@@ -480,7 +513,7 @@ public class VibratorManagerServiceTest {
@Test
public void vibrate_withAudioAttributes_usesOriginalAudioUsageInAppOpsManager() {
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
VibrationEffect effect = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
AudioAttributes audioAttributes = new AudioAttributes.Builder()
@@ -496,7 +529,7 @@ public class VibratorManagerServiceTest {
@Test
public void vibrate_withVibrationAttributes_usesCorrespondingAudioUsageInAppOpsManager() {
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_CLICK), ALARM_ATTRS);
vibrate(service, VibrationEffect.get(VibrationEffect.EFFECT_TICK), NOTIFICATION_ATTRS);
@@ -534,7 +567,7 @@ public class VibratorManagerServiceTest {
when(mIInputManagerMock.getVibratorIds(eq(1))).thenReturn(new int[]{1});
when(mIInputManagerMock.getInputDevice(eq(1))).thenReturn(createInputDeviceWithVibrator(1));
setUserSetting(Settings.System.VIBRATE_INPUT_DEVICES, 1);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
CombinedVibrationEffect effect = CombinedVibrationEffect.createSynced(
VibrationEffect.createOneShot(10, 10));
@@ -550,7 +583,7 @@ public class VibratorManagerServiceTest {
public void vibrate_withNativeCallbackTriggered_finishesVibration() throws Exception {
mockVibrators(1);
mVibratorProviders.get(1).setSupportedEffects(VibrationEffect.EFFECT_CLICK);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
// The native callback will be dispatched manually in this test.
mTestLooper.stopAutoDispatchAndIgnoreExceptions();
@@ -573,7 +606,7 @@ public class VibratorManagerServiceTest {
mockVibrators(1, 2);
mVibratorProviders.get(1).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
// The native callback will be dispatched manually in this test.
mTestLooper.stopAutoDispatchAndIgnoreExceptions();
@@ -619,7 +652,7 @@ public class VibratorManagerServiceTest {
FakeVibratorControllerProvider fakeVibrator1 = mVibratorProviders.get(1);
fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
mVibratorProviders.get(2).setCapabilities(IVibrator.CAP_COMPOSE_EFFECTS);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
@@ -645,7 +678,7 @@ public class VibratorManagerServiceTest {
mockVibrators(1, 2);
FakeVibratorControllerProvider fakeVibrator1 = mVibratorProviders.get(1);
fakeVibrator1.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
@@ -665,7 +698,7 @@ public class VibratorManagerServiceTest {
mockCapabilities(IVibratorManager.CAP_SYNC, IVibratorManager.CAP_PREPARE_ON);
mockVibrators(1, 2);
when(mNativeWrapperMock.prepareSynced(any())).thenReturn(false);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.createOneShot(10, 50))
@@ -686,7 +719,7 @@ public class VibratorManagerServiceTest {
mockVibrators(1, 2);
when(mNativeWrapperMock.prepareSynced(eq(new int[]{1, 2}))).thenReturn(true);
when(mNativeWrapperMock.triggerSynced(anyLong())).thenReturn(false);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
CombinedVibrationEffect effect = CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.createOneShot(10, 50))
@@ -716,7 +749,7 @@ public class VibratorManagerServiceTest {
fakeVibrator.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL,
IVibrator.CAP_COMPOSE_EFFECTS);
fakeVibrator.setSupportedEffects(VibrationEffect.EFFECT_CLICK);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
vibrate(service, CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.get(VibrationEffect.EFFECT_CLICK))
@@ -762,7 +795,7 @@ public class VibratorManagerServiceTest {
@Test
public void vibrate_withPowerModeChange_cancelVibrationIfNotAllowed() throws Exception {
mockVibrators(1, 2);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
vibrate(service,
CombinedVibrationEffect.startSynced()
.addVibrator(1, VibrationEffect.createOneShot(1000, 100))
@@ -780,7 +813,7 @@ public class VibratorManagerServiceTest {
@Test
public void vibrate_withSettingsChange_doNotCancelVibration() throws Exception {
mockVibrators(1);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
vibrate(service, VibrationEffect.createOneShot(1000, 100), HAPTIC_FEEDBACK_ATTRS);
assertTrue(waitUntil(s -> s.isVibrating(1), service, TEST_TIMEOUT_MILLIS));
@@ -793,7 +826,7 @@ public class VibratorManagerServiceTest {
@Test
public void cancelVibrate_stopsVibrating() throws Exception {
mockVibrators(1);
- VibratorManagerService service = createService();
+ VibratorManagerService service = createSystemReadyService();
service.cancelVibrate(service);
assertFalse(service.isVibrating(1));
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
index 47cf53b621d3..074ef3667857 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTests.java
@@ -323,4 +323,16 @@ public class DisplayPolicyTests extends WindowTestsBase {
assertFalse(navBarSource.getFrame().isEmpty());
assertTrue(imeSource.getFrame().contains(navBarSource.getFrame()));
}
+
+ @UseTestDisplay
+ @Test
+ public void testDisplayPolicyNotCrash() {
+ final DisplayPolicy displayPolicy = mDisplayContent.getDisplayPolicy();
+
+ // Verify if modules initialized after DisplayContent ctr throws NPE.
+ displayPolicy.onDisplayInfoChanged(mDisplayInfo);
+ displayPolicy.onConfigurationChanged();
+ displayPolicy.onOverlayChangedLw();
+ displayPolicy.release();
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
index be036034542e..80961d7afb70 100644
--- a/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/InsetsStateControllerTest.java
@@ -416,6 +416,16 @@ public class InsetsStateControllerTest extends WindowTestsBase {
verify(navBar, atLeastOnce()).notifyInsetsChanged();
}
+ @Test
+ public void testDispatchGlobalInsets() {
+ final WindowState navBar = createWindow(null, TYPE_APPLICATION, "navBar");
+ getController().getSourceProvider(ITYPE_NAVIGATION_BAR).setWindow(navBar, null, null);
+ final WindowState app = createWindow(null, TYPE_APPLICATION, "app");
+ assertNull(getController().getInsetsForWindow(app).peekSource(ITYPE_NAVIGATION_BAR));
+ app.mAttrs.receiveInsetsIgnoringZOrder = true;
+ assertNotNull(getController().getInsetsForWindow(app).peekSource(ITYPE_NAVIGATION_BAR));
+ }
+
private WindowState createTestWindow(String name) {
final WindowState win = createWindow(null, TYPE_APPLICATION, name);
win.setHasSurface(true);
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
index a1e5afb8b758..fb2272ed9fd3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskLaunchParamsModifierTests.java
@@ -521,6 +521,7 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
WINDOWING_MODE_FULLSCREEN);
}
+
@Test
public void testKeepsPictureInPictureLaunchModeInOptions() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
@@ -588,11 +589,14 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
}
@Test
- public void testNonEmptyLayoutInfersFreeformWithEmptySize() {
+ public void testLayoutWithGravityAndEmptySizeInfersFreeformAndRespectsCurrentSize() {
final TestDisplayContent freeformDisplay = createNewDisplayContent(
WINDOWING_MODE_FREEFORM);
+ final Rect expectedLaunchBounds = new Rect(0, 0, 200, 100);
+
mCurrent.mPreferredTaskDisplayArea = freeformDisplay.getDefaultTaskDisplayArea();
+ mCurrent.mBounds.set(expectedLaunchBounds);
final ActivityInfo.WindowLayout layout = new WindowLayoutBuilder()
.setGravity(Gravity.LEFT).build();
@@ -600,6 +604,9 @@ public class TaskLaunchParamsModifierTests extends WindowTestsBase {
assertEquals(RESULT_CONTINUE,
new CalculateRequestBuilder().setLayout(layout).calculate());
+ assertEquals(expectedLaunchBounds.width(), mResult.mBounds.width());
+ assertEquals(expectedLaunchBounds.height(), mResult.mBounds.height());
+
assertEquivalentWindowingMode(WINDOWING_MODE_FREEFORM, mResult.mWindowingMode,
WINDOWING_MODE_FREEFORM);
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index c13d6b19bf1d..ebc5c4ff280a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -538,9 +538,8 @@ class WindowTestsBase extends SystemServiceTestsBase {
/** Creates a {@link DisplayContent} and adds it to the system. */
private DisplayContent createNewDisplay(DisplayInfo info, @DisplayImePolicy int imePolicy) {
- final DisplayContent display =
+ final DisplayContent dc =
new TestDisplayContent.Builder(mAtm, info).build();
- final DisplayContent dc = display.mDisplayContent;
// this display can show IME.
dc.mWmService.mDisplayWindowSettings.setDisplayImePolicy(dc, imePolicy);
return dc;
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerService.java b/services/translation/java/com/android/server/translation/TranslationManagerService.java
index 6aadd23d211f..b6244b8fb93b 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerService.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerService.java
@@ -20,19 +20,28 @@ import static android.Manifest.permission.MANAGE_UI_TRANSLATION;
import static android.content.Context.TRANSLATION_MANAGER_SERVICE;
import static android.view.translation.TranslationManager.STATUS_SYNC_CALL_FAIL;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Binder;
import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.ShellCallback;
import android.util.Slog;
import android.view.autofill.AutofillId;
import android.view.translation.ITranslationManager;
import android.view.translation.TranslationSpec;
import android.view.translation.UiTranslationManager.UiTranslationState;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.os.IResultReceiver;
import com.android.server.infra.AbstractMasterSystemService;
import com.android.server.infra.FrameworkResourcesServiceNameResolver;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.util.List;
/**
@@ -48,6 +57,8 @@ public final class TranslationManagerService
private static final String TAG = "TranslationManagerService";
+ private static final int MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS = 2 * 60_000; // 2 minutes
+
public TranslationManagerService(Context context) {
// TODO: Discuss the disallow policy
super(context, new FrameworkResourcesServiceNameResolver(context,
@@ -60,19 +71,82 @@ public final class TranslationManagerService
return new TranslationManagerServiceImpl(this, mLock, resolvedUserId, disabled);
}
+ @Override
+ protected void enforceCallingPermissionForManagement() {
+ getContext().enforceCallingPermission(MANAGE_UI_TRANSLATION, TAG);
+ }
+
+ @Override
+ protected int getMaximumTemporaryServiceDurationMs() {
+ return MAX_TEMP_SERVICE_SUBSTITUTION_DURATION_MS;
+ }
+
+ @Override
+ protected void dumpLocked(String prefix, PrintWriter pw) {
+ super.dumpLocked(prefix, pw);
+ }
+
private void enforceCallerHasPermission(String permission) {
final String msg = "Permission Denial from pid =" + Binder.getCallingPid() + ", uid="
+ Binder.getCallingUid() + " doesn't hold " + permission;
getContext().enforceCallingPermission(permission, msg);
}
+ /** True if the currently set handler service is not overridden by the shell. */
+ @GuardedBy("mLock")
+ private boolean isDefaultServiceLocked(int userId) {
+ final String defaultServiceName = mServiceNameResolver.getDefaultServiceName(userId);
+ if (defaultServiceName == null) {
+ return false;
+ }
+
+ final String currentServiceName = mServiceNameResolver.getServiceName(userId);
+ return defaultServiceName.equals(currentServiceName);
+ }
+
+ /** True if the caller of the api is the same app which hosts the TranslationService. */
+ @GuardedBy("mLock")
+ private boolean isCalledByServiceAppLocked(int userId, @NonNull String methodName) {
+ final int callingUid = Binder.getCallingUid();
+
+ final String serviceName = mServiceNameResolver.getServiceName(userId);
+ if (serviceName == null) {
+ Slog.e(TAG, methodName + ": called by UID " + callingUid
+ + ", but there's no service set for user " + userId);
+ return false;
+ }
+
+ final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName);
+ if (serviceComponent == null) {
+ Slog.w(TAG, methodName + ": invalid service name: " + serviceName);
+ return false;
+ }
+
+ final String servicePackageName = serviceComponent.getPackageName();
+ final PackageManager pm = getContext().getPackageManager();
+ final int serviceUid;
+ try {
+ serviceUid = pm.getPackageUidAsUser(servicePackageName, userId);
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, methodName + ": could not verify UID for " + serviceName);
+ return false;
+ }
+ if (callingUid != serviceUid) {
+ Slog.e(TAG, methodName + ": called by UID " + callingUid + ", but service UID is "
+ + serviceUid);
+ return false;
+ }
+ return true;
+ }
+
final class TranslationManagerServiceStub extends ITranslationManager.Stub {
@Override
public void getSupportedLocales(IResultReceiver receiver, int userId)
throws RemoteException {
synchronized (mLock) {
final TranslationManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
+ if (service != null && (isDefaultServiceLocked(userId)
+ || isCalledByServiceAppLocked(userId, "getSupportedLocales"))) {
service.getSupportedLocalesLocked(receiver);
} else {
Slog.v(TAG, "getSupportedLocales(): no service for " + userId);
@@ -86,7 +160,8 @@ public final class TranslationManagerService
int sessionId, IResultReceiver receiver, int userId) throws RemoteException {
synchronized (mLock) {
final TranslationManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
+ if (service != null && (isDefaultServiceLocked(userId)
+ || isCalledByServiceAppLocked(userId, "onSessionCreated"))) {
service.onSessionCreatedLocked(sourceSpec, destSpec, sessionId, receiver);
} else {
Slog.v(TAG, "onSessionCreated(): no service for " + userId);
@@ -102,12 +177,35 @@ public final class TranslationManagerService
enforceCallerHasPermission(MANAGE_UI_TRANSLATION);
synchronized (mLock) {
final TranslationManagerServiceImpl service = getServiceForUserLocked(userId);
- if (service != null) {
+ if (service != null && (isDefaultServiceLocked(userId)
+ || isCalledByServiceAppLocked(userId, "updateUiTranslationState"))) {
service.updateUiTranslationState(state, sourceSpec, destSpec, viewIds,
taskId);
}
}
}
+
+ /**
+ * Dump the service state into the given stream. You run "adb shell dumpsys translation".
+ */
+ @Override
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ synchronized (mLock) {
+ dumpLocked("", pw);
+ }
+ }
+
+ @Override
+ public void onShellCommand(@Nullable FileDescriptor in,
+ @Nullable FileDescriptor out,
+ @Nullable FileDescriptor err,
+ @NonNull String[] args,
+ @Nullable ShellCallback callback,
+ @NonNull ResultReceiver resultReceiver) throws RemoteException {
+ new TranslationManagerServiceShellCommand(
+ TranslationManagerService.this).exec(this, in, out, err, args, callback,
+ resultReceiver);
+ }
}
@Override // from SystemService
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceShellCommand.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceShellCommand.java
new file mode 100644
index 000000000000..ba1b3908a91e
--- /dev/null
+++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceShellCommand.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2021 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.translation;
+
+import android.os.ShellCommand;
+
+import java.io.PrintWriter;
+
+/** Handles adb shell commands send to TranslationManagerService. */
+public class TranslationManagerServiceShellCommand extends ShellCommand {
+ private final TranslationManagerService mService;
+
+ TranslationManagerServiceShellCommand(TranslationManagerService service) {
+ mService = service;
+ }
+
+ @Override
+ public int onCommand(String cmd) {
+ if (cmd == null) {
+ return handleDefaultCommands(cmd);
+ }
+ final PrintWriter pw = getOutPrintWriter();
+ if ("set".equals(cmd)) {
+ return requestSet(pw);
+ }
+ return handleDefaultCommands(cmd);
+ }
+
+ private int requestSet(PrintWriter pw) {
+ final String what = getNextArgRequired();
+ if ("temporary-service".equals(what)) {
+ return setTemporaryService(pw);
+ }
+ pw.println("Invalid set: " + what);
+ return -1;
+ }
+
+ private int setTemporaryService(PrintWriter pw) {
+ final int userId = Integer.parseInt(getNextArgRequired());
+ final String serviceName = getNextArg();
+ if (serviceName == null) {
+ mService.resetTemporaryService(userId);
+ return 0;
+ }
+ final int duration = Integer.parseInt(getNextArgRequired());
+ mService.setTemporaryService(userId, serviceName, duration);
+ pw.println("TranslationService temporarily set to " + serviceName + " for "
+ + duration + "ms");
+ return 0;
+ }
+
+ @Override
+ public void onHelp() {
+ try (PrintWriter pw = getOutPrintWriter();) {
+ pw.println("Translation Service (translation) commands:");
+ pw.println(" help");
+ pw.println(" Prints this help text.");
+ pw.println("");
+ pw.println(" set temporary-service USER_ID [COMPONENT_NAME DURATION]");
+ pw.println(" Temporarily (for DURATION ms) changes the service implementation.");
+ pw.println(" To reset, call with just the USER_ID argument.");
+ pw.println("");
+ }
+ }
+}
diff --git a/telephony/java/android/telephony/NetworkRegistrationInfo.java b/telephony/java/android/telephony/NetworkRegistrationInfo.java
index 706e3cb93a0f..a78f81331c8c 100644
--- a/telephony/java/android/telephony/NetworkRegistrationInfo.java
+++ b/telephony/java/android/telephony/NetworkRegistrationInfo.java
@@ -371,6 +371,7 @@ public final class NetworkRegistrationInfo implements Parcelable {
* Get the 5G NR connection state.
*
* @return the 5G NR connection state.
+ * @hide
*/
public @NRState int getNrState() {
return mNrState;
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index 386dafc590af..b61310aa4bd8 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -102,7 +102,7 @@ class OpenAppWarmTest(private val testSpec: FlickerTestParameter) {
@Test
fun statusBarWindowIsAlwaysVisible() = testSpec.statusBarWindowIsAlwaysVisible()
- @Presubmit
+ @FlakyTest
@Test
fun visibleWindowsShownMoreThanOneConsecutiveEntry() =
testSpec.visibleWindowsShownMoreThanOneConsecutiveEntry()
diff --git a/tests/UpdatableSystemFontTest/Android.bp b/tests/UpdatableSystemFontTest/Android.bp
index ee24d48f0ed5..d4f1ad317d31 100644
--- a/tests/UpdatableSystemFontTest/Android.bp
+++ b/tests/UpdatableSystemFontTest/Android.bp
@@ -26,13 +26,9 @@ java_test_host {
srcs: ["src/**/*.java"],
libs: ["tradefed", "compatibility-tradefed", "compatibility-host-util"],
static_libs: [
- "block_device_writer_jar",
"frameworks-base-hostutils",
],
test_suites: ["general-tests", "vts"],
- target_required: [
- "block_device_writer_module",
- ],
data: [
":NotoColorEmojiTtf",
":UpdatableSystemFontTestCertDer",
diff --git a/tests/UpdatableSystemFontTest/AndroidTest.xml b/tests/UpdatableSystemFontTest/AndroidTest.xml
index 7b919bd4b114..efe5d703880c 100644
--- a/tests/UpdatableSystemFontTest/AndroidTest.xml
+++ b/tests/UpdatableSystemFontTest/AndroidTest.xml
@@ -21,7 +21,6 @@
<target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
<option name="cleanup" value="true" />
- <option name="push" value="block_device_writer->/data/local/tmp/block_device_writer" />
<option name="push" value="UpdatableSystemFontTestCert.der->/data/local/tmp/UpdatableSystemFontTestCert.der" />
<option name="push" value="NotoColorEmoji.ttf->/data/local/tmp/NotoColorEmoji.ttf" />
<option name="push" value="UpdatableSystemFontTestNotoColorEmoji.ttf.fsv_sig->/data/local/tmp/UpdatableSystemFontTestNotoColorEmoji.ttf.fsv_sig" />
diff --git a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
index e249f8a99b0c..92fa498f8326 100644
--- a/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
+++ b/tests/UpdatableSystemFontTest/src/com/android/updatablesystemfont/UpdatableSystemFontTest.java
@@ -21,7 +21,6 @@ import static com.google.common.truth.Truth.assertWithMessage;
import android.platform.test.annotations.RootPermissionTest;
-import com.android.blockdevicewriter.BlockDeviceWriter;
import com.android.fsverity.AddFsVerityCertRule;
import com.android.tradefed.device.DeviceNotAvailableException;
import com.android.tradefed.log.LogUtil.CLog;
@@ -144,30 +143,6 @@ public class UpdatableSystemFontTest extends BaseHostJUnit4Test {
assertThat(fontPathAfterReboot).isEqualTo(fontPath);
}
- @Test
- public void reboot_clearDamagedFiles() throws Exception {
- expectRemoteCommandToSucceed(String.format("cmd font update %s %s",
- TEST_NOTO_COLOR_EMOJI_V1_TTF, TEST_NOTO_COLOR_EMOJI_V1_TTF_FSV_SIG));
- String fontPath = getFontPath(NOTO_COLOR_EMOJI_TTF);
- assertThat(fontPath).startsWith("/data/fonts/files/");
- assertThat(BlockDeviceWriter.canReadByte(getDevice(), fontPath, 0)).isTrue();
-
- BlockDeviceWriter.damageFileAgainstBlockDevice(getDevice(), fontPath, 0);
- expectRemoteCommandToSucceed("stop");
- // We have to make sure system_server is gone before dropping caches, because system_server
- // process holds font memory maps and prevents cache eviction.
- waitUntilSystemServerIsGone();
- BlockDeviceWriter.assertFileNotOpen(getDevice(), fontPath);
- BlockDeviceWriter.dropCaches(getDevice());
- assertThat(BlockDeviceWriter.canReadByte(getDevice(), fontPath, 0)).isFalse();
-
- expectRemoteCommandToSucceed("start");
- waitUntilFontCommandIsReady();
- String fontPathAfterReboot = getFontPath(NOTO_COLOR_EMOJI_TTF);
- assertWithMessage("Damaged file should be deleted")
- .that(fontPathAfterReboot).startsWith("/system");
- }
-
private String getFontPath(String fontFileName) throws Exception {
// TODO: add a dedicated command for testing.
String lines = expectRemoteCommandToSucceed("cmd font dump");
diff --git a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
index 56b56efd501b..0ca4d9551f39 100644
--- a/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
+++ b/tests/net/common/java/android/net/NetworkStateSnapshotTest.kt
@@ -63,10 +63,10 @@ class NetworkStateSnapshotTest {
@Test
fun testParcelUnparcel() {
- val emptySnapshot = NetworkStateSnapshot(LinkProperties(), NetworkCapabilities(),
- Network(TEST_NETID), null, TYPE_NONE)
+ val emptySnapshot = NetworkStateSnapshot(Network(TEST_NETID), NetworkCapabilities(),
+ LinkProperties(), null, TYPE_NONE)
val snapshot = NetworkStateSnapshot(
- TEST_LINK_PROPERTIES, TEST_CAPABILITIES, Network(TEST_NETID), TEST_IMSI, TYPE_WIFI)
+ Network(TEST_NETID), TEST_CAPABILITIES, TEST_LINK_PROPERTIES, TEST_IMSI, TYPE_WIFI)
assertParcelSane(emptySnapshot, 5)
assertParcelSane(snapshot, 5)
}
diff --git a/tests/net/common/java/android/net/UidRangeTest.java b/tests/net/common/java/android/net/UidRangeTest.java
new file mode 100644
index 000000000000..1b1c95431d6f
--- /dev/null
+++ b/tests/net/common/java/android/net/UidRangeTest.java
@@ -0,0 +1,113 @@
+/*
+ * 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.
+ */
+
+package android.net;
+
+import static android.os.UserHandle.MIN_SECONDARY_USER_ID;
+import static android.os.UserHandle.SYSTEM;
+import static android.os.UserHandle.USER_SYSTEM;
+import static android.os.UserHandle.getUid;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import android.os.Build;
+import android.os.UserHandle;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.testutils.DevSdkIgnoreRule;
+import com.android.testutils.DevSdkIgnoreRule.IgnoreUpTo;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+@SmallTest
+public class UidRangeTest {
+
+ /*
+ * UidRange is no longer passed to netd. UID ranges between the framework and netd are passed as
+ * UidRangeParcel objects.
+ */
+
+ @Rule
+ public final DevSdkIgnoreRule mIgnoreRule = new DevSdkIgnoreRule();
+
+ @Test
+ public void testSingleItemUidRangeAllowed() {
+ new UidRange(123, 123);
+ new UidRange(0, 0);
+ new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
+ }
+
+ @Test
+ public void testNegativeUidsDisallowed() {
+ try {
+ new UidRange(-2, 100);
+ fail("Exception not thrown for negative start UID");
+ } catch (IllegalArgumentException expected) {
+ }
+
+ try {
+ new UidRange(-200, -100);
+ fail("Exception not thrown for negative stop UID");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testStopLessThanStartDisallowed() {
+ final int x = 4195000;
+ try {
+ new UidRange(x, x - 1);
+ fail("Exception not thrown for negative-length UID range");
+ } catch (IllegalArgumentException expected) {
+ }
+ }
+
+ @Test
+ public void testGetStartAndEndUser() throws Exception {
+ final UidRange uidRangeOfPrimaryUser = new UidRange(
+ getUid(USER_SYSTEM, 10000), getUid(USER_SYSTEM, 10100));
+ final UidRange uidRangeOfSecondaryUser = new UidRange(
+ getUid(MIN_SECONDARY_USER_ID, 10000), getUid(MIN_SECONDARY_USER_ID, 10100));
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser());
+ assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getStartUser());
+ assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser());
+
+ final UidRange uidRangeForDifferentUsers = new UidRange(
+ getUid(USER_SYSTEM, 10000), getUid(MIN_SECONDARY_USER_ID, 10100));
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+ assertEquals(MIN_SECONDARY_USER_ID, uidRangeOfSecondaryUser.getEndUser());
+ }
+
+ @Test @IgnoreUpTo(Build.VERSION_CODES.R)
+ public void testCreateForUser() throws Exception {
+ final UidRange uidRangeOfPrimaryUser = UidRange.createForUser(SYSTEM);
+ final UidRange uidRangeOfSecondaryUser = UidRange.createForUser(
+ UserHandle.of(USER_SYSTEM + 1));
+ assertTrue(uidRangeOfPrimaryUser.stop < uidRangeOfSecondaryUser.start);
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getStartUser());
+ assertEquals(USER_SYSTEM, uidRangeOfPrimaryUser.getEndUser());
+ assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getStartUser());
+ assertEquals(USER_SYSTEM + 1, uidRangeOfSecondaryUser.getEndUser());
+ }
+}
diff --git a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
index 9ed55f098a16..c10c573aa024 100644
--- a/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
+++ b/tests/net/integration/src/com/android/server/net/integrationtests/ConnectivityServiceIntegrationTest.kt
@@ -177,7 +177,7 @@ class ConnectivityServiceIntegrationTest {
}
private inner class TestConnectivityService(deps: Dependencies) : ConnectivityService(
- context, netManager, statsService, dnsResolver, log, netd, deps)
+ context, statsService, dnsResolver, log, netd, deps)
private fun makeDependencies(): ConnectivityService.Dependencies {
val deps = spy(ConnectivityService.Dependencies())
diff --git a/tests/net/java/android/net/IpSecAlgorithmTest.java b/tests/net/java/android/net/IpSecAlgorithmTest.java
index 2e1c29a2e405..3a8d6004f66f 100644
--- a/tests/net/java/android/net/IpSecAlgorithmTest.java
+++ b/tests/net/java/android/net/IpSecAlgorithmTest.java
@@ -129,6 +129,7 @@ public class IpSecAlgorithmTest {
checkCryptKeyLenValidation(IpSecAlgorithm.CRYPT_AES_CTR, len);
}
checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_XCBC, 128, 96);
+ checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_AES_CMAC, 128, 96);
checkAuthKeyAndTruncLenValidation(IpSecAlgorithm.AUTH_CRYPT_CHACHA20_POLY1305, 288, 128);
}
diff --git a/tests/net/java/android/net/NetworkTemplateTest.kt b/tests/net/java/android/net/NetworkTemplateTest.kt
index 27224c216db3..64b774cc4340 100644
--- a/tests/net/java/android/net/NetworkTemplateTest.kt
+++ b/tests/net/java/android/net/NetworkTemplateTest.kt
@@ -20,14 +20,13 @@ import android.content.Context
import android.net.ConnectivityManager.TYPE_MOBILE
import android.net.ConnectivityManager.TYPE_WIFI
import android.net.NetworkIdentity.SUBTYPE_COMBINED
-import android.net.NetworkIdentity.OEM_NONE;
-import android.net.NetworkIdentity.OEM_PAID;
-import android.net.NetworkIdentity.OEM_PRIVATE;
+import android.net.NetworkIdentity.OEM_NONE
+import android.net.NetworkIdentity.OEM_PAID
+import android.net.NetworkIdentity.OEM_PRIVATE
import android.net.NetworkIdentity.buildNetworkIdentity
import android.net.NetworkStats.DEFAULT_NETWORK_ALL
import android.net.NetworkStats.METERED_ALL
import android.net.NetworkStats.ROAMING_ALL
-import android.net.NetworkTemplate.MATCH_ETHERNET
import android.net.NetworkTemplate.MATCH_MOBILE
import android.net.NetworkTemplate.MATCH_MOBILE_WILDCARD
import android.net.NetworkTemplate.MATCH_WIFI
@@ -50,7 +49,6 @@ import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
-import kotlin.test.fail
private const val TEST_IMSI1 = "imsi1"
private const val TEST_IMSI2 = "imsi2"
@@ -60,17 +58,17 @@ private const val TEST_SSID1 = "ssid1"
class NetworkTemplateTest {
private val mockContext = mock(Context::class.java)
- private fun buildMobileNetworkState(subscriberId: String): NetworkState =
+ private fun buildMobileNetworkState(subscriberId: String): NetworkStateSnapshot =
buildNetworkState(TYPE_MOBILE, subscriberId = subscriberId)
- private fun buildWifiNetworkState(ssid: String): NetworkState =
+ private fun buildWifiNetworkState(ssid: String): NetworkStateSnapshot =
buildNetworkState(TYPE_WIFI, ssid = ssid)
private fun buildNetworkState(
type: Int,
subscriberId: String? = null,
ssid: String? = null,
- oemManaged: Int = OEM_NONE,
- ): NetworkState {
+ oemManaged: Int = OEM_NONE
+ ): NetworkStateSnapshot {
val lp = LinkProperties()
val caps = NetworkCapabilities().apply {
setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false)
@@ -81,7 +79,7 @@ class NetworkTemplateTest {
setCapability(NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
(oemManaged and OEM_PRIVATE) == OEM_PRIVATE)
}
- return NetworkState(type, lp, caps, mock(Network::class.java), subscriberId)
+ return NetworkStateSnapshot(mock(Network::class.java), caps, lp, subscriberId, type)
}
private fun NetworkTemplate.assertMatches(ident: NetworkIdentity) =
@@ -179,7 +177,7 @@ class NetworkTemplateTest {
OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
// Verify that "not OEM managed network" constants are equal.
- assertEquals(OEM_MANAGED_NO, OEM_NONE);
+ assertEquals(OEM_MANAGED_NO, OEM_NONE)
// Verify the constants don't conflict.
assertEquals(constantValues.size, constantValues.distinct().count())
@@ -201,8 +199,13 @@ class NetworkTemplateTest {
* @param identSsid If networkType is {@code TYPE_WIFI}, this value must *NOT* be null. Provide
* one of {@code TEST_SSID*}.
*/
- private fun matchOemManagedIdent(networkType: Int, matchType:Int, subscriberId: String? = null,
- templateSsid: String? = null, identSsid: String? = null) {
+ private fun matchOemManagedIdent(
+ networkType: Int,
+ matchType: Int,
+ subscriberId: String? = null,
+ templateSsid: String? = null,
+ identSsid: String? = null
+ ) {
val oemManagedStates = arrayOf(OEM_NONE, OEM_PAID, OEM_PRIVATE, OEM_PAID or OEM_PRIVATE)
// A null subscriberId needs a null matchSubscriberIds argument as well.
val matchSubscriberIds = if (subscriberId == null) null else arrayOf(subscriberId)
diff --git a/tests/net/java/android/net/UidRangeTest.java b/tests/net/java/android/net/UidRangeTest.java
deleted file mode 100644
index ea1df096e208..000000000000
--- a/tests/net/java/android/net/UidRangeTest.java
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.net;
-
-import static org.junit.Assert.fail;
-
-import androidx.test.filters.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-@SmallTest
-public class UidRangeTest {
-
- /*
- * UidRange is no longer passed to netd. UID ranges between the framework and netd are passed as
- * UidRangeParcel objects.
- */
-
- @Test
- public void testSingleItemUidRangeAllowed() {
- new UidRange(123, 123);
- new UidRange(0, 0);
- new UidRange(Integer.MAX_VALUE, Integer.MAX_VALUE);
- }
-
- @Test
- public void testNegativeUidsDisallowed() {
- try {
- new UidRange(-2, 100);
- fail("Exception not thrown for negative start UID");
- } catch (IllegalArgumentException expected) {
- }
-
- try {
- new UidRange(-200, -100);
- fail("Exception not thrown for negative stop UID");
- } catch (IllegalArgumentException expected) {
- }
- }
-
- @Test
- public void testStopLessThanStartDisallowed() {
- final int x = 4195000;
- try {
- new UidRange(x, x - 1);
- fail("Exception not thrown for negative-length UID range");
- } catch (IllegalArgumentException expected) {
- }
- }
-} \ No newline at end of file
diff --git a/tests/net/java/com/android/server/ConnectivityServiceTest.java b/tests/net/java/com/android/server/ConnectivityServiceTest.java
index 1cfc3f9f9e5c..60670ade1a96 100644
--- a/tests/net/java/com/android/server/ConnectivityServiceTest.java
+++ b/tests/net/java/com/android/server/ConnectivityServiceTest.java
@@ -199,7 +199,7 @@ import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.NetworkStack;
import android.net.NetworkStackClient;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
import android.net.NetworkTestResultParcelable;
import android.net.OemNetworkPreferences;
import android.net.ProxyInfo;
@@ -1462,7 +1462,6 @@ public class ConnectivityServiceTest {
mDeps = makeDependencies();
returnRealCallingUid();
mService = new ConnectivityService(mServiceContext,
- mNetworkManagementService,
mStatsService,
mMockDnsResolver,
mock(IpConnectivityLog.class),
@@ -5485,7 +5484,7 @@ public class ConnectivityServiceTest {
UnderlyingNetworkInfo[].class);
verify(mStatsService, atLeastOnce()).forceUpdateIfaces(networksCaptor.capture(),
- any(NetworkState[].class), eq(defaultIface), vpnInfosCaptor.capture());
+ any(NetworkStateSnapshot[].class), eq(defaultIface), vpnInfosCaptor.capture());
assertSameElementsNoDuplicates(networksCaptor.getValue(), networks);
@@ -5555,9 +5554,8 @@ public class ConnectivityServiceTest {
// Temp metered change shouldn't update ifaces
mCellNetworkAgent.addCapability(NetworkCapabilities.NET_CAPABILITY_TEMPORARILY_NOT_METERED);
waitForIdle();
- verify(mStatsService, never())
- .forceUpdateIfaces(eq(onlyCell), any(NetworkState[].class), eq(MOBILE_IFNAME),
- eq(new UnderlyingNetworkInfo[0]));
+ verify(mStatsService, never()).forceUpdateIfaces(eq(onlyCell), any(
+ NetworkStateSnapshot[].class), eq(MOBILE_IFNAME), eq(new UnderlyingNetworkInfo[0]));
reset(mStatsService);
// Roaming change should update ifaces
@@ -5639,7 +5637,7 @@ public class ConnectivityServiceTest {
// Confirm that we never tell NetworkStatsService that cell is no longer the underlying
// network for the VPN...
verify(mStatsService, never()).forceUpdateIfaces(any(Network[].class),
- any(NetworkState[].class), any() /* anyString() doesn't match null */,
+ any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */,
argThat(infos -> infos[0].underlyingIfaces.size() == 1
&& WIFI_IFNAME.equals(infos[0].underlyingIfaces.get(0))));
verifyNoMoreInteractions(mStatsService);
@@ -5653,7 +5651,7 @@ public class ConnectivityServiceTest {
mEthernetNetworkAgent.connect(false);
waitForIdle();
verify(mStatsService).forceUpdateIfaces(any(Network[].class),
- any(NetworkState[].class), any() /* anyString() doesn't match null */,
+ any(NetworkStateSnapshot[].class), any() /* anyString() doesn't match null */,
argThat(vpnInfos -> vpnInfos[0].underlyingIfaces.size() == 1
&& WIFI_IFNAME.equals(vpnInfos[0].underlyingIfaces.get(0))));
mEthernetNetworkAgent.disconnect();
@@ -7856,7 +7854,6 @@ public class ConnectivityServiceTest {
cellLp.addRoute(defaultRoute);
cellLp.addRoute(ipv6Subnet);
mCellNetworkAgent = new TestNetworkAgentWrapper(TRANSPORT_CELLULAR, cellLp);
- reset(mNetworkManagementService);
reset(mMockDnsResolver);
reset(mMockNetd);
reset(mBatteryStatsService);
@@ -7896,7 +7893,6 @@ public class ConnectivityServiceTest {
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
- reset(mNetworkManagementService);
reset(mMockNetd);
reset(mMockDnsResolver);
when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
@@ -7996,7 +7992,6 @@ public class ConnectivityServiceTest {
verify(mMockNetd, times(1)).networkRemoveInterface(cellNetId, CLAT_PREFIX + MOBILE_IFNAME);
verifyNoMoreInteractions(mMockNetd);
verifyNoMoreInteractions(mMockDnsResolver);
- reset(mNetworkManagementService);
reset(mMockNetd);
reset(mMockDnsResolver);
when(mMockNetd.interfaceGetCfg(CLAT_PREFIX + MOBILE_IFNAME))
@@ -8233,7 +8228,6 @@ public class ConnectivityServiceTest {
final LinkProperties cellLp = new LinkProperties();
cellLp.setInterfaceName(MOBILE_IFNAME);
mCellNetworkAgent.sendLinkProperties(cellLp);
- reset(mNetworkManagementService);
mCellNetworkAgent.connect(true);
networkCallback.expectAvailableThenValidatedCallbacks(mCellNetworkAgent);
verify(mMockNetd, times(1)).idletimerAddInterface(eq(MOBILE_IFNAME), anyInt(),
@@ -8927,8 +8921,8 @@ public class ConnectivityServiceTest {
ConnectivityManager.getNetworkTypeName(TYPE_MOBILE),
TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_LTE));
return new NetworkAgentInfo(null, new Network(NET_ID), info, new LinkProperties(),
- nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, null,
- 0, INVALID_UID, mQosCallbackTracker);
+ nc, 0, mServiceContext, null, new NetworkAgentConfig(), mService, null, null, 0,
+ INVALID_UID, mQosCallbackTracker);
}
@Test
diff --git a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
index 52cb836e19c8..a913673c2a1e 100644
--- a/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
+++ b/tests/net/java/com/android/server/connectivity/LingerMonitorTest.java
@@ -41,7 +41,6 @@ import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkProvider;
import android.os.Binder;
-import android.os.INetworkManagementService;
import android.text.format.DateUtils;
import androidx.test.filters.SmallTest;
@@ -74,7 +73,6 @@ public class LingerMonitorTest {
@Mock ConnectivityService mConnService;
@Mock IDnsResolver mDnsResolver;
@Mock INetd mNetd;
- @Mock INetworkManagementService mNMS;
@Mock Context mCtx;
@Mock NetworkNotificationManager mNotifier;
@Mock Resources mResources;
@@ -358,8 +356,8 @@ public class LingerMonitorTest {
caps.addTransportType(transport);
NetworkAgentInfo nai = new NetworkAgentInfo(null, new Network(netId), info,
new LinkProperties(), caps, 50, mCtx, null, new NetworkAgentConfig() /* config */,
- mConnService, mNetd, mDnsResolver, mNMS, NetworkProvider.ID_NONE,
- Binder.getCallingUid(), mQosCallbackTracker);
+ mConnService, mNetd, mDnsResolver, NetworkProvider.ID_NONE, Binder.getCallingUid(),
+ mQosCallbackTracker);
nai.everValidated = true;
return nai;
}
diff --git a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
index 4f65b67fa3da..5f56e25356c2 100644
--- a/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
+++ b/tests/net/java/com/android/server/connectivity/Nat464XlatTest.java
@@ -36,7 +36,6 @@ import android.net.LinkProperties;
import android.net.NetworkAgentConfig;
import android.net.NetworkInfo;
import android.os.Handler;
-import android.os.INetworkManagementService;
import android.os.test.TestLooper;
import androidx.test.filters.SmallTest;
@@ -67,7 +66,6 @@ public class Nat464XlatTest {
@Mock ConnectivityService mConnectivity;
@Mock IDnsResolver mDnsResolver;
@Mock INetd mNetd;
- @Mock INetworkManagementService mNms;
@Mock NetworkAgentInfo mNai;
TestLooper mLooper;
@@ -75,7 +73,7 @@ public class Nat464XlatTest {
NetworkAgentConfig mAgentConfig = new NetworkAgentConfig();
Nat464Xlat makeNat464Xlat() {
- return new Nat464Xlat(mNai, mNetd, mDnsResolver, mNms) {
+ return new Nat464Xlat(mNai, mNetd, mDnsResolver) {
@Override protected int getNetId() {
return NETID;
}
@@ -206,7 +204,6 @@ public class Nat464XlatTest {
// Start clat.
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// Stacked interface up notification arrives.
@@ -225,7 +222,6 @@ public class Nat464XlatTest {
verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
- verify(mNms).unregisterObserver(eq(nat));
assertTrue(c.getValue().getStackedLinks().isEmpty());
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
@@ -235,7 +231,7 @@ public class Nat464XlatTest {
nat.interfaceRemoved(STACKED_IFACE);
mLooper.dispatchNext();
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
@Test
@@ -346,7 +342,6 @@ public class Nat464XlatTest {
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// Stacked interface up notification arrives.
@@ -365,7 +360,6 @@ public class Nat464XlatTest {
verify(mNetd).clatdStop(eq(BASE_IFACE));
verify(mConnectivity, times(2)).handleUpdateLinkProperties(eq(mNai), c.capture());
- verify(mNms).unregisterObserver(eq(nat));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertTrue(c.getValue().getStackedLinks().isEmpty());
assertFalse(c.getValue().getAllInterfaceNames().contains(STACKED_IFACE));
@@ -374,7 +368,7 @@ public class Nat464XlatTest {
// ConnectivityService stops clat: no-op.
nat.stop();
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
private void checkStopBeforeClatdStarts(boolean dueToDisconnect) throws Exception {
@@ -386,7 +380,6 @@ public class Nat464XlatTest {
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
@@ -394,7 +387,6 @@ public class Nat464XlatTest {
nat.stop();
verify(mNetd).clatdStop(eq(BASE_IFACE));
- verify(mNms).unregisterObserver(eq(nat));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertIdle(nat);
@@ -408,7 +400,7 @@ public class Nat464XlatTest {
assertIdle(nat);
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
@Test
@@ -430,7 +422,6 @@ public class Nat464XlatTest {
nat.start();
- verify(mNms).registerObserver(eq(nat));
verify(mNetd).clatdStart(eq(BASE_IFACE), eq(NAT64_PREFIX));
// ConnectivityService immediately stops clat (Network disconnects, IPv4 addr appears, ...)
@@ -438,11 +429,10 @@ public class Nat464XlatTest {
nat.stop();
verify(mNetd).clatdStop(eq(BASE_IFACE));
- verify(mNms).unregisterObserver(eq(nat));
verify(mDnsResolver).stopPrefix64Discovery(eq(NETID));
assertIdle(nat);
- verifyNoMoreInteractions(mNetd, mNms, mConnectivity);
+ verifyNoMoreInteractions(mNetd, mConnectivity);
}
@Test
diff --git a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
index 54d6fb9f2c12..9334e2c4ad77 100644
--- a/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
+++ b/tests/net/java/com/android/server/net/NetworkStatsServiceTest.java
@@ -19,9 +19,7 @@ package com.android.server.net;
import static android.content.Intent.ACTION_UID_REMOVED;
import static android.content.Intent.EXTRA_UID;
import static android.net.ConnectivityManager.TYPE_MOBILE;
-import static android.net.ConnectivityManager.TYPE_VPN;
import static android.net.ConnectivityManager.TYPE_WIFI;
-import static android.net.NetworkIdentity.OEM_NONE;
import static android.net.NetworkIdentity.OEM_PAID;
import static android.net.NetworkIdentity.OEM_PRIVATE;
import static android.net.NetworkStats.DEFAULT_NETWORK_ALL;
@@ -86,7 +84,7 @@ import android.net.INetworkStatsSession;
import android.net.LinkProperties;
import android.net.Network;
import android.net.NetworkCapabilities;
-import android.net.NetworkState;
+import android.net.NetworkStateSnapshot;
import android.net.NetworkStats;
import android.net.NetworkStatsHistory;
import android.net.NetworkTemplate;
@@ -286,7 +284,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -329,7 +327,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -403,7 +401,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectSettings(0L, HOUR_IN_MILLIS, WEEK_IN_MILLIS);
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -444,7 +442,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testUidStatsAcrossNetworks() throws Exception {
// pretend first mobile network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildMobile3gState(IMSI_1)};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -475,7 +473,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// disappearing, to verify we don't count backwards.
incrementCurrentTime(HOUR_IN_MILLIS);
expectDefaultSettings();
- states = new NetworkState[] {buildMobile3gState(IMSI_2)};
+ states = new NetworkStateSnapshot[] {buildMobile3gState(IMSI_2)};
expectNetworkStatsSummary(new NetworkStats(getElapsedRealtime(), 1)
.insertEntry(TEST_IFACE, 2048L, 16L, 512L, 4L));
expectNetworkStatsUidDetail(new NetworkStats(getElapsedRealtime(), 3)
@@ -519,7 +517,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testUidRemovedIsMoved() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -583,7 +581,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_LTE);
final NetworkTemplate template5g =
buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_NR);
- final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
// 3G network comes online.
expectNetworkStatsSummary(buildEmptyStats());
@@ -673,7 +672,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
METERED_ALL, ROAMING_ALL, DEFAULT_NETWORK_ALL, NETWORK_TYPE_ALL, OEM_MANAGED_NO);
// OEM_PAID network comes online.
- NetworkState[] states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
+ buildOemManagedMobileState(IMSI_1, false,
new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -688,7 +688,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
forcePollAndWaitForIdle();
// OEM_PRIVATE network comes online.
- states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+ states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE})};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -703,7 +703,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
forcePollAndWaitForIdle();
// OEM_PAID + OEM_PRIVATE network comes online.
- states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false,
+ states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false,
new int[]{NetworkCapabilities.NET_CAPABILITY_OEM_PRIVATE,
NetworkCapabilities.NET_CAPABILITY_OEM_PAID})};
expectNetworkStatsSummary(buildEmptyStats());
@@ -719,7 +719,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
forcePollAndWaitForIdle();
// OEM_NONE network comes online.
- states = new NetworkState[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
+ states = new NetworkStateSnapshot[]{buildOemManagedMobileState(IMSI_1, false, new int[]{})};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_MOBILE, states, getActiveIface(states),
@@ -771,7 +771,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testSummaryForAllUid() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -830,7 +830,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testDetailedUidStats() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -871,9 +871,9 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
final String stackedIface = "stacked-test0";
final LinkProperties stackedProp = new LinkProperties();
stackedProp.setInterfaceName(stackedIface);
- final NetworkState wifiState = buildWifiState();
+ final NetworkStateSnapshot wifiState = buildWifiState();
wifiState.linkProperties.addStackedLink(stackedProp);
- NetworkState[] states = new NetworkState[] {wifiState};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {wifiState};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -929,7 +929,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testForegroundBackground() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -986,8 +986,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testMetered() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states =
- new NetworkState[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
+ NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[] {buildWifiState(true /* isMetered */, TEST_IFACE)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1026,8 +1026,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testRoaming() throws Exception {
// pretend that network comes online
expectDefaultSettings();
- NetworkState[] states =
- new NetworkState[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
+ NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[] {buildMobile3gState(IMSI_1, true /* isRoaming */)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1065,7 +1065,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testTethering() throws Exception {
// pretend first mobile network comes online
expectDefaultSettings();
- final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1122,7 +1123,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
// pretend that wifi network comes online; service should ask about full
// network state, and poll any existing interfaces before updating.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[] {buildWifiState()};
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[] {buildWifiState()};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1220,8 +1221,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testStatsProviderUpdateStats() throws Exception {
// Pretend that network comes online.
expectDefaultSettings();
- final NetworkState[] states =
- new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1282,8 +1283,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testStatsProviderSetAlert() throws Exception {
// Pretend that network comes online.
expectDefaultSettings();
- NetworkState[] states =
- new NetworkState[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
+ NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildWifiState(true /* isMetered */, TEST_IFACE)};
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
new UnderlyingNetworkInfo[0]);
@@ -1326,7 +1327,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
buildTemplateMobileWithRatType(null, TelephonyManager.NETWORK_TYPE_UNKNOWN);
final NetworkTemplate templateAll =
buildTemplateMobileWithRatType(null, NETWORK_TYPE_ALL);
- final NetworkState[] states = new NetworkState[]{buildMobile3gState(IMSI_1)};
+ final NetworkStateSnapshot[] states =
+ new NetworkStateSnapshot[]{buildMobile3gState(IMSI_1)};
expectNetworkStatsSummary(buildEmptyStats());
expectNetworkStatsUidDetail(buildEmptyStats());
@@ -1401,7 +1403,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
public void testOperationCount_nonDefault_traffic() throws Exception {
// Pretend mobile network comes online, but wifi is the default network.
expectDefaultSettings();
- NetworkState[] states = new NetworkState[]{
+ NetworkStateSnapshot[] states = new NetworkStateSnapshot[]{
buildWifiState(true /*isMetered*/, TEST_IFACE2), buildMobile3gState(IMSI_1)};
expectNetworkStatsUidDetail(buildEmptyStats());
mService.forceUpdateIfaces(NETWORKS_WIFI, states, getActiveIface(states),
@@ -1489,7 +1491,7 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
expectNetworkStatsSummary(buildEmptyStats());
}
- private String getActiveIface(NetworkState... states) throws Exception {
+ private String getActiveIface(NetworkStateSnapshot... states) throws Exception {
if (states == null || states.length == 0 || states[0].linkProperties == null) {
return null;
}
@@ -1565,11 +1567,11 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
assertEquals("unexpected operations", operations, entry.operations);
}
- private static NetworkState buildWifiState() {
+ private static NetworkStateSnapshot buildWifiState() {
return buildWifiState(false, TEST_IFACE);
}
- private static NetworkState buildWifiState(boolean isMetered, @NonNull String iface) {
+ private static NetworkStateSnapshot buildWifiState(boolean isMetered, @NonNull String iface) {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(iface);
final NetworkCapabilities capabilities = new NetworkCapabilities();
@@ -1577,35 +1579,30 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, true);
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
capabilities.setSSID(TEST_SSID);
- return new NetworkState(TYPE_WIFI, prop, capabilities, WIFI_NETWORK, null);
+ return new NetworkStateSnapshot(WIFI_NETWORK, capabilities, prop, null, TYPE_WIFI);
}
- private static NetworkState buildMobile3gState(String subscriberId) {
+ private static NetworkStateSnapshot buildMobile3gState(String subscriberId) {
return buildMobile3gState(subscriberId, false /* isRoaming */);
}
- private static NetworkState buildMobile3gState(String subscriberId, boolean isRoaming) {
+ private static NetworkStateSnapshot buildMobile3gState(String subscriberId, boolean isRoaming) {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
final NetworkCapabilities capabilities = new NetworkCapabilities();
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_METERED, false);
capabilities.setCapability(NetworkCapabilities.NET_CAPABILITY_NOT_ROAMING, !isRoaming);
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId);
+ return new NetworkStateSnapshot(
+ MOBILE_NETWORK, capabilities, prop, subscriberId, TYPE_MOBILE);
}
private NetworkStats buildEmptyStats() {
return new NetworkStats(getElapsedRealtime(), 0);
}
- private static NetworkState buildVpnState() {
- final LinkProperties prop = new LinkProperties();
- prop.setInterfaceName(TUN_IFACE);
- return new NetworkState(TYPE_VPN, prop, new NetworkCapabilities(), VPN_NETWORK, null);
- }
-
- private static NetworkState buildOemManagedMobileState(String subscriberId, boolean isRoaming,
- int[] oemNetCapabilities) {
+ private static NetworkStateSnapshot buildOemManagedMobileState(
+ String subscriberId, boolean isRoaming, int[] oemNetCapabilities) {
final LinkProperties prop = new LinkProperties();
prop.setInterfaceName(TEST_IFACE);
final NetworkCapabilities capabilities = new NetworkCapabilities();
@@ -1615,7 +1612,8 @@ public class NetworkStatsServiceTest extends NetworkStatsBaseTest {
capabilities.setCapability(nc, true);
}
capabilities.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
- return new NetworkState(TYPE_MOBILE, prop, capabilities, MOBILE_NETWORK, subscriberId);
+ return new NetworkStateSnapshot(MOBILE_NETWORK, capabilities, prop, subscriberId,
+ TYPE_MOBILE);
}
private long getElapsedRealtime() {
diff --git a/tools/aapt2/cmd/Link.cpp b/tools/aapt2/cmd/Link.cpp
index b760958e0edc..13e090d9d843 100644
--- a/tools/aapt2/cmd/Link.cpp
+++ b/tools/aapt2/cmd/Link.cpp
@@ -2263,6 +2263,16 @@ int LinkCommand::Action(const std::vector<std::string>& args) {
return 1;
}
+ if (shared_lib_ && options_.private_symbols) {
+ // If a shared library styleable in a public R.java uses a private attribute, attempting to
+ // reference the private attribute within the styleable array will cause a link error because
+ // the private attribute will not be emitted in the public R.java.
+ context.GetDiagnostics()->Error(DiagMessage()
+ << "--shared-lib cannot currently be used in combination with"
+ << " --private-symbols");
+ return 1;
+ }
+
if (options_.merge_only && !static_lib_) {
context.GetDiagnostics()->Error(
DiagMessage() << "the --merge-only flag can be only used when building a static library");
diff --git a/tools/aapt2/cmd/Link_test.cpp b/tools/aapt2/cmd/Link_test.cpp
index 062dd8eac975..73072a963d09 100644
--- a/tools/aapt2/cmd/Link_test.cpp
+++ b/tools/aapt2/cmd/Link_test.cpp
@@ -14,13 +14,16 @@
* limitations under the License.
*/
-#include "AppInfo.h"
#include "Link.h"
+#include <android-base/file.h>
+
+#include "AppInfo.h"
#include "LoadedApk.h"
#include "test/Test.h"
using testing::Eq;
+using testing::HasSubstr;
using testing::Ne;
namespace aapt {
@@ -317,4 +320,76 @@ TEST_F(LinkTest, AppInfoWithUsesSplit) {
ASSERT_TRUE(Link(link_args, feature2_files_dir, &diag));
}
+TEST_F(LinkTest, SharedLibraryAttributeRJava) {
+ StdErrDiagnostics diag;
+ const std::string lib_values =
+ R"(<resources>
+ <attr name="foo"/>
+ <public type="attr" name="foo" id="0x00010001"/>
+ <declare-styleable name="LibraryStyleable">
+ <attr name="foo" />
+ </declare-styleable>
+ </resources>)";
+
+ const std::string client_values =
+ R"(<resources>
+ <attr name="bar" />
+ <declare-styleable name="ClientStyleable">
+ <attr name="com.example.lib:foo" />
+ <attr name="bar" />
+ </declare-styleable>
+ </resources>)";
+
+ // Build a library with a public attribute
+ const std::string lib_res = GetTestPath("library-res");
+ ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), lib_values, lib_res, &diag));
+
+ const std::string lib_apk = GetTestPath("library.apk");
+ const std::string lib_java = GetTestPath("library_java");
+ // clang-format off
+ auto lib_manifest = ManifestBuilder(this)
+ .SetPackageName("com.example.lib")
+ .Build();
+
+ auto lib_link_args = LinkCommandBuilder(this)
+ .SetManifestFile(lib_manifest)
+ .AddFlag("--shared-lib")
+ .AddParameter("--java", lib_java)
+ .AddCompiledResDir(lib_res, &diag)
+ .Build(lib_apk);
+ // clang-format on
+ ASSERT_TRUE(Link(lib_link_args, &diag));
+
+ const std::string lib_r_java = lib_java + "/com/example/lib/R.java";
+ std::string lib_r_contents;
+ ASSERT_TRUE(android::base::ReadFileToString(lib_r_java, &lib_r_contents));
+ EXPECT_THAT(lib_r_contents, HasSubstr(" public static int foo=0x00010001;"));
+ EXPECT_THAT(lib_r_contents, HasSubstr(" com.example.lib.R.attr.foo"));
+
+ // Build a client that uses the library attribute in a declare-styleable
+ const std::string client_res = GetTestPath("client-res");
+ ASSERT_TRUE(CompileFile(GetTestPath("res/values/values.xml"), client_values, client_res, &diag));
+
+ const std::string client_apk = GetTestPath("client.apk");
+ const std::string client_java = GetTestPath("client_java");
+ // clang-format off
+ auto client_manifest = ManifestBuilder(this)
+ .SetPackageName("com.example.client")
+ .Build();
+
+ auto client_link_args = LinkCommandBuilder(this)
+ .SetManifestFile(client_manifest)
+ .AddParameter("--java", client_java)
+ .AddParameter("-I", lib_apk)
+ .AddCompiledResDir(client_res, &diag)
+ .Build(client_apk);
+ // clang-format on
+ ASSERT_TRUE(Link(client_link_args, &diag));
+
+ const std::string client_r_java = client_java + "/com/example/client/R.java";
+ std::string client_r_contents;
+ ASSERT_TRUE(android::base::ReadFileToString(client_r_java, &client_r_contents));
+ EXPECT_THAT(client_r_contents, HasSubstr(" com.example.lib.R.attr.foo, 0x7f010000"));
+}
+
} // namespace aapt
diff --git a/tools/aapt2/format/binary/TableFlattener.cpp b/tools/aapt2/format/binary/TableFlattener.cpp
index eb0ade62d542..4b90b4f534cc 100644
--- a/tools/aapt2/format/binary/TableFlattener.cpp
+++ b/tools/aapt2/format/binary/TableFlattener.cpp
@@ -570,7 +570,6 @@ class PackageFlattener {
ResourceEntry* entry = sorted_entries->at(entryIndex);
// Populate the config masks for this entry.
-
if (entry->visibility.level == Visibility::Level::kPublic) {
config_masks[entry->id.value()] |= util::HostToDevice32(ResTable_typeSpec::SPEC_PUBLIC);
}
diff --git a/tools/aapt2/java/ClassDefinition.h b/tools/aapt2/java/ClassDefinition.h
index 1e4b6816075a..995495ac56a8 100644
--- a/tools/aapt2/java/ClassDefinition.h
+++ b/tools/aapt2/java/ClassDefinition.h
@@ -70,8 +70,8 @@ class PrimitiveMember : public ClassMember {
return name_;
}
- void Print(bool final, text::Printer* printer, bool strip_api_annotations = false)
- const override {
+ void Print(bool final, text::Printer* printer,
+ bool strip_api_annotations = false) const override {
using std::to_string;
ClassMember::Print(final, printer, strip_api_annotations);
@@ -127,13 +127,13 @@ using IntMember = PrimitiveMember<uint32_t>;
using ResourceMember = PrimitiveMember<ResourceId>;
using StringMember = PrimitiveMember<std::string>;
-template <typename T>
+template <typename T, typename StringConverter>
class PrimitiveArrayMember : public ClassMember {
public:
explicit PrimitiveArrayMember(const android::StringPiece& name) : name_(name.to_string()) {}
void AddElement(const T& val) {
- elements_.push_back(val);
+ elements_.emplace_back(val);
}
bool empty() const override {
@@ -158,7 +158,7 @@ class PrimitiveArrayMember : public ClassMember {
printer->Println();
}
- printer->Print(to_string(*current));
+ printer->Print(StringConverter::ToString(*current));
if (std::distance(current, end) > 1) {
printer->Print(", ");
}
@@ -175,7 +175,24 @@ class PrimitiveArrayMember : public ClassMember {
std::vector<T> elements_;
};
-using ResourceArrayMember = PrimitiveArrayMember<ResourceId>;
+struct FieldReference {
+ explicit FieldReference(std::string reference) : ref(std::move(reference)) {
+ }
+ std::string ref;
+};
+
+struct ResourceArrayMemberStringConverter {
+ static std::string ToString(const std::variant<ResourceId, FieldReference>& ref) {
+ if (auto id = std::get_if<ResourceId>(&ref)) {
+ return to_string(*id);
+ } else {
+ return std::get<FieldReference>(ref).ref;
+ }
+ }
+};
+
+using ResourceArrayMember = PrimitiveArrayMember<std::variant<ResourceId, FieldReference>,
+ ResourceArrayMemberStringConverter>;
// Represents a method in a class.
class MethodDefinition : public ClassMember {
diff --git a/tools/aapt2/java/JavaClassGenerator.cpp b/tools/aapt2/java/JavaClassGenerator.cpp
index f0f839d968d5..59dd481607e9 100644
--- a/tools/aapt2/java/JavaClassGenerator.cpp
+++ b/tools/aapt2/java/JavaClassGenerator.cpp
@@ -224,7 +224,16 @@ static bool operator<(const StyleableAttr& lhs, const StyleableAttr& rhs) {
return cmp_ids_dynamic_after_framework(lhs_id, rhs_id);
}
-void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
+static FieldReference GetRFieldReference(const ResourceName& name,
+ StringPiece fallback_package_name) {
+ const std::string package_name =
+ name.package.empty() ? fallback_package_name.to_string() : name.package;
+ const std::string entry = JavaClassGenerator::TransformToFieldName(name.entry);
+ return FieldReference(
+ StringPrintf("%s.R.%s.%s", package_name.c_str(), to_string(name.type).data(), entry.c_str()));
+}
+
+bool JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
const Styleable& styleable,
const StringPiece& package_name_to_generate,
ClassDefinition* out_class_def,
@@ -340,14 +349,29 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
// Add the ResourceIds to the array member.
for (size_t i = 0; i < attr_count; i++) {
- const ResourceId id = sorted_attributes[i].attr_ref->id.value_or_default(ResourceId(0));
- array_def->AddElement(id);
+ const StyleableAttr& attr = sorted_attributes[i];
+ std::string r_txt_contents;
+ if (attr.symbol && attr.symbol.value().is_dynamic) {
+ if (!attr.attr_ref->name) {
+ error_ = "unable to determine R.java field name of dynamic resource";
+ return false;
+ }
+
+ const FieldReference field_name =
+ GetRFieldReference(attr.attr_ref->name.value(), package_name_to_generate);
+ array_def->AddElement(field_name);
+ r_txt_contents = field_name.ref;
+ } else {
+ const ResourceId attr_id = attr.attr_ref->id.value_or_default(ResourceId(0));
+ array_def->AddElement(attr_id);
+ r_txt_contents = to_string(attr_id);
+ }
if (r_txt_printer != nullptr) {
if (i != 0) {
r_txt_printer->Print(",");
}
- r_txt_printer->Print(" ").Print(id.to_string());
+ r_txt_printer->Print(" ").Print(r_txt_contents);
}
}
@@ -419,19 +443,7 @@ void JavaClassGenerator::ProcessStyleable(const ResourceNameRef& name, const Res
}
}
- // If there is a rewrite method to generate, add the statements that rewrite package IDs
- // for this styleable.
- if (out_rewrite_method != nullptr) {
- out_rewrite_method->AppendStatement(
- StringPrintf("for (int i = 0; i < styleable.%s.length; i++) {", array_field_name.data()));
- out_rewrite_method->AppendStatement(
- StringPrintf(" if ((styleable.%s[i] & 0xff000000) == 0) {", array_field_name.data()));
- out_rewrite_method->AppendStatement(
- StringPrintf(" styleable.%s[i] = (styleable.%s[i] & 0x00ffffff) | packageIdBits;",
- array_field_name.data(), array_field_name.data()));
- out_rewrite_method->AppendStatement(" }");
- out_rewrite_method->AppendStatement("}");
- }
+ return true;
}
void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const ResourceId& id,
@@ -448,8 +460,7 @@ void JavaClassGenerator::ProcessResource(const ResourceNameRef& name, const Reso
const std::string field_name = TransformToFieldName(name.entry);
if (out_class_def != nullptr) {
- std::unique_ptr<ResourceMember> resource_member =
- util::make_unique<ResourceMember>(field_name, real_id);
+ auto resource_member = util::make_unique<ResourceMember>(field_name, real_id);
// Build the comments and annotations for this entry.
AnnotationProcessor* processor = resource_member->GetCommentBuilder();
@@ -551,12 +562,11 @@ bool JavaClassGenerator::ProcessType(const StringPiece& package_name_to_generate
if (resource_name.type == ResourceType::kStyleable) {
CHECK(!entry->values.empty());
-
- const Styleable* styleable =
- static_cast<const Styleable*>(entry->values.front()->value.get());
-
- ProcessStyleable(resource_name, id, *styleable, package_name_to_generate, out_type_class_def,
- out_rewrite_method_def, r_txt_printer);
+ const auto styleable = reinterpret_cast<const Styleable*>(entry->values.front()->value.get());
+ if (!ProcessStyleable(resource_name, id, *styleable, package_name_to_generate,
+ out_type_class_def, out_rewrite_method_def, r_txt_printer)) {
+ return false;
+ }
} else {
ProcessResource(resource_name, id, *entry, out_type_class_def, out_rewrite_method_def,
r_txt_printer);
@@ -626,8 +636,7 @@ bool JavaClassGenerator::Generate(const StringPiece& package_name_to_generate,
if (type->type == ResourceType::kAttr) {
// Also include private attributes in this same class.
- const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate);
- if (priv_type) {
+ if (const ResourceTableType* priv_type = package->FindType(ResourceType::kAttrPrivate)) {
if (!ProcessType(package_name_to_generate, *package, *priv_type, class_def.get(),
rewrite_method.get(), r_txt_printer.get())) {
return false;
diff --git a/tools/aapt2/java/JavaClassGenerator.h b/tools/aapt2/java/JavaClassGenerator.h
index 853120b3cb98..d9d1b39805f9 100644
--- a/tools/aapt2/java/JavaClassGenerator.h
+++ b/tools/aapt2/java/JavaClassGenerator.h
@@ -105,7 +105,7 @@ class JavaClassGenerator {
// Writes a styleable resource to the R.java file, optionally writing out a rewrite rule for
// its package ID if `out_rewrite_method` is not nullptr.
// `package_name_to_generate` is the package
- void ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
+ bool ProcessStyleable(const ResourceNameRef& name, const ResourceId& id,
const Styleable& styleable,
const android::StringPiece& package_name_to_generate,
ClassDefinition* out_class_def, MethodDefinition* out_rewrite_method,
diff --git a/tools/aapt2/java/JavaClassGenerator_test.cpp b/tools/aapt2/java/JavaClassGenerator_test.cpp
index 04e20101a0dd..ec5b4151b1a6 100644
--- a/tools/aapt2/java/JavaClassGenerator_test.cpp
+++ b/tools/aapt2/java/JavaClassGenerator_test.cpp
@@ -581,7 +581,7 @@ TEST(JavaClassGeneratorTest, SortsDynamicAttributesAfterFrameworkAttributes) {
out.Flush();
EXPECT_THAT(output, HasSubstr("public static final int[] MyStyleable={"));
- EXPECT_THAT(output, HasSubstr("0x01010000, 0x00010000"));
+ EXPECT_THAT(output, HasSubstr("0x01010000, lib.R.attr.dynamic_attr"));
EXPECT_THAT(output, HasSubstr("public static final int MyStyleable_android_framework_attr=0;"));
EXPECT_THAT(output, HasSubstr("public static final int MyStyleable_dynamic_attr=1;"));
}
diff --git a/tools/aapt2/process/SymbolTable.cpp b/tools/aapt2/process/SymbolTable.cpp
index daedc2a14767..98ee63d2e5c6 100644
--- a/tools/aapt2/process/SymbolTable.cpp
+++ b/tools/aapt2/process/SymbolTable.cpp
@@ -370,11 +370,11 @@ std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindByName(
} else {
s = util::make_unique<SymbolTable::Symbol>();
s->id = res_id;
- s->is_dynamic = IsPackageDynamic(ResourceId(res_id).package_id(), real_name.package);
}
if (s) {
s->is_public = (type_spec_flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
+ s->is_dynamic = IsPackageDynamic(ResourceId(res_id).package_id(), real_name.package);
return s;
}
return {};
@@ -417,11 +417,11 @@ std::unique_ptr<SymbolTable::Symbol> AssetManagerSymbolSource::FindById(
} else {
s = util::make_unique<SymbolTable::Symbol>();
s->id = id;
- s->is_dynamic = IsPackageDynamic(ResourceId(id).package_id(), name.package);
}
if (s) {
s->is_public = (*flags & android::ResTable_typeSpec::SPEC_PUBLIC) != 0;
+ s->is_dynamic = IsPackageDynamic(ResourceId(id).package_id(), name.package);
return s;
}
return {};
diff --git a/tools/aapt2/test/Fixture.cpp b/tools/aapt2/test/Fixture.cpp
index 5386802dbc8e..f94f0fe1144a 100644
--- a/tools/aapt2/test/Fixture.cpp
+++ b/tools/aapt2/test/Fixture.cpp
@@ -18,18 +18,17 @@
#include <dirent.h>
-#include "android-base/errors.h"
-#include "android-base/file.h"
-#include "android-base/stringprintf.h"
-#include "android-base/utf8.h"
-#include "androidfw/StringPiece.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
+#include <android-base/errors.h>
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/utf8.h>
+#include <androidfw/StringPiece.h>
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
#include "cmd/Compile.h"
#include "cmd/Link.h"
#include "io/FileStream.h"
-#include "io/Util.h"
#include "util/Files.h"
using testing::Eq;
@@ -170,4 +169,74 @@ void CommandTestFixture::AssertLoadXml(LoadedApk* apk, const io::IData* data,
}
}
+ManifestBuilder::ManifestBuilder(CommandTestFixture* fixture) : fixture_(fixture) {
+}
+
+ManifestBuilder& ManifestBuilder::SetPackageName(const std::string& package_name) {
+ package_name_ = package_name;
+ return *this;
+}
+
+ManifestBuilder& ManifestBuilder::AddContents(const std::string& contents) {
+ contents_ += contents + "\n";
+ return *this;
+}
+
+std::string ManifestBuilder::Build(const std::string& file_path) {
+ const char* manifest_template = R"(
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="%s">
+ %s
+ </manifest>)";
+
+ fixture_->WriteFile(file_path, android::base::StringPrintf(
+ manifest_template, package_name_.c_str(), contents_.c_str()));
+ return file_path;
+}
+
+std::string ManifestBuilder::Build() {
+ return Build(fixture_->GetTestPath("AndroidManifest.xml"));
+}
+
+LinkCommandBuilder::LinkCommandBuilder(CommandTestFixture* fixture) : fixture_(fixture) {
+}
+
+LinkCommandBuilder& LinkCommandBuilder::SetManifestFile(const std::string& file) {
+ manifest_supplied_ = true;
+ args_.emplace_back("--manifest");
+ args_.emplace_back(file);
+ return *this;
+}
+
+LinkCommandBuilder& LinkCommandBuilder::AddFlag(const std::string& flag) {
+ args_.emplace_back(flag);
+ return *this;
+}
+
+LinkCommandBuilder& LinkCommandBuilder::AddCompiledResDir(const std::string& dir,
+ IDiagnostics* diag) {
+ if (auto files = file::FindFiles(dir, diag)) {
+ for (std::string& compile_file : files.value()) {
+ args_.emplace_back(file::BuildPath({dir, compile_file}));
+ }
+ }
+ return *this;
+}
+
+LinkCommandBuilder& LinkCommandBuilder::AddParameter(const std::string& param,
+ const std::string& value) {
+ args_.emplace_back(param);
+ args_.emplace_back(value);
+ return *this;
+}
+
+std::vector<std::string> LinkCommandBuilder::Build(const std::string& out_apk) {
+ if (!manifest_supplied_) {
+ SetManifestFile(ManifestBuilder(fixture_).Build());
+ }
+ args_.emplace_back("-o");
+ args_.emplace_back(out_apk);
+ return args_;
+}
+
} // namespace aapt \ No newline at end of file
diff --git a/tools/aapt2/test/Fixture.h b/tools/aapt2/test/Fixture.h
index 457d65e30b65..f8c4889aee3b 100644
--- a/tools/aapt2/test/Fixture.h
+++ b/tools/aapt2/test/Fixture.h
@@ -32,7 +32,7 @@ namespace aapt {
class TestDirectoryFixture : public ::testing::Test {
public:
TestDirectoryFixture() = default;
- virtual ~TestDirectoryFixture() = default;
+ ~TestDirectoryFixture() override = default;
// Creates the test directory or clears its contents if it contains previously created files.
void SetUp() override;
@@ -41,14 +41,14 @@ class TestDirectoryFixture : public ::testing::Test {
void TearDown() override;
// Retrieve the test directory of the fixture.
- const android::StringPiece GetTestDirectory() {
+ android::StringPiece GetTestDirectory() {
return temp_dir_;
}
// Retrieves the absolute path of the specified relative path in the test directory. Directories
// should be separated using forward slashes ('/'), and these slashes will be translated to
// backslashes when running Windows tests.
- const std::string GetTestPath(const android::StringPiece& path) {
+ std::string GetTestPath(const android::StringPiece& path) {
std::string base = temp_dir_;
for (android::StringPiece part : util::Split(path, '/')) {
file::AppendPath(&base, part);
@@ -68,7 +68,7 @@ class TestDirectoryFixture : public ::testing::Test {
class CommandTestFixture : public TestDirectoryFixture {
public:
CommandTestFixture() = default;
- virtual ~CommandTestFixture() = default;
+ ~CommandTestFixture() override = default;
// Wries the contents of the file to the specified path. The file is compiled and the flattened
// file is written to the out directory.
@@ -99,6 +99,33 @@ class CommandTestFixture : public TestDirectoryFixture {
DISALLOW_COPY_AND_ASSIGN(CommandTestFixture);
};
+struct ManifestBuilder {
+ explicit ManifestBuilder(CommandTestFixture* fixture);
+ ManifestBuilder& AddContents(const std::string& contents);
+ ManifestBuilder& SetPackageName(const std::string& package_name);
+ std::string Build(const std::string& file_path);
+ std::string Build();
+
+ private:
+ CommandTestFixture* fixture_;
+ std::string package_name_ = CommandTestFixture::kDefaultPackageName;
+ std::string contents_;
+};
+
+struct LinkCommandBuilder {
+ explicit LinkCommandBuilder(CommandTestFixture* fixture);
+ LinkCommandBuilder& AddCompiledResDir(const std::string& dir, IDiagnostics* diag);
+ LinkCommandBuilder& AddFlag(const std::string& flag);
+ LinkCommandBuilder& AddParameter(const std::string& param, const std::string& value);
+ LinkCommandBuilder& SetManifestFile(const std::string& manifest_path);
+ std::vector<std::string> Build(const std::string& out_apk_path);
+
+ private:
+ CommandTestFixture* fixture_;
+ std::vector<std::string> args_;
+ bool manifest_supplied_ = false;
+};
+
} // namespace aapt
#endif // AAPT_TEST_FIXTURE_H \ No newline at end of file