diff options
242 files changed, 4386 insertions, 2701 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index d4af94035fd1..d3f1d5d3f58b 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -74,6 +74,7 @@ aconfig_declarations_group { "android.view.inputmethod.flags-aconfig-java", "android.webkit.flags-aconfig-java", "android.widget.flags-aconfig-java", + "art_exported_aconfig_flags_lib", "backstage_power_flags_lib", "backup_flags_lib", "camera_platform_flags_core_java_lib", @@ -88,6 +89,7 @@ aconfig_declarations_group { "com.android.media.flags.performance-aconfig-java", "com.android.media.flags.projection-aconfig-java", "com.android.net.thread.platform.flags-aconfig-java", + "com.android.ranging.flags.ranging-aconfig-java", "com.android.server.contextualsearch.flags-java", "com.android.server.flags.services-aconfig-java", "com.android.text.flags-aconfig-java", @@ -133,6 +135,14 @@ java_defaults { libs: ["fake_device_config"], } +// ART +java_aconfig_library { + name: "art_exported_aconfig_flags_lib", + aconfig_declarations: "art-aconfig-flags", + mode: "exported", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Camera java_aconfig_library { name: "camera_platform_flags_core_java_lib", @@ -1453,6 +1463,13 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +// Ranging +java_aconfig_library { + name: "com.android.ranging.flags.ranging-aconfig-java", + aconfig_declarations: "ranging_aconfig_flags", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // System Server aconfig_declarations { name: "android.systemserver.flags-aconfig", diff --git a/TEST_MAPPING b/TEST_MAPPING index 49384cde5803..bdae506115e8 100644 --- a/TEST_MAPPING +++ b/TEST_MAPPING @@ -1,44 +1,17 @@ { "presubmit-large": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksServicesTests_Presubmit" } ], "presubmit-pm": [ { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_Presubmit" } ], "presubmit": [ { - "name": "ManagedProvisioningTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ManagedProvisioningTests" }, { "file_patterns": [ @@ -46,86 +19,28 @@ "SystemServer\\.java", "services/tests/apexsystemservices/.*" ], - "name": "ApexSystemServicesTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "ApexSystemServicesTestCases" }, { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksUiServicesTests" }, { - "name": "FrameworksInputMethodSystemServerTests", - "options": [ - {"include-filter": "com.android.server.inputmethod"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksInputMethodSystemServerTests_server_inputmethod" }, { - "name": "ExtServicesUnitTests-tplus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-tplus" }, { - "name": "ExtServicesUnitTests-sminus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-sminus" }, { - "name": "FrameworksCoreTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_Presubmit" }, { - "name": "FrameworkPermissionTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworkPermissionTests_Presubmit" }, { - "name": "FrameworksInProcessTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksInProcessTests" }, { "name": "vts_treble_vintf_framework_test" @@ -159,78 +74,25 @@ // infra during the hardening phase. // TODO: this tag to be removed once the above is no longer an issue. { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksUiServicesTests" }, { - "name": "ExtServicesUnitTests-tplus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-tplus" }, { - "name": "ExtServicesUnitTests-sminus", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ExtServicesUnitTests-sminus" }, { - "name": "TestablesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TestablesTests" }, { - "name": "FrameworksCoreTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_Presubmit" }, { - "name": "FrameworksServicesTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksServicesTests_presubmit" }, { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_Presubmit" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING index b58cb881fade..e3e72f43ef65 100644 --- a/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/TEST_MAPPING @@ -11,10 +11,7 @@ ], "postsubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server"} - ] + "name": "FrameworksMockingServicesTests_android_server" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING index afa509c6ea93..ed8851c93042 100644 --- a/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/deviceidle/TEST_MAPPING @@ -6,10 +6,7 @@ ], "postsubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server"} - ] + "name": "FrameworksMockingServicesTests_android_server" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING index 16c2fd4b73c3..d198bfdd03ee 100644 --- a/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/job/TEST_MAPPING @@ -1,11 +1,7 @@ { "presubmit": [ { - "name": "CtsJobSchedulerTestCases", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsJobSchedulerTestCases_com_android_server_job" }, { "name": "FrameworksMockingServicesTests_com_android_server_job_Presubmit" @@ -19,29 +15,16 @@ "name": "CtsJobSchedulerTestCases" }, { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server.job"} - ] + "name": "FrameworksMockingServicesTests_com_android_server_job" }, { - "name": "FrameworksServicesTests", - "options": [ - {"include-filter": "com.android.server.job"} - ] + "name": "FrameworksServicesTests_com_android_server_job" }, { - "name": "CtsHostsideNetworkPolicyTests", - "options": [ - {"include-filter": "com.android.cts.netpolicy.HostsideRestrictBackgroundNetworkTests#testMeteredNetworkAccess_expeditedJob"}, - {"include-filter": "com.android.cts.netpolicy.HostsideRestrictBackgroundNetworkTests#testNonMeteredNetworkAccess_expeditedJob"} - ] + "name": "CtsHostsideNetworkPolicyTests_com_android_server_job" }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - {"include-filter": "android.cts.statsdatom.jobscheduler"} - ] + "name": "CtsStatsdAtomHostTestCases_statsdatom_jobscheduler" } ] } diff --git a/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING b/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING index dd0d1b6285de..1a2013daf2cd 100644 --- a/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING +++ b/apex/jobscheduler/service/java/com/android/server/usage/TEST_MAPPING @@ -1,13 +1,7 @@ { "presubmit": [ { - "name": "CtsUsageStatsTestCases", - "options": [ - {"include-filter": "android.app.usage.cts.UsageStatsTest"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.MediumTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsUsageStatsTestCases_cts_usagestatstest" }, { "name": "CtsBRSTestCases" @@ -21,10 +15,7 @@ "name": "CtsUsageStatsTestCases" }, { - "name": "FrameworksServicesTests", - "options": [ - {"include-filter": "com.android.server.usage"} - ] + "name": "FrameworksServicesTests_com_android_server_usage" } ] } diff --git a/api/Android.bp b/api/Android.bp index 341be3d53844..3f2316f005bd 100644 --- a/api/Android.bp +++ b/api/Android.bp @@ -87,6 +87,7 @@ combined_apis { "framework-permission", "framework-permission-s", "framework-profiling", + "framework-photopicker", "framework-scheduling", "framework-sdkextensions", "framework-statsd", @@ -101,6 +102,11 @@ combined_apis { "framework-crashrecovery", ], default: [], + }) + select(release_flag("RELEASE_RANGING_STACK"), { + true: [ + "framework-ranging", + ], + default: [], }), system_server_classpath: [ "service-art", diff --git a/api/StubLibraries.bp b/api/StubLibraries.bp index b3a674fbd70e..d1aa23c8ea5f 100644 --- a/api/StubLibraries.bp +++ b/api/StubLibraries.bp @@ -466,6 +466,32 @@ java_library { } java_library { + name: "android-non-updatable.stubs.system_server", + defaults: ["android-non-updatable_defaults"], + static_libs: [ + "android-non-updatable.stubs.system_server.from-source", + ], + product_variables: { + build_from_text_stub: { + static_libs: [ + "android-non-updatable.stubs.system_server.from-text", + ], + exclude_static_libs: [ + "android-non-updatable.stubs.system_server.from-source", + ], + }, + }, +} + +java_library { + name: "android-non-updatable.stubs.exportable.system_server", + defaults: ["android-non-updatable_defaults"], + static_libs: [ + "android-non-updatable.stubs.exportable.system_server.from-source", + ], +} + +java_library { name: "android-non-updatable.stubs.from-source", defaults: [ "android-non-updatable_defaults", @@ -561,6 +587,30 @@ java_library { }, } +java_library { + name: "android-non-updatable.stubs.system_server.from-source", + defaults: [ + "android-non-updatable_defaults", + "android-non-updatable_from_source_defaults", + ], + srcs: [":services-non-updatable-stubs"], + libs: non_updatable_api_deps_on_modules, +} + +java_library { + name: "android-non-updatable.stubs.exportable.system_server.from-source", + defaults: [ + "android-non-updatable_defaults", + "android-non-updatable_from_source_defaults", + "android-non-updatable_exportable_from_source_defaults", + ], + srcs: [":services-non-updatable-stubs{.exportable}"], + libs: non_updatable_api_deps_on_modules, + dist: { + dir: "apistubs/android/system-server", + }, +} + java_defaults { name: "android-non-updatable_from_text_defaults", defaults: ["android-non-updatable-stubs-libs-defaults"], @@ -662,6 +712,25 @@ java_api_library { libs: ["all-modules-system-stubs"], } +java_api_library { + name: "android-non-updatable.stubs.system_server.from-text", + api_surface: "system_server", + api_contributions: [ + "api-stubs-docs-non-updatable.api.contribution", + "system-api-stubs-docs-non-updatable.api.contribution", + "module-lib-api-stubs-docs-non-updatable.api.contribution", + "services-non-updatable-stubs.api.contribution", + ], + defaults: [ + "module-classpath-java-defaults", + "android-non-updatable_everything_from_text_defaults", + ], + + // Use full Android API not just the non-updatable API as the latter is incomplete + // and can result in incorrect behavior. + previous_api: ":android.api.combined.system-server.latest", +} + java_defaults { name: "android_stubs_dists_default", dist: { @@ -813,9 +882,9 @@ java_library { defaults: [ "android.jar_defaults", ], - srcs: [":services-non-updatable-stubs"], installable: false, static_libs: [ + "android-non-updatable.stubs.system_server", "android_module_lib_stubs_current", ], visibility: ["//frameworks/base/services"], @@ -827,9 +896,9 @@ java_library { "android.jar_defaults", "android_stubs_dists_default", ], - srcs: [":services-non-updatable-stubs{.exportable}"], installable: false, static_libs: [ + "android-non-updatable.stubs.exportable.system_server", "android_module_lib_stubs_current_exportable", ], dist: { diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index fdf9abc49604..c2f6e3072507 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -70,8 +70,9 @@ namespace android { using ui::DisplayMode; static const char OEM_BOOTANIMATION_FILE[] = "/oem/media/bootanimation.zip"; -static const char PRODUCT_BOOTANIMATION_DARK_FILE[] = "/product/media/bootanimation-dark.zip"; -static const char PRODUCT_BOOTANIMATION_FILE[] = "/product/media/bootanimation.zip"; +static const char PRODUCT_BOOTANIMATION_DIR[] = "/product/media/"; +static const char PRODUCT_BOOTANIMATION_DARK_FILE[] = "bootanimation-dark.zip"; +static const char PRODUCT_BOOTANIMATION_FILE[] = "bootanimation.zip"; static const char SYSTEM_BOOTANIMATION_FILE[] = "/system/media/bootanimation.zip"; static const char APEX_BOOTANIMATION_FILE[] = "/apex/com.android.bootanimation/etc/bootanimation.zip"; static const char OEM_SHUTDOWNANIMATION_FILE[] = "/oem/media/shutdownanimation.zip"; @@ -749,8 +750,11 @@ bool BootAnimation::findBootAnimationFileInternal(const std::vector<std::string> void BootAnimation::findBootAnimationFile() { ATRACE_CALL(); const bool playDarkAnim = android::base::GetIntProperty("ro.boot.theme", 0) == 1; + const std::string productBootanimationFile = PRODUCT_BOOTANIMATION_DIR + + android::base::GetProperty("ro.product.bootanim.file", playDarkAnim ? + PRODUCT_BOOTANIMATION_DARK_FILE : PRODUCT_BOOTANIMATION_FILE); static const std::vector<std::string> bootFiles = { - APEX_BOOTANIMATION_FILE, playDarkAnim ? PRODUCT_BOOTANIMATION_DARK_FILE : PRODUCT_BOOTANIMATION_FILE, + APEX_BOOTANIMATION_FILE, productBootanimationFile, OEM_BOOTANIMATION_FILE, SYSTEM_BOOTANIMATION_FILE }; static const std::vector<std::string> shutdownFiles = { diff --git a/cmds/locksettings/TEST_MAPPING b/cmds/locksettings/TEST_MAPPING index af54a2decd89..0f502c9904e5 100644 --- a/cmds/locksettings/TEST_MAPPING +++ b/cmds/locksettings/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit-large": [ { - "name": "CtsDevicePolicyManagerTestCases", - "options": [ - { - "include-annotation": "com.android.cts.devicepolicy.annotations.LockSettingsTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.FlakyTest" - } - ] + "name": "CtsDevicePolicyManagerTestCases_LockSettingsTest" } ], "postsubmit": [ diff --git a/cmds/uiautomator/library/Android.bp b/cmds/uiautomator/library/Android.bp index 966bf13adfe4..5c5b220d20e9 100644 --- a/cmds/uiautomator/library/Android.bp +++ b/cmds/uiautomator/library/Android.bp @@ -28,9 +28,9 @@ droidstubs { "testrunner-src/**/*.java", ], libs: [ - "android.test.runner", + "android.test.runner.stubs.system", "junit", - "android.test.base", + "android.test.base.stubs.system", "unsupportedappusage", ], installable: false, @@ -56,9 +56,9 @@ droiddoc { ":uiautomator-stubs", ], libs: [ - "android.test.runner", + "android.test.runner.stubs", "junit", - "android.test.base", + "android.test.base.stubs", ], sdk_version: "current", installable: false, diff --git a/core/api/current.txt b/core/api/current.txt index 245d12df8eca..9881a90ff003 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -20396,23 +20396,23 @@ package android.hardware.fingerprint { method @Deprecated @RequiresPermission(anyOf={android.Manifest.permission.USE_BIOMETRIC, android.Manifest.permission.USE_FINGERPRINT}) public void authenticate(@Nullable android.hardware.fingerprint.FingerprintManager.CryptoObject, @Nullable android.os.CancellationSignal, int, @NonNull android.hardware.fingerprint.FingerprintManager.AuthenticationCallback, @Nullable android.os.Handler); method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean hasEnrolledFingerprints(); method @Deprecated @RequiresPermission(android.Manifest.permission.USE_FINGERPRINT) public boolean isHardwareDetected(); - field public static final int FINGERPRINT_ACQUIRED_GOOD = 0; // 0x0 - field public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3; // 0x3 - field public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2; // 0x2 - field public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1; // 0x1 - field public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5; // 0x5 - field public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4; // 0x4 - field public static final int FINGERPRINT_ERROR_CANCELED = 5; // 0x5 - field public static final int FINGERPRINT_ERROR_HW_NOT_PRESENT = 12; // 0xc - field public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1; // 0x1 - field public static final int FINGERPRINT_ERROR_LOCKOUT = 7; // 0x7 - field public static final int FINGERPRINT_ERROR_LOCKOUT_PERMANENT = 9; // 0x9 - field public static final int FINGERPRINT_ERROR_NO_FINGERPRINTS = 11; // 0xb - field public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4 - field public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3 - field public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2 - field public static final int FINGERPRINT_ERROR_USER_CANCELED = 10; // 0xa - field public static final int FINGERPRINT_ERROR_VENDOR = 8; // 0x8 + field @Deprecated public static final int FINGERPRINT_ACQUIRED_GOOD = 0; // 0x0 + field @Deprecated public static final int FINGERPRINT_ACQUIRED_IMAGER_DIRTY = 3; // 0x3 + field @Deprecated public static final int FINGERPRINT_ACQUIRED_INSUFFICIENT = 2; // 0x2 + field @Deprecated public static final int FINGERPRINT_ACQUIRED_PARTIAL = 1; // 0x1 + field @Deprecated public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 5; // 0x5 + field @Deprecated public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 4; // 0x4 + field @Deprecated public static final int FINGERPRINT_ERROR_CANCELED = 5; // 0x5 + field @Deprecated public static final int FINGERPRINT_ERROR_HW_NOT_PRESENT = 12; // 0xc + field @Deprecated public static final int FINGERPRINT_ERROR_HW_UNAVAILABLE = 1; // 0x1 + field @Deprecated public static final int FINGERPRINT_ERROR_LOCKOUT = 7; // 0x7 + field @Deprecated public static final int FINGERPRINT_ERROR_LOCKOUT_PERMANENT = 9; // 0x9 + field @Deprecated public static final int FINGERPRINT_ERROR_NO_FINGERPRINTS = 11; // 0xb + field @Deprecated public static final int FINGERPRINT_ERROR_NO_SPACE = 4; // 0x4 + field @Deprecated public static final int FINGERPRINT_ERROR_TIMEOUT = 3; // 0x3 + field @Deprecated public static final int FINGERPRINT_ERROR_UNABLE_TO_PROCESS = 2; // 0x2 + field @Deprecated public static final int FINGERPRINT_ERROR_USER_CANCELED = 10; // 0xa + field @Deprecated public static final int FINGERPRINT_ERROR_VENDOR = 8; // 0x8 } @Deprecated public abstract static class FingerprintManager.AuthenticationCallback { @@ -32570,6 +32570,13 @@ package android.os { method public boolean isCharging(); field public static final String ACTION_CHARGING = "android.os.action.CHARGING"; field public static final String ACTION_DISCHARGING = "android.os.action.DISCHARGING"; + field @FlaggedApi("android.os.battery_part_status_api") public static final int BATTERY_CAPACITY_LEVEL_CRITICAL = 1; // 0x1 + field @FlaggedApi("android.os.battery_part_status_api") public static final int BATTERY_CAPACITY_LEVEL_FULL = 5; // 0x5 + field @FlaggedApi("android.os.battery_part_status_api") public static final int BATTERY_CAPACITY_LEVEL_HIGH = 4; // 0x4 + field @FlaggedApi("android.os.battery_part_status_api") public static final int BATTERY_CAPACITY_LEVEL_LOW = 2; // 0x2 + field @FlaggedApi("android.os.battery_part_status_api") public static final int BATTERY_CAPACITY_LEVEL_NORMAL = 3; // 0x3 + field @FlaggedApi("android.os.battery_part_status_api") public static final int BATTERY_CAPACITY_LEVEL_UNKNOWN = 0; // 0x0 + field @FlaggedApi("android.os.battery_part_status_api") public static final int BATTERY_CAPACITY_LEVEL_UNSUPPORTED = -1; // 0xffffffff field public static final int BATTERY_HEALTH_COLD = 7; // 0x7 field public static final int BATTERY_HEALTH_DEAD = 4; // 0x4 field public static final int BATTERY_HEALTH_GOOD = 2; // 0x2 @@ -32594,6 +32601,7 @@ package android.os { field public static final int BATTERY_STATUS_NOT_CHARGING = 4; // 0x4 field public static final int BATTERY_STATUS_UNKNOWN = 1; // 0x1 field public static final String EXTRA_BATTERY_LOW = "battery_low"; + field @FlaggedApi("android.os.battery_part_status_api") public static final String EXTRA_CAPACITY_LEVEL = "android.os.extra.CAPACITY_LEVEL"; field public static final String EXTRA_CHARGING_STATUS = "android.os.extra.CHARGING_STATUS"; field public static final String EXTRA_CYCLE_COUNT = "android.os.extra.CYCLE_COUNT"; field public static final String EXTRA_HEALTH = "health"; @@ -33184,6 +33192,7 @@ package android.os { } public interface IBinder { + method @FlaggedApi("android.os.binder_frozen_state_change_callback") public default void addFrozenStateChangeCallback(@NonNull android.os.IBinder.FrozenStateChangeCallback) throws android.os.RemoteException; method public void dump(@NonNull java.io.FileDescriptor, @Nullable String[]) throws android.os.RemoteException; method public void dumpAsync(@NonNull java.io.FileDescriptor, @Nullable String[]) throws android.os.RemoteException; method @Nullable public String getInterfaceDescriptor() throws android.os.RemoteException; @@ -33192,6 +33201,7 @@ package android.os { method public void linkToDeath(@NonNull android.os.IBinder.DeathRecipient, int) throws android.os.RemoteException; method public boolean pingBinder(); method @Nullable public android.os.IInterface queryLocalInterface(@NonNull String); + method @FlaggedApi("android.os.binder_frozen_state_change_callback") public default boolean removeFrozenStateChangeCallback(@NonNull android.os.IBinder.FrozenStateChangeCallback); method public boolean transact(int, @NonNull android.os.Parcel, @Nullable android.os.Parcel, int) throws android.os.RemoteException; method public boolean unlinkToDeath(@NonNull android.os.IBinder.DeathRecipient, int); field public static final int DUMP_TRANSACTION = 1598311760; // 0x5f444d50 @@ -33209,6 +33219,12 @@ package android.os { method public default void binderDied(@NonNull android.os.IBinder); } + @FlaggedApi("android.os.binder_frozen_state_change_callback") public static interface IBinder.FrozenStateChangeCallback { + method public void onFrozenStateChanged(@NonNull android.os.IBinder, int); + field public static final int STATE_FROZEN = 0; // 0x0 + field public static final int STATE_UNFROZEN = 1; // 0x1 + } + public interface IInterface { method public android.os.IBinder asBinder(); } @@ -36252,9 +36268,9 @@ package android.provider { method @Deprecated public static int getTypeLabelResource(int); field @Deprecated public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/im"; field @Deprecated public static final String CUSTOM_PROTOCOL = "data6"; - field public static final String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX"; - field public static final String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS"; - field public static final String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES"; + field @Deprecated public static final String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX"; + field @Deprecated public static final String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS"; + field @Deprecated public static final String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES"; field @Deprecated public static final String PROTOCOL = "data5"; field @Deprecated public static final int PROTOCOL_AIM = 0; // 0x0 field @Deprecated public static final int PROTOCOL_CUSTOM = -1; // 0xffffffff @@ -36387,9 +36403,9 @@ package android.provider { method @Deprecated public static CharSequence getTypeLabel(android.content.res.Resources, int, @Nullable CharSequence); method @Deprecated public static int getTypeLabelResource(int); field @Deprecated public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/sip_address"; - field public static final String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX"; - field public static final String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS"; - field public static final String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES"; + field @Deprecated public static final String EXTRA_ADDRESS_BOOK_INDEX = "android.provider.extra.ADDRESS_BOOK_INDEX"; + field @Deprecated public static final String EXTRA_ADDRESS_BOOK_INDEX_COUNTS = "android.provider.extra.ADDRESS_BOOK_INDEX_COUNTS"; + field @Deprecated public static final String EXTRA_ADDRESS_BOOK_INDEX_TITLES = "android.provider.extra.ADDRESS_BOOK_INDEX_TITLES"; field @Deprecated public static final String SIP_ADDRESS = "data1"; field @Deprecated public static final int TYPE_HOME = 1; // 0x1 field @Deprecated public static final int TYPE_OTHER = 3; // 0x3 diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 24e73352ff33..84f2ab2f0915 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -380,6 +380,12 @@ package android.os { method @FlaggedApi("android.crashrecovery.flags.enable_crashrecovery") @NonNull public static java.io.File getDataSystemDeDirectory(); } + public class Handler { + method @FlaggedApi("android.os.mainline_vcn_platform_api") public final boolean hasMessagesOrCallbacks(); + method @FlaggedApi("android.os.mainline_vcn_platform_api") public final void removeCallbacksAndEqualMessages(@Nullable Object); + method @FlaggedApi("android.os.mainline_vcn_platform_api") public final void removeEqualMessages(int, @Nullable Object); + } + public class IpcDataCache<Query, Result> { ctor public IpcDataCache(int, @NonNull String, @NonNull String, @NonNull String, @NonNull android.os.IpcDataCache.QueryHandler<Query,Result>); method public void disableForCurrentProcess(); diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 0fd5da738da7..1019ce80c34d 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -3802,6 +3802,7 @@ package android.content { field @FlaggedApi("android.app.ondeviceintelligence.flags.enable_on_device_intelligence") public static final String ON_DEVICE_INTELLIGENCE_SERVICE = "on_device_intelligence"; field public static final String PERMISSION_CONTROLLER_SERVICE = "permission_controller"; field public static final String PERMISSION_SERVICE = "permission"; + field @FlaggedApi("com.android.ranging.flags.ranging_stack_enabled") public static final String RANGING_SERVICE = "ranging"; field public static final String REBOOT_READINESS_SERVICE = "reboot_readiness"; field public static final String ROLLBACK_SERVICE = "rollback"; field public static final String SAFETY_CENTER_SERVICE = "safety_center"; diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS index adeb0451cd43..cd7e40cf174d 100644 --- a/core/java/android/app/OWNERS +++ b/core/java/android/app/OWNERS @@ -112,6 +112,7 @@ per-file *VoiceInteract* = file:/core/java/android/service/voice/OWNERS # Wallpaper per-file *Wallpaper* = file:/core/java/android/service/wallpaper/OWNERS +per-file wallpaper.aconfig = file:/core/java/android/service/wallpaper/OWNERS # WindowManager per-file *Activity* = file:/services/core/java/com/android/server/wm/OWNERS diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING index 2358d67c55e8..5ed1f4e35533 100644 --- a/core/java/android/app/TEST_MAPPING +++ b/core/java/android/app/TEST_MAPPING @@ -16,12 +16,7 @@ }, { "file_patterns": ["(/|^)AppOpsManager.java"], - "name": "CtsAppOpsTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAppOpsTestCases" }, { "file_patterns": ["(/|^)AppOpsManager.java"], @@ -54,12 +49,7 @@ "file_patterns": ["INotificationManager\\.aidl"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.ToastWindowTest" - } - ], + "name": "CtsWindowManagerDeviceWindow_window_toastwindowtest", "file_patterns": ["INotificationManager\\.aidl"] }, { @@ -67,42 +57,15 @@ "file_patterns": ["(/|^)InstantAppResolve[^/]*"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.saveui.AutofillSaveDialogTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], + "name": "CtsAutoFillServiceTestCases_saveui_autofillsavedialogtest", "file_patterns": ["(/|^)Activity.java"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.saveui.PreSimpleSaveActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], + "name": "CtsAutoFillServiceTestCases_saveui_presimplesaveactivitytest", "file_patterns": ["(/|^)Activity.java"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.saveui.SimpleSaveActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - } - ], + "name": "CtsAutoFillServiceTestCases_saveui_simplesaveactivitytest", "file_patterns": ["(/|^)Activity.java"] }, { @@ -119,32 +82,10 @@ }, { "name": "CtsLocalVoiceInteraction", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], "file_patterns": ["(/|^)VoiceInteract[^/]*"] }, { - "name": "CtsOsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.os.cts.StrictModeTest" - } - ], + "name": "CtsOsTestCases_cts_strictmodetest_Presubmit", "file_patterns": ["(/|^)ContextImpl.java"] }, { @@ -153,12 +94,7 @@ }, { "file_patterns": ["(/|^)LocaleManager.java"], - "name": "CtsLocaleManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsLocaleManagerTestCases" }, { "name": "FrameworksCoreTests_keyguard_manager", @@ -173,172 +109,51 @@ ] }, { - "name": "FrameworksCoreGameManagerTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.app" - } - ], + "name": "FrameworksCoreGameManagerTests_android_app", "file_patterns": [ "(/|^)GameManager[^/]*", "(/|^)GameMode[^/]*" ] }, { - "name": "HdmiCecTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.hardware.hdmi" - } - ], + "name": "HdmiCecTests_hardware_hdmi", "file_patterns": [ "(/|^)DeviceFeature[^/]*", "(/|^)Hdmi[^/]*" ] }, { - "name": "CtsWindowManagerDeviceActivity", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceActivity_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceAm", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceAm_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceBackNavigation", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceBackNavigation_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceDisplay", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceDisplay_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceKeyguard", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceKeyguard_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceInsets", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceInsets_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceTaskFragment", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceTaskFragment_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceWindow_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { - "name": "CtsWindowManagerDeviceOther", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.content.wm.cts" - } - ], + "name": "CtsWindowManagerDeviceOther_wm_cts", "file_patterns": ["(/|^)ContextImpl.java"] }, { diff --git a/core/java/android/app/time/TEST_MAPPING b/core/java/android/app/time/TEST_MAPPING index 7673acacbfbe..9e416385bbfb 100644 --- a/core/java/android/app/time/TEST_MAPPING +++ b/core/java/android/app/time/TEST_MAPPING @@ -1,31 +1,13 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.app." - } - ] + "name": "FrameworksTimeCoreTests_android_app" }, { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { - "name": "FrameworksTimeServicesTests", - "options": [ - { - "include-filter": "com.android.server.timezonedetector." - }, - { - "include-filter": "com.android.server.timedetector." - } - ] + "name": "FrameworksTimeServicesTests_time" } ] } diff --git a/core/java/android/app/timedetector/TEST_MAPPING b/core/java/android/app/timedetector/TEST_MAPPING index c7ca6a230d43..d876308f4a9b 100644 --- a/core/java/android/app/timedetector/TEST_MAPPING +++ b/core/java/android/app/timedetector/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.app." - } - ] + "name": "FrameworksTimeCoreTests_android_app" }, { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { - "name": "FrameworksTimeServicesTests", - "options": [ - { - "include-filter": "com.android.server.timedetector." - } - ] + "name": "FrameworksTimeServicesTests_server_timedetector" } ] } diff --git a/core/java/android/app/timezonedetector/TEST_MAPPING b/core/java/android/app/timezonedetector/TEST_MAPPING index c8d0bb2306cd..dca7bbf17ab9 100644 --- a/core/java/android/app/timezonedetector/TEST_MAPPING +++ b/core/java/android/app/timezonedetector/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.app." - } - ] + "name": "FrameworksTimeCoreTests_android_app" }, { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { - "name": "FrameworksTimeServicesTests", - "options": [ - { - "include-filter": "com.android.server.timezonedetector." - } - ] + "name": "FrameworksTimeServicesTests_server_timezonedetector" } ] } diff --git a/core/java/android/app/trust/TEST_MAPPING b/core/java/android/app/trust/TEST_MAPPING index 23923eeb83ee..b0dd55100c8a 100644 --- a/core/java/android/app/trust/TEST_MAPPING +++ b/core/java/android/app/trust/TEST_MAPPING @@ -1,28 +1,12 @@ { "presubmit": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ], "trust-tablet": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ] }
\ No newline at end of file diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 8365840b1efb..4050b8231f14 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -4309,6 +4309,7 @@ public abstract class Context { SECURITY_STATE_SERVICE, //@hide: ECM_ENHANCED_CONFIRMATION_SERVICE, CONTACT_KEYS_SERVICE, + RANGING_SERVICE, }) @Retention(RetentionPolicy.SOURCE) @@ -6376,6 +6377,17 @@ public abstract class Context { /** * Use with {@link #getSystemService(String)} to retrieve a + * {@link android.ranging.RangingManager}. + * + * @see #getSystemService(String) + * @hide + */ + @FlaggedApi(com.android.ranging.flags.Flags.FLAG_RANGING_STACK_ENABLED) + @SystemApi + public static final String RANGING_SERVICE = "ranging"; + + /** + * Use with {@link #getSystemService(String)} to retrieve a * {@link android.app.DreamManager} for controlling Dream states. * * @see #getSystemService(String) diff --git a/core/java/android/content/TEST_MAPPING b/core/java/android/content/TEST_MAPPING index e353a0107bab..8d90b021fbfc 100644 --- a/core/java/android/content/TEST_MAPPING +++ b/core/java/android/content/TEST_MAPPING @@ -1,24 +1,7 @@ { "presubmit": [ { - "name": "CtsOsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.os.cts.StrictModeTest" - } - ], + "name": "CtsOsTestCases_cts_strictmodetest_Presubmit", "file_patterns": ["(/|^)Context.java", "(/|^)ContextWrapper.java"] }, { diff --git a/core/java/android/content/om/TEST_MAPPING b/core/java/android/content/om/TEST_MAPPING index 82c47a03863b..b36c8958ea71 100644 --- a/core/java/android/content/om/TEST_MAPPING +++ b/core/java/android/content/om/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.om" - } - ] + "name": "FrameworksServicesTests_server_om" }, { "name": "OverlayDeviceTests" diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java index 65ab379b182b..bca30b4fec5a 100644 --- a/core/java/android/content/pm/PackageManager.java +++ b/core/java/android/content/pm/PackageManager.java @@ -8842,6 +8842,7 @@ public abstract class PackageManager { try { ParsedPackage pp = parser2.parsePackage(apkFile, parserFlags, false); + pp.hideAsFinal(); return PackageInfoCommonUtils.generate(pp, flagsBits, UserHandle.myUserId()); } catch (PackageParserException e) { diff --git a/core/java/android/content/pm/verify/domain/TEST_MAPPING b/core/java/android/content/pm/verify/domain/TEST_MAPPING index 8a1982a339ea..db98c402eeeb 100644 --- a/core/java/android/content/pm/verify/domain/TEST_MAPPING +++ b/core/java/android/content/pm/verify/domain/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "PackageManagerServiceUnitTests", - "options": [ - { - "include-filter": "com.android.server.pm.test.verify.domain" - } - ] + "name": "PackageManagerServiceUnitTests_verify_domain" }, { "name": "CtsDomainVerificationDeviceStandaloneTestCases" diff --git a/core/java/android/net/TEST_MAPPING b/core/java/android/net/TEST_MAPPING index 3df56162bd2c..ea509bb24f0a 100644 --- a/core/java/android/net/TEST_MAPPING +++ b/core/java/android/net/TEST_MAPPING @@ -19,21 +19,7 @@ ], "presubmit": [ { - "name": "FrameworksCoreTests", - "options": [ - { - "include-filter": "android.net" - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_android_net" } ] } diff --git a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java index 6f11d3ae661c..af93c964a8ba 100644 --- a/core/java/android/net/vcn/VcnGatewayConnectionConfig.java +++ b/core/java/android/net/vcn/VcnGatewayConnectionConfig.java @@ -35,7 +35,6 @@ import android.os.PersistableBundle; import android.util.ArraySet; import com.android.internal.annotations.VisibleForTesting; -import com.android.internal.util.ArrayUtils; import com.android.internal.util.Preconditions; import com.android.server.vcn.util.PersistableBundleUtils; @@ -434,7 +433,14 @@ public final class VcnGatewayConnectionConfig { @NonNull public int[] getExposedCapabilities() { // Sorted set guarantees ordering - return ArrayUtils.convertToIntArray(new ArrayList<>(mExposedCapabilities)); + final int[] caps = new int[mExposedCapabilities.size()]; + + int i = 0; + for (int c : mExposedCapabilities) { + caps[i++] = c; + } + + return caps; } /** diff --git a/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java b/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java index a97563724e50..e1d1b3c65c99 100644 --- a/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java +++ b/core/java/android/net/vcn/VcnUnderlyingNetworkSpecifier.java @@ -24,7 +24,6 @@ import android.os.Parcelable; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; -import com.android.internal.util.ArrayUtils; import java.util.Arrays; import java.util.Objects; @@ -114,8 +113,13 @@ public final class VcnUnderlyingNetworkSpecifier extends NetworkSpecifier implem @Override public boolean canBeSatisfiedBy(NetworkSpecifier other) { if (other instanceof TelephonyNetworkSpecifier) { - return ArrayUtils.contains( - mSubIds, ((TelephonyNetworkSpecifier) other).getSubscriptionId()); + final int targetSubId = ((TelephonyNetworkSpecifier) other).getSubscriptionId(); + for (int subId : mSubIds) { + if (targetSubId == subId) { + return true; + } + } + return false; } // TODO(b/180140053): Allow matching against WifiNetworkAgentSpecifier diff --git a/core/java/android/os/BatteryManager.java b/core/java/android/os/BatteryManager.java index f3efd89d4bc3..8b267bf28c7e 100644 --- a/core/java/android/os/BatteryManager.java +++ b/core/java/android/os/BatteryManager.java @@ -141,6 +141,7 @@ public class BatteryManager { /** * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}: * integer containing the charge counter present in the battery. + * It shows the available battery power in µAh * {@hide} */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @@ -166,6 +167,76 @@ public class BatteryManager { public static final String EXTRA_CHARGING_STATUS = "android.os.extra.CHARGING_STATUS"; /** + * Extra for {@link android.content.Intent#ACTION_BATTERY_CHANGED}: + * Int value representing the battery's capacity level. These constants are key indicators of + * battery status and system capabilities, guiding power management decisions for both the + * system and apps: + * {@link #BATTERY_CAPACITY_LEVEL_UNSUPPORTED}: Feature not supported on this device. + * {@link #BATTERY_CAPACITY_LEVEL_UNKNOWN}: Battery status is unavailable or uninitialized. + * {@link #BATTERY_CAPACITY_LEVEL_CRITICAL}: Battery is critically low and the Android + * framework has been notified to schedule a shutdown by this value + * {@link #BATTERY_CAPACITY_LEVEL_LOW}: Android framework must limit background jobs to + * avoid impacting charging speed + * {@link #BATTERY_CAPACITY_LEVEL_NORMAL}: Battery level and charging rates are normal, + * battery temperature is within normal range and adapter power is enough to charge the + * battery at an acceptable rate. Android framework can run light background tasks without + * affecting charging performance severely. + * {@link #BATTERY_CAPACITY_LEVEL_HIGH}: Battery level is high, battery temperature is + * within normal range and adapter power is enough to charge the battery at an acceptable + * rate while running background loads. Android framework can run background tasks without + * affecting charging or battery performance. + * {@link #BATTERY_CAPACITY_LEVEL_FULL}: The battery is full, battery temperature is + * within normal range and adapter power is enough to sustain running background loads. + * Android framework can run background tasks without affecting the battery level or + * battery performance. + */ + + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final String EXTRA_CAPACITY_LEVEL = "android.os.extra.CAPACITY_LEVEL"; + + /** + * Battery capacity level is unsupported. @see EXTRA_CAPACITY_LEVEL + */ + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final int BATTERY_CAPACITY_LEVEL_UNSUPPORTED = -1; + + /** + * Battery capacity level is unknown. @see EXTRA_CAPACITY_LEVEL + */ + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final int BATTERY_CAPACITY_LEVEL_UNKNOWN = 0; + + /** + * Battery capacity level is critical. @see EXTRA_CAPACITY_LEVEL + */ + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final int BATTERY_CAPACITY_LEVEL_CRITICAL = 1; + + /** + * Battery capacity level is low. @see EXTRA_CAPACITY_LEVEL + */ + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final int BATTERY_CAPACITY_LEVEL_LOW = 2; + + /** + * Battery capacity level is normal. @see EXTRA_CAPACITY_LEVEL + */ + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final int BATTERY_CAPACITY_LEVEL_NORMAL = 3; + + /** + * Battery capacity level is high. @see EXTRA_CAPACITY_LEVEL + */ + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final int BATTERY_CAPACITY_LEVEL_HIGH = 4; + + /** + * Battery capacity level is full. @see EXTRA_CAPACITY_LEVEL + */ + @FlaggedApi(FLAG_BATTERY_PART_STATUS_API) + public static final int BATTERY_CAPACITY_LEVEL_FULL = 5; + + /** * Extra for {@link android.content.Intent#ACTION_BATTERY_LEVEL_CHANGED}: * Contains list of Bundles representing battery events * @hide diff --git a/core/java/android/os/BinderProxy.java b/core/java/android/os/BinderProxy.java index c22f46cdc2b5..80546cd6770f 100644 --- a/core/java/android/os/BinderProxy.java +++ b/core/java/android/os/BinderProxy.java @@ -650,13 +650,13 @@ public final class BinderProxy implements IBinder { * weakly referenced by JNI so the strong references here are needed to keep the callbacks * around until the proxy is GC'ed. */ - private List<IFrozenStateChangeCallback> mFrozenStateChangeCallbacks = + private List<FrozenStateChangeCallback> mFrozenStateChangeCallbacks = Collections.synchronizedList(new ArrayList<>()); /** - * See {@link IBinder#addFrozenStateChangeCallback(IFrozenStateChangeCallback)} + * See {@link IBinder#addFrozenStateChangeCallback(FrozenStateChangeCallback)} */ - public void addFrozenStateChangeCallback(IFrozenStateChangeCallback callback) + public void addFrozenStateChangeCallback(FrozenStateChangeCallback callback) throws RemoteException { addFrozenStateChangeCallbackNative(callback); mFrozenStateChangeCallbacks.add(callback); @@ -665,16 +665,16 @@ public final class BinderProxy implements IBinder { /** * See {@link IBinder#removeFrozenStateChangeCallback} */ - public boolean removeFrozenStateChangeCallback(IFrozenStateChangeCallback callback) { + public boolean removeFrozenStateChangeCallback(FrozenStateChangeCallback callback) { mFrozenStateChangeCallbacks.remove(callback); return removeFrozenStateChangeCallbackNative(callback); } - private native void addFrozenStateChangeCallbackNative(IFrozenStateChangeCallback callback) + private native void addFrozenStateChangeCallbackNative(FrozenStateChangeCallback callback) throws RemoteException; private native boolean removeFrozenStateChangeCallbackNative( - IFrozenStateChangeCallback callback); + FrozenStateChangeCallback callback); /** * Perform a dump on the remote object @@ -762,10 +762,9 @@ public final class BinderProxy implements IBinder { } private static void invokeFrozenStateChangeCallback( - IFrozenStateChangeCallback callback, IBinder binderProxy, int stateIndex) { + FrozenStateChangeCallback callback, IBinder binderProxy, int stateIndex) { try { - callback.onFrozenStateChanged(binderProxy, - IFrozenStateChangeCallback.State.values()[stateIndex]); + callback.onFrozenStateChanged(binderProxy, stateIndex); } catch (RuntimeException exc) { Log.w("BinderNative", "Uncaught exception from frozen state change callback", exc); diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java index 80f39bfbdc21..d0828c384664 100644 --- a/core/java/android/os/Handler.java +++ b/core/java/android/os/Handler.java @@ -16,8 +16,10 @@ package android.os; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SystemApi; import android.compat.annotation.UnsupportedAppUsage; import android.util.Log; import android.util.Printer; @@ -819,16 +821,25 @@ public class Handler { } /** + * WARNING: This API is dangerous because if the implementation + * of equals() is broken, it would delete unrelated events. For example, + * if object.equals() always returns true, it'd remove all messages. + * + * For this reason, never expose this API to non-platform code. i.e. + * this shouldn't be exposed to SystemApi.PRIVILEGED_APPS. + * * Remove any pending posts of messages with code 'what' and whose obj is * 'object' that are in the message queue. If <var>object</var> is null, * all messages will be removed. - * <p> - * Similar to {@link #removeMessages(int, Object)} but uses object equality + * + * <p>Similar to {@link #removeMessages(int, Object)} but uses object equality * ({@link Object#equals(Object)}) instead of reference equality (==) in * determining whether object is the message's obj'. * *@hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API) public final void removeEqualMessages(int what, @Nullable Object object) { mQueue.removeEqualMessages(this, what, disallowNullArgumentIfShared(object)); } @@ -843,12 +854,25 @@ public class Handler { } /** + * WARNING: This API is dangerous because if the implementation + * of equals() is broken, it would delete unrelated events. For example, + * if object.equals() always returns true, it'd remove all messages. + * + * For this reason, never expose this API to non-platform code. i.e. + * this shouldn't be exposed to SystemApi.PRIVILEGED_APPS. + * * Remove any pending posts of callbacks and sent messages whose * <var>obj</var> is <var>token</var>. If <var>token</var> is null, * all callbacks and messages will be removed. * + * <p>Similar to {@link #removeCallbacksAndMessages(Object)} but uses object + * equality ({@link Object#equals(Object)}) instead of reference equality (==) in + * determining whether object is the message's obj'. + * *@hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API) public final void removeCallbacksAndEqualMessages(@Nullable Object token) { mQueue.removeCallbacksAndEqualMessages(this, disallowNullArgumentIfShared(token)); } @@ -864,6 +888,8 @@ public class Handler { * Return whether there are any messages or callbacks currently scheduled on this handler. * @hide */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @FlaggedApi(android.os.Flags.FLAG_MAINLINE_VCN_PLATFORM_API) public final boolean hasMessagesOrCallbacks() { return mQueue.hasMessages(this); } diff --git a/core/java/android/os/IBinder.java b/core/java/android/os/IBinder.java index 8185e8e542e1..a997f4c86704 100644 --- a/core/java/android/os/IBinder.java +++ b/core/java/android/os/IBinder.java @@ -16,11 +16,15 @@ package android.os; +import android.annotation.FlaggedApi; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import java.io.FileDescriptor; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; /** * Base interface for a remotable object, the core part of a lightweight @@ -377,9 +381,24 @@ public interface IBinder { */ public boolean unlinkToDeath(@NonNull DeathRecipient recipient, int flags); - /** @hide */ - interface IFrozenStateChangeCallback { - enum State {FROZEN, UNFROZEN}; + /** + * A callback interface for receiving frozen state change events. + */ + @FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK) + interface FrozenStateChangeCallback { + /** + * @hide + */ + @IntDef(prefix = {"STATE_"}, value = { + STATE_FROZEN, + STATE_UNFROZEN, + }) + @Retention(RetentionPolicy.SOURCE) + @interface State { + } + + int STATE_FROZEN = 0; + int STATE_UNFROZEN = 1; /** * Interface for receiving a callback when the process hosting an IBinder @@ -387,13 +406,13 @@ public interface IBinder { * @param who The IBinder whose hosting process has changed state. * @param state The latest state. */ - void onFrozenStateChanged(@NonNull IBinder who, State state); + void onFrozenStateChanged(@NonNull IBinder who, @State int state); } /** - * {@link addFrozenStateChangeCallback} provides a callback mechanism to notify about process - * frozen/unfrozen events. Upon registration and any subsequent state changes, the callback is - * invoked with the latest process frozen state. + * This method provides a callback mechanism to notify about process frozen/unfrozen events. + * Upon registration and any subsequent state changes, the callback is invoked with the latest + * process frozen state. * * <p>If the listener process (the one using this API) is itself frozen, state change events * might be combined into a single one with the latest frozen state. This single event would @@ -410,19 +429,19 @@ public interface IBinder { * * <p>@throws {@link UnsupportedOperationException} if the kernel binder driver does not support * this feature. - * @hide */ - default void addFrozenStateChangeCallback(@NonNull IFrozenStateChangeCallback callback) + @FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK) + default void addFrozenStateChangeCallback(@NonNull FrozenStateChangeCallback callback) throws RemoteException { throw new UnsupportedOperationException(); } /** - * Unregister a {@link IFrozenStateChangeCallback}. The callback will no longer be invoked when + * Unregister a {@link FrozenStateChangeCallback}. The callback will no longer be invoked when * the hosting process changes its frozen state. - * @hide */ - default boolean removeFrozenStateChangeCallback(@NonNull IFrozenStateChangeCallback callback) { + @FlaggedApi(Flags.FLAG_BINDER_FROZEN_STATE_CHANGE_CALLBACK) + default boolean removeFrozenStateChangeCallback(@NonNull FrozenStateChangeCallback callback) { throw new UnsupportedOperationException(); } } diff --git a/core/java/android/os/TEST_MAPPING b/core/java/android/os/TEST_MAPPING index ce8a58081782..7c36cb91db93 100644 --- a/core/java/android/os/TEST_MAPPING +++ b/core/java/android/os/TEST_MAPPING @@ -38,33 +38,15 @@ }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "BugreportManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "BugreportManagerTestCases_android_server_os" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "CtsBugreportTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsBugreportTestCases_android_server_os" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "ShellTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ShellTests_android_server_os" }, { "file_patterns": [ @@ -99,12 +81,7 @@ "Parcel\\.java", "[^/]*Bundle[^/]*\\.java" ], - "name": "FrameworksMockingCoreTests", - "options": [ - { "include-filter": "android.os.BundleRecyclingTest"}, - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "FrameworksMockingCoreTests_os_bundlerecyclingtest" }, { "file_patterns": [ @@ -116,12 +93,7 @@ }, { "file_patterns": ["SharedMemory[^/]*\\.java"], - "name": "CtsOsTestCases", - "options": [ - { - "include-filter": "android.os.cts.SharedMemoryTest" - } - ] + "name": "CtsOsTestCases_cts_sharedmemorytest" }, { "file_patterns": ["Environment[^/]*\\.java"], diff --git a/core/java/android/os/flags.aconfig b/core/java/android/os/flags.aconfig index 11b1b08b787d..5d2e64d9ef07 100644 --- a/core/java/android/os/flags.aconfig +++ b/core/java/android/os/flags.aconfig @@ -169,6 +169,14 @@ flag { } flag { + name: "binder_frozen_state_change_callback" + is_exported: true + namespace: "system_performance" + description: "Guards the frozen state change callback API." + bug: "361157077" +} + +flag { name: "message_queue_tail_tracking" namespace: "system_performance" description: "track tail of message queue." @@ -209,3 +217,11 @@ flag { description: "Tracing using Perfetto SDK." bug: "303199244" } + +flag { + name: "mainline_vcn_platform_api" + namespace: "vcn" + description: "Expose platform APIs to mainline VCN" + is_exported: true + bug: "366598445" +} diff --git a/core/java/android/permission/TEST_MAPPING b/core/java/android/permission/TEST_MAPPING index b317b80d5677..3e5a131fbdc1 100644 --- a/core/java/android/permission/TEST_MAPPING +++ b/core/java/android/permission/TEST_MAPPING @@ -6,26 +6,10 @@ ], "postsubmit": [ { - "name": "CtsVirtualDevicesAudioTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.audio.VirtualAudioPermissionTest" - } - ] + "name": "CtsVirtualDevicesAudioTestCases_audio_virtualaudiopermissiontest" }, { - "name": "CtsVirtualDevicesAppLaunchTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.applaunch.VirtualDevicePermissionTest" - } - ] + "name": "CtsVirtualDevicesAppLaunchTestCases_applaunch_virtualdevicepermissiontest" } ] } diff --git a/core/java/android/print/TEST_MAPPING b/core/java/android/print/TEST_MAPPING index 4fa882265e53..1033b1a86edb 100644 --- a/core/java/android/print/TEST_MAPPING +++ b/core/java/android/print/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPrintTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "CtsPrintTestCases_Presubmit" } ] } diff --git a/core/java/android/provider/TEST_MAPPING b/core/java/android/provider/TEST_MAPPING index 2eb285dda0a2..a6fe3016e8ba 100644 --- a/core/java/android/provider/TEST_MAPPING +++ b/core/java/android/provider/TEST_MAPPING @@ -24,12 +24,7 @@ "name": "SettingsProviderTest" }, { - "name": "CtsPackageManagerHostTestCases", - "options": [ - { - "include-filter": "android.appsecurity.cts.ReadableSettingsFieldsTest" - } - ] + "name": "CtsPackageManagerHostTestCases_cts_readablesettingsfieldstest" } ], "postsubmit": [ diff --git a/core/java/android/security/TEST_MAPPING b/core/java/android/security/TEST_MAPPING index 5a679b1a2bf7..e1c7f3c2f3d3 100644 --- a/core/java/android/security/TEST_MAPPING +++ b/core/java/android/security/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsSecurityTestCases", - "options": [ - { - "include-filter": "android.security.cts.FileIntegrityManagerTest" - } - ], + "name": "CtsSecurityTestCases_cts_fileintegritymanagertest", "file_patterns": [ "FileIntegrityManager\\.java", "IFileIntegrityService\\.aidl" diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig index f6f0eff918e3..a86c961e6785 100644 --- a/core/java/android/security/flags.aconfig +++ b/core/java/android/security/flags.aconfig @@ -99,3 +99,10 @@ flag { description: "Causes TrustManagerService to listen for credential attempts and ignore reports from upstream" bug: "323086607" } + +flag { + name: "clear_strong_auth_on_add_primary_credential" + namespace: "biometrics" + description: "Clear StrongAuth on add credential" + bug: "320817991" +} diff --git a/core/java/android/service/notification/TEST_MAPPING b/core/java/android/service/notification/TEST_MAPPING index 468c4518602e..dc7129cde5e5 100644 --- a/core/java/android/service/notification/TEST_MAPPING +++ b/core/java/android/service/notification/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "CtsNotificationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsNotificationTestCases_notification" }, { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "FrameworksUiServicesTests_notification" } ], "postsubmit": [ diff --git a/core/java/android/service/quicksettings/TEST_MAPPING b/core/java/android/service/quicksettings/TEST_MAPPING index 2d45c5b252cc..986dc5fd2ba9 100644 --- a/core/java/android/service/quicksettings/TEST_MAPPING +++ b/core/java/android/service/quicksettings/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTileServiceTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTileServiceTestCases" } ] }
\ No newline at end of file diff --git a/core/java/android/service/timezone/TEST_MAPPING b/core/java/android/service/timezone/TEST_MAPPING index bf46ff2ffe06..2071717e5f60 100644 --- a/core/java/android/service/timezone/TEST_MAPPING +++ b/core/java/android/service/timezone/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksTimeCoreTests", - "options": [ - { - "include-filter": "android.service." - } - ] + "name": "FrameworksTimeCoreTests_android_service" }, { "name": "CtsLocationTimeZoneManagerHostTest" diff --git a/core/java/android/speech/TEST_MAPPING b/core/java/android/speech/TEST_MAPPING index 7b125c2b0851..cb490f5b62d4 100644 --- a/core/java/android/speech/TEST_MAPPING +++ b/core/java/android/speech/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsVoiceRecognitionTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceRecognitionTestCases" } ] } diff --git a/core/java/android/text/TEST_MAPPING b/core/java/android/text/TEST_MAPPING index c9bd2cacb138..9f8a72cb5975 100644 --- a/core/java/android/text/TEST_MAPPING +++ b/core/java/android/text/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index c30212657c57..3e1d93c3133c 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -521,8 +521,6 @@ public final class PointerIcon implements Parcelable { // Assumes they have the exact duration. mDurationPerFrame = animationDrawable.getDuration(0); mBitmapFrames = new Bitmap[frames - 1]; - final int width = drawable.getIntrinsicWidth(); - final int height = drawable.getIntrinsicHeight(); final boolean isVectorAnimation = drawable instanceof VectorDrawable; mDrawNativeDropShadow = isVectorAnimation; for (int i = 1; i < frames; ++i) { @@ -537,12 +535,6 @@ public final class PointerIcon implements Parcelable { + "is a different type from the others. All frames should be the " + "same type."); } - if (drawableFrame.getIntrinsicWidth() != width || - drawableFrame.getIntrinsicHeight() != height) { - throw new IllegalArgumentException("The bitmap size of " + i + "-th frame " - + "is different. All frames should have the exact same size and " - + "share the same hotspot."); - } if (isVectorAnimation) { drawableFrame = getBitmapDrawableFromVectorDrawable(resources, (VectorDrawable) drawableFrame, pointerScale); diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index 0bdb4ad645f3..505a82a1518f 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -3491,7 +3491,7 @@ public final class SurfaceControl implements Parcelable { checkPreconditions(sc); if (SurfaceControlRegistry.sCallStackDebuggingEnabled) { SurfaceControlRegistry.getProcessInstance().checkCallStackDebugging( - "reparent", this, sc, + "setColor", this, sc, "r=" + color[0] + " g=" + color[1] + " b=" + color[2]); } nativeSetColor(mNativeObject, sc.mNativeObject, color); diff --git a/core/java/android/view/TEST_MAPPING b/core/java/android/view/TEST_MAPPING index db3590814e08..ac6cd02b58aa 100644 --- a/core/java/android/view/TEST_MAPPING +++ b/core/java/android/view/TEST_MAPPING @@ -4,39 +4,11 @@ "name": "CtsAccelerationTestCases" }, { - "name": "CtsOsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.os.cts.StrictModeTest" - } - ], + "name": "CtsOsTestCases_cts_strictmodetest_Presubmit", "file_patterns": ["(/|^)ViewConfiguration.java", "(/|^)GestureDetector.java"] }, { - "name": "CtsViewReceiveContentTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ], + "name": "CtsViewReceiveContentTestCases_Presubmit", "file_patterns": ["ContentInfo\\.java", "OnReceiveContentListener\\.java", "View\\.java"] } ], diff --git a/core/java/android/view/inputmethod/TEST_MAPPING b/core/java/android/view/inputmethod/TEST_MAPPING index ad59463ea1f1..989b686d6281 100644 --- a/core/java/android/view/inputmethod/TEST_MAPPING +++ b/core/java/android/view/inputmethod/TEST_MAPPING @@ -1,21 +1,7 @@ { "presubmit": [ { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.inline" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsAutoFillServiceTestCases_cts_inline_ExcludeAppModeFull" } ] } diff --git a/core/java/android/view/textclassifier/TEST_MAPPING b/core/java/android/view/textclassifier/TEST_MAPPING index 050c65191cad..bc7f3b0e2dc1 100644 --- a/core/java/android/view/textclassifier/TEST_MAPPING +++ b/core/java/android/view/textclassifier/TEST_MAPPING @@ -4,20 +4,10 @@ "name": "FrameworksCoreTests_textclassifier" }, { - "name": "CtsTextClassifierTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTextClassifierTestCases" }, { - "name": "TextClassifierServiceTest", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TextClassifierServiceTest" } ] } diff --git a/core/java/android/webkit/TEST_MAPPING b/core/java/android/webkit/TEST_MAPPING index 07f438329e43..38580595dc2d 100644 --- a/core/java/android/webkit/TEST_MAPPING +++ b/core/java/android/webkit/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "CtsWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsWebkitTestCases" }, { - "name": "CtsSdkSandboxWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSdkSandboxWebkitTestCases" }, { - "name": "CtsHostsideWebViewTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsHostsideWebViewTests" }, { "name": "GtsWebViewTestCases", diff --git a/core/java/android/widget/TEST_MAPPING b/core/java/android/widget/TEST_MAPPING index bc71bee33d06..624fa864aea6 100644 --- a/core/java/android/widget/TEST_MAPPING +++ b/core/java/android/widget/TEST_MAPPING @@ -10,52 +10,17 @@ "file_patterns": ["Toast\\.java"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.ToastWindowTest" - } - ], + "name": "CtsWindowManagerDeviceWindow_window_toastwindowtest", "file_patterns": ["Toast\\.java"] }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.dropdown.LoginActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - } - ] + "name": "CtsAutoFillServiceTestCases_dropdown_loginactivitytest" }, { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.dropdown.CheckoutActivityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.AppModeFull" - } - ] + "name": "CtsAutoFillServiceTestCases_dropdown_checkoutactivitytest" }, { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/core/java/android/widget/inline/TEST_MAPPING b/core/java/android/widget/inline/TEST_MAPPING index 82c6f61c3486..eb412f110def 100644 --- a/core/java/android/widget/inline/TEST_MAPPING +++ b/core/java/android/widget/inline/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit-large": [ { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-filter": "android.autofillservice.cts.inline" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsAutoFillServiceTestCases_cts_inline" } ] } diff --git a/core/java/com/android/internal/infra/TEST_MAPPING b/core/java/com/android/internal/infra/TEST_MAPPING index 35f0553d41d7..092aa20ba730 100644 --- a/core/java/com/android/internal/infra/TEST_MAPPING +++ b/core/java/com/android/internal/infra/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsRoleTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsRoleTestCases" }, { "name": "CtsPermissionTestCases_Platform" diff --git a/core/java/com/android/internal/os/TEST_MAPPING b/core/java/com/android/internal/os/TEST_MAPPING index 467cd77f15b4..83773e251a9e 100644 --- a/core/java/com/android/internal/os/TEST_MAPPING +++ b/core/java/com/android/internal/os/TEST_MAPPING @@ -49,12 +49,7 @@ ], "postsubmit": [ { - "name": "PowerStatsTests", - "options": [ - { - "include-filter": "com.android.server.power.stats.BstatsCpuTimesValidationTest" - } - ], + "name": "PowerStatsTests_stats_bstatscputimesvalidationtest", "file_patterns": [ "Kernel[^/]*\\.java" ] diff --git a/core/jni/Android.bp b/core/jni/Android.bp index 17c4ee96c68a..387180600953 100644 --- a/core/jni/Android.bp +++ b/core/jni/Android.bp @@ -288,7 +288,6 @@ cc_library_shared_for_libandroid_runtime { "libasync_safe", "libbinderthreadstateutils", "libdmabufinfo", - "libgif", "libgui_window_info_static", "libkernelconfigs", "libseccomp_policy", diff --git a/core/jni/android_util_Binder.cpp b/core/jni/android_util_Binder.cpp index 921b77d61f4d..ef50a95b6287 100644 --- a/core/jni/android_util_Binder.cpp +++ b/core/jni/android_util_Binder.cpp @@ -1747,9 +1747,9 @@ static const JNINativeMethod gBinderProxyMethods[] = { {"linkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath}, {"unlinkToDeathNative", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath}, {"addFrozenStateChangeCallbackNative", - "(Landroid/os/IBinder$IFrozenStateChangeCallback;)V", (void*)android_os_BinderProxy_addFrozenStateChangeCallback}, + "(Landroid/os/IBinder$FrozenStateChangeCallback;)V", (void*)android_os_BinderProxy_addFrozenStateChangeCallback}, {"removeFrozenStateChangeCallbackNative", - "(Landroid/os/IBinder$IFrozenStateChangeCallback;)Z", (void*)android_os_BinderProxy_removeFrozenStateChangeCallback}, + "(Landroid/os/IBinder$FrozenStateChangeCallback;)Z", (void*)android_os_BinderProxy_removeFrozenStateChangeCallback}, {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer}, {"getExtension", "()Landroid/os/IBinder;", (void*)android_os_BinderProxy_getExtension}, }; @@ -1774,7 +1774,7 @@ static int int_register_android_os_BinderProxy(JNIEnv* env) "(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V"); gBinderProxyOffsets.mInvokeFrozenStateChangeCallback = GetStaticMethodIDOrDie(env, clazz, "invokeFrozenStateChangeCallback", - "(Landroid/os/IBinder$IFrozenStateChangeCallback;Landroid/os/" + "(Landroid/os/IBinder$FrozenStateChangeCallback;Landroid/os/" "IBinder;I)V"); gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J"); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java index 516253b0ebff..44beb55b77db 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java @@ -19,18 +19,18 @@ package com.android.server.broadcastradio; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doThrow; -import static com.google.common.truth.Truth.assertWithMessage; - import static org.mockito.Mockito.when; import android.app.ActivityManager; -import android.app.compat.CompatChanges; import android.os.Binder; import android.os.UserHandle; import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; +import com.google.common.truth.Expect; + import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.mockito.Mock; @@ -41,36 +41,40 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe private static final int USER_ID_1 = 11; private static final int USER_ID_2 = 12; + private RadioServiceUserController mUserController; @Mock private UserHandle mUserHandleMock; + @Rule + public final Expect expect = Expect.create(); + @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(ActivityManager.class).spyStatic(Binder.class) - .spyStatic(CompatChanges.class); + builder.spyStatic(ActivityManager.class).spyStatic(Binder.class); } @Before public void setUp() { doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); doReturn(USER_ID_1).when(() -> ActivityManager.getCurrentUser()); + mUserController = new RadioServiceUserControllerImpl(); } @Test public void isCurrentOrSystemUser_forCurrentUser_returnsFalse() { when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); - assertWithMessage("Current user") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue(); + expect.withMessage("Current user") + .that(mUserController.isCurrentOrSystemUser()).isTrue(); } @Test public void isCurrentOrSystemUser_forNonCurrentUser_returnsFalse() { when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_2); - assertWithMessage("Non-current user") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse(); + expect.withMessage("Non-current user") + .that(mUserController.isCurrentOrSystemUser()).isFalse(); } @Test @@ -78,8 +82,8 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); when(mUserHandleMock.getIdentifier()).thenReturn(UserHandle.USER_SYSTEM); - assertWithMessage("System user") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isTrue(); + expect.withMessage("System user") + .that(mUserController.isCurrentOrSystemUser()).isTrue(); } @Test @@ -87,14 +91,14 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser); - assertWithMessage("User when activity manager fails") - .that(RadioServiceUserController.isCurrentOrSystemUser()).isFalse(); + expect.withMessage("User when activity manager fails") + .that(mUserController.isCurrentOrSystemUser()).isFalse(); } @Test public void getCurrentUser() { - assertWithMessage("Current user") - .that(RadioServiceUserController.getCurrentUser()).isEqualTo(USER_ID_1); + expect.withMessage("Current user") + .that(mUserController.getCurrentUser()).isEqualTo(USER_ID_1); } @Test @@ -102,7 +106,15 @@ public final class RadioServiceUserControllerTest extends ExtendedRadioMockitoTe when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); doThrow(new RuntimeException()).when(ActivityManager::getCurrentUser); - assertWithMessage("Current user when activity manager fails") - .that(RadioServiceUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL); + expect.withMessage("Current user when activity manager fails") + .that(mUserController.getCurrentUser()).isEqualTo(UserHandle.USER_NULL); + } + + @Test + public void getCallingUserId() { + when(mUserHandleMock.getIdentifier()).thenReturn(USER_ID_1); + + expect.withMessage("Calling user id") + .that(mUserController.getCallingUserId()).isEqualTo(USER_ID_1); } } diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java index 22f3bd4abe11..63f12d82b48a 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java @@ -91,12 +91,13 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes private IAnnouncementListener mAnnouncementListenerMock; @Mock private IBinder mListenerBinderMock; + @Mock + private RadioServiceUserController mUserControllerMock; @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { builder.spyStatic(ServiceManager.class) - .spyStatic(RadioModule.class) - .spyStatic(RadioServiceUserController.class); + .spyStatic(RadioModule.class); } @Test @@ -156,7 +157,7 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes @Test public void openSession_forNonCurrentUser_throwsException() throws Exception { createBroadcastRadioService(); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID, @@ -206,9 +207,9 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes } private void createBroadcastRadioService() throws RemoteException { - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); mockServiceManager(); - mBroadcastRadioService = new BroadcastRadioServiceImpl(SERVICE_LIST); + mBroadcastRadioService = new BroadcastRadioServiceImpl(SERVICE_LIST, mUserControllerMock); } private void mockServiceManager() throws RemoteException { @@ -222,9 +223,9 @@ public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTes any(IServiceCallback.class))); doReturn(mFmRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(FM_RADIO_MODULE_ID), anyString(), any(IBinder.class))); + eq(FM_RADIO_MODULE_ID), anyString(), any(IBinder.class), any())); doReturn(mDabRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(DAB_RADIO_MODULE_ID), anyString(), any(IBinder.class))); + eq(DAB_RADIO_MODULE_ID), anyString(), any(IBinder.class), any())); when(mFmRadioModuleMock.getProperties()).thenReturn(mFmModuleMock); when(mDabRadioModuleMock.getProperties()).thenReturn(mDabModuleMock); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java index a952bde956d8..368df090070b 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/RadioModuleTest.java @@ -34,6 +34,8 @@ import android.hardware.radio.RadioManager; import android.os.ParcelableException; import android.os.RemoteException; +import com.android.server.broadcastradio.RadioServiceUserController; + import com.google.common.truth.Expect; import org.junit.Before; @@ -63,6 +65,8 @@ public final class RadioModuleTest { private IAnnouncementListener mListenerMock; @Mock private android.hardware.broadcastradio.ICloseHandle mHalCloseHandleMock; + @Mock + private RadioServiceUserController mUserControllerMock; // RadioModule under test private RadioModule mRadioModule; @@ -70,7 +74,8 @@ public final class RadioModuleTest { @Before public void setup() throws RemoteException { - mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES); + mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES, + mUserControllerMock); // TODO(b/241118988): test non-null image for getImage method when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(null); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java index e963caffb175..016a9006a4ae 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java @@ -49,12 +49,10 @@ import android.hardware.radio.ProgramSelector; import android.hardware.radio.RadioManager; import android.hardware.radio.RadioTuner; import android.hardware.radio.UniqueProgramIdentifier; -import android.os.Binder; import android.os.DeadObjectException; import android.os.ParcelableException; import android.os.RemoteException; import android.os.ServiceSpecificException; -import android.os.UserHandle; import android.platform.test.flag.junit.SetFlagsRule; import android.util.ArrayMap; import android.util.ArraySet; @@ -147,10 +145,10 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { // Mocks @Mock - private UserHandle mUserHandleMock; - @Mock private IBroadcastRadio mBroadcastRadioMock; private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks; + @Mock + private RadioServiceUserController mUserControllerMock; // RadioModule under test private RadioModule mRadioModule; @@ -169,8 +167,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class) - .spyStatic(Binder.class); + builder.spyStatic(CompatChanges.class); } @Before @@ -181,13 +178,12 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { doReturn(true).when(() -> CompatChanges.isChangeEnabled( eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt())); - doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier(); - doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); - doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(USER_ID_1).when(mUserControllerMock).getCallingUserId(); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); + doReturn(USER_ID_1).when(mUserControllerMock).getCurrentUser(); mRadioModule = new RadioModule(mBroadcastRadioMock, - AidlTestUtils.makeDefaultModuleProperties()); + AidlTestUtils.makeDefaultModuleProperties(), mUserControllerMock); doAnswer(invocation -> { mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0]; @@ -224,7 +220,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void setConfiguration_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfiguration(FM_BAND_CONFIG); @@ -421,7 +417,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void tune_forNonCurrentUser_doesNotTune() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); RadioManager.ProgramInfo tuneInfo = AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); @@ -501,7 +497,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo( ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -580,7 +576,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = AidlTestUtils.makeHalProgramInfo( ConversionUtils.programSelectorToHalProgramSelector(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -614,7 +610,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void cancel_forNonCurrentUser_doesNotCancel() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].cancel(); @@ -685,7 +681,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { @Test public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startBackgroundScan(); @@ -955,7 +951,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startProgramListUpdates(filter); @@ -994,7 +990,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); mTunerSessions[0].startProgramListUpdates(filter); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].stopProgramListUpdates(); @@ -1060,7 +1056,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { public void setConfigFlag_forNonCurrentUser_doesNotSetConfigFlag() throws Exception { openAidlClients(/* numClients= */ 1); int flag = UNSUPPORTED_CONFIG_FLAG + 1; - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfigFlag(flag, /* value= */ true); @@ -1125,7 +1121,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1", "mockParam2", "mockValue2"); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setParameters(parametersSet); @@ -1179,7 +1175,7 @@ public final class TunerSessionTest extends ExtendedRadioMockitoTestCase { public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback() throws Exception { openAidlClients(1); - doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(USER_ID_2).when(mUserControllerMock).getCurrentUser(); mHalTunerCallback.onCurrentProgramInfoChanged(AidlTestUtils.makeHalProgramInfo( AidlTestUtils.makeHalFmSelector(AM_FM_FREQUENCY_LIST[1]), SIGNAL_QUALITY)); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java index acf698bce33d..7c3f221f9bf5 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/BroadcastRadioServiceHidlTest.java @@ -88,11 +88,12 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes private IAnnouncementListener mAnnouncementListenerMock; @Mock private IBinder mBinderMock; + @Mock + private RadioServiceUserController mUserControllerMock; @Override protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioModule.class) - .spyStatic(RadioServiceUserController.class); + builder.spyStatic(RadioModule.class); } @Test @@ -156,7 +157,7 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes @Test public void openSession_forNonCurrentUser_throwsException() throws Exception { createBroadcastRadioService(); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + when(mUserControllerMock.isCurrentOrSystemUser()).thenReturn(false); IllegalStateException thrown = assertThrows(IllegalStateException.class, () -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID, @@ -206,11 +207,11 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes } private void createBroadcastRadioService() throws RemoteException { - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + when(mUserControllerMock.isCurrentOrSystemUser()).thenReturn(true); mockServiceManager(); mBroadcastRadioService = new BroadcastRadioService(/* nextModuleId= */ FM_RADIO_MODULE_ID, - mServiceManagerMock); + mServiceManagerMock, mUserControllerMock); } private void mockServiceManager() throws RemoteException { @@ -231,9 +232,9 @@ public final class BroadcastRadioServiceHidlTest extends ExtendedRadioMockitoTes }).thenReturn(true); doReturn(mFmRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(FM_RADIO_MODULE_ID), anyString())); + eq(FM_RADIO_MODULE_ID), anyString(), any())); doReturn(mDabRadioModuleMock).when(() -> RadioModule.tryLoadingModule( - eq(DAB_RADIO_MODULE_ID), anyString())); + eq(DAB_RADIO_MODULE_ID), anyString(), any())); when(mFmRadioModuleMock.getProperties()).thenReturn(mFmModuleMock); when(mDabRadioModuleMock.getProperties()).thenReturn(mDabModuleMock); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java index 1f5e77038728..b53f7ca879aa 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/RadioModuleHidlTest.java @@ -36,6 +36,8 @@ import android.hardware.radio.ICloseHandle; import android.hardware.radio.RadioManager; import android.os.RemoteException; +import com.android.server.broadcastradio.RadioServiceUserController; + import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -61,13 +63,16 @@ public final class RadioModuleHidlTest { private IAnnouncementListener mListenerMock; @Mock private android.hardware.broadcastradio.V2_0.ICloseHandle mHalCloseHandleMock; + @Mock + private RadioServiceUserController mUserControllerMock; private RadioModule mRadioModule; private android.hardware.broadcastradio.V2_0.IAnnouncementListener mHalListener; @Before public void setup() throws RemoteException { - mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES); + mRadioModule = new RadioModule(mBroadcastRadioMock, TEST_MODULE_PROPERTIES, + mUserControllerMock); when(mBroadcastRadioMock.getImage(anyInt())).thenReturn(new ArrayList<Byte>(0)); diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java index 8c16d79133ce..fa0744775f6d 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/StartProgramListUpdatesFanoutTest.java @@ -38,13 +38,13 @@ import android.hardware.radio.RadioManager; import android.hardware.radio.UniqueProgramIdentifier; import android.os.RemoteException; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; -import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase; import com.android.server.broadcastradio.RadioServiceUserController; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import org.mockito.stubbing.Answer; import org.mockito.verification.VerificationWithTimeout; @@ -55,7 +55,8 @@ import java.util.List; /** * Tests for v2 HAL RadioModule. */ -public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestCase { +@RunWith(MockitoJUnitRunner.class) +public class StartProgramListUpdatesFanoutTest { private static final String TAG = "BroadcastRadioTests.hal2.StartProgramListUpdatesFanout"; private static final VerificationWithTimeout CB_TIMEOUT = timeout(500); @@ -64,6 +65,8 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC @Mock IBroadcastRadio mBroadcastRadioMock; @Mock ITunerSession mHalTunerSessionMock; private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks; + @Mock + private RadioServiceUserController mUserControllerMock; // RadioModule under test private RadioModule mRadioModule; @@ -110,17 +113,12 @@ public class StartProgramListUpdatesFanoutTest extends ExtendedRadioMockitoTestC private static final RadioManager.ProgramInfo TEST_DAB_INFO = TestUtils.makeProgramInfo( TEST_DAB_SELECTOR, TEST_QUALITY); - @Override - protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioServiceUserController.class); - } - @Before public void setup() throws RemoteException { - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); - mRadioModule = new RadioModule(mBroadcastRadioMock, - TestUtils.makeDefaultModuleProperties()); + mRadioModule = new RadioModule(mBroadcastRadioMock, TestUtils.makeDefaultModuleProperties(), + mUserControllerMock); doAnswer((Answer) invocation -> { mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0]; diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java index 55aae9d3396a..62445cf90028 100644 --- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java +++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/hal2/TunerSessionHidlTest.java @@ -44,16 +44,12 @@ import android.hardware.radio.ProgramList; import android.hardware.radio.ProgramSelector; import android.hardware.radio.RadioManager; import android.hardware.radio.RadioTuner; -import android.os.Binder; import android.os.DeadObjectException; import android.os.ParcelableException; import android.os.RemoteException; -import android.os.UserHandle; import android.util.ArrayMap; import android.util.ArraySet; -import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder; -import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase; import com.android.server.broadcastradio.RadioServiceUserController; import com.google.common.truth.Expect; @@ -76,7 +72,7 @@ import java.util.Map; * Tests for HIDL HAL TunerSession. */ @RunWith(MockitoJUnitRunner.class) -public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { +public final class TunerSessionHidlTest { private static final int USER_ID_1 = 11; private static final int USER_ID_2 = 12; @@ -104,27 +100,21 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { public final Expect mExpect = Expect.create(); @Mock - private UserHandle mUserHandleMock; - @Mock private IBroadcastRadio mBroadcastRadioMock; @Mock ITunerSession mHalTunerSessionMock; private android.hardware.radio.ITunerCallback[] mAidlTunerCallbackMocks; - - @Override - protected void initializeSession(StaticMockitoSessionBuilder builder) { - builder.spyStatic(RadioServiceUserController.class).spyStatic(Binder.class); - } + @Mock + private RadioServiceUserController mUserControllerMock; @Before public void setup() throws Exception { - doReturn(USER_ID_1).when(mUserHandleMock).getIdentifier(); - doReturn(mUserHandleMock).when(() -> Binder.getCallingUserHandle()); - doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); - doReturn(USER_ID_1).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(USER_ID_1).when(mUserControllerMock).getCallingUserId(); + doReturn(true).when(mUserControllerMock).isCurrentOrSystemUser(); + doReturn(USER_ID_1).when(mUserControllerMock).getCurrentUser(); mRadioModule = new RadioModule(mBroadcastRadioMock, - TestUtils.makeDefaultModuleProperties()); + TestUtils.makeDefaultModuleProperties(), mUserControllerMock); doAnswer(invocation -> { mHalTunerCallback = (ITunerCallback) invocation.getArguments()[0]; @@ -228,7 +218,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void setConfiguration_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfiguration(FM_BAND_CONFIG); @@ -403,7 +393,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void tune_forNonCurrentUser_doesNotTune() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); ProgramSelector initialSel = TestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]); RadioManager.ProgramInfo tuneInfo = TestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY); @@ -481,7 +471,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = TestUtils.makeHalProgramInfo( Convert.programSelectorToHal(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].step(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -559,7 +549,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); mHalCurrentInfo = TestUtils.makeHalProgramInfo( Convert.programSelectorToHal(initialSel), SIGNAL_QUALITY); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].seek(/* directionDown= */ true, /* skipSubChannel= */ false); @@ -593,7 +583,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void cancel_forNonCurrentUser_doesNotCancel() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].cancel(); @@ -663,7 +653,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { @Test public void startBackgroundScan_forNonCurrentUser_doesNotInvokesCallback() throws Exception { openAidlClients(/* numClients= */ 1); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startBackgroundScan(); @@ -676,7 +666,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); ProgramList.Filter filter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].startProgramListUpdates(filter); @@ -715,7 +705,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { ProgramList.Filter aidlFilter = new ProgramList.Filter(new ArraySet<>(), new ArraySet<>(), /* includeCategories= */ true, /* excludeModifications= */ false); mTunerSessions[0].startProgramListUpdates(aidlFilter); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].stopProgramListUpdates(); @@ -781,7 +771,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { public void setConfigFlag_forNonCurrentUser_doesNotSetConfigFlag() throws Exception { openAidlClients(/* numClients= */ 1); int flag = UNSUPPORTED_CONFIG_FLAG + 1; - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setConfigFlag(flag, /* value= */ true); @@ -846,7 +836,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { openAidlClients(/* numClients= */ 1); Map<String, String> parametersSet = Map.of("mockParam1", "mockValue1", "mockParam2", "mockValue2"); - doReturn(false).when(() -> RadioServiceUserController.isCurrentOrSystemUser()); + doReturn(false).when(mUserControllerMock).isCurrentOrSystemUser(); mTunerSessions[0].setParameters(parametersSet); @@ -900,7 +890,7 @@ public final class TunerSessionHidlTest extends ExtendedRadioMockitoTestCase { public void onCurrentProgramInfoChanged_withNonCurrentUser_doesNotInvokeCallback() throws Exception { openAidlClients(1); - doReturn(USER_ID_2).when(() -> RadioServiceUserController.getCurrentUser()); + doReturn(USER_ID_2).when(mUserControllerMock).getCurrentUser(); mHalTunerCallback.onCurrentProgramInfoChanged(TestUtils.makeHalProgramInfo( TestUtils.makeHalFmSelector(/* freq= */ 97300), SIGNAL_QUALITY)); diff --git a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java index 77e8a404a0ff..fe54aa8d87f0 100644 --- a/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java +++ b/core/tests/coretests/BinderFrozenStateChangeCallbackTestApp/src/com/android/frameworks/coretests/bfscctestapp/BfsccTestAppCmdService.java @@ -30,31 +30,30 @@ import java.util.concurrent.TimeUnit; public class BfsccTestAppCmdService extends Service { private IBfsccTestAppCmdService.Stub mBinder = new IBfsccTestAppCmdService.Stub() { - private final LinkedBlockingQueue<IBinder.IFrozenStateChangeCallback.State> mNotifications = + private final LinkedBlockingQueue<Integer> mNotifications = new LinkedBlockingQueue<>(); @Override public void listenTo(IBinder binder) throws RemoteException { binder.addFrozenStateChangeCallback( - (IBinder who, IBinder.IFrozenStateChangeCallback.State state) - -> mNotifications.offer(state)); + (IBinder who, int state) -> mNotifications.offer(state)); } @Override public boolean[] waitAndConsumeNotifications() { List<Boolean> results = new ArrayList<>(); try { - IBinder.IFrozenStateChangeCallback.State state = - mNotifications.poll(5, TimeUnit.SECONDS); + Integer state = mNotifications.poll(5, TimeUnit.SECONDS); if (state != null) { - results.add(state == IBinder.IFrozenStateChangeCallback.State.FROZEN); + results.add( + state.intValue() == IBinder.FrozenStateChangeCallback.STATE_FROZEN); } } catch (InterruptedException e) { return null; } while (mNotifications.size() > 0) { - results.add(mNotifications.poll() - == IBinder.IFrozenStateChangeCallback.State.FROZEN); + results.add(mNotifications.poll().intValue() + == IBinder.FrozenStateChangeCallback.STATE_FROZEN); } boolean[] convertedResults = new boolean[results.size()]; for (int i = 0; i < results.size(); i++) { diff --git a/core/tests/coretests/src/android/content/pm/TEST_MAPPING b/core/tests/coretests/src/android/content/pm/TEST_MAPPING index 9ab438ef9fd2..b350d7d50251 100644 --- a/core/tests/coretests/src/android/content/pm/TEST_MAPPING +++ b/core/tests/coretests/src/android/content/pm/TEST_MAPPING @@ -6,21 +6,7 @@ ], "postsubmit": [ { - "name": "FrameworksCoreTests", - "options": [ - { - "include-filter": "android.content.pm." - }, - { - "include-annotation": "android.platform.test.annotations.Postsubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksCoreTests_android_content_pm_PostSubmit" } ] } diff --git a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java index ee2e7e06081e..195a18a5f521 100644 --- a/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java +++ b/core/tests/coretests/src/android/os/BinderFrozenStateChangeNotificationTest.java @@ -52,7 +52,7 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; /** - * Tests functionality of {@link android.os.IBinder.IFrozenStateChangeCallback}. + * Tests functionality of {@link android.os.IBinder.FrozenStateChangeCallback}. */ @RunWith(AndroidJUnit4.class) @IgnoreUnderRavenwood(blockedBy = ActivityManager.class) @@ -157,7 +157,7 @@ public class BinderFrozenStateChangeNotificationTest { @Test public void onStateChangeNotCalledAfterCallbackRemoved() throws Exception { final LinkedBlockingQueue<Boolean> results = new LinkedBlockingQueue<>(); - IBinder.IFrozenStateChangeCallback callback; + IBinder.FrozenStateChangeCallback callback; if ((callback = createCallback(mBfsccTestAppCmdService.asBinder(), results)) == null) { return; } @@ -171,7 +171,7 @@ public class BinderFrozenStateChangeNotificationTest { public void multipleCallbacks() throws Exception { final LinkedBlockingQueue<Boolean> results1 = new LinkedBlockingQueue<>(); final LinkedBlockingQueue<Boolean> results2 = new LinkedBlockingQueue<>(); - IBinder.IFrozenStateChangeCallback callback1; + IBinder.FrozenStateChangeCallback callback1; if ((callback1 = createCallback(mBfsccTestAppCmdService.asBinder(), results1)) == null) { return; } @@ -197,8 +197,8 @@ public class BinderFrozenStateChangeNotificationTest { public void onStateChangeCalledWithTheRightBinder() throws Exception { final IBinder binder = mBfsccTestAppCmdService.asBinder(); final LinkedBlockingQueue<IBinder> results = new LinkedBlockingQueue<>(); - IBinder.IFrozenStateChangeCallback callback = - (IBinder who, IBinder.IFrozenStateChangeCallback.State state) -> results.offer(who); + IBinder.FrozenStateChangeCallback callback = + (IBinder who, int state) -> results.offer(who); try { binder.addFrozenStateChangeCallback(callback); } catch (UnsupportedOperationException e) { @@ -221,12 +221,12 @@ public class BinderFrozenStateChangeNotificationTest { } } - private IBinder.IFrozenStateChangeCallback createCallback(IBinder binder, Queue<Boolean> queue) + private IBinder.FrozenStateChangeCallback createCallback(IBinder binder, Queue<Boolean> queue) throws RemoteException { try { - final IBinder.IFrozenStateChangeCallback callback = - (IBinder who, IBinder.IFrozenStateChangeCallback.State state) -> - queue.offer(state == IBinder.IFrozenStateChangeCallback.State.FROZEN); + final IBinder.FrozenStateChangeCallback callback = + (IBinder who, int state) -> + queue.offer(state == IBinder.FrozenStateChangeCallback.STATE_FROZEN); binder.addFrozenStateChangeCallback(callback); return callback; } catch (UnsupportedOperationException e) { diff --git a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java index d12cba00f0dc..d0070678d4fa 100644 --- a/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BinderDeathDispatcherTest.java @@ -125,12 +125,12 @@ public class BinderDeathDispatcherTest { } @Override - public void addFrozenStateChangeCallback(IFrozenStateChangeCallback callback) + public void addFrozenStateChangeCallback(FrozenStateChangeCallback callback) throws RemoteException { } @Override - public boolean removeFrozenStateChangeCallback(IFrozenStateChangeCallback callback) { + public boolean removeFrozenStateChangeCallback(FrozenStateChangeCallback callback) { return false; } diff --git a/core/tests/vibrator/TEST_MAPPING b/core/tests/vibrator/TEST_MAPPING index 54a5ff1d675d..d91b883b873e 100644 --- a/core/tests/vibrator/TEST_MAPPING +++ b/core/tests/vibrator/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksVibratorCoreTests", - "options": [ - {"exclude-annotation": "androidx.test.filters.LargeTest"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksVibratorCoreTests" } ], "postsubmit": [ diff --git a/graphics/TEST_MAPPING b/graphics/TEST_MAPPING index 8afc30d54a53..75cb87c0e737 100644 --- a/graphics/TEST_MAPPING +++ b/graphics/TEST_MAPPING @@ -1,23 +1,10 @@ { "presubmit": [ { - "name": "CtsGraphicsTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsGraphicsTestCases" }, { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ], + "name": "CtsTextTestCases_text", "file_patterns": ["(/|^)Typeface\\.java", "(/|^)Paint\\.java"] } ] diff --git a/graphics/java/android/graphics/TEST_MAPPING b/graphics/java/android/graphics/TEST_MAPPING index df912222909a..5cc31ba840f7 100644 --- a/graphics/java/android/graphics/TEST_MAPPING +++ b/graphics/java/android/graphics/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ], + "name": "CtsTextTestCases_text", "file_patterns": [ "Typeface\\.java", "Paint\\.java", diff --git a/graphics/java/android/graphics/drawable/TEST_MAPPING b/graphics/java/android/graphics/drawable/TEST_MAPPING index 4f064522b037..da0a721c89ef 100644 --- a/graphics/java/android/graphics/drawable/TEST_MAPPING +++ b/graphics/java/android/graphics/drawable/TEST_MAPPING @@ -1,14 +1,8 @@ { "presubmit": [ { - - "name": "CtsGraphicsTestCases", - "file_patterns": ["(/|^)Icon\\.java"], - "options" : [ - { - "include-filter": "android.graphics.drawable.cts.IconTest" - } - ] + "name": "CtsGraphicsTestCases_cts_icontest", + "file_patterns": ["(/|^)Icon\\.java"] }, { diff --git a/graphics/java/android/graphics/fonts/TEST_MAPPING b/graphics/java/android/graphics/fonts/TEST_MAPPING index 99cbfe720c05..9f8a72cb5975 100644 --- a/graphics/java/android/graphics/fonts/TEST_MAPPING +++ b/graphics/java/android/graphics/fonts/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/graphics/java/android/graphics/pdf/TEST_MAPPING b/graphics/java/android/graphics/pdf/TEST_MAPPING index afec35c76371..8720b9571474 100644 --- a/graphics/java/android/graphics/pdf/TEST_MAPPING +++ b/graphics/java/android/graphics/pdf/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPdfTestCases", - "options": [ - { - "include-filter": "android.graphics.pdf.cts.PdfDocumentTest" - } - ] + "name": "CtsPdfTestCases_cts_pdfdocumenttest" } ] } diff --git a/graphics/java/android/graphics/text/TEST_MAPPING b/graphics/java/android/graphics/text/TEST_MAPPING index 99cbfe720c05..9f8a72cb5975 100644 --- a/graphics/java/android/graphics/text/TEST_MAPPING +++ b/graphics/java/android/graphics/text/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "CtsTextTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsTextTestCases_text" } ] } diff --git a/libs/WindowManager/Jetpack/src/TEST_MAPPING b/libs/WindowManager/Jetpack/src/TEST_MAPPING index f8f64001dd24..600c79bb88a4 100644 --- a/libs/WindowManager/Jetpack/src/TEST_MAPPING +++ b/libs/WindowManager/Jetpack/src/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "WMJetpackUnitTests", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "WMJetpackUnitTests_Presubmit" }, { - "name": "CtsWindowManagerJetpackTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "CtsWindowManagerJetpackTestCases_Presubmit" } ], "imports": [ diff --git a/libs/WindowManager/Shell/OWNERS b/libs/WindowManager/Shell/OWNERS index c6044a45200d..394093c6ab30 100644 --- a/libs/WindowManager/Shell/OWNERS +++ b/libs/WindowManager/Shell/OWNERS @@ -1,4 +1,6 @@ xutan@google.com +pbdr@google.com +pragyabajoria@google.com # Give submodule owners in shell resource approval per-file res*/*/*.xml = atsjenk@google.com, hwwang@google.com, jorgegil@google.com, lbill@google.com, madym@google.com, vaniadesmonda@google.com, pbdr@google.com, tkachenkoi@google.com, mpodolian@google.com, liranb@google.com, pragyabajoria@google.com, uysalorhan@google.com, gsennton@google.com, mattsziklay@google.com, mdehaini@google.com diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING index f02559f36169..df3a369febbc 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "WMShellUnitTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "com.android.wm.shell.back" - } - ] + "name": "WMShellUnitTests_shell_back" }, { - "name": "CtsWindowManagerDeviceBackNavigation", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.server.wm.backnavigation.BackGestureInvokedTest" - }, - { - "include-filter": "android.server.wm.backnavigation.BackNavigationTests" - }, - { - "include-filter": "android.server.wm.backnavigation.OnBackInvokedCallbackGestureTest" - } - ] + "name": "CtsWindowManagerDeviceBackNavigation_com_android_wm_shell_back" } ] } diff --git a/libs/appfunctions/OWNERS b/libs/appfunctions/OWNERS new file mode 100644 index 000000000000..c093675ee580 --- /dev/null +++ b/libs/appfunctions/OWNERS @@ -0,0 +1,3 @@ +set noparent + +include /core/java/android/app/appfunctions/OWNERS diff --git a/libs/hwui/hwui/DrawTextFunctor.h b/libs/hwui/hwui/DrawTextFunctor.h index cfca48084d97..d264058737e5 100644 --- a/libs/hwui/hwui/DrawTextFunctor.h +++ b/libs/hwui/hwui/DrawTextFunctor.h @@ -62,6 +62,7 @@ static void simplifyPaint(int color, Paint* paint) { } paint->setStrokeJoin(SkPaint::kRound_Join); paint->setLooper(nullptr); + paint->setBlendMode(SkBlendMode::kSrcOver); } class DrawTextFunctor { diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING index 6ac969527d89..e52e0b16eca3 100644 --- a/media/TEST_MAPPING +++ b/media/TEST_MAPPING @@ -30,24 +30,14 @@ "file_patterns": ["(?i)drm|crypto"] }, { - "name": "CtsMediaDrmFrameworkTestCases", - "options" : [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ], + "name": "CtsMediaDrmFrameworkTestCases_Presubmit", "file_patterns": ["(?i)drm|crypto"] }, { "file_patterns": [ "[^/]*(LoudnessCodec)[^/]*\\.java" ], - "name": "LoudnessCodecApiTest", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "LoudnessCodecApiTest_Presubmit" } ] } diff --git a/media/java/android/media/AudioTrack.java b/media/java/android/media/AudioTrack.java index 73deb17d0055..03cd53580b1b 100644 --- a/media/java/android/media/AudioTrack.java +++ b/media/java/android/media/AudioTrack.java @@ -1797,6 +1797,7 @@ public class AudioTrack extends PlayerBase (flags != 0 // cannot have any special flags || attributes.getUsage() != AudioAttributes.USAGE_MEDIA || (attributes.getContentType() != AudioAttributes.CONTENT_TYPE_UNKNOWN + && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_SPEECH && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MUSIC && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MOVIE))) { return false; diff --git a/media/java/android/media/projection/OWNERS b/media/java/android/media/projection/OWNERS index 880ec8fdef88..2b727445c797 100644 --- a/media/java/android/media/projection/OWNERS +++ b/media/java/android/media/projection/OWNERS @@ -1,7 +1,7 @@ # Bug component: 1345447 -michaelwr@google.com -santoscordon@google.com -chaviw@google.com -nmusgrave@google.com +marvinramin@google.com dakinola@google.com +vaniadesmonda@google.com +caen@google.com +santoscordon@google.com
\ No newline at end of file diff --git a/media/java/android/media/projection/TEST_MAPPING b/media/java/android/media/projection/TEST_MAPPING index 7aa9118e45ee..b33097c50002 100644 --- a/media/java/android/media/projection/TEST_MAPPING +++ b/media/java/android/media/projection/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "MediaProjectionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "MediaProjectionTests" } ] } diff --git a/native/android/TEST_MAPPING b/native/android/TEST_MAPPING index 7c710982e4f6..be84574e6a2c 100644 --- a/native/android/TEST_MAPPING +++ b/native/android/TEST_MAPPING @@ -14,12 +14,7 @@ "file_patterns": ["permission_manager.cpp"] }, { - "name": "CtsOsTestCases", - "options": [ - { - "include-filter": "android.os.cts.PerformanceHintManagerTest" - } - ], + "name": "CtsOsTestCases_cts_performancehintmanagertest", "file_patterns": ["performance_hint.cpp"] } ], diff --git a/native/webview/TEST_MAPPING b/native/webview/TEST_MAPPING index 07f438329e43..38580595dc2d 100644 --- a/native/webview/TEST_MAPPING +++ b/native/webview/TEST_MAPPING @@ -1,28 +1,13 @@ { "presubmit": [ { - "name": "CtsWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsWebkitTestCases" }, { - "name": "CtsSdkSandboxWebkitTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSdkSandboxWebkitTestCases" }, { - "name": "CtsHostsideWebViewTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsHostsideWebViewTests" }, { "name": "GtsWebViewTestCases", diff --git a/nfc/api/current.txt b/nfc/api/current.txt index 5b6b6c0b192e..e7cb76c370fd 100644 --- a/nfc/api/current.txt +++ b/nfc/api/current.txt @@ -205,6 +205,7 @@ package android.nfc.cardemulation { method public int getSelectionModeForCategory(String); method public boolean isDefaultServiceForAid(android.content.ComponentName, String); method public boolean isDefaultServiceForCategory(android.content.ComponentName, String); + method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported(); method public boolean registerAidsForService(android.content.ComponentName, String, java.util.List<java.lang.String>); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean); method @FlaggedApi("android.nfc.nfc_read_polling_loop") public boolean registerPollingLoopPatternFilterForService(@NonNull android.content.ComponentName, @NonNull String, boolean); diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt index cc5ff8168567..9603c0a9f7c7 100644 --- a/nfc/api/system-current.txt +++ b/nfc/api/system-current.txt @@ -60,8 +60,13 @@ package android.nfc { method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.List<java.lang.String> getActiveNfceeList(); method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void maybeTriggerFirmwareUpdate(); method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcOemExtension.Callback); + method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void setControllerAlwaysOn(int); method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void synchronizeScreenState(); method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterCallback(@NonNull android.nfc.NfcOemExtension.Callback); + field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int DISABLE = 0; // 0x0 + field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_DEFAULT = 1; // 0x1 + field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_EE = 3; // 0x3 + field @FlaggedApi("android.nfc.nfc_oem_extension") public static final int ENABLE_TRANSPARENT = 2; // 0x2 field public static final int HCE_ACTIVATE = 1; // 0x1 field public static final int HCE_DATA_TRANSFERRED = 2; // 0x2 field public static final int HCE_DEACTIVATE = 3; // 0x3 @@ -98,7 +103,6 @@ package android.nfc.cardemulation { public final class CardEmulation { method @FlaggedApi("android.permission.flags.wallet_role_enabled") @Nullable @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static android.content.ComponentName getPreferredPaymentService(@NonNull android.content.Context); method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int); - method @FlaggedApi("android.nfc.enable_card_emulation_euicc") public boolean isEuiccSupported(); method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void overrideRoutingTable(@NonNull android.app.Activity, int, int); method @FlaggedApi("android.nfc.nfc_override_recover_routing_table") public void recoverRoutingTable(@NonNull android.app.Activity); } diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl index e2ec95215d1a..246efc7ca557 100644 --- a/nfc/java/android/nfc/INfcAdapter.aidl +++ b/nfc/java/android/nfc/INfcAdapter.aidl @@ -73,7 +73,7 @@ interface INfcAdapter boolean setNfcSecure(boolean enable); NfcAntennaInfo getNfcAntennaInfo(); - boolean setControllerAlwaysOn(boolean value); + void setControllerAlwaysOn(int mode); boolean isControllerAlwaysOn(); boolean isControllerAlwaysOnSupported(); void registerControllerAlwaysOnListener(in INfcControllerAlwaysOnListener listener); diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java index f47879385070..28045460ef27 100644 --- a/nfc/java/android/nfc/NfcAdapter.java +++ b/nfc/java/android/nfc/NfcAdapter.java @@ -258,7 +258,7 @@ public final class NfcAdapter { /** * Mandatory String extra field in {@link #ACTION_TRANSACTION_DETECTED} * Indicates the Secure Element on which the transaction occurred. - * eSE1...eSEn for Embedded Secure Elements, SIM1...SIMn for UICC, etc. + * eSE1...eSEn for Embedded Secure Elements, SIM1...SIMn for UICC/EUICC, etc. */ public static final String EXTRA_SECURE_ELEMENT_NAME = "android.nfc.extra.SECURE_ELEMENT_NAME"; @@ -559,6 +559,18 @@ public final class NfcAdapter { @Retention(RetentionPolicy.SOURCE) public @interface TagIntentAppPreferenceResult {} + /** + * Mode Type for {@link NfcOemExtension#setControllerAlwaysOn(int)}. + * @hide + */ + public static final int CONTROLLER_ALWAYS_ON_MODE_DEFAULT = 1; + + /** + * Mode Type for {@link NfcOemExtension#setControllerAlwaysOn(int)}. + * @hide + */ + public static final int CONTROLLER_ALWAYS_ON_DISABLE = 0; + // Guarded by sLock static boolean sIsInitialized = false; static boolean sHasNfcFeature; @@ -721,7 +733,7 @@ public final class NfcAdapter { * * @return List<String> containing secure elements on the device which supports * off host card emulation. eSE for Embedded secure element, - * SIM for UICC, eSIM for EUICC and so on. + * SIM for UICC/EUICC and so on. * @hide */ public @NonNull List<String> getSupportedOffHostSecureElements() { @@ -741,11 +753,6 @@ public final class NfcAdapter { if (pm.hasSystemFeature(PackageManager.FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE)) { offHostSE.add("eSE"); } - if (Flags.enableCardEmulationEuicc() - && callServiceReturn( - () -> sCardEmulationService.isEuiccSupported(), false)) { - offHostSE.add("eSIM"); - } return offHostSE; } @@ -2330,7 +2337,8 @@ public final class NfcAdapter { * FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF, * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE * are unavailable - * @return void + * @return true if feature is supported by the device and operation has bee initiated, + * false if the feature is not supported by the device. * @hide */ @SystemApi @@ -2339,8 +2347,13 @@ public final class NfcAdapter { if (!sHasNfcFeature && !sHasCeFeature) { throw new UnsupportedOperationException(); } - return callServiceReturn(() -> sService.setControllerAlwaysOn(value), false); - + int mode = value ? CONTROLLER_ALWAYS_ON_MODE_DEFAULT : CONTROLLER_ALWAYS_ON_DISABLE; + try { + callService(() -> sService.setControllerAlwaysOn(mode)); + } catch (UnsupportedOperationException e) { + return false; + } + return true; } /** diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java index d51b704a7e7f..45038d41e237 100644 --- a/nfc/java/android/nfc/NfcOemExtension.java +++ b/nfc/java/android/nfc/NfcOemExtension.java @@ -70,6 +70,58 @@ public final class NfcOemExtension { private boolean mRfDiscoveryStarted = false; /** + * Mode Type for {@link #setControllerAlwaysOn(int)}. + * Enables the controller in default mode when NFC is disabled (existing API behavior). + * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}. + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) + public static final int ENABLE_DEFAULT = NfcAdapter.CONTROLLER_ALWAYS_ON_MODE_DEFAULT; + + /** + * Mode Type for {@link #setControllerAlwaysOn(int)}. + * Enables the controller in transparent mode when NFC is disabled. + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) + public static final int ENABLE_TRANSPARENT = 2; + + /** + * Mode Type for {@link #setControllerAlwaysOn(int)}. + * Enables the controller and initializes and enables the EE subsystem when NFC is disabled. + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) + public static final int ENABLE_EE = 3; + + /** + * Mode Type for {@link #setControllerAlwaysOn(int)}. + * Disable the Controller Always On Mode. + * works same as {@link NfcAdapter#setControllerAlwaysOn(boolean)}. + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) + public static final int DISABLE = NfcAdapter.CONTROLLER_ALWAYS_ON_DISABLE; + + /** + * Possible controller modes for {@link #setControllerAlwaysOn(int)}. + * + * @hide + */ + @IntDef(prefix = { "" }, value = { + ENABLE_DEFAULT, + ENABLE_TRANSPARENT, + ENABLE_EE, + DISABLE, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ControllerMode{} + + /** * Event that Host Card Emulation is activated. */ public static final int HCE_ACTIVATE = 1; @@ -389,6 +441,32 @@ public final class NfcOemExtension { NfcAdapter.sService.fetchActiveNfceeList(), new ArrayList<String>()); } + /** + * Sets NFC controller always on feature. + * <p>This API is for the NFCC internal state management. It allows to discriminate + * the controller function from the NFC function by keeping the NFC controller on without + * any NFC RF enabled if necessary. + * <p>This call is asynchronous, register listener {@link NfcAdapter.ControllerAlwaysOnListener} + * by {@link NfcAdapter#registerControllerAlwaysOnListener} to find out when the operation is + * complete. + * @param mode one of {@link ControllerMode} modes + * @throws UnsupportedOperationException if + * <li> if FEATURE_NFC, FEATURE_NFC_HOST_CARD_EMULATION, FEATURE_NFC_HOST_CARD_EMULATION_NFCF, + * FEATURE_NFC_OFF_HOST_CARD_EMULATION_UICC and FEATURE_NFC_OFF_HOST_CARD_EMULATION_ESE + * are unavailable </li> + * <li> if the feature is unavailable @see NfcAdapter#isNfcControllerAlwaysOnSupported() </li> + * @hide + */ + @SystemApi + @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION) + @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) + public void setControllerAlwaysOn(@ControllerMode int mode) { + if (!NfcAdapter.sHasNfcFeature && !NfcAdapter.sHasCeFeature) { + throw new UnsupportedOperationException(); + } + NfcAdapter.callService(() -> NfcAdapter.sService.setControllerAlwaysOn(mode)); + } + private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub { @Override diff --git a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java index ea5a03613ddc..3cf0a4dc4873 100644 --- a/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java +++ b/nfc/java/android/nfc/cardemulation/ApduServiceInfo.java @@ -308,8 +308,6 @@ public final class ApduServiceInfo implements Parcelable { mOffHostName = "eSE1"; } else if (mOffHostName.equals("SIM")) { mOffHostName = "SIM1"; - } else if (Flags.enableCardEmulationEuicc() && mOffHostName.equals("eSIM")) { - mOffHostName = "eSIM1"; } } mStaticOffHostName = mOffHostName; diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java index a72a8964203a..4be082ccc02f 100644 --- a/nfc/java/android/nfc/cardemulation/CardEmulation.java +++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java @@ -548,13 +548,11 @@ public final class CardEmulation { List<String> validSE = adapter.getSupportedOffHostSecureElements(); if ((offHostSecureElement.startsWith("eSE") && !validSE.contains("eSE")) - || (offHostSecureElement.startsWith("SIM") && !validSE.contains("SIM")) - || (offHostSecureElement.startsWith("eSIM") && !validSE.contains("eSIM"))) { + || (offHostSecureElement.startsWith("SIM") && !validSE.contains("SIM"))) { return false; } - if (!offHostSecureElement.startsWith("eSE") && !offHostSecureElement.startsWith("SIM") - && !(Flags.enableCardEmulationEuicc() && offHostSecureElement.startsWith("eSIM"))) { + if (!offHostSecureElement.startsWith("eSE") && !offHostSecureElement.startsWith("SIM")) { return false; } @@ -562,8 +560,6 @@ public final class CardEmulation { offHostSecureElement = "eSE1"; } else if (offHostSecureElement.equals("SIM")) { offHostSecureElement = "SIM1"; - } else if (Flags.enableCardEmulationEuicc() && offHostSecureElement.equals("eSIM")) { - offHostSecureElement = "eSIM1"; } final String offHostSecureElementV = new String(offHostSecureElement); return callServiceReturn(() -> @@ -992,9 +988,7 @@ public final class CardEmulation { * Is EUICC supported as a Secure Element EE which supports off host card emulation. * * @return true if the device supports EUICC for off host card emulation, false otherwise. - * @hide */ - @SystemApi @FlaggedApi(android.nfc.Flags.FLAG_ENABLE_CARD_EMULATION_EUICC) public boolean isEuiccSupported() { return callServiceReturn(() -> sService.isEuiccSupported(), false); diff --git a/packages/PrintSpooler/TEST_MAPPING b/packages/PrintSpooler/TEST_MAPPING index ad3b44f1bcce..f8bf8a0d5c84 100644 --- a/packages/PrintSpooler/TEST_MAPPING +++ b/packages/PrintSpooler/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPrintTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "CtsPrintTestCases_Presubmit" } ], "postsubmit": [ diff --git a/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING b/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING index 71cbcb54a1ff..1346ee565a5d 100644 --- a/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING +++ b/packages/SettingsLib/src/com/android/settingslib/users/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "SettingsLibTests", - "options": [ - { - "include-filter": "com.android.settingslib.users." - } - ] + "name": "SettingsLibTests_settingslib_users" } ] }
\ No newline at end of file diff --git a/packages/SettingsProvider/TEST_MAPPING b/packages/SettingsProvider/TEST_MAPPING index 0eed2b7490d4..cf9ed2e6c1df 100644 --- a/packages/SettingsProvider/TEST_MAPPING +++ b/packages/SettingsProvider/TEST_MAPPING @@ -4,12 +4,7 @@ "name": "SettingsProviderTest" }, { - "name": "CtsProviderTestCases", - "options": [ - { - "include-filter": "android.provider.cts.settings." - } - ] + "name": "CtsProviderTestCases_cts_settings" } ], "postsubmit": [ diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 00a7826aa8e8..f6960360cfb3 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -1993,8 +1993,6 @@ public class SettingsProvider extends ContentProvider { if (!isValidMediaUri(name, value)) { return false; } - // Invalidate any relevant cache files - cacheFile.delete(); } final boolean success; @@ -2032,6 +2030,11 @@ public class SettingsProvider extends ContentProvider { return false; } + if (cacheFile != null) { + // Invalidate any relevant cache files + cacheFile.delete(); + } + if ((operation == MUTATION_OPERATION_INSERT || operation == MUTATION_OPERATION_UPDATE) && cacheFile != null && value != null) { final Uri ringtoneUri = Uri.parse(value); diff --git a/packages/Shell/TEST_MAPPING b/packages/Shell/TEST_MAPPING index 9bb1b4b99207..6b9f1ebd4061 100644 --- a/packages/Shell/TEST_MAPPING +++ b/packages/Shell/TEST_MAPPING @@ -1,23 +1,10 @@ { "presubmit": [ { - "name": "CtsBugreportTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsBugreportTestCases_android_server_os" }, { - "name": "ShellTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ShellTests_android_server_os" }, { "name": "CtsUiAutomationTestCases", diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp index 1eae218ffed9..387dae550884 100644 --- a/packages/SystemUI/Android.bp +++ b/packages/SystemUI/Android.bp @@ -784,6 +784,7 @@ android_app { resource_dirs: [], kotlincflags: ["-Xjvm-default=all"], optimize: { + optimize: false, shrink_resources: false, optimized_shrink_resources: false, proguard_flags_files: ["proguard.flags"], @@ -856,9 +857,9 @@ android_robolectric_test { "RoboTestLibraries", ], libs: [ - "android.test.runner", - "android.test.base", - "android.test.mock", + "android.test.runner.stubs.system", + "android.test.base.stubs.system", + "android.test.mock.stubs.system", "truth", ], diff --git a/packages/SystemUI/TEST_MAPPING b/packages/SystemUI/TEST_MAPPING index 16dd4e5a800e..07a1e630e1ad 100644 --- a/packages/SystemUI/TEST_MAPPING +++ b/packages/SystemUI/TEST_MAPPING @@ -21,15 +21,7 @@ // v2/android-virtual-infra/test_mapping/presubmit-avd "presubmit": [ { - "name": "SystemUIGoogleTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIGoogleTests" }, { // Permission indicators @@ -48,15 +40,7 @@ }, { // Permission indicators - "name": "CtsVoiceRecognitionTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceRecognitionTestCases" } ], diff --git a/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING b/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING index 4a10108b3e04..1820f39bb180 100644 --- a/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING +++ b/packages/SystemUI/accessibility/accessibilitymenu/TEST_MAPPING @@ -2,12 +2,7 @@ // TODO: b/324945360 - Re-enable on presubmit after fixing failures "postsubmit": [ { - "name": "AccessibilityMenuServiceTests", - "options": [ - { - "exclude-annotation": "android.support.test.filters.FlakyTest" - } - ] + "name": "AccessibilityMenuServiceTests" } ] }
\ No newline at end of file diff --git a/packages/SystemUI/compose/core/TEST_MAPPING b/packages/SystemUI/compose/core/TEST_MAPPING index b71c5fb29fd7..56e531d2bee0 100644 --- a/packages/SystemUI/compose/core/TEST_MAPPING +++ b/packages/SystemUI/compose/core/TEST_MAPPING @@ -1,26 +1,10 @@ { "presubmit": [ { - "name": "PlatformComposeCoreTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "PlatformComposeCoreTests" }, { - "name": "SystemUIComposeGalleryTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIComposeGalleryTests" } ] }
\ No newline at end of file diff --git a/packages/SystemUI/compose/scene/TEST_MAPPING b/packages/SystemUI/compose/scene/TEST_MAPPING index f9424ed62d78..65ba037cf995 100644 --- a/packages/SystemUI/compose/scene/TEST_MAPPING +++ b/packages/SystemUI/compose/scene/TEST_MAPPING @@ -1,37 +1,13 @@ { "presubmit": [ { - "name": "PlatformComposeSceneTransitionLayoutTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "PlatformComposeSceneTransitionLayoutTests" }, { - "name": "PlatformComposeCoreTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "PlatformComposeCoreTests" }, { - "name": "SystemUIComposeGalleryTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIComposeGalleryTests" } ] }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt b/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt index 81ea2e74d799..62720a5b1377 100644 --- a/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/display/ui/viewmodel/ConnectingDisplayViewModel.kt @@ -79,7 +79,7 @@ constructor( .combine(concurrentDisplaysInProgessFlow) { pendingDisplay, concurrentDisplaysInProgress -> if (pendingDisplay == null) { - hideDialog() + dismissDialog() } else { showDialog(pendingDisplay, concurrentDisplaysInProgress) } @@ -88,17 +88,17 @@ constructor( } private fun showDialog(pendingDisplay: PendingDisplay, concurrentDisplaysInProgess: Boolean) { - hideDialog() + dismissDialog() dialog = bottomSheetFactory .createDialog( onStartMirroringClickListener = { scope.launch(bgDispatcher) { pendingDisplay.enable() } - hideDialog() + dismissDialog() }, onCancelMirroring = { scope.launch(bgDispatcher) { pendingDisplay.ignore() } - hideDialog() + dismissDialog() }, navbarBottomInsetsProvider = { Utils.getNavbarInsets(context).bottom }, showConcurrentDisplayInfo = concurrentDisplaysInProgess @@ -106,8 +106,8 @@ constructor( .apply { show() } } - private fun hideDialog() { - dialog?.hide() + private fun dismissDialog() { + dialog?.dismiss() dialog = null } diff --git a/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING b/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING index 66f020f24e80..75140bee3cdd 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING +++ b/packages/SystemUI/src/com/android/systemui/qs/TEST_MAPPING @@ -1,28 +1,12 @@ { "presubmit": [ { - "name": "CtsTileServiceTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTileServiceTestCases" } ], "postsubmit": [ { - "name": "QuickSettingsDeviceResetTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "QuickSettingsDeviceResetTests" } ] }
\ No newline at end of file diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING b/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING index 718c1c0f683b..323268440c4a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING +++ b/packages/SystemUI/src/com/android/systemui/statusbar/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit": [ { - "name": "CtsNotificationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsNotificationTestCases_notification" } ], "postsubmit": [ diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java index 103449b6b0f7..ee8ce17cecd4 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/MenuViewTest.java @@ -26,6 +26,7 @@ import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import android.app.UiModeManager; +import android.content.res.Configuration; import android.graphics.Rect; import android.graphics.drawable.GradientDrawable; import android.platform.test.annotations.EnableFlags; @@ -78,6 +79,12 @@ public class MenuViewTest extends SysuiTestCase { mNightMode = mUiModeManager.getNightMode(); mUiModeManager.setNightMode(MODE_NIGHT_YES); + // Programmatically update the resource's configuration to night mode to reduce flakiness + Configuration nightConfig = new Configuration(mContext.getResources().getConfiguration()); + nightConfig.uiMode = Configuration.UI_MODE_NIGHT_YES; + mContext.getResources().updateConfiguration(nightConfig, + mContext.getResources().getDisplayMetrics(), null); + mSpyContext = spy(mContext); doNothing().when(mSpyContext).startActivity(any()); @@ -101,6 +108,8 @@ public class MenuViewTest extends SysuiTestCase { @Test public void insetsOnDarkTheme_menuOnLeft_matchInsets() { + // In dark theme, the inset is not 0 to avoid weird spacing issue between the menu and + // the edge of the screen. mMenuView.onConfigurationChanged(/* newConfig= */ null); final InstantInsetLayerDrawable insetLayerDrawable = (InstantInsetLayerDrawable) mMenuView.getBackground(); diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp index ea588b56f3ab..ac62687f1b77 100644 --- a/ravenwood/Android.bp +++ b/ravenwood/Android.bp @@ -321,7 +321,10 @@ java_library { android_ravenwood_libgroup { name: "ravenwood-runtime", data: [ - "framework-res", + ":framework-res", + ":ravenwood-empty-res", + ":framework-platform-compat-config", + ":services-platform-compat-config", ], libs: [ "100-framework-minus-apex.ravenwood", diff --git a/ravenwood/OWNERS b/ravenwood/OWNERS index f7b13d19dbb3..8722ad92ff49 100644 --- a/ravenwood/OWNERS +++ b/ravenwood/OWNERS @@ -1,5 +1,7 @@ +# Bug component: 25698 set noparent +omakoto@google.com topjohnwu@google.com hackbod@google.com #{LAST_RESORT_SUGGESTION} diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING index fbf27fa5bf4b..57548378579c 100644 --- a/ravenwood/TEST_MAPPING +++ b/ravenwood/TEST_MAPPING @@ -17,28 +17,12 @@ }, // The sysui tests should match vendor/unbundled_google/packages/SystemUIGoogle/TEST_MAPPING { - "name": "SystemUIGoogleTests", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "SystemUIGoogleTests" } ], "presubmit-large": [ { - "name": "SystemUITests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "SystemUITests" } ], "ravenwood-presubmit": [ diff --git a/ravenwood/empty-res/Android.bp b/ravenwood/empty-res/Android.bp new file mode 100644 index 000000000000..3af769067d35 --- /dev/null +++ b/ravenwood/empty-res/Android.bp @@ -0,0 +1,4 @@ +android_app { + name: "ravenwood-empty-res", + sdk_version: "current", +} diff --git a/ravenwood/empty-res/AndroidManifest.xml b/ravenwood/empty-res/AndroidManifest.xml new file mode 100644 index 000000000000..f73460b42213 --- /dev/null +++ b/ravenwood/empty-res/AndroidManifest.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.android.ravenwood.emptyres"> +</manifest> diff --git a/services/accessibility/Android.bp b/services/accessibility/Android.bp index 7a99b605c4fb..8ea8c9a40a0c 100644 --- a/services/accessibility/Android.bp +++ b/services/accessibility/Android.bp @@ -19,11 +19,6 @@ java_library_static { defaults: [ "platform_service_defaults", ], - lint: { - error_checks: ["MissingPermissionAnnotation"], - baseline_filename: "lint-baseline.xml", - - }, srcs: [ ":services.accessibility-sources", "//frameworks/base/packages/SettingsLib/RestrictedLockUtils:SettingsLibRestrictedLockUtilsSrc", diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java index f9196f3e0e0e..754965533d0f 100644 --- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java +++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java @@ -62,7 +62,6 @@ import java.util.StringJoiner; * * NOTE: This class has to be created and poked only from the main thread. */ -@SuppressWarnings("MissingPermissionAnnotation") class AccessibilityInputFilter extends InputFilter implements EventStreamTransformation { private static final String TAG = AccessibilityInputFilter.class.getSimpleName(); diff --git a/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java b/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java index e10e87c51d59..c9ec16edc54e 100644 --- a/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java +++ b/services/accessibility/java/com/android/server/accessibility/FingerprintGestureDispatcher.java @@ -33,7 +33,6 @@ import java.util.List; /** * Encapsulate fingerprint gesture logic */ -@SuppressWarnings("MissingPermissionAnnotation") public class FingerprintGestureDispatcher extends IFingerprintClientActiveCallback.Stub implements Handler.Callback{ private static final int MSG_REGISTER = 1; diff --git a/services/autofill/java/com/android/server/autofill/TEST_MAPPING b/services/autofill/java/com/android/server/autofill/TEST_MAPPING index d8a69177387d..1dbeebe95904 100644 --- a/services/autofill/java/com/android/server/autofill/TEST_MAPPING +++ b/services/autofill/java/com/android/server/autofill/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit-large": [ { - "name": "CtsAutoFillServiceTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAutoFillServiceTestCases_android_server_autofill_Presubmit" } ] } diff --git a/services/backup/TEST_MAPPING b/services/backup/TEST_MAPPING index e1532309b78e..0c14e56932df 100644 --- a/services/backup/TEST_MAPPING +++ b/services/backup/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - { - "include-filter": "com.android.server.backup" - } - ] + "name": "FrameworksMockingServicesTests_backup" }, { "name": "CtsBackupTestCases", diff --git a/services/companion/java/com/android/server/companion/virtual/OWNERS b/services/companion/java/com/android/server/companion/virtual/OWNERS index 4fe0592f9075..4b732ac8e5a9 100644 --- a/services/companion/java/com/android/server/companion/virtual/OWNERS +++ b/services/companion/java/com/android/server/companion/virtual/OWNERS @@ -2,7 +2,9 @@ set noparent -marvinramin@google.com vladokom@google.com +marvinramin@google.com +caen@google.com +biswarupp@google.com ogunwale@google.com michaelwr@google.com
\ No newline at end of file diff --git a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING index caa877c2b964..14579c6fa3ad 100644 --- a/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING +++ b/services/companion/java/com/android/server/companion/virtual/TEST_MAPPING @@ -1,81 +1,32 @@ { "presubmit": [ { - "name": "CtsVirtualDevicesTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesTestCases" }, { - "name": "CtsVirtualDevicesAudioTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesAudioTestCases" }, { - "name": "CtsVirtualDevicesSensorTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesSensorTestCases" }, { - "name": "CtsVirtualDevicesAppLaunchTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVirtualDevicesAppLaunchTestCases" }, { "name": "CtsVirtualDevicesCameraTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], "keywords": ["primary-device"] }, { - "name": "CtsHardwareTestCases", - "options": [ - { - "include-filter": "android.hardware.input.cts.tests" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ], + "name": "CtsHardwareTestCases_cts_tests", "file_patterns": ["Virtual[^/]*\\.java"] }, { - "name": "CtsAccessibilityServiceTestCases", - "options": [ - { - "include-filter": "android.accessibilityservice.cts.AccessibilityDisplayProxyTest" - }, - { - "exclude-annotation": "android.support.test.filters.FlakyTest" - } - ] + "name": "CtsAccessibilityServiceTestCases_cts_accessibilitydisplayproxytest" } ], "postsubmit": [ { - "name": "CtsMediaAudioTestCases", - "options": [ - { - "include-filter": "android.media.audio.cts.AudioFocusWithVdmTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsMediaAudioTestCases_cts_audiofocuswithvdmtest" }, { "name": "CtsPermissionTestCases", @@ -92,12 +43,7 @@ ] }, { - "name": "CtsPermissionMultiDeviceTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsPermissionMultiDeviceTestCases" } ] } diff --git a/services/core/Android.bp b/services/core/Android.bp index 89bac5123084..3532b0a59f3d 100644 --- a/services/core/Android.bp +++ b/services/core/Android.bp @@ -235,6 +235,7 @@ java_library_static { "dreams_flags_lib", "aconfig_new_storage_flags_lib", "powerstats_flags_lib", + "locksettings_flags_lib", ], javac_shard_size: 50, javacflags: [ diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java index 2de44820ec05..8891d8eedfa6 100644 --- a/services/core/java/com/android/server/BatteryService.java +++ b/services/core/java/com/android/server/BatteryService.java @@ -158,6 +158,7 @@ public final class BatteryService extends SystemService { private int mLastChargeCounter; private int mLastBatteryCycleCount; private int mLastChargingState; + private int mLastBatteryCapacityLevel; /** * The last seen charging policy. This requires the * {@link android.Manifest.permission#BATTERY_STATS} permission and should therefore not be @@ -555,7 +556,8 @@ public final class BatteryService extends SystemService { || mHealthInfo.batteryChargeCounterUah != mLastChargeCounter || mInvalidCharger != mLastInvalidCharger || mHealthInfo.batteryCycleCount != mLastBatteryCycleCount - || mHealthInfo.chargingState != mLastChargingState)) { + || mHealthInfo.chargingState != mLastChargingState + || mHealthInfo.batteryCapacityLevel != mLastBatteryCapacityLevel)) { if (mPlugType != mLastPlugType) { if (mLastPlugType == BATTERY_PLUGGED_NONE) { @@ -739,6 +741,7 @@ public final class BatteryService extends SystemService { mLastInvalidCharger = mInvalidCharger; mLastBatteryCycleCount = mHealthInfo.batteryCycleCount; mLastChargingState = mHealthInfo.chargingState; + mLastBatteryCapacityLevel = mHealthInfo.batteryCapacityLevel; } } @@ -772,6 +775,7 @@ public final class BatteryService extends SystemService { intent.putExtra(BatteryManager.EXTRA_CHARGE_COUNTER, mHealthInfo.batteryChargeCounterUah); intent.putExtra(BatteryManager.EXTRA_CYCLE_COUNT, mHealthInfo.batteryCycleCount); intent.putExtra(BatteryManager.EXTRA_CHARGING_STATUS, mHealthInfo.chargingState); + intent.putExtra(BatteryManager.EXTRA_CAPACITY_LEVEL, mHealthInfo.batteryCapacityLevel); if (DEBUG) { Slog.d(TAG, "Sending ACTION_BATTERY_CHANGED. scale:" + BATTERY_SCALE + ", info:" + mHealthInfo.toString()); @@ -817,6 +821,7 @@ public final class BatteryService extends SystemService { event.putLong(BatteryManager.EXTRA_EVENT_TIMESTAMP, now); event.putInt(BatteryManager.EXTRA_CYCLE_COUNT, mHealthInfo.batteryCycleCount); event.putInt(BatteryManager.EXTRA_CHARGING_STATUS, mHealthInfo.chargingState); + event.putInt(BatteryManager.EXTRA_CAPACITY_LEVEL, mHealthInfo.batteryCapacityLevel); boolean queueWasEmpty = mBatteryLevelsEventQueue.isEmpty(); mBatteryLevelsEventQueue.add(event); @@ -1254,6 +1259,7 @@ public final class BatteryService extends SystemService { pw.println(" technology: " + mHealthInfo.batteryTechnology); pw.println(" Charging state: " + mHealthInfo.chargingState); pw.println(" Charging policy: " + mHealthInfo.chargingPolicy); + pw.println(" Capacity level: " + mHealthInfo.batteryCapacityLevel); } else { Shell shell = new Shell(); shell.exec(mBinderService, null, fd, null, args, null, new ResultReceiver(null)); diff --git a/services/core/java/com/android/server/TEST_MAPPING b/services/core/java/com/android/server/TEST_MAPPING index dd4239cdd37e..f2e4e7319075 100644 --- a/services/core/java/com/android/server/TEST_MAPPING +++ b/services/core/java/com/android/server/TEST_MAPPING @@ -1,13 +1,7 @@ { "presubmit": [ { - "name": "CtsLocationFineTestCases", - "options": [ - { - // TODO: Wait for test to deflake - b/293934372 - "exclude-filter":"android.location.cts.fine.ScanningSettingsTest" - } - ] + "name": "CtsLocationFineTestCases_android_server_location" }, { "name": "CtsLocationCoarseTestCases" @@ -20,12 +14,7 @@ "file_patterns": ["NotificationManagerService\\.java"] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.ToastWindowTest" - } - ], + "name": "CtsWindowManagerDeviceWindow_window_toastwindowtest", "file_patterns": ["NotificationManagerService\\.java"] }, { @@ -78,24 +67,11 @@ "file_patterns": ["StorageManagerService\\.java"] }, { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.BinaryTransparencyServiceTest" - } - ], + "name": "FrameworksServicesTests_binary_transparency", "file_patterns": ["BinaryTransparencyService\\.java"] }, { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.PinnerServiceTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ], + "name": "FrameworksServicesTests_pinner_service", "file_patterns": ["PinnerService\\.java"] }, { @@ -116,12 +92,7 @@ "file_patterns": ["VcnManagementService\\.java"] }, { - "name": "FrameworksVpnTests", - "options": [ - { - "exclude-annotation": "com.android.testutils.SkipPresubmit" - } - ], + "name": "FrameworksVpnTests_android_server_connectivity", "file_patterns": ["VpnManagerService\\.java"] }, { @@ -176,15 +147,7 @@ "name": "CtsPackageManagerTestCases" }, { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.PinnerServiceTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ], + "name": "FrameworksServicesTests_pinner_service", "file_patterns": ["PinnerService\\.java"] }, { diff --git a/services/core/java/com/android/server/VcnManagementService.java b/services/core/java/com/android/server/VcnManagementService.java index e2b6bd6ae360..d19899f03d71 100644 --- a/services/core/java/com/android/server/VcnManagementService.java +++ b/services/core/java/com/android/server/VcnManagementService.java @@ -489,7 +489,10 @@ public class VcnManagementService extends IVcnManagementService.Stub { // Check subscription is active first; much cheaper/faster check, and an app (currently) // cannot be carrier privileged for inactive subscriptions. - if (subMgr.isValidSlotIndex(info.getSimSlotIndex()) + final int simSlotIndex = info.getSimSlotIndex(); + final boolean isValidSlotIndex = + simSlotIndex >= 0 && simSlotIndex < telMgr.getActiveModemCount(); + if (isValidSlotIndex && telMgr.checkCarrierPrivilegesForPackage(pkgName) == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) { // TODO (b/173717728): Allow configuration for inactive, but manageable diff --git a/services/core/java/com/android/server/adb/AdbDebuggingManager.java b/services/core/java/com/android/server/adb/AdbDebuggingManager.java index 34c3d7ec8433..a73a991bc6a6 100644 --- a/services/core/java/com/android/server/adb/AdbDebuggingManager.java +++ b/services/core/java/com/android/server/adb/AdbDebuggingManager.java @@ -74,6 +74,7 @@ import android.util.Slog; import android.util.Xml; import com.android.internal.R; +import com.android.internal.annotations.Keep; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; import com.android.internal.util.FrameworkStatsLog; @@ -214,7 +215,7 @@ public class AdbDebuggingManager { class PairingThread extends Thread implements NsdManager.RegistrationListener { private NsdManager mNsdManager; - private String mPublicKey; + @Keep private String mPublicKey; private String mPairingCode; private String mGuid; private String mServiceName; diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 995c17635a0a..e0db1f6e1f51 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -749,12 +749,14 @@ public class ActivityManagerService extends IActivityManager.Stub /** * Map userId to its companion app uids. */ + @GuardedBy("mCompanionAppUidsMap") private final Map<Integer, Set<Integer>> mCompanionAppUidsMap = new ArrayMap<>(); /** * The profile owner UIDs. */ - private ArraySet<Integer> mProfileOwnerUids = null; + @GuardedBy("mProfileOwnerUids") + private final ArraySet<Integer> mProfileOwnerUids = new ArraySet<>(); final UserController mUserController; @VisibleForTesting @@ -19604,32 +19606,35 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public void setProfileOwnerUid(ArraySet<Integer> profileOwnerUids) { - synchronized (ActivityManagerService.this) { - mProfileOwnerUids = profileOwnerUids; + synchronized (mProfileOwnerUids) { + mProfileOwnerUids.clear(); + mProfileOwnerUids.addAll(profileOwnerUids); } } @Override public boolean isProfileOwner(int uid) { - synchronized (ActivityManagerService.this) { - return mProfileOwnerUids != null && mProfileOwnerUids.indexOf(uid) >= 0; + synchronized (mProfileOwnerUids) { + return mProfileOwnerUids.indexOf(uid) >= 0; } } @Override public void setCompanionAppUids(int userId, Set<Integer> companionAppUids) { - synchronized (ActivityManagerService.this) { + synchronized (mCompanionAppUidsMap) { mCompanionAppUidsMap.put(userId, companionAppUids); } } @Override public boolean isAssociatedCompanionApp(int userId, int uid) { - final Set<Integer> allUids = mCompanionAppUidsMap.get(userId); - if (allUids == null) { - return false; + synchronized (mCompanionAppUidsMap) { + final Set<Integer> allUids = mCompanionAppUidsMap.get(userId); + if (allUids == null) { + return false; + } + return allUids.contains(uid); } - return allUids.contains(uid); } @Override diff --git a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java index 21842db590b0..fb1c2e9a1f9d 100644 --- a/services/core/java/com/android/server/am/OomAdjusterModernImpl.java +++ b/services/core/java/com/android/server/am/OomAdjusterModernImpl.java @@ -331,7 +331,7 @@ public class OomAdjusterModernImpl extends OomAdjuster { void forEachNewNode(int slot, @NonNull Consumer<OomAdjusterArgs> callback) { ProcessRecordNode node = mLastNode[slot].mNext; final ProcessRecordNode tail = mProcessRecordNodes[slot].TAIL; - while (node != tail) { + while (node != null && node != tail) { mTmpOomAdjusterArgs.mApp = node.mApp; if (node.mApp == null) { // TODO(b/336178916) - Temporary logging for root causing b/336178916. @@ -365,7 +365,9 @@ public class OomAdjusterModernImpl extends OomAdjuster { } // Save the next before calling callback, since that may change the node.mNext. final ProcessRecordNode next = node.mNext; - callback.accept(mTmpOomAdjusterArgs); + if (mTmpOomAdjusterArgs.mApp != null) { + callback.accept(mTmpOomAdjusterArgs); + } // There are couple of cases: // a) The current node is moved to another slot // - for this case, we'd need to keep using the "next" node. diff --git a/services/core/java/com/android/server/am/TEST_MAPPING b/services/core/java/com/android/server/am/TEST_MAPPING index 6e8eb7d76108..6383dcb000ab 100644 --- a/services/core/java/com/android/server/am/TEST_MAPPING +++ b/services/core/java/com/android/server/am/TEST_MAPPING @@ -22,32 +22,10 @@ ] }, { - "name": "CtsAppFgsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAppFgsTestCases_pm_Presubmit" }, { - "name": "CtsShortFgsTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsShortFgsTestCases_pm_Presubmit" }, { "name": "FrameworksServicesTests_android_server_am_Presubmit" @@ -73,33 +51,19 @@ }, { "file_patterns": ["Broadcast.*"], - "name": "CtsBroadcastTestCases", - "options": [ - { "exclude-annotation": "androidx.test.filters.LargeTest" }, - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "CtsBroadcastTestCases_android_server_am" }, { - "name": "CtsBRSTestCases", "file_patterns": [ "ActivityManagerService\\.java", "BroadcastQueue\\.java" ], - "options": [ - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "CtsBRSTestCases" } ], "postsubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.am." - } - ] + "name": "FrameworksServicesTests_android_server_am" }, { "name": "CtsAppDataIsolationHostTestCases" @@ -115,13 +79,7 @@ ] }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - { "include-filter": "android.cts.statsdatom.appexit.AppExitHostTest" }, - { "exclude-annotation": "androidx.test.filters.LargeTest" }, - { "exclude-annotation": "androidx.test.filters.FlakyTest" }, - { "exclude-annotation": "org.junit.Ignore" } - ] + "name": "CtsStatsdAtomHostTestCases_appexit_appexithosttest" }, { "name": "CtsContentTestCases", diff --git a/services/core/java/com/android/server/app/TEST_MAPPING b/services/core/java/com/android/server/app/TEST_MAPPING index b718ce62c118..9e76175ae866 100644 --- a/services/core/java/com/android/server/app/TEST_MAPPING +++ b/services/core/java/com/android/server/app/TEST_MAPPING @@ -1,26 +1,10 @@ { "presubmit": [ { - "name": "CtsGameManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsGameManagerTestCases" }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.cts.statsdatom.gamemanager" - } - ], + "name": "CtsStatsdAtomHostTestCases_statsdatom_gamemanager", "file_patterns": [ "(/|^)GameManagerService.java" ] @@ -29,18 +13,7 @@ "name": "FrameworksMockingServicesTests_android_server_app" }, { - "name": "FrameworksCoreGameManagerTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.app" - } - ], + "name": "FrameworksCoreGameManagerTests_android_app", "file_patterns": [ "(/|^)GameManagerService.java", "(/|^)GameManagerSettings.java" ] diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING index 9317c1eda088..25dd30b0226a 100644 --- a/services/core/java/com/android/server/appop/TEST_MAPPING +++ b/services/core/java/com/android/server/appop/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsAppOpsTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAppOpsTestCases" }, { "name": "CtsAppOps2TestCases" @@ -21,12 +16,7 @@ "name": "CtsPermissionTestCases_Platform" }, { - "name": "CtsAppTestCases", - "options": [ - { - "include-filter": "android.app.cts.ActivityManagerApi29Test" - } - ] + "name": "CtsAppTestCases_cts_activitymanagerapi29test" }, { "name": "CtsStatsdAtomHostTestCases", diff --git a/services/core/java/com/android/server/attention/TEST_MAPPING b/services/core/java/com/android/server/attention/TEST_MAPPING index e5b034415824..519ed071830d 100644 --- a/services/core/java/com/android/server/attention/TEST_MAPPING +++ b/services/core/java/com/android/server/attention/TEST_MAPPING @@ -1,24 +1,7 @@ { "presubmit": [ { - "name": "CtsVoiceInteractionTestCases", - "options": [ - { - "include-filter": "android.voiceinteraction.cts.AlwaysOnHotwordDetectorTest" - }, - { - "include-filter": "android.voiceinteraction.cts.unittests.HotwordDetectedResultTest" - }, - { - "include-filter": "android.voiceinteraction.cts.HotwordDetectionServiceBasicTest" - }, - { - "include-filter": "android.voiceinteraction.cts.HotwordDetectionServiceProximityTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceInteractionTestCases_android_server_attention" } ] } diff --git a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java index 028b9b0bcbc0..fcbcb0262c95 100644 --- a/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/BroadcastRadioService.java @@ -32,8 +32,9 @@ public final class BroadcastRadioService extends SystemService { public BroadcastRadioService(Context context) { super(context); ArrayList<String> serviceNameList = IRadioServiceAidlImpl.getServicesNames(); - mServiceImpl = serviceNameList.isEmpty() ? new IRadioServiceHidlImpl(this) - : new IRadioServiceAidlImpl(this, serviceNameList); + RadioServiceUserController userController = new RadioServiceUserControllerImpl(); + mServiceImpl = serviceNameList.isEmpty() ? new IRadioServiceHidlImpl(this, userController) + : new IRadioServiceAidlImpl(this, serviceNameList, userController); } @Override diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java index 16514fa813dc..332958d39a8c 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java @@ -69,8 +69,9 @@ final class IRadioServiceAidlImpl extends IRadioService.Stub { return serviceList; } - IRadioServiceAidlImpl(BroadcastRadioService service, ArrayList<String> serviceList) { - this(service, new BroadcastRadioServiceImpl(serviceList)); + IRadioServiceAidlImpl(BroadcastRadioService service, List<String> serviceList, + RadioServiceUserController userController) { + this(service, new BroadcastRadioServiceImpl(serviceList, userController)); Slogf.i(TAG, "Initialize BroadcastRadioServiceAidl(%s)", service); } diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java index ab083429a200..67d3c95f3a23 100644 --- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java +++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java @@ -59,13 +59,16 @@ final class IRadioServiceHidlImpl extends IRadioService.Stub { @GuardedBy("mLock") private final List<RadioManager.ModuleProperties> mV1Modules; - IRadioServiceHidlImpl(BroadcastRadioService service) { + IRadioServiceHidlImpl(BroadcastRadioService service, + RadioServiceUserController userController) { mService = Objects.requireNonNull(service, "broadcast radio service cannot be null"); - mHal1Client = new com.android.server.broadcastradio.hal1.BroadcastRadioService(); + Objects.requireNonNull(userController, "user controller cannot be null"); + mHal1Client = new com.android.server.broadcastradio.hal1.BroadcastRadioService( + userController); mV1Modules = mHal1Client.loadModules(); OptionalInt max = mV1Modules.stream().mapToInt(RadioManager.ModuleProperties::getId).max(); mHal2Client = new com.android.server.broadcastradio.hal2.BroadcastRadioService( - max.isPresent() ? max.getAsInt() + 1 : 0); + max.isPresent() ? max.getAsInt() + 1 : 0, userController); } @VisibleForTesting diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java index c705ebe686f2..c15ccf193563 100644 --- a/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java +++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserController.java @@ -16,19 +16,11 @@ package com.android.server.broadcastradio; -import android.app.ActivityManager; -import android.os.Binder; -import android.os.UserHandle; - /** - * Controller to handle users in {@link com.android.server.broadcastradio.BroadcastRadioService} + * Controller interface to handle users in + * {@link com.android.server.broadcastradio.BroadcastRadioService} */ -public final class RadioServiceUserController { - - private RadioServiceUserController() { - throw new UnsupportedOperationException( - "RadioServiceUserController class is noninstantiable"); - } +public interface RadioServiceUserController { /** * Check if the user calling the method in Broadcast Radio Service is the current user or the @@ -37,26 +29,20 @@ public final class RadioServiceUserController { * @return {@code true} if the user calling this method is the current user of system user, * {@code false} otherwise. */ - public static boolean isCurrentOrSystemUser() { - int callingUser = Binder.getCallingUserHandle().getIdentifier(); - return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM; - } + boolean isCurrentOrSystemUser(); /** * Get current foreground user for Broadcast Radio Service * * @return foreground user id. */ - public static int getCurrentUser() { - int userId = UserHandle.USER_NULL; - final long identity = Binder.clearCallingIdentity(); - try { - userId = ActivityManager.getCurrentUser(); - } catch (RuntimeException e) { - // Activity manager not running, nothing we can do assume user 0. - } finally { - Binder.restoreCallingIdentity(identity); - } - return userId; - } -} + int getCurrentUser(); + + /** + * Get id of the user handle assigned to the process that sent the binder transaction that is + * being processed + * + * @return Id of the user handle + */ + int getCallingUserId(); +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java b/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java new file mode 100644 index 000000000000..e305d208000c --- /dev/null +++ b/services/core/java/com/android/server/broadcastradio/RadioServiceUserControllerImpl.java @@ -0,0 +1,62 @@ +/** + * Copyright (C) 2024 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.broadcastradio; + +import android.app.ActivityManager; +import android.os.Binder; +import android.os.UserHandle; + +/** + * Implementation for the controller to handle users in + * {@link com.android.server.broadcastradio.BroadcastRadioService} + */ +public final class RadioServiceUserControllerImpl implements RadioServiceUserController { + + /** + * @see RadioServiceUserController#isCurrentOrSystemUser() + */ + @Override + public boolean isCurrentOrSystemUser() { + int callingUser = getCallingUserId(); + return callingUser == getCurrentUser() || callingUser == UserHandle.USER_SYSTEM; + } + + /** + * @see RadioServiceUserController#getCurrentUser() + */ + @Override + public int getCurrentUser() { + int userId = UserHandle.USER_NULL; + final long identity = Binder.clearCallingIdentity(); + try { + userId = ActivityManager.getCurrentUser(); + } catch (RuntimeException e) { + // Activity manager not running, nothing we can do assume user 0. + } finally { + Binder.restoreCallingIdentity(identity); + } + return userId; + } + + /** + * @see RadioServiceUserController#getCallingUserId() + */ + @Override + public int getCallingUserId() { + return Binder.getCallingUserHandle().getIdentifier(); + } +} diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java index d9f8588039da..bf9d1a34a37e 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java @@ -51,6 +51,7 @@ public final class BroadcastRadioServiceImpl { private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); private final Object mLock = new Object(); + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private int mNextModuleId; @@ -77,7 +78,7 @@ public final class BroadcastRadioServiceImpl { } RadioModule radioModule = - RadioModule.tryLoadingModule(moduleId, name, newBinder); + RadioModule.tryLoadingModule(moduleId, name, newBinder, mUserController); if (radioModule == null) { Slogf.w(TAG, "No module %s with id %d (HAL AIDL)", name, moduleId); return; @@ -141,9 +142,12 @@ public final class BroadcastRadioServiceImpl { * BroadcastRadio HAL services * * @param serviceNameList list of names of AIDL BroadcastRadio HAL services + * @param userController User controller implementation */ - public BroadcastRadioServiceImpl(ArrayList<String> serviceNameList) { + public BroadcastRadioServiceImpl(List<String> serviceNameList, + RadioServiceUserController userController) { mNextModuleId = 0; + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); if (DEBUG) { Slogf.d(TAG, "Initializing BroadcastRadioServiceImpl %s", IBroadcastRadio.DESCRIPTOR); } @@ -202,7 +206,7 @@ public final class BroadcastRadioServiceImpl { if (DEBUG) { Slogf.d(TAG, "Open AIDL radio session"); } - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.e(TAG, "Cannot open tuner on AIDL HAL client for non-current user"); throw new IllegalStateException("Cannot open session for non-current user"); } diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java index 03e347a903b5..928fa29b8f03 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java @@ -62,6 +62,7 @@ final class RadioModule { private final Handler mHandler; private final RadioEventLogger mLogger; private final RadioManager.ModuleProperties mProperties; + private final RadioServiceUserController mUserController; /** * Tracks antenna state reported by HAL (if any). @@ -194,15 +195,18 @@ final class RadioModule { }; @VisibleForTesting - RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties) { + RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties, + RadioServiceUserController userController) { mProperties = Objects.requireNonNull(properties, "properties cannot be null"); mService = Objects.requireNonNull(service, "service cannot be null"); mHandler = new Handler(Looper.getMainLooper()); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); mLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); } @Nullable - static RadioModule tryLoadingModule(int moduleId, String moduleName, IBinder serviceBinder) { + static RadioModule tryLoadingModule(int moduleId, String moduleName, IBinder serviceBinder, + RadioServiceUserController userController) { try { Slogf.i(TAG, "Try loading module for module id = %d, module name = %s", moduleId, moduleName); @@ -232,7 +236,7 @@ final class RadioModule { RadioManager.ModuleProperties prop = ConversionUtils.propertiesFromHalProperties( moduleId, moduleName, service.getProperties(), amfmConfig, dabConfig); - return new RadioModule(service, prop); + return new RadioModule(service, prop, userController); } catch (RemoteException ex) { Slogf.e(TAG, ex, "Failed to load module %s", moduleName); return null; @@ -255,7 +259,7 @@ final class RadioModule { RadioManager.ProgramInfo currentProgramInfo; synchronized (mLock) { boolean isFirstTunerSession = mAidlTunerSessions.isEmpty(); - tunerSession = new TunerSession(this, mService, userCb); + tunerSession = new TunerSession(this, mService, userCb, mUserController); mAidlTunerSessions.add(tunerSession); antennaConnected = mAntennaConnected; currentProgramInfo = mCurrentProgramInfo; @@ -433,7 +437,7 @@ final class RadioModule { @GuardedBy("mLock") private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) { - int currentUserId = RadioServiceUserController.getCurrentUser(); + int currentUserId = mUserController.getCurrentUser(); List<TunerSession> deadSessions = null; for (int i = 0; i < mAidlTunerSessions.size(); i++) { if (mAidlTunerSessions.valueAt(i).mUserId != currentUserId diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java index e90a1dda6cf5..f22661b72da1 100644 --- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java @@ -52,6 +52,7 @@ final class TunerSession extends ITuner.Stub { final android.hardware.radio.ITunerCallback mCallback; private final int mUid; private final IBroadcastRadio mService; + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private boolean mIsClosed; @@ -65,11 +66,13 @@ final class TunerSession extends ITuner.Stub { private RadioManager.BandConfig mPlaceHolderConfig; TunerSession(RadioModule radioModule, IBroadcastRadio service, - android.hardware.radio.ITunerCallback callback) { + android.hardware.radio.ITunerCallback callback, + RadioServiceUserController userController) { mModule = Objects.requireNonNull(radioModule, "radioModule cannot be null"); mService = Objects.requireNonNull(service, "service cannot be null"); - mUserId = Binder.getCallingUserHandle().getIdentifier(); mCallback = Objects.requireNonNull(callback, "callback cannot be null"); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); + mUserId = mUserController.getCallingUserId(); mUid = Binder.getCallingUid(); mLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); } @@ -126,7 +129,7 @@ final class TunerSession extends ITuner.Stub { @Override public void setConfiguration(RadioManager.BandConfig config) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set configuration for AIDL HAL client from non-current user"); return; } @@ -169,7 +172,7 @@ final class TunerSession extends ITuner.Stub { public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException { mLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot step on AIDL HAL client from non-current user"); return; } @@ -187,7 +190,7 @@ final class TunerSession extends ITuner.Stub { public void seek(boolean directionDown, boolean skipSubChannel) throws RemoteException { mLogger.logRadioEvent("Seek with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot scan on AIDL HAL client from non-current user"); return; } @@ -204,7 +207,7 @@ final class TunerSession extends ITuner.Stub { @Override public void tune(ProgramSelector selector) throws RemoteException { mLogger.logRadioEvent("Tune with selector %s", selector); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot tune on AIDL HAL client from non-current user"); return; } @@ -226,7 +229,7 @@ final class TunerSession extends ITuner.Stub { @Override public void cancel() { Slogf.i(TAG, "Cancel"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel on AIDL HAL client from non-current user"); return; } @@ -255,7 +258,7 @@ final class TunerSession extends ITuner.Stub { @Override public boolean startBackgroundScan() { Slogf.w(TAG, "Explicit background scan trigger is not supported with HAL AIDL"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start background scan on AIDL HAL client from non-current user"); return false; } @@ -268,7 +271,7 @@ final class TunerSession extends ITuner.Stub { @Override public void startProgramListUpdates(ProgramList.Filter filter) throws RemoteException { mLogger.logRadioEvent("Start programList updates %s", filter); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start program list updates on AIDL HAL client from non-current user"); return; @@ -344,7 +347,7 @@ final class TunerSession extends ITuner.Stub { @Override public void stopProgramListUpdates() throws RemoteException { mLogger.logRadioEvent("Stop programList updates"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot stop program list updates on AIDL HAL client from non-current user"); return; @@ -389,7 +392,7 @@ final class TunerSession extends ITuner.Stub { public void setConfigFlag(int flag, boolean value) throws RemoteException { mLogger.logRadioEvent("set ConfigFlag %s to %b ", ConfigFlag.$.toString(flag), value); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set config flag for AIDL HAL client from non-current user"); return; } @@ -406,7 +409,7 @@ final class TunerSession extends ITuner.Stub { @Override public Map<String, String> setParameters(Map<String, String> parameters) { mLogger.logRadioEvent("Set parameters "); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set parameters for AIDL HAL client from non-current user"); return new ArrayMap<>(); } diff --git a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java index fb42c94b56f4..6a6a3ae44c8b 100644 --- a/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal1/BroadcastRadioService.java @@ -35,6 +35,7 @@ public class BroadcastRadioService { * This field is used by native code, do not access or modify. */ private final long mNativeContext = nativeInit(); + private final RadioServiceUserController mUserController; private final Object mLock = new Object(); @@ -50,6 +51,10 @@ public class BroadcastRadioService { private native Tuner nativeOpenTuner(long nativeContext, int moduleId, RadioManager.BandConfig config, boolean withAudio, ITunerCallback callback); + public BroadcastRadioService(RadioServiceUserController userController) { + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); + } + public @NonNull List<RadioManager.ModuleProperties> loadModules() { synchronized (mLock) { return Objects.requireNonNull(nativeLoadModules(mNativeContext)); @@ -58,7 +63,7 @@ public class BroadcastRadioService { public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig, boolean withAudio, ITunerCallback callback) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.e(TAG, "Cannot open tuner on HAL 1.x client for non-current user"); throw new IllegalStateException("Cannot open tuner for non-current user"); } diff --git a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java index 7cac4091c583..8e64600d2694 100644 --- a/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java +++ b/services/core/java/com/android/server/broadcastradio/hal1/Tuner.java @@ -28,6 +28,7 @@ import android.os.IBinder; import android.os.RemoteException; import com.android.server.broadcastradio.RadioServiceUserController; +import com.android.server.broadcastradio.RadioServiceUserControllerImpl; import com.android.server.utils.Slogf; import java.util.List; @@ -51,6 +52,7 @@ class Tuner extends ITuner.Stub { private boolean mIsMuted = false; private int mRegion; private final boolean mWithAudio; + private final RadioServiceUserController mUserController = new RadioServiceUserControllerImpl(); Tuner(@NonNull ITunerCallback clientCallback, int halRev, int region, boolean withAudio, int band) { @@ -127,7 +129,7 @@ class Tuner extends ITuner.Stub { @Override public void setConfiguration(RadioManager.BandConfig config) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set configuration for HAL 1.x client from non-current user"); return; } @@ -176,7 +178,7 @@ class Tuner extends ITuner.Stub { @Override public void step(boolean directionDown, boolean skipSubChannel) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot step on HAL 1.x client from non-current user"); return; } @@ -189,7 +191,7 @@ class Tuner extends ITuner.Stub { @Override public void seek(boolean directionDown, boolean skipSubChannel) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot seek on HAL 1.x client from non-current user"); return; } @@ -202,7 +204,7 @@ class Tuner extends ITuner.Stub { @Override public void tune(ProgramSelector selector) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot tune on HAL 1.x client from non-current user"); return; } @@ -219,7 +221,7 @@ class Tuner extends ITuner.Stub { @Override public void cancel() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel on HAL 1.x client from non-current user"); return; } @@ -231,7 +233,7 @@ class Tuner extends ITuner.Stub { @Override public void cancelAnnouncement() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel announcement on HAL 1.x client from non-current user"); return; } @@ -260,7 +262,7 @@ class Tuner extends ITuner.Stub { @Override public boolean startBackgroundScan() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start background scan on HAL 1.x client from non-current user"); return false; @@ -285,7 +287,7 @@ class Tuner extends ITuner.Stub { @Override public void startProgramListUpdates(ProgramList.Filter filter) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start program list updates on HAL 1.x client from non-current user"); return; @@ -295,7 +297,7 @@ class Tuner extends ITuner.Stub { @Override public void stopProgramListUpdates() { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot stop program list updates on HAL 1.x client from non-current user"); return; @@ -321,7 +323,7 @@ class Tuner extends ITuner.Stub { @Override public void setConfigFlag(int flag, boolean value) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set config flag for HAL 1.x client from non-current user"); return; } diff --git a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java index a4efa2e330f8..3227afd82dbd 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/BroadcastRadioService.java @@ -50,6 +50,8 @@ public final class BroadcastRadioService { private final Object mLock = new Object(); + private final RadioServiceUserController mUserController; + @GuardedBy("mLock") private int mNextModuleId; @@ -75,7 +77,8 @@ public final class BroadcastRadioService { moduleId = mNextModuleId; } - RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName); + RadioModule radioModule = RadioModule.tryLoadingModule(moduleId, serviceName, + mUserController); if (radioModule == null) { return; } @@ -123,8 +126,9 @@ public final class BroadcastRadioService { } }; - public BroadcastRadioService(int nextModuleId) { + public BroadcastRadioService(int nextModuleId, RadioServiceUserController userController) { mNextModuleId = nextModuleId; + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); try { IServiceManager manager = IServiceManager.getService(); if (manager == null) { @@ -138,8 +142,10 @@ public final class BroadcastRadioService { } @VisibleForTesting - BroadcastRadioService(int nextModuleId, IServiceManager manager) { + BroadcastRadioService(int nextModuleId, IServiceManager manager, + RadioServiceUserController userController) { mNextModuleId = nextModuleId; + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); Objects.requireNonNull(manager, "Service manager cannot be null"); try { manager.registerForNotifications(IBroadcastRadio.kInterfaceName, "", mServiceListener); @@ -171,7 +177,7 @@ public final class BroadcastRadioService { public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig, boolean withAudio, @NonNull ITunerCallback callback) throws RemoteException { Slogf.v(TAG, "Open HIDL 2.0 session with module id " + moduleId); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.e(TAG, "Cannot open tuner on HAL 2.0 client for non-current user"); throw new IllegalStateException("Cannot open session for non-current user"); } diff --git a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java index d3b244886a64..a0d6cc2c75b0 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/RadioModule.java @@ -66,6 +66,7 @@ final class RadioModule { private final Object mLock = new Object(); private final Handler mHandler; private final RadioEventLogger mEventLogger; + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private ITunerSession mHalTunerSession; @@ -148,16 +149,18 @@ final class RadioModule { private final Set<TunerSession> mAidlTunerSessions = new ArraySet<>(); @VisibleForTesting - RadioModule(@NonNull IBroadcastRadio service, - @NonNull RadioManager.ModuleProperties properties) { + RadioModule(IBroadcastRadio service, RadioManager.ModuleProperties properties, + RadioServiceUserController userController) { mProperties = Objects.requireNonNull(properties); mService = Objects.requireNonNull(service); mHandler = new Handler(Looper.getMainLooper()); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); mEventLogger = new RadioEventLogger(TAG, RADIO_EVENT_LOGGER_QUEUE_SIZE); } @Nullable - static RadioModule tryLoadingModule(int idx, @NonNull String fqName) { + static RadioModule tryLoadingModule(int idx, String fqName, + RadioServiceUserController controller) { try { Slogf.i(TAG, "Try loading module for idx " + idx + ", fqName " + fqName); IBroadcastRadio service = IBroadcastRadio.getService(fqName); @@ -179,7 +182,7 @@ final class RadioModule { RadioManager.ModuleProperties prop = Convert.propertiesFromHal(idx, fqName, service.getProperties(), amfmConfig.value, dabConfig.value); - return new RadioModule(service, prop); + return new RadioModule(service, prop, controller); } catch (RemoteException ex) { Slogf.e(TAG, "Failed to load module " + fqName, ex); return null; @@ -208,7 +211,8 @@ final class RadioModule { }); mHalTunerSession = Objects.requireNonNull(hwSession.value); } - TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb); + TunerSession tunerSession = new TunerSession(this, mHalTunerSession, userCb, + mUserController); mAidlTunerSessions.add(tunerSession); // Propagate state to new client. Note: These callbacks are invoked while holding mLock @@ -375,7 +379,7 @@ final class RadioModule { @GuardedBy("mLock") private void fanoutAidlCallbackLocked(AidlCallbackRunnable runnable) { - int currentUserId = RadioServiceUserController.getCurrentUser(); + int currentUserId = mUserController.getCurrentUser(); List<TunerSession> deadSessions = null; for (TunerSession tunerSession : mAidlTunerSessions) { if (tunerSession.mUserId != currentUserId && tunerSession.mUserId diff --git a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java index 80efacdb12ee..dc164b1e6eff 100644 --- a/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java +++ b/services/core/java/com/android/server/broadcastradio/hal2/TunerSession.java @@ -16,7 +16,6 @@ package com.android.server.broadcastradio.hal2; -import android.annotation.NonNull; import android.annotation.Nullable; import android.graphics.Bitmap; import android.hardware.broadcastradio.V2_0.ConfigFlag; @@ -27,7 +26,6 @@ import android.hardware.radio.ITuner; import android.hardware.radio.ProgramList; import android.hardware.radio.ProgramSelector; import android.hardware.radio.RadioManager; -import android.os.Binder; import android.os.RemoteException; import android.util.ArrayMap; import android.util.ArraySet; @@ -55,6 +53,7 @@ final class TunerSession extends ITuner.Stub { private final ITunerSession mHwSession; final int mUserId; final android.hardware.radio.ITunerCallback mCallback; + private final RadioServiceUserController mUserController; @GuardedBy("mLock") private boolean mIsClosed = false; @@ -66,12 +65,14 @@ final class TunerSession extends ITuner.Stub { // necessary only for older APIs compatibility private RadioManager.BandConfig mDummyConfig = null; - TunerSession(@NonNull RadioModule module, @NonNull ITunerSession hwSession, - @NonNull android.hardware.radio.ITunerCallback callback) { + TunerSession(RadioModule module, ITunerSession hwSession, + android.hardware.radio.ITunerCallback callback, + RadioServiceUserController userController) { mModule = Objects.requireNonNull(module); mHwSession = Objects.requireNonNull(hwSession); - mUserId = Binder.getCallingUserHandle().getIdentifier(); mCallback = Objects.requireNonNull(callback); + mUserController = Objects.requireNonNull(userController, "User controller can not be null"); + mUserId = mUserController.getCallingUserId(); mEventLogger = new RadioEventLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE); } @@ -120,7 +121,7 @@ final class TunerSession extends ITuner.Stub { @Override public void setConfiguration(RadioManager.BandConfig config) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set configuration for HAL 2.0 client from non-current user"); return; } @@ -162,7 +163,7 @@ final class TunerSession extends ITuner.Stub { public void step(boolean directionDown, boolean skipSubChannel) throws RemoteException { mEventLogger.logRadioEvent("Step with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot step on HAL 2.0 client from non-current user"); return; } @@ -177,7 +178,7 @@ final class TunerSession extends ITuner.Stub { public void seek(boolean directionDown, boolean skipSubChannel) throws RemoteException { mEventLogger.logRadioEvent("Seek with direction %s, skipSubChannel? %s", directionDown ? "down" : "up", skipSubChannel ? "yes" : "no"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot scan on HAL 2.0 client from non-current user"); return; } @@ -191,7 +192,7 @@ final class TunerSession extends ITuner.Stub { @Override public void tune(ProgramSelector selector) throws RemoteException { mEventLogger.logRadioEvent("Tune with selector %s", selector); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot tune on HAL 2.0 client from non-current user"); return; } @@ -205,7 +206,7 @@ final class TunerSession extends ITuner.Stub { @Override public void cancel() { Slogf.i(TAG, "Cancel"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot cancel on HAL 2.0 client from non-current user"); return; } @@ -230,7 +231,7 @@ final class TunerSession extends ITuner.Stub { @Override public boolean startBackgroundScan() { Slogf.w(TAG, "Explicit background scan trigger is not supported with HAL 2.0"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start background scan on HAL 2.0 client from non-current user"); return false; @@ -242,7 +243,7 @@ final class TunerSession extends ITuner.Stub { @Override public void startProgramListUpdates(ProgramList.Filter filter) { mEventLogger.logRadioEvent("start programList updates %s", filter); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot start program list updates on HAL 2.0 client from non-current user"); return; @@ -306,7 +307,7 @@ final class TunerSession extends ITuner.Stub { @Override public void stopProgramListUpdates() throws RemoteException { mEventLogger.logRadioEvent("Stop programList updates"); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot stop program list updates on HAL 2.0 client from non-current user"); return; @@ -355,7 +356,7 @@ final class TunerSession extends ITuner.Stub { @Override public void setConfigFlag(int flag, boolean value) throws RemoteException { mEventLogger.logRadioEvent("Set ConfigFlag %s = %b", ConfigFlag.toString(flag), value); - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set config flag for HAL 2.0 client from non-current user"); return; } @@ -368,7 +369,7 @@ final class TunerSession extends ITuner.Stub { @Override public Map<String, String> setParameters(Map<String, String> parameters) { - if (!RadioServiceUserController.isCurrentOrSystemUser()) { + if (!mUserController.isCurrentOrSystemUser()) { Slogf.w(TAG, "Cannot set parameters for HAL 2.0 client from non-current user"); return new ArrayMap<>(); } diff --git a/services/core/java/com/android/server/display/DisplayPowerController.java b/services/core/java/com/android/server/display/DisplayPowerController.java index ae59d491b8f4..df768dcc564f 100644 --- a/services/core/java/com/android/server/display/DisplayPowerController.java +++ b/services/core/java/com/android/server/display/DisplayPowerController.java @@ -587,7 +587,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call mUniqueDisplayId, mThermalBrightnessThrottlingDataId, logicalDisplay.getPowerThrottlingDataIdLocked(), - mDisplayDeviceConfig), mContext, flags, mSensorManager); + mDisplayDeviceConfig, + mDisplayId), mContext, flags, mSensorManager); // Seed the cached brightness saveBrightnessInfo(getScreenBrightnessSetting()); mAutomaticBrightnessStrategy = @@ -892,7 +893,8 @@ final class DisplayPowerController implements AutomaticBrightnessController.Call // will call updatePowerState if needed. mBrightnessClamperController.onDisplayChanged( new BrightnessClamperController.DisplayDeviceData(uniqueId, - thermalBrightnessThrottlingDataId, powerThrottlingDataId, config)); + thermalBrightnessThrottlingDataId, powerThrottlingDataId, + config, mDisplayId)); if (changed) { updatePowerState(); diff --git a/services/core/java/com/android/server/display/TEST_MAPPING b/services/core/java/com/android/server/display/TEST_MAPPING index 049b2fd032db..4d7962f467fd 100644 --- a/services/core/java/com/android/server/display/TEST_MAPPING +++ b/services/core/java/com/android/server/display/TEST_MAPPING @@ -1,21 +1,12 @@ { "presubmit": [ { - "name": "DisplayServiceTests", - "options": [ - {"include-filter": "com.android.server.display"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DisplayServiceTests_server_display" } ], "postsubmit": [ { - "name": "DisplayServiceTests", - "options": [ - {"include-filter": "com.android.server.display"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DisplayServiceTests_server_display" } ] } diff --git a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java index 101ad307f50a..220640270e02 100644 --- a/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java +++ b/services/core/java/com/android/server/display/brightness/clamper/BrightnessClamperController.java @@ -23,23 +23,17 @@ import static com.android.server.display.brightness.clamper.BrightnessClamper.Ty import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; -import android.content.res.Resources; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManagerInternal; import android.os.Handler; import android.os.HandlerExecutor; import android.os.PowerManager; -import android.os.SystemClock; import android.provider.DeviceConfig; import android.provider.DeviceConfigInterface; import android.util.IndentingPrintWriter; import android.util.Slog; -import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.server.display.DisplayBrightnessState; import com.android.server.display.DisplayDeviceConfig; @@ -50,30 +44,22 @@ import com.android.server.display.brightness.BrightnessReason; import com.android.server.display.config.SensorData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.feature.DisplayManagerFlags; -import com.android.server.display.utils.AmbientFilter; -import com.android.server.display.utils.AmbientFilterFactory; -import com.android.server.display.utils.DebugUtils; -import com.android.server.display.utils.SensorUtils; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; -import java.util.concurrent.TimeUnit; /** * Clampers controller, all in DisplayControllerHandler */ public class BrightnessClamperController { private static final String TAG = "BrightnessClamperController"; - // To enable these logs, run: - // 'adb shell setprop persist.log.tag.BrightnessClamperController DEBUG && adb reboot' - private static final boolean DEBUG = DebugUtils.isDebuggable(TAG); - public static final float INVALID_LUX = -1f; private final DeviceConfigParameterProvider mDeviceConfigParameterProvider; private final Handler mHandler; - private final SensorManager mSensorManager; + private final LightSensorController mLightSensorController; + private final ClamperChangeListener mClamperChangeListenerExternal; private final Executor mExecutor; private final List<BrightnessClamper<? super DisplayDeviceData>> mClampers; @@ -85,70 +71,49 @@ public class BrightnessClamperController { private float mCustomAnimationRate = DisplayBrightnessState.CUSTOM_ANIMATION_RATE_NOT_SET; @Nullable private Type mClamperType = null; - private final SensorEventListener mLightSensorListener; - private Sensor mRegisteredLightSensor = null; - private Sensor mLightSensor; - private String mLightSensorType; - private String mLightSensorName; - private AmbientFilter mAmbientFilter; - private final DisplayDeviceConfig mDisplayDeviceConfig; - private final Resources mResources; - private final int mLightSensorRate; - - private final Injector mInjector; + private boolean mClamperApplied = false; + private final LightSensorController.LightSensorListener mLightSensorListener = + new LightSensorController.LightSensorListener() { + @Override + public void onAmbientLuxChange(float lux) { + mModifiers.forEach(mModifier -> mModifier.setAmbientLux(lux)); + } + }; + public BrightnessClamperController(Handler handler, ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context, DisplayManagerFlags flags, SensorManager sensorManager) { - this(null, handler, clamperChangeListener, data, context, flags, sensorManager); + this(new Injector(), handler, clamperChangeListener, data, context, flags, sensorManager); } @VisibleForTesting BrightnessClamperController(Injector injector, Handler handler, ClamperChangeListener clamperChangeListener, DisplayDeviceData data, Context context, DisplayManagerFlags flags, SensorManager sensorManager) { - mInjector = injector == null ? new Injector() : injector; - mDeviceConfigParameterProvider = mInjector.getDeviceConfigParameterProvider(); + mDeviceConfigParameterProvider = injector.getDeviceConfigParameterProvider(); mHandler = handler; - mSensorManager = sensorManager; - mDisplayDeviceConfig = data.mDisplayDeviceConfig; - mLightSensorListener = new SensorEventListener() { - @Override - public void onSensorChanged(SensorEvent event) { - long now = SystemClock.elapsedRealtime(); - mAmbientFilter.addValue(TimeUnit.NANOSECONDS.toMillis(event.timestamp), - event.values[0]); - final float lux = mAmbientFilter.getEstimate(now); - mModifiers.forEach(mModifier -> mModifier.setAmbientLux(lux)); - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // unused - } - }; + mLightSensorController = injector.getLightSensorController(sensorManager, context, + mLightSensorListener, mHandler); mClamperChangeListenerExternal = clamperChangeListener; mExecutor = new HandlerExecutor(handler); - mResources = context.getResources(); - mLightSensorRate = context.getResources().getInteger( - R.integer.config_autoBrightnessLightSensorRate); Runnable clamperChangeRunnableInternal = this::recalculateBrightnessCap; - ClamperChangeListener clamperChangeListenerInternal = () -> { if (!mHandler.hasCallbacks(clamperChangeRunnableInternal)) { mHandler.post(clamperChangeRunnableInternal); } }; - mClampers = mInjector.getClampers(handler, clamperChangeListenerInternal, data, flags, + mClampers = injector.getClampers(handler, clamperChangeListenerInternal, data, flags, context); - mModifiers = mInjector.getModifiers(flags, context, handler, clamperChangeListener, - data.mDisplayDeviceConfig, mSensorManager); + mModifiers = injector.getModifiers(flags, context, handler, clamperChangeListener, + data.mDisplayDeviceConfig); mOnPropertiesChangedListener = properties -> mClampers.forEach(BrightnessClamper::onDeviceConfigChanged); + mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId()); start(); } @@ -156,7 +121,9 @@ public class BrightnessClamperController { * Should be called when display changed. Forwards the call to individual clampers */ public void onDisplayChanged(DisplayDeviceData data) { + mLightSensorController.configure(data.getAmbientLightSensor(), data.getDisplayId()); mClampers.forEach(clamper -> clamper.onDisplayChanged(data)); + adjustLightSensorSubscription(); } /** @@ -184,9 +151,9 @@ public class BrightnessClamperController { } if (displayState != STATE_ON) { - unregisterSensorListener(); + mLightSensorController.stop(); } else { - maybeRegisterLightSensor(); + adjustLightSensorSubscription(); } for (int i = 0; i < mModifiers.size(); i++) { @@ -231,9 +198,8 @@ public class BrightnessClamperController { writer.println(" mBrightnessCap: " + mBrightnessCap); writer.println(" mClamperType: " + mClamperType); writer.println(" mClamperApplied: " + mClamperApplied); - writer.println(" mLightSensor=" + mLightSensor); - writer.println(" mRegisteredLightSensor=" + mRegisteredLightSensor); IndentingPrintWriter ipw = new IndentingPrintWriter(writer, " "); + mLightSensorController.dump(ipw); mClampers.forEach(clamper -> clamper.dump(ipw)); mModifiers.forEach(modifier -> modifier.dump(ipw)); } @@ -245,6 +211,7 @@ public class BrightnessClamperController { public void stop() { mDeviceConfigParameterProvider.removeOnPropertiesChangedListener( mOnPropertiesChangedListener); + mLightSensorController.stop(); mClampers.forEach(BrightnessClamper::stop); mModifiers.forEach(BrightnessStateModifier::stop); } @@ -281,10 +248,15 @@ public class BrightnessClamperController { if (!mClampers.isEmpty()) { mDeviceConfigParameterProvider.addOnPropertiesChangedListener( mExecutor, mOnPropertiesChangedListener); - reloadLightSensorData(mDisplayDeviceConfig); - mLightSensor = mInjector.getLightSensor( - mSensorManager, mLightSensorType, mLightSensorName); - maybeRegisterLightSensor(); + } + adjustLightSensorSubscription(); + } + + private void adjustLightSensorSubscription() { + if (mModifiers.stream().anyMatch(BrightnessStateModifier::shouldListenToLightSensor)) { + mLightSensorController.restart(); + } else { + mLightSensorController.stop(); } } @@ -323,7 +295,7 @@ public class BrightnessClamperController { List<BrightnessStateModifier> getModifiers(DisplayManagerFlags flags, Context context, Handler handler, ClamperChangeListener listener, - DisplayDeviceConfig displayDeviceConfig, SensorManager sensorManager) { + DisplayDeviceConfig displayDeviceConfig) { List<BrightnessStateModifier> modifiers = new ArrayList<>(); modifiers.add(new DisplayDimModifier(context)); modifiers.add(new BrightnessLowPowerModeModifier()); @@ -335,11 +307,12 @@ public class BrightnessClamperController { return modifiers; } - Sensor getLightSensor(SensorManager sensorManager, String type, String name) { - return SensorUtils.findSensor(sensorManager, type, - name, Sensor.TYPE_LIGHT); + LightSensorController getLightSensorController(SensorManager sensorManager, + Context context, LightSensorController.LightSensorListener listener, + Handler handler) { + return new LightSensorController(sensorManager, context.getResources(), + listener, handler); } - } /** @@ -354,17 +327,21 @@ public class BrightnessClamperController { private final String mThermalThrottlingDataId; @NonNull private final String mPowerThrottlingDataId; - + @NonNull private final DisplayDeviceConfig mDisplayDeviceConfig; + private final int mDisplayId; + public DisplayDeviceData(@NonNull String uniqueDisplayId, @NonNull String thermalThrottlingDataId, @NonNull String powerThrottlingDataId, - @NonNull DisplayDeviceConfig displayDeviceConfig) { + @NonNull DisplayDeviceConfig displayDeviceConfig, + int displayId) { mUniqueDisplayId = uniqueDisplayId; mThermalThrottlingDataId = thermalThrottlingDataId; mPowerThrottlingDataId = powerThrottlingDataId; mDisplayDeviceConfig = displayDeviceConfig; + mDisplayId = displayId; } @@ -412,55 +389,18 @@ public class BrightnessClamperController { } @NonNull + @Override public SensorData getTempSensor() { return mDisplayDeviceConfig.getTempSensor(); } - } - - private void maybeRegisterLightSensor() { - if (mModifiers.stream().noneMatch(BrightnessStateModifier::shouldListenToLightSensor)) { - return; - } - - if (mRegisteredLightSensor == mLightSensor) { - return; - } - if (mRegisteredLightSensor != null) { - unregisterSensorListener(); - } - - mAmbientFilter = AmbientFilterFactory.createBrightnessFilter(TAG, mResources); - mSensorManager.registerListener(mLightSensorListener, - mLightSensor, mLightSensorRate * 1000, mHandler); - mRegisteredLightSensor = mLightSensor; - - if (DEBUG) { - Slog.d(TAG, "maybeRegisterLightSensor"); - } - } - - private void unregisterSensorListener() { - mSensorManager.unregisterListener(mLightSensorListener); - mRegisteredLightSensor = null; - mModifiers.forEach(mModifier -> mModifier.setAmbientLux(INVALID_LUX)); // set lux to invalid - if (DEBUG) { - Slog.d(TAG, "unregisterSensorListener"); + @NonNull + SensorData getAmbientLightSensor() { + return mDisplayDeviceConfig.getAmbientLightSensor(); } - } - private void reloadLightSensorData(DisplayDeviceConfig displayDeviceConfig) { - // The displayDeviceConfig (ddc) contains display specific preferences. When loaded, - // it naturally falls back to the global config.xml. - if (displayDeviceConfig != null - && displayDeviceConfig.getAmbientLightSensor() != null) { - // This covers both the ddc and the config.xml fallback - mLightSensorType = displayDeviceConfig.getAmbientLightSensor().type; - mLightSensorName = displayDeviceConfig.getAmbientLightSensor().name; - } else if (mLightSensorName == null && mLightSensorType == null) { - mLightSensorType = mResources.getString( - com.android.internal.R.string.config_displayLightSensorType); - mLightSensorName = ""; + int getDisplayId() { + return mDisplayId; } } } diff --git a/services/core/java/com/android/server/display/brightness/clamper/LightSensorController.java b/services/core/java/com/android/server/display/brightness/clamper/LightSensorController.java new file mode 100644 index 000000000000..d89dd28c4a89 --- /dev/null +++ b/services/core/java/com/android/server/display/brightness/clamper/LightSensorController.java @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2024 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.display.brightness.clamper; + +import android.annotation.Nullable; +import android.content.res.Resources; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.os.Handler; +import android.os.SystemClock; +import android.util.Slog; +import android.view.Display; + +import com.android.internal.R; +import com.android.internal.annotations.VisibleForTesting; +import com.android.server.display.config.SensorData; +import com.android.server.display.utils.AmbientFilter; +import com.android.server.display.utils.AmbientFilterFactory; +import com.android.server.display.utils.DebugUtils; +import com.android.server.display.utils.SensorUtils; + +import java.io.PrintWriter; +import java.util.concurrent.TimeUnit; + +/** + * Manages light sensor subscription and notifies its listener about ambient lux changes + */ +public class LightSensorController { + private static final String TAG = "LightSensorController"; + + // To enable these logs, run: + // 'adb shell setprop persist.log.tag.LightSensorController DEBUG && adb reboot' + private static final boolean DEBUG = DebugUtils.isDebuggable(TAG); + static final float INVALID_LUX = -1f; + + private final SensorManager mSensorManager; + private final LightSensorListener mLightSensorListener; + private final Handler mHandler; + private final Injector mInjector; + private final AmbientFilter mAmbientFilter; + + private Sensor mLightSensor; + private Sensor mRegisteredLightSensor = null; + private final int mLightSensorRate; + + private final SensorEventListener mLightSensorEventListener = new SensorEventListener() { + @Override + public void onSensorChanged(SensorEvent event) { + long now = mInjector.getTime(); + mAmbientFilter.addValue(TimeUnit.NANOSECONDS.toMillis(event.timestamp), + event.values[0]); + final float lux = mAmbientFilter.getEstimate(now); + mLightSensorListener.onAmbientLuxChange(lux); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + // unused + } + }; + + LightSensorController(SensorManager sensorManager, Resources resources, + LightSensorListener listener, Handler handler) { + this(sensorManager, resources, listener, handler, new Injector()); + } + + @VisibleForTesting + LightSensorController(SensorManager sensorManager, Resources resources, + LightSensorListener listener, Handler handler, Injector injector) { + mSensorManager = sensorManager; + mLightSensorRate = injector.getLightSensorRate(resources); + mAmbientFilter = injector.getAmbientFilter(resources); + mLightSensorListener = listener; + mHandler = handler; + mInjector = injector; + } + + void restart() { + if (mRegisteredLightSensor == mLightSensor) { + return; + } + if (mRegisteredLightSensor != null) { + stop(); + } + if (mLightSensor == null) { + return; + } + + mSensorManager.registerListener(mLightSensorEventListener, + mLightSensor, mLightSensorRate * 1000, mHandler); + mRegisteredLightSensor = mLightSensor; + + if (DEBUG) { + Slog.d(TAG, "restart"); + } + } + + void stop() { + if (mRegisteredLightSensor == null) { + return; + } + mSensorManager.unregisterListener(mLightSensorEventListener); + mRegisteredLightSensor = null; + mAmbientFilter.clear(); + mLightSensorListener.onAmbientLuxChange(INVALID_LUX); + if (DEBUG) { + Slog.d(TAG, "stop"); + } + } + + void configure(SensorData sensorData, int displayId) { + final int fallbackType = displayId == Display.DEFAULT_DISPLAY + ? Sensor.TYPE_LIGHT : SensorUtils.NO_FALLBACK; + mLightSensor = mInjector.getLightSensor(mSensorManager, sensorData, fallbackType); + } + + void dump(PrintWriter writer) { + writer.println("LightSensorController"); + writer.println(" mLightSensor=" + mLightSensor); + writer.println(" mRegisteredLightSensor=" + mRegisteredLightSensor); + } + + static class Injector { + @Nullable + Sensor getLightSensor(SensorManager sensorManager, SensorData sensorData, + int fallbackType) { + return SensorUtils.findSensor(sensorManager, sensorData, fallbackType); + } + + AmbientFilter getAmbientFilter(Resources resources) { + return AmbientFilterFactory.createBrightnessFilter(TAG, resources); + } + + int getLightSensorRate(Resources resources) { + return resources.getInteger(R.integer.config_autoBrightnessLightSensorRate); + } + + // should be consistent with SensorEvent.timestamp + long getTime() { + return SystemClock.elapsedRealtime(); + } + } + + interface LightSensorListener { + void onAmbientLuxChange(float ambientLux); + } +} diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java index cd2c0378446e..339a062c1a80 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecController.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java @@ -1207,9 +1207,11 @@ final class HdmiCecController { @Override public void onValues(int result, short addr) { - if (result == Result.SUCCESS) { - synchronized (mLock) { - mPhysicalAddress = new Short(addr).intValue(); + synchronized (mLock) { + if (result == Result.SUCCESS) { + mPhysicalAddress = Short.toUnsignedInt(addr); + } else { + mPhysicalAddress = INVALID_PHYSICAL_ADDRESS; } } } @@ -1605,9 +1607,11 @@ final class HdmiCecController { @Override public void onValues(int result, short addr) { - if (result == Result.SUCCESS) { - synchronized (mLock) { - mPhysicalAddress = new Short(addr).intValue(); + synchronized (mLock) { + if (result == Result.SUCCESS) { + mPhysicalAddress = Short.toUnsignedInt(addr); + } else { + mPhysicalAddress = INVALID_PHYSICAL_ADDRESS; } } } diff --git a/services/core/java/com/android/server/hdmi/TEST_MAPPING b/services/core/java/com/android/server/hdmi/TEST_MAPPING index 1c85c7f1233c..bacacafb1153 100644 --- a/services/core/java/com/android/server/hdmi/TEST_MAPPING +++ b/services/core/java/com/android/server/hdmi/TEST_MAPPING @@ -6,32 +6,13 @@ ], "postsubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.hdmi" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksServicesTests_android_server_hdmi" } ], // Postsubmit tests for TV devices "tv-postsubmit": [ { - "name": "HdmiCecTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "include-filter": "android.hardware.hdmi" - } - ], + "name": "HdmiCecTests_hardware_hdmi", "file_patterns": [ "(/|^)DeviceFeature[^/]*", "(/|^)Hdmi[^/]*" ] diff --git a/services/core/java/com/android/server/lights/TEST_MAPPING b/services/core/java/com/android/server/lights/TEST_MAPPING index 1d2cd3c6e217..8abdf0069e1f 100644 --- a/services/core/java/com/android/server/lights/TEST_MAPPING +++ b/services/core/java/com/android/server/lights/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsHardwareTestCases", - "options": [ - {"include-filter": "com.android.hardware.lights"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsHardwareTestCases_hardware_lights" }, { "name": "FrameworksServicesTests_android_server_lights" diff --git a/services/core/java/com/android/server/location/TEST_MAPPING b/services/core/java/com/android/server/location/TEST_MAPPING index 64b1ed20656e..b2ac7d1ef7e7 100644 --- a/services/core/java/com/android/server/location/TEST_MAPPING +++ b/services/core/java/com/android/server/location/TEST_MAPPING @@ -1,13 +1,7 @@ { "presubmit": [ { - "name": "CtsLocationFineTestCases", - "options": [ - { - // TODO: Wait for test to deflake - b/293934372 - "exclude-filter":"android.location.cts.fine.ScanningSettingsTest" - } - ] + "name": "CtsLocationFineTestCases_android_server_location" }, { "name": "CtsLocationCoarseTestCases" diff --git a/services/core/java/com/android/server/locksettings/Android.bp b/services/core/java/com/android/server/locksettings/Android.bp new file mode 100644 index 000000000000..53f1ac668e49 --- /dev/null +++ b/services/core/java/com/android/server/locksettings/Android.bp @@ -0,0 +1,11 @@ +aconfig_declarations { + name: "locksettings_flags", + package: "com.android.server.locksettings", + container: "system", + srcs: ["*.aconfig"], +} + +java_aconfig_library { + name: "locksettings_flags_lib", + aconfig_declarations: "locksettings_flags", +} diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 7d44ba199119..3780fbd61e79 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -16,7 +16,6 @@ package com.android.server.locksettings; -import static android.security.Flags.reportPrimaryAuthAttempts; import static android.Manifest.permission.ACCESS_KEYGUARD_SECURE_STORAGE; import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION; import static android.Manifest.permission.MANAGE_BIOMETRIC; @@ -32,6 +31,7 @@ import static android.content.Intent.ACTION_MAIN_USER_LOCKSCREEN_KNOWLEDGE_FACTO import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.os.UserHandle.USER_ALL; import static android.os.UserHandle.USER_SYSTEM; +import static android.security.Flags.reportPrimaryAuthAttempts; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_PASSWORD_OR_PIN; @@ -1836,6 +1836,13 @@ public class LockSettingsService extends ILockSettings.Stub { } /** + * Set a new LSKF for the given user/profile. Only succeeds if the synthetic password for the + * user is protected by the given {@param savedCredential}. + * <p> + * When {@link android.security.Flags#clearStrongAuthOnAddPrimaryCredential()} is enabled and + * setting a new credential where there was none, updates the strong auth state for + * {@param userId} to <tt>STRONG_AUTH_NOT_REQUIRED</tt>. + * * @param savedCredential if the user is a profile with * {@link UserManager#isCredentialSharableWithParent()} with unified challenge and * savedCredential is empty, LSS will try to re-derive the profile password internally. @@ -1884,6 +1891,12 @@ public class LockSettingsService extends ILockSettings.Stub { onSyntheticPasswordUnlocked(userId, sp); setLockCredentialWithSpLocked(credential, sp, userId); + if (android.security.Flags.clearStrongAuthOnAddPrimaryCredential() + && savedCredential.isNone() && !credential.isNone()) { + // Clear the strong auth value, since the LSKF has just been entered and set, + // but only when the previous credential was None. + mStrongAuth.reportUnlock(userId); + } sendCredentialsOnChangeIfRequired(credential, userId, isLockTiedToParent); return true; } diff --git a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java index 158d444bcff2..1e25f1cf1d5e 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsStorage.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsStorage.java @@ -140,7 +140,7 @@ class LockSettingsStorage { try { db.delete(TABLE, COLUMN_KEY + "=? AND " + COLUMN_USERID + "=?", new String[] {key, Integer.toString(userId)}); - db.insert(TABLE, null, cv); + db.insertOrThrow(TABLE, null, cv); db.setTransactionSuccessful(); mCache.putKeyValue(key, value, userId); } finally { diff --git a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java index f44b85273af6..820c0efcc1cf 100644 --- a/services/core/java/com/android/server/locksettings/RebootEscrowManager.java +++ b/services/core/java/com/android/server/locksettings/RebootEscrowManager.java @@ -273,11 +273,6 @@ class RebootEscrowManager { "server_based_ror_enabled", false); } - public boolean waitForInternet() { - return DeviceConfig.getBoolean( - DeviceConfig.NAMESPACE_OTA, "wait_for_internet_ror", false); - } - public boolean isNetworkConnected() { final ConnectivityManager connectivityManager = mContext.getSystemService(ConnectivityManager.class); @@ -433,7 +428,7 @@ class RebootEscrowManager { /** Wrapper function to set error code serialized through handler, */ private void setLoadEscrowDataErrorCode(@RebootEscrowErrorCode int value, Handler handler) { - if (mInjector.waitForInternet()) { + if (Flags.waitForInternetRor()) { mInjector.post( handler, () -> { @@ -516,7 +511,7 @@ class RebootEscrowManager { mWakeLock.acquire(mInjector.getWakeLockTimeoutMillis()); } - if (mInjector.waitForInternet()) { + if (Flags.waitForInternetRor()) { // Timeout to stop retrying same as the wake lock timeout. mInjector.postDelayed( retryHandler, @@ -553,7 +548,7 @@ class RebootEscrowManager { return; } - if (mInjector.waitForInternet()) { + if (Flags.waitForInternetRor()) { if (mRebootEscrowTimedOut) { Slog.w(TAG, "Failed to load reboot escrow data within timeout"); compareAndSetLoadEscrowDataErrorCode( diff --git a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java index cc58f38db65a..3a429b041b3c 100644 --- a/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java +++ b/services/core/java/com/android/server/locksettings/SyntheticPasswordManager.java @@ -1701,7 +1701,7 @@ class SyntheticPasswordManager { .setGatekeeperHAT(response.getPayload()).build(); if (response.getShouldReEnroll()) { try { - response = gatekeeper.enroll(userId, spHandle, spHandle, + response = gatekeeper.enroll(userId, spHandle, gatekeeperPassword, gatekeeperPassword); } catch (RemoteException e) { Slog.e(TAG, "Failed to invoke gatekeeper.enroll", e); diff --git a/services/core/java/com/android/server/locksettings/TEST_MAPPING b/services/core/java/com/android/server/locksettings/TEST_MAPPING index ffbdf7f2bf8b..d338c50bb8c1 100644 --- a/services/core/java/com/android/server/locksettings/TEST_MAPPING +++ b/services/core/java/com/android/server/locksettings/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit-large": [ { - "name": "CtsDevicePolicyManagerTestCases", - "options": [ - { - "include-annotation": "com.android.cts.devicepolicy.annotations.LockSettingsTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsDevicePolicyManagerTestCases_LockSettingsTest" } ], "presubmit": [ diff --git a/services/core/java/com/android/server/locksettings/flags.aconfig b/services/core/java/com/android/server/locksettings/flags.aconfig new file mode 100644 index 000000000000..6818de91c98e --- /dev/null +++ b/services/core/java/com/android/server/locksettings/flags.aconfig @@ -0,0 +1,9 @@ +package: "com.android.server.locksettings" +container: "system" + +flag { + name: "wait_for_internet_ror" + namespace: "sudo" + description: "Feature flag to wait for internet connectivity before calling resume on reboot server." + bug: "231660348" +}
\ No newline at end of file diff --git a/services/core/java/com/android/server/media/projection/TEST_MAPPING b/services/core/java/com/android/server/media/projection/TEST_MAPPING index 7aa9118e45ee..b33097c50002 100644 --- a/services/core/java/com/android/server/media/projection/TEST_MAPPING +++ b/services/core/java/com/android/server/media/projection/TEST_MAPPING @@ -1,15 +1,7 @@ { "presubmit": [ { - "name": "MediaProjectionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "MediaProjectionTests" } ] } diff --git a/services/core/java/com/android/server/net/TEST_MAPPING b/services/core/java/com/android/server/net/TEST_MAPPING index ad6b0ca71527..d95849ec6d6a 100644 --- a/services/core/java/com/android/server/net/TEST_MAPPING +++ b/services/core/java/com/android/server/net/TEST_MAPPING @@ -1,40 +1,16 @@ { "presubmit-large": [ { - "name": "CtsHostsideNetworkPolicyTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "android.platform.test.annotations.FlakyTest" - } - ] + "name": "CtsHostsideNetworkPolicyTests" } ], "presubmit": [ { - "name": "FrameworksServicesTests", - "file_patterns": ["(/|^)Network(Policy|Management)[^/]*\\.java"], - "options": [ - { - "include-filter": "com.android.server.net." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksServicesTests_android_server_net_Presubmit", + "file_patterns": ["(/|^)Network(Policy|Management)[^/]*\\.java"] }, { - "name": "FrameworksVpnTests", - "options": [ - { - "exclude-annotation": "com.android.testutils.SkipPresubmit" - } - ], + "name": "FrameworksVpnTests_android_server_connectivity", "file_patterns": ["VpnManagerService\\.java"] } ] diff --git a/services/core/java/com/android/server/notification/TEST_MAPPING b/services/core/java/com/android/server/notification/TEST_MAPPING index 468c4518602e..dc7129cde5e5 100644 --- a/services/core/java/com/android/server/notification/TEST_MAPPING +++ b/services/core/java/com/android/server/notification/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "CtsNotificationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsNotificationTestCases_notification" }, { - "name": "FrameworksUiServicesTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "FrameworksUiServicesTests_notification" } ], "postsubmit": [ diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index 59f1e69d6a77..56e459057bfa 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -295,13 +295,12 @@ public final class OverlayManagerService extends SystemService { restoreSettings(); - if (Build.IS_USER) { - // Wipe all shell overlays on boot, to recover from a potentially broken device - String shellPkgName = TextUtils.emptyIfNull( - getContext().getString(android.R.string.config_systemShell)); - mSettings.removeIf(overlayInfo -> overlayInfo.isFabricated - && shellPkgName.equals(overlayInfo.packageName)); - } + // Wipe all shell overlays on boot, to recover from a potentially broken device + String shellPkgName = TextUtils.emptyIfNull( + getContext().getString(android.R.string.config_systemShell)); + mSettings.removeIf(overlayInfo -> overlayInfo.isFabricated + && shellPkgName.equals(overlayInfo.packageName)); + initIfNeeded(); onStartUser(UserHandle.USER_SYSTEM); diff --git a/services/core/java/com/android/server/os/TEST_MAPPING b/services/core/java/com/android/server/os/TEST_MAPPING index 50c8964b2aa4..3ffcd186dc4b 100644 --- a/services/core/java/com/android/server/os/TEST_MAPPING +++ b/services/core/java/com/android/server/os/TEST_MAPPING @@ -2,36 +2,18 @@ "presubmit": [ { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "BugreportManagerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "BugreportManagerTestCases_android_server_os" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "CtsBugreportTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - } - ] + "name": "CtsBugreportTestCases_android_server_os" }, { "name": "CtsUsbTests" }, { "file_patterns": ["Bugreport[^/]*\\.java"], - "name": "ShellTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "ShellTests_android_server_os" } ], "postsubmit": [ diff --git a/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING b/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING index 8a1982a339ea..db98c402eeeb 100644 --- a/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/verify/domain/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "PackageManagerServiceUnitTests", - "options": [ - { - "include-filter": "com.android.server.pm.test.verify.domain" - } - ] + "name": "PackageManagerServiceUnitTests_verify_domain" }, { "name": "CtsDomainVerificationDeviceStandaloneTestCases" diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING index bdb174d98137..76a050350393 100644 --- a/services/core/java/com/android/server/policy/TEST_MAPPING +++ b/services/core/java/com/android/server/policy/TEST_MAPPING @@ -1,32 +1,10 @@ { "presubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.policy." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksServicesTests_android_server_policy_Presubmit" }, { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.policy." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "WmTests_server_policy_Presubmit" }, { "name": "CtsPermissionPolicyTestCases", @@ -49,30 +27,15 @@ "name": "CtsPermissionTestCases_Platform" }, { - "name": "CtsBackupTestCases", - "options": [ - { - "include-filter": "android.backup.cts.PermissionTest" - } - ] + "name": "CtsBackupTestCases_cts_permissiontest" } ], "postsubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.policy." - } - ] + "name": "FrameworksServicesTests_android_server_policy" }, { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.policy." - } - ] + "name": "WmTests_server_policy" }, { "name": "CtsPermissionPolicyTestCases", diff --git a/services/core/java/com/android/server/power/TEST_MAPPING b/services/core/java/com/android/server/power/TEST_MAPPING index 4ce01d21903f..f67f56db3c1e 100644 --- a/services/core/java/com/android/server/power/TEST_MAPPING +++ b/services/core/java/com/android/server/power/TEST_MAPPING @@ -1,22 +1,13 @@ { "presubmit": [ { - "name": "CtsBatterySavingTestCases", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"} - ] + "name": "CtsBatterySavingTestCases_android_server_power" }, { "name": "FrameworksMockingServicesTests_android_server_power_Presubmit" }, { - "name": "PowerServiceTests", - "options": [ - {"include-filter": "com.android.server.power"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerServiceTests_server_power" } ], "postsubmit": [ @@ -24,31 +15,16 @@ "name": "CtsBatterySavingTestCases" }, { - "name": "FrameworksMockingServicesTests", - "options": [ - {"include-filter": "com.android.server.power"} - ] + "name": "FrameworksMockingServicesTests_android_server_power" }, { - "name": "FrameworksServicesTests", - "options": [ - {"include-filter": "com.android.server.power"} - ] + "name": "FrameworksServicesTests_android_server_power" }, { - "name": "PowerServiceTests", - "options": [ - {"include-filter": "com.android.server.power"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerServiceTests_server_power" }, { - "name": "CtsStatsdAtomHostTestCases", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"}, - {"include-filter": "android.cts.statsdatom.powermanager"} - ], + "name": "CtsStatsdAtomHostTestCases_statsdatom_powermanager", "file_patterns": [ "(/|^)ThermalManagerService.java" ] diff --git a/services/core/java/com/android/server/power/ThermalManagerService.java b/services/core/java/com/android/server/power/ThermalManagerService.java index 6847a5c699ac..dc6b1644db4d 100644 --- a/services/core/java/com/android/server/power/ThermalManagerService.java +++ b/services/core/java/com/android/server/power/ThermalManagerService.java @@ -1628,9 +1628,9 @@ public class ThermalManagerService extends SystemService { long mInactivityThresholdMillis = INACTIVITY_THRESHOLD_MILLIS; void updateThresholds() { - synchronized (mSamples) { - List<TemperatureThreshold> thresholds = + List<TemperatureThreshold> thresholds = mHalWrapper.getTemperatureThresholds(true, Temperature.TYPE_SKIN); + synchronized (mSamples) { if (Flags.allowThermalHeadroomThresholds()) { Arrays.fill(mHeadroomThresholds, Float.NaN); } diff --git a/services/core/java/com/android/server/security/TEST_MAPPING b/services/core/java/com/android/server/security/TEST_MAPPING index 29d52fff3eff..284e08e1e526 100644 --- a/services/core/java/com/android/server/security/TEST_MAPPING +++ b/services/core/java/com/android/server/security/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsSecurityTestCases", - "options": [ - { - "include-filter": "android.security.cts.FileIntegrityManagerTest" - } - ], + "name": "CtsSecurityTestCases_cts_fileintegritymanagertest", "file_patterns": ["FileIntegrity[^/]*\\.java"] } ] diff --git a/services/core/java/com/android/server/statusbar/TEST_MAPPING b/services/core/java/com/android/server/statusbar/TEST_MAPPING index 67ea557d7806..8c7e74c7e2c5 100644 --- a/services/core/java/com/android/server/statusbar/TEST_MAPPING +++ b/services/core/java/com/android/server/statusbar/TEST_MAPPING @@ -1,29 +1,10 @@ { "presubmit": [ { - "name": "CtsTileServiceTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTileServiceTestCases" }, { - "name": "CtsAppTestCases", - "options": [ - { - "exclude-annotation": "org.junit.Ignore" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.app.cts.RequestTileServiceAddTest" - } - ] + "name": "CtsAppTestCases_cts_requesttileserviceaddtest" } ] }
\ No newline at end of file diff --git a/services/core/java/com/android/server/timedetector/TEST_MAPPING b/services/core/java/com/android/server/timedetector/TEST_MAPPING index 17d327e94d4d..f57b819e241f 100644 --- a/services/core/java/com/android/server/timedetector/TEST_MAPPING +++ b/services/core/java/com/android/server/timedetector/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { "name": "FrameworksTimeServicesTests" diff --git a/services/core/java/com/android/server/timezonedetector/TEST_MAPPING b/services/core/java/com/android/server/timezonedetector/TEST_MAPPING index 004d79964354..a237c346a637 100644 --- a/services/core/java/com/android/server/timezonedetector/TEST_MAPPING +++ b/services/core/java/com/android/server/timezonedetector/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsTimeTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTimeTestCases" }, { "name": "FrameworksTimeServicesTests" diff --git a/services/core/java/com/android/server/trust/TEST_MAPPING b/services/core/java/com/android/server/trust/TEST_MAPPING index 0de7c28c209b..4c08455f713a 100644 --- a/services/core/java/com/android/server/trust/TEST_MAPPING +++ b/services/core/java/com/android/server/trust/TEST_MAPPING @@ -1,41 +1,17 @@ { "presubmit": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ], "postsubmit": [ { - "name": "FrameworksMockingServicesTests", - "options": [ - { - "include-filter": "com.android.server.trust" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksMockingServicesTests_android_server_trust" } ], "trust-tablet": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ] }
\ No newline at end of file diff --git a/services/core/java/com/android/server/uri/TEST_MAPPING b/services/core/java/com/android/server/uri/TEST_MAPPING index 0d756bb984d1..45e3051d4d5d 100644 --- a/services/core/java/com/android/server/uri/TEST_MAPPING +++ b/services/core/java/com/android/server/uri/TEST_MAPPING @@ -4,24 +4,7 @@ "name": "FrameworksServicesTests_android_server_uri" }, { - "name": "CtsStorageHostTestCases", - "options": [ - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testGrantUriPermission" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testGrantUriPermission29" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone28" - }, - { - "include-filter": "android.appsecurity.cts.ExternalStorageHostTest#testMediaNone29" - } - ] + "name": "CtsStorageHostTestCases_android_server_uri" } ], "postsubmit": [ @@ -34,12 +17,7 @@ ] }, { - "name": "CtsWindowManagerDeviceWindow", - "options": [ - { - "include-filter": "android.server.wm.window.CrossAppDragAndDropTests" - } - ] + "name": "CtsWindowManagerDeviceWindow_window_crossappdraganddroptests" } ] } diff --git a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java index ecd140e23ab6..1e82b8999834 100644 --- a/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java +++ b/services/core/java/com/android/server/vcn/TelephonySubscriptionTracker.java @@ -44,7 +44,6 @@ import android.util.Slog; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting.Visibility; -import com.android.internal.telephony.flags.Flags; import com.android.internal.util.IndentingPrintWriter; import com.android.server.vcn.util.PersistableBundleUtils.PersistableBundleWrapper; @@ -323,12 +322,16 @@ public class TelephonySubscriptionTracker extends BroadcastReceiver { if (SubscriptionManager.isValidSubscriptionId(subId)) { // Get only configs as needed to save memory. - final PersistableBundle carrierConfig = - Flags.fixCrashOnGettingConfigWhenPhoneIsGone() - ? CarrierConfigManager.getCarrierConfigSubset(mContext, subId, - VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS) - : mCarrierConfigManager.getConfigForSubId(subId, - VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS); + PersistableBundle carrierConfig = new PersistableBundle(); + try { + carrierConfig = + mCarrierConfigManager.getConfigForSubId( + subId, VcnManager.VCN_RELATED_CARRIER_CONFIG_KEYS); + + } catch (RuntimeException exception) { + Slog.w(TAG, "CarrierConfigLoader is not available."); + } + if (mDeps.isConfigForIdentifiedCarrier(carrierConfig)) { mReadySubIdsBySlotId.put(slotId, subId); diff --git a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java index 8d378a021f17..b5747828349e 100644 --- a/services/core/java/com/android/server/vcn/VcnGatewayConnection.java +++ b/services/core/java/com/android/server/vcn/VcnGatewayConnection.java @@ -177,6 +177,10 @@ public class VcnGatewayConnection extends StateMachine { /** Default number of parallel SAs requested */ static final int TUNNEL_AGGREGATION_SA_COUNT_MAX_DEFAULT = 1; + // The returned string of + // TelephonyManager#getNetworkTypeName(TelephonyManager.NETWORK_TYPE_UNKNOWN) + private static final String NETWORK_TYPE_STRING_UNKNOWN = "UNKNOWN"; + // Matches DataConnection.NETWORK_TYPE private constant, and magic string from // ConnectivityManager#getNetworkTypeName() @VisibleForTesting(visibility = Visibility.PRIVATE) @@ -1815,9 +1819,7 @@ public class VcnGatewayConnection extends StateMachine { .setLegacyType(ConnectivityManager.TYPE_MOBILE) .setLegacyTypeName(NETWORK_INFO_NETWORK_TYPE_STRING) .setLegacySubType(TelephonyManager.NETWORK_TYPE_UNKNOWN) - .setLegacySubTypeName( - TelephonyManager.getNetworkTypeName( - TelephonyManager.NETWORK_TYPE_UNKNOWN)) + .setLegacySubTypeName(NETWORK_TYPE_STRING_UNKNOWN) .setLegacyExtraInfo(NETWORK_INFO_EXTRA_INFO) .build(); diff --git a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java index 3f8d39e72e89..2b0ca0802359 100644 --- a/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java +++ b/services/core/java/com/android/server/vcn/routeselection/UnderlyingNetworkController.java @@ -360,7 +360,10 @@ public class UnderlyingNetworkController { final NetworkRequest.Builder nrBuilder = getBaseNetworkRequestBuilder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) - .setNetworkSpecifier(new TelephonyNetworkSpecifier(subId)); + .setNetworkSpecifier( + new TelephonyNetworkSpecifier.Builder() + .setSubscriptionId(subId) + .build()); for (CapabilityMatchCriteria capMatchCriteria : capsMatchCriteria) { final int cap = capMatchCriteria.capability; diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java index 728f739f9f8d..eee282122792 100644 --- a/services/core/java/com/android/server/wm/Task.java +++ b/services/core/java/com/android/server/wm/Task.java @@ -2790,11 +2790,15 @@ class Task extends TaskFragment { @Override void onDisplayChanged(DisplayContent dc) { + final int lastDisplayId = getDisplayId(); super.onDisplayChanged(dc); if (isLeafTask()) { final int displayId = (dc != null) ? dc.getDisplayId() : INVALID_DISPLAY; - mWmService.mAtmService.getTaskChangeNotificationController().notifyTaskDisplayChanged( - mTaskId, displayId); + //Send the callback when the task reparented to another display. + if (lastDisplayId != displayId) { + mWmService.mAtmService.getTaskChangeNotificationController() + .notifyTaskDisplayChanged(mTaskId, displayId); + } } if (isRootTask()) { updateSurfaceBounds(); diff --git a/services/core/java/com/android/server/wm/utils/TEST_MAPPING b/services/core/java/com/android/server/wm/utils/TEST_MAPPING index aa69d2a18948..6f34cd047d5f 100644 --- a/services/core/java/com/android/server/wm/utils/TEST_MAPPING +++ b/services/core/java/com/android/server/wm/utils/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit": [ { - "name": "WmTests", - "options": [ - { - "include-filter": "com.android.server.wm.utils" - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "WmTests_wm_utils_Presubmit" } ] } diff --git a/services/foldables/devicestateprovider/TEST_MAPPING b/services/foldables/devicestateprovider/TEST_MAPPING index 47de131803c5..05383814a040 100644 --- a/services/foldables/devicestateprovider/TEST_MAPPING +++ b/services/foldables/devicestateprovider/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "foldable-device-state-provider-tests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "foldable-device-state-provider-tests" } ] } diff --git a/services/incremental/TEST_MAPPING b/services/incremental/TEST_MAPPING index 4c9403c9b21a..cbb99627d918 100644 --- a/services/incremental/TEST_MAPPING +++ b/services/incremental/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPackageManagerStatsHostTestCases", - "options": [ - { - "include-filter": "com.android.cts.packagemanager.stats.host.PackageInstallerV2StatsTests" - } - ] + "name": "CtsPackageManagerStatsHostTestCases_host_packageinstallerv2statstests" }, { "name": "CtsPackageManagerIncrementalStatsHostTestCases", diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java index cdca948f91ac..b676fa2455b1 100644 --- a/services/java/com/android/server/SystemServer.java +++ b/services/java/com/android/server/SystemServer.java @@ -428,6 +428,10 @@ public final class SystemServer implements Dumpable { private static final String PROFILING_SERVICE_JAR_PATH = "/apex/com.android.profiling/javalib/service-profiling.jar"; + private static final String RANGING_APEX_SERVICE_JAR_PATH = + "/apex/com.android.uwb/javalib/service-ranging.jar"; + private static final String RANGING_SERVICE_CLASS = "com.android.server.ranging.RangingService"; + private static final String TETHERING_CONNECTOR_CLASS = "android.net.ITetheringConnector"; private static final String PERSISTENT_DATA_BLOCK_PROP = "ro.frp.pst"; @@ -2961,6 +2965,17 @@ public final class SystemServer implements Dumpable { t.traceEnd(); } + if (com.android.ranging.flags.Flags.rangingStackEnabled()) { + if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB) + || context.getPackageManager().hasSystemFeature( + PackageManager.FEATURE_WIFI_RTT)) { + t.traceBegin("RangingService"); + mSystemServiceManager.startServiceFromJar(RANGING_SERVICE_CLASS, + RANGING_APEX_SERVICE_JAR_PATH); + t.traceEnd(); + } + } + t.traceBegin("StartBootPhaseDeviceSpecificServicesReady"); mSystemServiceManager.startBootPhase(t, SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY); t.traceEnd(); diff --git a/services/lint-baseline.xml b/services/lint-baseline.xml index a311d07e52fb..95da56da156c 100644 --- a/services/lint-baseline.xml +++ b/services/lint-baseline.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> -<issues format="6" by="lint 8.4.0-alpha01" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha01"> +<issues format="6" by="lint 8.4.0-alpha08" type="baseline" client="" dependencies="true" name="" variant="all" version="8.4.0-alpha08"> <issue id="SimpleManualPermissionEnforcement" @@ -8,7 +8,7 @@ errorLine2=" ^"> <location file="frameworks/base/services/java/com/android/server/SystemConfigService.java" - line="46" + line="50" column="13"/> </issue> @@ -19,7 +19,7 @@ errorLine2=" ^"> <location file="frameworks/base/services/java/com/android/server/SystemConfigService.java" - line="54" + line="58" column="13"/> </issue> @@ -30,7 +30,7 @@ errorLine2=" ^"> <location file="frameworks/base/services/java/com/android/server/SystemConfigService.java" - line="67" + line="71" column="13"/> </issue> @@ -41,7 +41,7 @@ errorLine2=" ^"> <location file="frameworks/base/services/java/com/android/server/SystemConfigService.java" - line="76" + line="80" column="13"/> </issue> @@ -52,8 +52,30 @@ errorLine2=" ^"> <location file="frameworks/base/services/java/com/android/server/SystemConfigService.java" - line="107" + line="111" column="13"/> </issue> -</issues>
\ No newline at end of file + <issue + id="SimpleManualPermissionEnforcement" + message="ISystemConfig permission check should be converted to @EnforcePermission annotation" + errorLine1=" getContext().enforceCallingOrSelfPermission(" + errorLine2=" ^"> + <location + file="frameworks/base/services/java/com/android/server/SystemConfigService.java" + line="127" + column="13"/> + </issue> + + <issue + id="SimpleManualPermissionEnforcement" + message="ISystemConfig permission check should be converted to @EnforcePermission annotation" + errorLine1=" getContext().enforceCallingOrSelfPermission(" + errorLine2=" ^"> + <location + file="frameworks/base/services/java/com/android/server/SystemConfigService.java" + line="137" + column="13"/> + </issue> + +</issues> diff --git a/services/people/java/com/android/server/people/TEST_MAPPING b/services/people/java/com/android/server/people/TEST_MAPPING index 55b355cbc991..867733754967 100644 --- a/services/people/java/com/android/server/people/TEST_MAPPING +++ b/services/people/java/com/android/server/people/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.people.data" - } - ] + "name": "FrameworksServicesTests_people_data" } ] }
\ No newline at end of file diff --git a/services/permission/TEST_MAPPING b/services/permission/TEST_MAPPING index 4de4a56aa806..af4aaf9736d8 100644 --- a/services/permission/TEST_MAPPING +++ b/services/permission/TEST_MAPPING @@ -105,26 +105,10 @@ ] }, { - "name": "CtsVirtualDevicesAudioTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.audio.VirtualAudioPermissionTest" - } - ] + "name": "CtsVirtualDevicesAudioTestCases_audio_virtualaudiopermissiontest" }, { - "name": "CtsVirtualDevicesAppLaunchTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "include-filter": "android.virtualdevice.cts.applaunch.VirtualDevicePermissionTest" - } - ] + "name": "CtsVirtualDevicesAppLaunchTestCases_applaunch_virtualdevicepermissiontest" } ], "imports": [ diff --git a/services/print/java/com/android/server/print/TEST_MAPPING b/services/print/java/com/android/server/print/TEST_MAPPING index 4fa882265e53..1033b1a86edb 100644 --- a/services/print/java/com/android/server/print/TEST_MAPPING +++ b/services/print/java/com/android/server/print/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsPrintTestCases", - "options": [ - { - "include-annotation": "android.platform.test.annotations.Presubmit" - } - ] + "name": "CtsPrintTestCases_Presubmit" } ] } diff --git a/services/tests/InputMethodSystemServerTests/TEST_MAPPING b/services/tests/InputMethodSystemServerTests/TEST_MAPPING index de9f771a2a36..7313941f57b4 100644 --- a/services/tests/InputMethodSystemServerTests/TEST_MAPPING +++ b/services/tests/InputMethodSystemServerTests/TEST_MAPPING @@ -1,22 +1,12 @@ { "presubmit": [ { - "name": "FrameworksInputMethodSystemServerTests", - "options": [ - {"include-filter": "com.android.server.inputmethod"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksInputMethodSystemServerTests_server_inputmethod" } ], "postsubmit": [ { - "name": "FrameworksImeTests", - "options": [ - {"include-filter": "com.android.inputmethodservice"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksImeTests_android_inputmethodservice" } ] } diff --git a/services/tests/PackageManagerServiceTests/TEST_MAPPING b/services/tests/PackageManagerServiceTests/TEST_MAPPING index 5d96af9df1fb..13ba3171e455 100644 --- a/services/tests/PackageManagerServiceTests/TEST_MAPPING +++ b/services/tests/PackageManagerServiceTests/TEST_MAPPING @@ -4,21 +4,7 @@ "name": "AppEnumerationInternalTests" }, { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-filter": "com.android.server.pm." - }, - { - "include-annotation": "android.platform.test.annotations.Presubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_server_pm_Presubmit" } ], "postsubmit": [ @@ -26,21 +12,7 @@ "name": "PackageManagerServiceHostTests" }, { - "name": "PackageManagerServiceServerTests", - "options": [ - { - "include-filter": "com.android.server.pm." - }, - { - "include-annotation": "android.platform.test.annotations.Postsubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "PackageManagerServiceServerTests_server_pm_Postsubmit" } ], "kernel-presubmit": [ diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java index 69043f5704de..e982153acbd1 100644 --- a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/BrightnessClamperControllerTest.java @@ -16,19 +16,19 @@ package com.android.server.display.brightness.clamper; +import static android.view.Display.STATE_OFF; import static android.view.Display.STATE_ON; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.clearInvocations; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import android.content.Context; -import android.hardware.Sensor; -import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.hardware.display.BrightnessInfo; import android.hardware.display.DisplayManagerInternal; @@ -40,12 +40,10 @@ import android.testing.TestableContext; import androidx.test.filters.SmallTest; import androidx.test.platform.app.InstrumentationRegistry; -import com.android.internal.util.test.FakeSettingsProvider; -import com.android.internal.util.test.FakeSettingsProviderRule; import com.android.server.display.DisplayBrightnessState; import com.android.server.display.DisplayDeviceConfig; -import com.android.server.display.TestUtils; import com.android.server.display.brightness.BrightnessReason; +import com.android.server.display.config.SensorData; import com.android.server.display.feature.DeviceConfigParameterProvider; import com.android.server.display.feature.DisplayManagerFlags; import com.android.server.testutils.OffsettableClock; @@ -63,6 +61,7 @@ import java.util.List; @SmallTest public class BrightnessClamperControllerTest { private static final float FLOAT_TOLERANCE = 0.001f; + private static final int DISPLAY_ID = 2; private final OffsettableClock mClock = new OffsettableClock(); private final TestHandler mTestHandler = new TestHandler(null, mClock); @@ -78,8 +77,12 @@ public class BrightnessClamperControllerTest { @Mock private BrightnessClamperController.DisplayDeviceData mMockDisplayDeviceData; @Mock + private SensorData mMockSensorData; + @Mock private DeviceConfigParameterProvider mMockDeviceConfigParameterProvider; @Mock + private LightSensorController mMockLightSensorController; + @Mock private BrightnessClamper<BrightnessClamperController.DisplayDeviceData> mMockClamper; @Mock private DisplayManagerFlags mFlags; @@ -88,23 +91,17 @@ public class BrightnessClamperControllerTest { @Mock private DisplayManagerInternal.DisplayPowerRequest mMockRequest; - Sensor mLightSensor; - @Mock private DeviceConfig.Properties mMockProperties; private BrightnessClamperController mClamperController; private TestInjector mTestInjector; - @Rule - public FakeSettingsProviderRule mSettingsProviderRule = FakeSettingsProvider.rule(); - @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); - mLightSensor = TestUtils.createSensor(Sensor.TYPE_LIGHT, "Light Sensor"); mTestInjector = new TestInjector(List.of(mMockClamper), List.of(mMockModifier)); - when(mSensorManager.getDefaultSensor(anyInt())).thenReturn(mLightSensor); - when(mMockModifier.shouldListenToLightSensor()).thenReturn(true); + when(mMockDisplayDeviceData.getDisplayId()).thenReturn(DISPLAY_ID); + when(mMockDisplayDeviceData.getAmbientLightSensor()).thenReturn(mMockSensorData); mClamperController = createBrightnessClamperController(); } @@ -115,6 +112,25 @@ public class BrightnessClamperControllerTest { } @Test + public void testConstructor_ConfiguresLightSensorController() { + verify(mMockLightSensorController).configure(mMockSensorData, DISPLAY_ID); + } + + @Test + public void testConstructor_doesNotStartsLightSensorController() { + verify(mMockLightSensorController, never()).restart(); + } + + @Test + public void testConstructor_startsLightSensorController() { + when(mMockModifier.shouldListenToLightSensor()).thenReturn(true); + + mClamperController = createBrightnessClamperController(); + + verify(mMockLightSensorController).restart(); + } + + @Test public void testStop_RemovesOnPropertiesChangeListener() { ArgumentCaptor<DeviceConfig.OnPropertiesChangedListener> captor = ArgumentCaptor.forClass( DeviceConfig.OnPropertiesChangedListener.class); @@ -152,6 +168,21 @@ public class BrightnessClamperControllerTest { } @Test + public void testOnDisplayChanged_doesNotRestartLightSensor() { + mClamperController.onDisplayChanged(mMockDisplayDeviceData); + + verify(mMockLightSensorController, never()).restart(); + } + + @Test + public void testOnDisplayChanged_restartsLightSensor() { + when(mMockModifier.shouldListenToLightSensor()).thenReturn(true); + mClamperController.onDisplayChanged(mMockDisplayDeviceData); + + verify(mMockLightSensorController).restart(); + } + + @Test public void testClamp_AppliesModifier() { float initialBrightness = 0.2f; boolean initialSlowChange = true; @@ -161,6 +192,26 @@ public class BrightnessClamperControllerTest { } @Test + public void testClamp_restartsLightSensor() { + float initialBrightness = 0.2f; + boolean initialSlowChange = true; + when(mMockModifier.shouldListenToLightSensor()).thenReturn(true); + mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_ON); + + verify(mMockLightSensorController).restart(); + } + + @Test + public void testClamp_stopsLightSensor() { + float initialBrightness = 0.2f; + boolean initialSlowChange = true; + clearInvocations(mMockLightSensorController); + mClamperController.clamp(mMockRequest, initialBrightness, initialSlowChange, STATE_OFF); + + verify(mMockLightSensorController).stop(); + } + + @Test public void testClamp_inactiveClamperNotApplied() { float initialBrightness = 0.8f; boolean initialSlowChange = true; @@ -260,33 +311,17 @@ public class BrightnessClamperControllerTest { } @Test - public void testAmbientLuxChanges() throws Exception { - ArgumentCaptor<SensorEventListener> listenerCaptor = ArgumentCaptor.forClass( - SensorEventListener.class); - - verify(mSensorManager).registerListener(listenerCaptor.capture(), eq(mLightSensor), - anyInt(), any(Handler.class)); - SensorEventListener listener = listenerCaptor.getValue(); - - when(mSensorManager.getSensorList(eq(Sensor.TYPE_ALL))).thenReturn(List.of(mLightSensor)); - - float initialBrightness = 0.8f; - boolean initialSlowChange = true; - - DisplayBrightnessState state = mClamperController.clamp(mMockRequest, initialBrightness, - initialSlowChange, STATE_ON); - assertEquals(initialBrightness, state.getBrightness(), FLOAT_TOLERANCE); + public void testAmbientLuxChanges() { + mTestInjector.mCapturedLightSensorListener.onAmbientLuxChange(50); - listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 50, mClock.now())); verify(mMockModifier).setAmbientLux(50); - - listener.onSensorChanged(TestUtils.createSensorEvent(mLightSensor, 300, mClock.now())); - verify(mMockModifier).setAmbientLux(300); } @Test public void testStop() { + clearInvocations(mMockLightSensorController); mClamperController.stop(); + verify(mMockLightSensorController).stop(); verify(mMockModifier).stop(); verify(mMockClamper).stop(); } @@ -303,6 +338,7 @@ public class BrightnessClamperControllerTest { private final List<BrightnessStateModifier> mModifiers; private BrightnessClamperController.ClamperChangeListener mCapturedChangeListener; + private LightSensorController.LightSensorListener mCapturedLightSensorListener; private TestInjector( List<BrightnessClamper<? super BrightnessClamperController.DisplayDeviceData>> @@ -330,8 +366,15 @@ public class BrightnessClamperControllerTest { @Override List<BrightnessStateModifier> getModifiers(DisplayManagerFlags flags, Context context, Handler handler, BrightnessClamperController.ClamperChangeListener listener, - DisplayDeviceConfig displayDeviceConfig, SensorManager sensorManager) { + DisplayDeviceConfig displayDeviceConfig) { return mModifiers; } + + @Override + LightSensorController getLightSensorController(SensorManager sensorManager, Context context, + LightSensorController.LightSensorListener listener, Handler handler) { + mCapturedLightSensorListener = listener; + return mMockLightSensorController; + } } } diff --git a/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/LightSensorControllerTest.kt b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/LightSensorControllerTest.kt new file mode 100644 index 000000000000..b742d021f2e9 --- /dev/null +++ b/services/tests/displayservicetests/src/com/android/server/display/brightness/clamper/LightSensorControllerTest.kt @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2023 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.display.brightness.clamper + +import android.content.res.Resources +import android.hardware.Sensor +import android.hardware.SensorEventListener +import android.hardware.SensorManager +import android.os.Handler +import androidx.test.filters.SmallTest +import com.android.server.display.TestUtils +import com.android.server.display.brightness.clamper.LightSensorController.Injector +import com.android.server.display.brightness.clamper.LightSensorController.LightSensorListener +import com.android.server.display.config.SensorData +import com.android.server.display.utils.AmbientFilter +import org.junit.Before +import org.mockito.kotlin.any +import org.mockito.kotlin.argumentCaptor +import org.mockito.kotlin.eq +import org.mockito.kotlin.inOrder +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.verifyNoMoreInteractions +import org.mockito.kotlin.whenever + +private const val LIGHT_SENSOR_RATE: Int = 10 +private const val DISPLAY_ID: Int = 3 +private const val NOW: Long = 3_000 + +@SmallTest +class LightSensorControllerTest { + + private val mockSensorManager: SensorManager = mock() + private val mockResources: Resources = mock() + private val mockLightSensorListener: LightSensorListener = mock() + private val mockHandler: Handler = mock() + private val mockAmbientFilter: AmbientFilter = mock() + + private val testInjector = TestInjector() + private val dummySensorData = SensorData() + + private lateinit var controller: LightSensorController + + @Before + fun setUp() { + controller = LightSensorController(mockSensorManager, mockResources, + mockLightSensorListener, mockHandler, testInjector) + } + + fun `does not register light sensor if is not configured`() { + controller.restart() + + verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener) + } + + fun `does not register light sensor if missing`() { + controller.configure(dummySensorData, DISPLAY_ID) + controller.restart() + + verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener) + } + + fun `register light sensor if configured and present`() { + testInjector.lightSensor = TestUtils + .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT) + controller.configure(dummySensorData, DISPLAY_ID) + controller.restart() + + verify(mockSensorManager).registerListener(any(), + testInjector.lightSensor, LIGHT_SENSOR_RATE * 1000, mockHandler) + verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener) + } + + fun `register light sensor once if not changed`() { + testInjector.lightSensor = TestUtils + .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT) + controller.configure(dummySensorData, DISPLAY_ID) + + controller.restart() + controller.restart() + + verify(mockSensorManager).registerListener(any(), + testInjector.lightSensor, LIGHT_SENSOR_RATE * 1000, mockHandler) + verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener) + } + + fun `register new light sensor and unregister old if changed`() { + val lightSensor1 = TestUtils + .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT) + testInjector.lightSensor = lightSensor1 + controller.configure(dummySensorData, DISPLAY_ID) + controller.restart() + + val lightSensor2 = TestUtils + .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT) + testInjector.lightSensor = lightSensor2 + controller.configure(dummySensorData, DISPLAY_ID) + controller.restart() + + inOrder { + verify(mockSensorManager).registerListener(any(), + lightSensor1, LIGHT_SENSOR_RATE * 1000, mockHandler) + verify(mockSensorManager).unregisterListener(any<SensorEventListener>()) + verify(mockAmbientFilter).clear() + verify(mockLightSensorListener).onAmbientLuxChange(LightSensorController.INVALID_LUX) + verify(mockSensorManager).registerListener(any(), + lightSensor2, LIGHT_SENSOR_RATE * 1000, mockHandler) + } + verifyNoMoreInteractions(mockSensorManager, mockAmbientFilter, mockLightSensorListener) + } + + fun `notifies listener on ambient lux change`() { + val expectedLux = 40f + val eventLux = 50 + val eventTime = 60L + whenever(mockAmbientFilter.getEstimate(NOW)).thenReturn(expectedLux) + val listenerCaptor = argumentCaptor<SensorEventListener>() + testInjector.lightSensor = TestUtils + .createSensor(Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT) + controller.configure(dummySensorData, DISPLAY_ID) + controller.restart() + verify(mockSensorManager).registerListener(listenerCaptor.capture(), + eq(testInjector.lightSensor), eq(LIGHT_SENSOR_RATE * 1000), eq(mockHandler)) + + val listener = listenerCaptor.lastValue + listener.onSensorChanged(TestUtils.createSensorEvent(testInjector.lightSensor, + eventLux, eventTime * 1_000_000)) + + inOrder { + verify(mockAmbientFilter).addValue(eventTime, eventLux.toFloat()) + verify(mockLightSensorListener).onAmbientLuxChange(expectedLux) + } + } + + private inner class TestInjector : Injector() { + var lightSensor: Sensor? = null + override fun getLightSensor(sensorManager: SensorManager?, + sensorData: SensorData?, fallbackType: Int): Sensor? { + return lightSensor + } + + override fun getLightSensorRate(resources: Resources?): Int { + return LIGHT_SENSOR_RATE + } + + override fun getAmbientFilter(resources: Resources?): AmbientFilter { + return mockAmbientFilter + } + + override fun getTime(): Long { + return NOW + } + } +}
\ No newline at end of file diff --git a/services/tests/dreamservicetests/TEST_MAPPING b/services/tests/dreamservicetests/TEST_MAPPING index a644ea690dcd..38d7000ceb6e 100644 --- a/services/tests/dreamservicetests/TEST_MAPPING +++ b/services/tests/dreamservicetests/TEST_MAPPING @@ -1,21 +1,12 @@ { "presubmit": [ { - "name": "DreamServiceTests", - "options": [ - {"include-filter": "com.android.server.dreams"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DreamServiceTests_server_dreams" } ], "postsubmit": [ { - "name": "DreamServiceTests", - "options": [ - {"include-filter": "com.android.server.dreams"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "DreamServiceTests_server_dreams" } ] } diff --git a/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING b/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING index 4ac4484956fc..ef2d60530a73 100644 --- a/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING +++ b/services/tests/mockingservicestests/src/com/android/server/rollback/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "RollbackPackageHealthObserverTests", - "options": [ - { - "include-filter": "com.android.server.rollback" - } - ] + "name": "RollbackPackageHealthObserverTests_server_rollback" } ] }
\ No newline at end of file diff --git a/services/tests/ondeviceintelligencetests/Android.bp b/services/tests/ondeviceintelligencetests/Android.bp index aa859422f54f..a31a3fb65700 100644 --- a/services/tests/ondeviceintelligencetests/Android.bp +++ b/services/tests/ondeviceintelligencetests/Android.bp @@ -47,9 +47,9 @@ android_test { ], libs: [ - "android.test.mock", - "android.test.base", - "android.test.runner", + "android.test.mock.stubs.system", + "android.test.base.stubs.system", + "android.test.runner.stubs.system", ], certificate: "platform", diff --git a/services/tests/powerstatstests/TEST_MAPPING b/services/tests/powerstatstests/TEST_MAPPING index fb243616292d..4e209f473ff3 100644 --- a/services/tests/powerstatstests/TEST_MAPPING +++ b/services/tests/powerstatstests/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "PowerStatsTests", - "options": [ - {"include-filter": "com.android.server.power.stats"}, - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerStatsTests_power_stats" } ], "ravenwood-presubmit": [ @@ -21,11 +16,7 @@ ], "postsubmit": [ { - "name": "PowerStatsTests", - "options": [ - {"include-filter": "com.android.server.power.stats"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "PowerStatsTests_power_stats" } ] } diff --git a/services/tests/selinux/Android.bp b/services/tests/selinux/Android.bp index 12a70387affd..048978ab88a3 100644 --- a/services/tests/selinux/Android.bp +++ b/services/tests/selinux/Android.bp @@ -42,9 +42,9 @@ android_test { "mockito_extended", ], libs: [ - "android.test.base", - "android.test.mock", - "android.test.runner", + "android.test.base.stubs.system", + "android.test.mock.stubs.system", + "android.test.runner.stubs.system", "servicestests-core-utils", ], static_libs: [ diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp index a5798c643b59..d0b23a0f2dbb 100644 --- a/services/tests/servicestests/Android.bp +++ b/services/tests/servicestests/Android.bp @@ -88,6 +88,7 @@ android_test { "net_flags_lib", "CtsVirtualDeviceCommonLib", "com_android_server_accessibility_flags_lib", + "locksettings_flags_lib", ], libs: [ diff --git a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING index 58f5bb3eb7d0..9b23b4908a78 100644 --- a/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING +++ b/services/tests/servicestests/src/com/android/server/location/contexthub/TEST_MAPPING @@ -6,23 +6,7 @@ ], "postsubmit": [ { - "name": "FrameworksServicesTests", - "options": [ - { - "include-filter": "com.android.server.location.contexthub." - }, - { - // I believe this include annotation is preventing tests from being run - // as there are no matching tests with the Postsubmit annotation. - "include-annotation": "android.platform.test.annotations.Postsubmit" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "FrameworksServicesTests_com_android_server_location_contexthub" } ] } diff --git a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java index 2ba3969bb9e5..87c9db2fe565 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/BaseLockSettingsServiceTests.java @@ -92,6 +92,7 @@ public abstract class BaseLockSettingsServiceTests { MockLockSettingsContext mContext; LockSettingsStorageTestable mStorage; + LockSettingsStrongAuth mStrongAuth; Resources mResources; FakeGateKeeperService mGateKeeperService; @@ -135,6 +136,7 @@ public abstract class BaseLockSettingsServiceTests { mFingerprintManager = mock(FingerprintManager.class); mFaceManager = mock(FaceManager.class); mPackageManager = mock(PackageManager.class); + mStrongAuth = mock(LockSettingsStrongAuth.class); LocalServices.removeServiceForTest(LockSettingsInternal.class); LocalServices.removeServiceForTest(DevicePolicyManagerInternal.class); @@ -162,7 +164,7 @@ public abstract class BaseLockSettingsServiceTests { mInjector = new LockSettingsServiceTestable.MockInjector( mContext, - mStorage, + mStorage, mStrongAuth, mActivityManager, setUpStorageManagerMock(), mSpManager, diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java index 93fc071a5bb7..abd39b0bb963 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTestable.java @@ -50,6 +50,7 @@ public class LockSettingsServiceTestable extends LockSettingsService { public static class MockInjector extends LockSettingsService.Injector { private LockSettingsStorage mLockSettingsStorage; + private final LockSettingsStrongAuth mStrongAuth; private IActivityManager mActivityManager; private IStorageManager mStorageManager; private SyntheticPasswordManager mSpManager; @@ -62,12 +63,14 @@ public class LockSettingsServiceTestable extends LockSettingsService { public boolean mIsMainUserPermanentAdmin = false; public MockInjector(Context context, LockSettingsStorage storage, + LockSettingsStrongAuth strongAuth, IActivityManager activityManager, IStorageManager storageManager, SyntheticPasswordManager spManager, FakeGsiService gsiService, RecoverableKeyStoreManager recoverableKeyStoreManager, UserManagerInternal userManagerInternal, DeviceStateCache deviceStateCache) { super(context); mLockSettingsStorage = storage; + mStrongAuth = strongAuth; mActivityManager = activityManager; mStorageManager = storageManager; mSpManager = spManager; @@ -89,7 +92,7 @@ public class LockSettingsServiceTestable extends LockSettingsService { @Override public LockSettingsStrongAuth getStrongAuth() { - return mock(LockSettingsStrongAuth.class); + return mStrongAuth; } @Override diff --git a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java index 601a01624189..2868e559e02f 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/LockSettingsServiceTests.java @@ -17,6 +17,7 @@ package com.android.server.locksettings; import static android.Manifest.permission.CONFIGURE_FACTORY_RESET_PROTECTION; +import static android.security.Flags.FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL; import static android.security.Flags.FLAG_REPORT_PRIMARY_AUTH_ATTEMPTS; import static com.android.internal.widget.LockPatternUtils.CREDENTIAL_TYPE_NONE; @@ -46,6 +47,10 @@ import android.os.UserHandle; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsDisabled; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import android.platform.test.flag.junit.SetFlagsRule; import android.service.gatekeeper.GateKeeperResponse; import android.text.TextUtils; @@ -71,6 +76,8 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); @Before public void setUp() { @@ -258,6 +265,34 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { } @Test + @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL) + public void setLockCredential_forPrimaryUser_clearsStrongAuthWhenFlagIsOn() + throws Exception { + setCredential(PRIMARY_USER_ID, newPassword("password")); + + verify(mStrongAuth).reportUnlock(PRIMARY_USER_ID); + } + + @Test + @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL) + public void setLockCredential_forPrimaryUser_leavesStrongAuthWhenFlagIsOff() + throws Exception { + setCredential(PRIMARY_USER_ID, newPassword("password")); + + verify(mStrongAuth, never()).reportUnlock(anyInt()); + } + + @Test + public void setLockCredential_forPrimaryUserWithCredential_leavesStrongAuth() throws Exception { + setCredential(PRIMARY_USER_ID, newPassword("password")); + reset(mStrongAuth); + + setCredential(PRIMARY_USER_ID, newPassword("password2"), newPassword("password")); + + verify(mStrongAuth, never()).reportUnlock(anyInt()); + } + + @Test public void testSetLockCredential_forProfileWithSeparateChallenge_sendsCredentials() throws Exception { setCredential(MANAGED_PROFILE_USER_ID, newPattern("12345")); @@ -278,6 +313,28 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { } @Test + @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL) + public void setLockCredential_profileWithNewSeparateChallenge_clearsStrongAuthWhenFlagIsOn() + throws Exception { + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null); + + setCredential(MANAGED_PROFILE_USER_ID, newPattern("12345")); + + verify(mStrongAuth).reportUnlock(MANAGED_PROFILE_USER_ID); + } + + @Test + @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL) + public void setLockCredential_profileWithNewSeparateChallenge_leavesStrongAuthWhenFlagIsOff() + throws Exception { + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, true, null); + + setCredential(MANAGED_PROFILE_USER_ID, newPattern("12345")); + + verify(mStrongAuth, never()).reportUnlock(anyInt()); + } + + @Test public void testSetLockCredential_forProfileWithUnifiedChallenge_doesNotSendRandomCredential() throws Exception { mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); @@ -305,6 +362,67 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { MANAGED_PROFILE_USER_ID); } + + @Test + public void setLockCredential_primaryWithUnifiedProfileAndCredential_leavesStrongAuthForBoth() + throws Exception { + final LockscreenCredential oldCredential = newPassword("oldPassword"); + final LockscreenCredential newCredential = newPassword("newPassword"); + setCredential(PRIMARY_USER_ID, oldCredential); + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); + reset(mStrongAuth); + + setCredential(PRIMARY_USER_ID, newCredential, oldCredential); + + verify(mStrongAuth, never()).reportUnlock(anyInt()); + } + + @Test + @RequiresFlagsEnabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL) + public void setLockCredential_primaryWithUnifiedProfile_clearsStrongAuthForBothWhenFlagIsOn() + throws Exception { + final LockscreenCredential credential = newPassword("oldPassword"); + setCredential(PRIMARY_USER_ID, credential); + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); + clearCredential(PRIMARY_USER_ID, credential); + reset(mStrongAuth); + + setCredential(PRIMARY_USER_ID, credential); + + verify(mStrongAuth).reportUnlock(PRIMARY_USER_ID); + verify(mStrongAuth).reportUnlock(MANAGED_PROFILE_USER_ID); + } + + @Test + @RequiresFlagsDisabled(FLAG_CLEAR_STRONG_AUTH_ON_ADD_PRIMARY_CREDENTIAL) + public void setLockCredential_primaryWithUnifiedProfile_leavesStrongAuthForBothWhenFlagIsOff() + throws Exception { + final LockscreenCredential credential = newPassword("oldPassword"); + setCredential(PRIMARY_USER_ID, credential); + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); + clearCredential(PRIMARY_USER_ID, credential); + reset(mStrongAuth); + + setCredential(PRIMARY_USER_ID, credential); + + verify(mStrongAuth, never()).reportUnlock(anyInt()); + } + + + @Test + public void setLockCredential_primaryWithUnifiedProfileWithCredential_leavesStrongAuthForBoth() + throws Exception { + final LockscreenCredential oldCredential = newPassword("oldPassword"); + final LockscreenCredential newCredential = newPassword("newPassword"); + setCredential(PRIMARY_USER_ID, oldCredential); + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); + reset(mStrongAuth); + + setCredential(PRIMARY_USER_ID, newCredential, oldCredential); + + verify(mStrongAuth, never()).reportUnlock(anyInt()); + } + @Test public void testSetLockCredential_forPrimaryUserWithUnifiedChallengeProfile_removesBothCredentials() @@ -343,6 +461,18 @@ public class LockSettingsServiceTests extends BaseLockSettingsServiceTests { } @Test + public void clearLockCredential_primaryWithUnifiedProfile_leavesStrongAuthForBoth() + throws Exception { + setCredential(PRIMARY_USER_ID, newPassword("password")); + mService.setSeparateProfileChallengeEnabled(MANAGED_PROFILE_USER_ID, false, null); + reset(mStrongAuth); + + clearCredential(PRIMARY_USER_ID, newPassword("password")); + + verify(mStrongAuth, never()).reportUnlock(anyInt()); + } + + @Test public void testSetLockCredential_forUnifiedToSeparateChallengeProfile_sendsNewCredentials() throws Exception { final LockscreenCredential parentPassword = newPassword("parentPassword"); diff --git a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java index d6f7e21a2069..d071c159d6f5 100644 --- a/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java +++ b/services/tests/servicestests/src/com/android/server/locksettings/RebootEscrowManagerTests.java @@ -60,6 +60,9 @@ import android.os.RemoteException; import android.os.ServiceSpecificException; import android.os.UserManager; import android.platform.test.annotations.Presubmit; +import android.platform.test.annotations.RequiresFlagsEnabled; +import android.platform.test.flag.junit.CheckFlagsRule; +import android.platform.test.flag.junit.DeviceFlagsValueProvider; import androidx.test.InstrumentationRegistry; import androidx.test.filters.SmallTest; @@ -70,6 +73,7 @@ import com.android.server.locksettings.ResumeOnRebootServiceProvider.ResumeOnReb import com.android.server.pm.UserManagerInternal; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -108,6 +112,9 @@ public class RebootEscrowManagerTests { 0x26, 0x52, 0x72, 0x63, 0x63, 0x61, 0x78, 0x23, }; + @Rule + public final CheckFlagsRule mCheckFlagsRule = DeviceFlagsValueProvider.createCheckFlagsRule(); + private Context mContext; private UserManager mUserManager; private UserManagerInternal mUserManagerInternal; @@ -145,7 +152,6 @@ public class RebootEscrowManagerTests { private RebootEscrowProviderInterface mRebootEscrowProviderInUse; private ConnectivityManager.NetworkCallback mNetworkCallback; private Consumer<ConnectivityManager.NetworkCallback> mNetworkConsumer; - private boolean mWaitForInternet; MockInjector( Context context, @@ -159,7 +165,6 @@ public class RebootEscrowManagerTests { super(context, storage, userManagerInternal); mRebootEscrow = rebootEscrow; mServerBased = false; - mWaitForInternet = false; RebootEscrowProviderHalImpl.Injector halInjector = new RebootEscrowProviderHalImpl.Injector() { @Override @@ -185,7 +190,6 @@ public class RebootEscrowManagerTests { super(context, storage, userManagerInternal); mRebootEscrow = null; mServerBased = true; - mWaitForInternet = false; RebootEscrowProviderServerBasedImpl.Injector injector = new RebootEscrowProviderServerBasedImpl.Injector(serviceConnection) { @Override @@ -227,15 +231,6 @@ public class RebootEscrowManagerTests { } @Override - public boolean waitForInternet() { - return mWaitForInternet; - } - - public void setWaitForNetwork(boolean waitForNetworkEnabled) { - mWaitForInternet = waitForNetworkEnabled; - } - - @Override public boolean isNetworkConnected() { return false; } @@ -934,10 +929,10 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_serverBasedWaitForInternet_success() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -987,10 +982,10 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_serverBasedWaitForInternetRemoteException_Failure() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -1042,10 +1037,10 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_waitForInternet_networkUnavailable() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -1090,9 +1085,9 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_waitForInternet_networkLost() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -1145,10 +1140,10 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_waitForInternet_networkAvailableWithDelay() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -1204,10 +1199,10 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_waitForInternet_timeoutExhausted() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -1264,10 +1259,10 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_serverBasedWaitForNetwork_retryCountExhausted() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); @@ -1320,10 +1315,10 @@ public class RebootEscrowManagerTests { } @Test + @RequiresFlagsEnabled(Flags.FLAG_WAIT_FOR_INTERNET_ROR) public void loadRebootEscrowDataIfAvailable_ServerBasedWaitForInternet_RetrySuccess() throws Exception { setServerBasedRebootEscrowProvider(); - mMockInjector.setWaitForNetwork(true); when(mInjected.getBootCount()).thenReturn(0); RebootEscrowListener mockListener = mock(RebootEscrowListener.class); diff --git a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING index 944c1df94b92..dc3b1447c13e 100644 --- a/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING +++ b/services/tests/servicestests/src/com/android/server/om/TEST_MAPPING @@ -4,12 +4,7 @@ "name": "FrameworksServicesTests_om" }, { - "name": "PackageManagerServiceHostTests", - "options": [ - { - "include-filter": "com.android.server.pm.test.OverlayActorVisibilityTest" - } - ] + "name": "PackageManagerServiceHostTests_test_overlayactorvisibilitytest" } ] } diff --git a/services/tests/servicestests/test-apps/DisplayManagerTestApp/OWNERS b/services/tests/servicestests/test-apps/DisplayManagerTestApp/OWNERS new file mode 100644 index 000000000000..e9557f84f8fb --- /dev/null +++ b/services/tests/servicestests/test-apps/DisplayManagerTestApp/OWNERS @@ -0,0 +1,3 @@ +# Bug component: 345010 + +include /services/core/java/com/android/server/display/OWNERS diff --git a/services/tests/vibrator/TEST_MAPPING b/services/tests/vibrator/TEST_MAPPING index 39bd238fc202..b17b96add466 100644 --- a/services/tests/vibrator/TEST_MAPPING +++ b/services/tests/vibrator/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksVibratorServicesTests", - "options": [ - {"exclude-annotation": "androidx.test.filters.FlakyTest"}, - {"exclude-annotation": "androidx.test.filters.LargeTest"}, - {"exclude-annotation": "org.junit.Ignore"} - ] + "name": "FrameworksVibratorServicesTests" } ], "postsubmit": [ diff --git a/services/tests/voiceinteractiontests/TEST_MAPPING b/services/tests/voiceinteractiontests/TEST_MAPPING index 6cbc49a2a7e1..466ba54fc8a4 100644 --- a/services/tests/voiceinteractiontests/TEST_MAPPING +++ b/services/tests/voiceinteractiontests/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "FrameworksVoiceInteractionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksVoiceInteractionTests" } ], "postsubmit": [ diff --git a/services/translation/java/com/android/server/translation/TEST_MAPPING b/services/translation/java/com/android/server/translation/TEST_MAPPING index 4090b4ab2c75..0b97358d430d 100644 --- a/services/translation/java/com/android/server/translation/TEST_MAPPING +++ b/services/translation/java/com/android/server/translation/TEST_MAPPING @@ -1,12 +1,7 @@ { "presubmit": [ { - "name": "CtsTranslationTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTranslationTestCases" } ] } diff --git a/services/usage/java/com/android/server/usage/TEST_MAPPING b/services/usage/java/com/android/server/usage/TEST_MAPPING index c8780546865e..79b294c00262 100644 --- a/services/usage/java/com/android/server/usage/TEST_MAPPING +++ b/services/usage/java/com/android/server/usage/TEST_MAPPING @@ -7,33 +7,15 @@ "name": "FrameworksServicesTests_android_server_usage" }, { - "name": "CtsBRSTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "CtsBRSTestCases" } ], "postsubmit": [ { - "name": "CtsUsageStatsTestCases", - "options": [ - { - "include-filter": "android.app.usage.cts.UsageStatsTest" - } - ] + "name": "CtsUsageStatsTestCases_cts_usagestatstest_ExcludeMediumAndLarge" }, { - "name": "CtsShortcutManagerTestCases", - "options": [ - { - "include-filter": "android.content.pm.cts.shortcutmanager.ShortcutManagerUsageTest" - } - ] + "name": "CtsShortcutManagerTestCases_shortcutmanager_shortcutmanagerusagetest" } ] } diff --git a/services/voiceinteraction/TEST_MAPPING b/services/voiceinteraction/TEST_MAPPING index e3d254948f8d..3a68b3327bbd 100644 --- a/services/voiceinteraction/TEST_MAPPING +++ b/services/voiceinteraction/TEST_MAPPING @@ -12,44 +12,19 @@ ] }, { - "name": "CtsAssistTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsAssistTestCases" }, { - "name": "CtsVoiceInteractionHostTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsVoiceInteractionHostTestCases" }, { - "name": "CtsLocalVoiceInteraction", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsLocalVoiceInteraction" }, { - "name": "FrameworksVoiceInteractionTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "FrameworksVoiceInteractionTests" }, { - "name": "CtsSoundTriggerTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSoundTriggerTestCases" } ] } diff --git a/telecomm/TEST_MAPPING b/telecomm/TEST_MAPPING index 775f1b83af94..4f6e55858b8d 100644 --- a/telecomm/TEST_MAPPING +++ b/telecomm/TEST_MAPPING @@ -1,70 +1,30 @@ { "presubmit": [ { - "name": "TeleServiceTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TeleServiceTests" }, { - "name": "TelecomUnitTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelecomUnitTests" }, { - "name": "TelephonyProviderTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelephonyProviderTests" }, { - "name": "CtsTelephony2TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony2TestCases" }, { - "name": "CtsTelephony3TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony3TestCases" }, { - "name": "CtsSimRestrictedApisTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSimRestrictedApisTestCases" }, { - "name": "CtsTelephonyProviderTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephonyProviderTestCases" } ], "presubmit-large": [ { - "name": "CtsTelecomTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelecomTestCases" } ] } diff --git a/telephony/TEST_MAPPING b/telephony/TEST_MAPPING index 73e3dcdb8dd0..4a4bae32ed8d 100644 --- a/telephony/TEST_MAPPING +++ b/telephony/TEST_MAPPING @@ -1,60 +1,25 @@ { "presubmit": [ { - "name": "TeleServiceTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TeleServiceTests" }, { - "name": "TelecomUnitTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelecomUnitTests" }, { - "name": "TelephonyProviderTests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TelephonyProviderTests" }, { - "name": "CtsTelephony2TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony2TestCases" }, { - "name": "CtsTelephony3TestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephony3TestCases" }, { - "name": "CtsSimRestrictedApisTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsSimRestrictedApisTestCases" }, { - "name": "CtsTelephonyProviderTestCases", - "options": [ - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "CtsTelephonyProviderTestCases" } ] } diff --git a/tests/TrustTests/TEST_MAPPING b/tests/TrustTests/TEST_MAPPING index 23923eeb83ee..b0dd55100c8a 100644 --- a/tests/TrustTests/TEST_MAPPING +++ b/tests/TrustTests/TEST_MAPPING @@ -1,28 +1,12 @@ { "presubmit": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ], "trust-tablet": [ { - "name": "TrustTests", - "options": [ - { - "include-filter": "android.trust.test" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - } - ] + "name": "TrustTests_trust_test" } ] }
\ No newline at end of file diff --git a/tests/UsbManagerTests/Android.bp b/tests/UsbManagerTests/Android.bp index 2909e66b53be..331a21a0215b 100644 --- a/tests/UsbManagerTests/Android.bp +++ b/tests/UsbManagerTests/Android.bp @@ -44,7 +44,7 @@ android_test { "libstaticjvmtiagent", ], libs: [ - "android.test.mock", + "android.test.mock.stubs.system", ], certificate: "platform", platform_apis: true, diff --git a/tests/utils/testutils/TEST_MAPPING b/tests/utils/testutils/TEST_MAPPING index 52fd5a8779ad..71e9ad37dd3c 100644 --- a/tests/utils/testutils/TEST_MAPPING +++ b/tests/utils/testutils/TEST_MAPPING @@ -1,18 +1,7 @@ { "presubmit": [ { - "name": "frameworks-base-testutils-tests", - "options": [ - { - "exclude-annotation": "androidx.test.filters.LargeTest" - }, - { - "exclude-annotation": "androidx.test.filters.FlakyTest" - }, - { - "exclude-annotation": "org.junit.Ignore" - } - ] + "name": "frameworks-base-testutils-tests" } ], "postsubmit": [ diff --git a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java index 580efe126ea3..4cb7c91b2451 100644 --- a/tests/vcn/java/com/android/server/VcnManagementServiceTest.java +++ b/tests/vcn/java/com/android/server/VcnManagementServiceTest.java @@ -146,6 +146,8 @@ public class VcnManagementServiceTest { private static final LinkProperties TEST_LP_1 = new LinkProperties(); private static final LinkProperties TEST_LP_2 = new LinkProperties(); + private static final int ACTIVE_MODEM_COUNT = 2; + static { TEST_LP_1.setInterfaceName(TEST_IFACE_NAME); TEST_LP_2.setInterfaceName(TEST_IFACE_NAME_2); @@ -233,6 +235,7 @@ public class VcnManagementServiceTest { setupSystemService(mMockContext, mUserManager, Context.USER_SERVICE, UserManager.class); doReturn(TEST_USER_HANDLE).when(mUserManager).getMainUser(); + doReturn(ACTIVE_MODEM_COUNT).when(mTelMgr).getActiveModemCount(); doReturn(TEST_PACKAGE_NAME).when(mMockContext).getOpPackageName(); diff --git a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java index 887630b03a8c..b5cc5536532c 100644 --- a/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java +++ b/tests/vcn/java/com/android/server/vcn/TelephonySubscriptionTrackerTest.java @@ -59,7 +59,6 @@ import android.os.HandlerExecutor; import android.os.ParcelUuid; import android.os.PersistableBundle; import android.os.test.TestLooper; -import android.platform.test.flag.junit.SetFlagsRule; import android.telephony.CarrierConfigManager; import android.telephony.SubscriptionInfo; import android.telephony.SubscriptionManager; @@ -73,10 +72,7 @@ import android.util.ArraySet; import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; -import com.android.internal.telephony.flags.Flags; - import org.junit.Before; -import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.ArgumentCaptor; @@ -133,8 +129,6 @@ public class TelephonySubscriptionTrackerTest { TEST_SUBID_TO_CARRIER_CONFIG_MAP = Collections.unmodifiableMap(subIdToCarrierConfigMap); } - @Rule public final SetFlagsRule mSetFlagsRule = new SetFlagsRule(); - @NonNull private final Context mContext; @NonNull private final TestLooper mTestLooper; @@ -193,7 +187,6 @@ public class TelephonySubscriptionTrackerTest { @Before public void setUp() throws Exception { - mSetFlagsRule.enableFlags(Flags.FLAG_FIX_CRASH_ON_GETTING_CONFIG_WHEN_PHONE_IS_GONE); doReturn(2).when(mTelephonyManager).getActiveModemCount(); mCallback = mock(TelephonySubscriptionTrackerCallback.class); diff --git a/tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt b/tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt index 24d203fd1116..b79563f740ee 100644 --- a/tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt +++ b/tools/lint/common/src/main/java/com/google/android/lint/aidl/EnforcePermissionUtils.kt @@ -24,20 +24,31 @@ import com.intellij.psi.PsiReferenceList import org.jetbrains.uast.UMethod /** - * Given a UMethod, determine if this method is the entrypoint to an interface - * generated by AIDL, returning the interface name if so, otherwise returning - * null + * Given a UMethod, determine if this method is the entrypoint to an interface generated by AIDL, + * returning the interface name if so, otherwise returning null. */ fun getContainingAidlInterface(context: JavaContext, node: UMethod): String? { + return containingAidlInterfacePsiClass(context, node)?.name +} + +/** + * Given a UMethod, determine if this method is the entrypoint to an interface generated by AIDL, + * returning the fully qualified interface name if so, otherwise returning null. + */ +fun getContainingAidlInterfaceQualified(context: JavaContext, node: UMethod): String? { + return containingAidlInterfacePsiClass(context, node)?.qualifiedName +} + +private fun containingAidlInterfacePsiClass(context: JavaContext, node: UMethod): PsiClass? { val containingStub = containingStub(context, node) ?: return null val superMethod = node.findSuperMethods(containingStub) if (superMethod.isEmpty()) return null - return containingStub.containingClass?.name + return containingStub.containingClass } -/* Returns the containing Stub class if any. This is not sufficient to infer - * that the method itself extends an AIDL generated method. See - * getContainingAidlInterface for that purpose. +/** + * Returns the containing Stub class if any. This is not sufficient to infer that the method itself + * extends an AIDL generated method. See getContainingAidlInterface for that purpose. */ fun containingStub(context: JavaContext, node: UMethod?): PsiClass? { var superClass = node?.containingClass?.superClass @@ -48,7 +59,7 @@ fun containingStub(context: JavaContext, node: UMethod?): PsiClass? { return null } -private fun isStub(context: JavaContext, psiClass: PsiClass?): Boolean { +fun isStub(context: JavaContext, psiClass: PsiClass?): Boolean { if (psiClass == null) return false if (psiClass.name != "Stub") return false if (!context.evaluator.isStatic(psiClass)) return false @@ -92,3 +103,26 @@ fun getHelperMethodFix( return fix.build() } + +/** + * PermissionAnnotationDetector uses this method to determine whether a specific file should be + * checked for unannotated methods. Only files located in directories whose paths begin with one + * of these prefixes will be considered. + */ +fun isSystemServicePath(context: JavaContext): Boolean { + val systemServicePathPrefixes = setOf( + "frameworks/base/services", + "frameworks/base/apex", + "frameworks/opt/wear", + "packages/modules" + ) + + val filePath = context.file.path + + // We perform `filePath.contains` instead of `filePath.startsWith` since getting the + // relative path of a source file is non-trivial. That is because `context.file.path` + // returns the path to where soong builds the file (i.e. /out/soong/...). Moreover, the + // logic to extract the relative path would need to consider several /out/soong/... + // locations patterns. + return systemServicePathPrefixes.any { filePath.contains(it) } +} diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt index 624a1987638e..af753e5963a3 100644 --- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt @@ -20,7 +20,6 @@ import com.android.tools.lint.client.api.IssueRegistry import com.android.tools.lint.client.api.Vendor import com.android.tools.lint.detector.api.CURRENT_API import com.google.android.lint.parcel.SaferParcelChecker -import com.google.android.lint.aidl.PermissionAnnotationDetector import com.google.auto.service.AutoService @AutoService(IssueRegistry::class) @@ -38,9 +37,9 @@ class AndroidFrameworkIssueRegistry : IssueRegistry() { SaferParcelChecker.ISSUE_UNSAFE_API_USAGE, // TODO: Currently crashes due to OOM issue // PackageVisibilityDetector.ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS, - PermissionAnnotationDetector.ISSUE_MISSING_PERMISSION_ANNOTATION, PermissionMethodDetector.ISSUE_PERMISSION_METHOD_USAGE, PermissionMethodDetector.ISSUE_CAN_BE_PERMISSION_METHOD, + FeatureAutomotiveDetector.ISSUE, ) override val api: Int diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/FeatureAutomotiveDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/FeatureAutomotiveDetector.kt new file mode 100644 index 000000000000..972b0c98eb94 --- /dev/null +++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/FeatureAutomotiveDetector.kt @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2024 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.google.android.lint + +import com.android.tools.lint.detector.api.Category +import com.android.tools.lint.detector.api.ConstantEvaluator +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Implementation +import com.android.tools.lint.detector.api.Issue +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.Scope +import com.android.tools.lint.detector.api.Severity +import com.android.tools.lint.detector.api.SourceCodeScanner +import com.intellij.psi.PsiMethod +import java.util.EnumSet +import org.jetbrains.uast.UCallExpression +import org.jetbrains.uast.ULiteralExpression +import org.jetbrains.uast.UReferenceExpression + +/** + * A detector to check the usage of PackageManager.hasSystemFeature(" + * android.hardware.type.automotive") in CTS tests. + */ +class FeatureAutomotiveDetector : Detector(), SourceCodeScanner { + + companion object { + + val EXPLANATION = + """ + This class uses PackageManager.hasSystemFeature(\"android.hardware.type.automotive\") \ + or other equivalent methods. \ + If it is used to make a CTS test behave differently on AAOS, you should use \ + @RequireAutomotive or @RequireNotAutomotive instead; otherwise, please ignore this \ + warning. See https://g3doc.corp.google.com/wireless/android/partner/compatibility/\ + g3doc/dev/write-a-test/index.md#write-a-test-that-behaves-differently-on-aaos + """ + + val ISSUE: Issue = + Issue.create( + id = "UsingFeatureAutomotiveInCTS", + briefDescription = + "PackageManager.hasSystemFeature(\"" + + " android.hardware.type.automotive\") is used in CTS tests", + explanation = EXPLANATION, + category = Category.TESTING, + priority = 8, + severity = Severity.WARNING, + implementation = + Implementation( + FeatureAutomotiveDetector::class.java, + EnumSet.of(Scope.JAVA_FILE, Scope.TEST_SOURCES) + ) + ) + } + + override fun getApplicableMethodNames() = + listOf("hasSystemFeature", "hasFeature", "hasDeviceFeature", "bypassTestForFeatures") + + override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) { + node.valueArguments.forEach { + val value = + when (it) { + is ULiteralExpression -> it.value + is UReferenceExpression -> ConstantEvaluator.evaluate(context, it) + else -> null + } + if (value is String && value == "android.hardware.type.automotive") { + context.report( + issue = ISSUE, + location = context.getNameLocation(method), + message = EXPLANATION + ) + } + } + } +} diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/FeatureAutomotiveDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/FeatureAutomotiveDetectorTest.kt new file mode 100644 index 000000000000..b5e2c00965f5 --- /dev/null +++ b/tools/lint/framework/checks/src/test/java/com/google/android/lint/FeatureAutomotiveDetectorTest.kt @@ -0,0 +1,366 @@ +/* + * Copyright (C) 2024 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.google.android.lint + +import com.android.tools.lint.checks.infrastructure.LintDetectorTest +import com.android.tools.lint.checks.infrastructure.TestFile +import com.android.tools.lint.checks.infrastructure.TestLintTask +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Issue +import org.junit.Test + +@Suppress("UnstableApiUsage") +class FeatureAutomotiveDetectorTest : LintDetectorTest() { + val explanation = + FeatureAutomotiveDetector.EXPLANATION.replace("\\", "").replace("\n ", "") + + " [UsingFeatureAutomotiveInCTS]" + + override fun getDetector(): Detector = FeatureAutomotiveDetector() + override fun getIssues(): List<Issue> = listOf(FeatureAutomotiveDetector.ISSUE) + override fun lint(): TestLintTask = super.lint().allowMissingSdk(true) + + @Test + fun testWarning1() { + lint() + .files( + java( + """ + import android.content.pm.PackageManager; + + public class Foo { + + private void fun() { + PackageManager.getInstance().hasSystemFeature( + "android.hardware.type.automotive"); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/android/content/pm/PackageManager.java:13: Warning: $explanation + public boolean hasSystemFeature(String feature) { + ~~~~~~~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testWarning2() { + lint() + .files( + java( + """ + import android.content.pm.PackageManager; + + public class Foo { + + private void fun() { + String featureName = "android.hardware.type.automotive"; + PackageManager.getInstance().hasSystemFeature(featureName); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/android/content/pm/PackageManager.java:13: Warning: $explanation + public boolean hasSystemFeature(String feature) { + ~~~~~~~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testWarning3() { + lint() + .files( + java( + """ + import android.content.pm.PackageManager; + + public class Foo { + + private void fun() { + PackageManager.getInstance().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/android/content/pm/PackageManager.java:13: Warning: $explanation + public boolean hasSystemFeature(String feature) { + ~~~~~~~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testWarning4() { + lint() + .files( + java( + """ + import android.content.pm.PackageManager; + + public class Foo { + + private void fun() { + String featureName = PackageManager.FEATURE_AUTOMOTIVE; + PackageManager.getInstance().hasSystemFeature(featureName); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/android/content/pm/PackageManager.java:13: Warning: $explanation + public boolean hasSystemFeature(String feature) { + ~~~~~~~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testWarning5() { + lint() + .files( + java( + """ + import com.android.example.Utils; + + public class Foo { + + private void fun() { + Utils.hasFeature("android.hardware.type.automotive"); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/com/android/example/Utils.java:7: Warning: $explanation + public static boolean hasFeature(String feature) { + ~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testWarning6() { + lint() + .files( + java( + """ + import com.android.example.Utils; + + public class Foo { + + private void fun() { + Utils.hasDeviceFeature("android.hardware.type.automotive"); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/com/android/example/Utils.java:11: Warning: $explanation + public static boolean hasDeviceFeature(String feature) { + ~~~~~~~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testWarning7() { + lint() + .files( + java( + """ + import com.android.example.Utils; + + public class Foo { + + private void fun() { + Utils.hasFeature(new Object(), "android.hardware.type.automotive"); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/com/android/example/Utils.java:15: Warning: $explanation + public static boolean hasFeature(Object object, String feature) { + ~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testWarning8() { + lint() + .files( + java( + """ + import com.android.example.Utils; + + public class Foo { + + private void fun() { + Utils.bypassTestForFeatures("android.hardware.type.automotive"); + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expect( + """ + src/com/android/example/Utils.java:19: Warning: $explanation + public static boolean bypassTestForFeatures(String feature) { + ~~~~~~~~~~~~~~~~~~~~~ + 0 errors, 1 warnings + """ + ) + } + + @Test + fun testNoWarning() { + lint() + .files( + java( + """ + import android.content.pm.PackageManager; + + public class Foo { + private void fun() { + String featureName1 = "android.hardware.type.automotive"; + String featureName2 = PackageManager.FEATURE_AUTOMOTIVE; + String notFeatureName = "FEATURE_AUTOMOTIVE"; + PackageManager.getInstance().hasSystemFeature(notFeatureName); + /* + PackageManager.getInstance().hasSystemFeature( + "android.hardware.type.automotive"); + */ + } + } + """ + ) + .indented(), + *stubs + ) + .issues(FeatureAutomotiveDetector.ISSUE) + .run() + .expectClean() + } + + private val pmStub: TestFile = + java( + """ + package android.content.pm; + + import java.lang.String; + + public class PackageManager { + public static final String FEATURE_AUTOMOTIVE = "android.hardware.type.automotive"; + + public static PackageManager getInstance() { + return new PackageManager(); + } + + public boolean hasSystemFeature(String feature) { + return true; + } + } + """ + ) + + private val exampleStub: TestFile = + java( + """ + package com.android.example; + + import java.lang.String; + + public class Utils { + public static boolean hasFeature(String feature) { + return true; + } + + public static boolean hasDeviceFeature(String feature) { + return true; + } + + public static boolean hasFeature(Object object, String feature) { + return true; + } + + public static boolean bypassTestForFeatures(String feature) { + return true; + } + } + """ + ) + + private val stubs = arrayOf(pmStub, exampleStub) +} diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/PermissionAnnotationDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/PermissionAnnotationDetectorTest.kt deleted file mode 100644 index bce848a2e3a7..000000000000 --- a/tools/lint/framework/checks/src/test/java/com/google/android/lint/PermissionAnnotationDetectorTest.kt +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2023 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.google.android.lint.aidl - -import com.android.tools.lint.checks.infrastructure.LintDetectorTest -import com.android.tools.lint.checks.infrastructure.TestFile -import com.android.tools.lint.checks.infrastructure.TestLintTask -import com.android.tools.lint.detector.api.Detector -import com.android.tools.lint.detector.api.Issue - -@Suppress("UnstableApiUsage") -class PermissionAnnotationDetectorTest : LintDetectorTest() { - override fun getDetector(): Detector = PermissionAnnotationDetector() - - override fun getIssues(): List<Issue> = listOf( - PermissionAnnotationDetector.ISSUE_MISSING_PERMISSION_ANNOTATION, - ) - - override fun lint(): TestLintTask = super.lint().allowMissingSdk(true) - - /** No issue scenario */ - - fun testDoesNotDetectIssuesInCorrectScenario() { - lint().files( - java( - """ - public class Foo extends IFoo.Stub { - @Override - @android.annotation.EnforcePermission("android.Manifest.permission.READ_CONTACTS") - public void testMethod() { } - } - """ - ).indented(), - *stubs - ) - .run() - .expectClean() - } - - fun testMissingAnnotation() { - lint().files( - java( - """ - public class Bar extends IBar.Stub { - public void testMethod() { } - } - """ - ).indented(), - *stubs - ) - .run() - .expect( - """ - src/Bar.java:2: Error: The method testMethod is not permission-annotated. [MissingPermissionAnnotation] - public void testMethod() { } - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 1 errors, 0 warnings - """ - ) - } - - fun testNoIssueWhenExtendingWithAnotherSubclass() { - lint().files( - java( - """ - public class Foo extends IFoo.Stub { - @Override - @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) - public void testMethod() { } - // not an AIDL method, just another method - public void someRandomMethod() { } - } - """).indented(), - java( - """ - public class Baz extends Bar { - @Override - public void someRandomMethod() { } - } - """).indented(), - *stubs - ) - .run() - .expectClean() - } - - /* Stubs */ - - // A service with permission annotation on the method. - private val interfaceIFoo: TestFile = java( - """ - public interface IFoo extends android.os.IInterface { - public static abstract class Stub extends android.os.Binder implements IFoo { - } - @Override - @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) - public void testMethod(); - @Override - @android.annotation.RequiresNoPermission - public void testMethodNoPermission(); - @Override - @android.annotation.PermissionManuallyEnforced - public void testMethodManual(); - } - """ - ).indented() - - // A service with no permission annotation. - private val interfaceIBar: TestFile = java( - """ - public interface IBar extends android.os.IInterface { - public static abstract class Stub extends android.os.Binder implements IBar { - } - public void testMethod(); - } - """ - ).indented() - - private val stubs = arrayOf(interfaceIFoo, interfaceIBar) -} diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt index 28eab8f62e74..94674348df08 100644 --- a/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/AndroidGlobalIssueRegistry.kt @@ -20,7 +20,9 @@ import com.android.tools.lint.client.api.IssueRegistry import com.android.tools.lint.client.api.Vendor import com.android.tools.lint.detector.api.CURRENT_API import com.google.android.lint.aidl.EnforcePermissionDetector +import com.google.android.lint.aidl.PermissionAnnotationDetector import com.google.android.lint.aidl.SimpleManualPermissionEnforcementDetector +import com.google.android.lint.aidl.SimpleRequiresNoPermissionDetector import com.google.auto.service.AutoService @AutoService(IssueRegistry::class) @@ -31,7 +33,9 @@ class AndroidGlobalIssueRegistry : IssueRegistry() { EnforcePermissionDetector.ISSUE_MISMATCHING_ENFORCE_PERMISSION, EnforcePermissionDetector.ISSUE_ENFORCE_PERMISSION_HELPER, EnforcePermissionDetector.ISSUE_MISUSING_ENFORCE_PERMISSION, + PermissionAnnotationDetector.ISSUE_MISSING_PERMISSION_ANNOTATION, SimpleManualPermissionEnforcementDetector.ISSUE_SIMPLE_MANUAL_PERMISSION_ENFORCEMENT, + SimpleRequiresNoPermissionDetector.ISSUE_SIMPLE_REQUIRES_NO_PERMISSION, ) override val api: Int diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/ExemptAidlInterfaces.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/ExemptAidlInterfaces.kt new file mode 100644 index 000000000000..675a59e6ae3e --- /dev/null +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/ExemptAidlInterfaces.kt @@ -0,0 +1,766 @@ +/* + * Copyright (C) 2024 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.google.android.lint.aidl + +/** + * The exemptAidlInterfaces set was generated by running ExemptAidlInterfacesGenerator on the + * entire source tree. To reproduce the results, run generate-exempt-aidl-interfaces.sh + * located in tools/lint/utils. + */ +val exemptAidlInterfaces = setOf( + "android.accessibilityservice.IBrailleDisplayConnection", + "android.accounts.IAccountAuthenticatorResponse", + "android.accounts.IAccountManager", + "android.accounts.IAccountManagerResponse", + "android.adservices.adid.IAdIdProviderService", + "android.adservices.adid.IAdIdService", + "android.adservices.adid.IGetAdIdCallback", + "android.adservices.adid.IGetAdIdProviderCallback", + "android.adservices.adselection.AdSelectionCallback", + "android.adservices.adselection.AdSelectionOverrideCallback", + "android.adservices.adselection.AdSelectionService", + "android.adservices.adselection.GetAdSelectionDataCallback", + "android.adservices.adselection.PersistAdSelectionResultCallback", + "android.adservices.adselection.ReportImpressionCallback", + "android.adservices.adselection.ReportInteractionCallback", + "android.adservices.adselection.SetAppInstallAdvertisersCallback", + "android.adservices.adselection.UpdateAdCounterHistogramCallback", + "android.adservices.appsetid.IAppSetIdProviderService", + "android.adservices.appsetid.IAppSetIdService", + "android.adservices.appsetid.IGetAppSetIdCallback", + "android.adservices.appsetid.IGetAppSetIdProviderCallback", + "android.adservices.cobalt.IAdServicesCobaltUploadService", + "android.adservices.common.IAdServicesCommonCallback", + "android.adservices.common.IAdServicesCommonService", + "android.adservices.common.IAdServicesCommonStatesCallback", + "android.adservices.common.IEnableAdServicesCallback", + "android.adservices.common.IUpdateAdIdCallback", + "android.adservices.customaudience.CustomAudienceOverrideCallback", + "android.adservices.customaudience.FetchAndJoinCustomAudienceCallback", + "android.adservices.customaudience.ICustomAudienceCallback", + "android.adservices.customaudience.ICustomAudienceService", + "android.adservices.customaudience.ScheduleCustomAudienceUpdateCallback", + "android.adservices.extdata.IAdServicesExtDataStorageService", + "android.adservices.extdata.IGetAdServicesExtDataCallback", + "android.adservices.measurement.IMeasurementApiStatusCallback", + "android.adservices.measurement.IMeasurementCallback", + "android.adservices.measurement.IMeasurementService", + "android.adservices.ondevicepersonalization.aidl.IDataAccessService", + "android.adservices.ondevicepersonalization.aidl.IDataAccessServiceCallback", + "android.adservices.ondevicepersonalization.aidl.IExecuteCallback", + "android.adservices.ondevicepersonalization.aidl.IFederatedComputeCallback", + "android.adservices.ondevicepersonalization.aidl.IFederatedComputeService", + "android.adservices.ondevicepersonalization.aidl.IIsolatedModelService", + "android.adservices.ondevicepersonalization.aidl.IIsolatedModelServiceCallback", + "android.adservices.ondevicepersonalization.aidl.IIsolatedService", + "android.adservices.ondevicepersonalization.aidl.IIsolatedServiceCallback", + "android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationConfigService", + "android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationConfigServiceCallback", + "android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationDebugService", + "android.adservices.ondevicepersonalization.aidl.IOnDevicePersonalizationManagingService", + "android.adservices.ondevicepersonalization.aidl.IRegisterMeasurementEventCallback", + "android.adservices.ondevicepersonalization.aidl.IRequestSurfacePackageCallback", + "android.adservices.shell.IShellCommand", + "android.adservices.shell.IShellCommandCallback", + "android.adservices.signals.IProtectedSignalsService", + "android.adservices.signals.UpdateSignalsCallback", + "android.adservices.topics.IGetTopicsCallback", + "android.adservices.topics.ITopicsService", + "android.app.admin.IDevicePolicyManager", + "android.app.adservices.IAdServicesManager", + "android.app.ambientcontext.IAmbientContextManager", + "android.app.ambientcontext.IAmbientContextObserver", + "android.app.appsearch.aidl.IAppFunctionService", + "android.app.appsearch.aidl.IAppSearchBatchResultCallback", + "android.app.appsearch.aidl.IAppSearchManager", + "android.app.appsearch.aidl.IAppSearchObserverProxy", + "android.app.appsearch.aidl.IAppSearchResultCallback", + "android.app.backup.IBackupCallback", + "android.app.backup.IBackupManager", + "android.app.backup.IRestoreSession", + "android.app.blob.IBlobCommitCallback", + "android.app.blob.IBlobStoreManager", + "android.app.blob.IBlobStoreSession", + "android.app.contentsuggestions.IContentSuggestionsManager", + "android.app.contextualsearch.IContextualSearchManager", + "android.app.ecm.IEnhancedConfirmationManager", + "android.apphibernation.IAppHibernationService", + "android.app.IActivityClientController", + "android.app.IActivityController", + "android.app.IActivityTaskManager", + "android.app.IAlarmCompleteListener", + "android.app.IAlarmListener", + "android.app.IAlarmManager", + "android.app.IApplicationThread", + "android.app.IAppTask", + "android.app.IAppTraceRetriever", + "android.app.IAssistDataReceiver", + "android.app.IForegroundServiceObserver", + "android.app.IGameManagerService", + "android.app.IGrammaticalInflectionManager", + "android.app.ILocaleManager", + "android.app.INotificationManager", + "android.app.IParcelFileDescriptorRetriever", + "android.app.IProcessObserver", + "android.app.ISearchManager", + "android.app.IStopUserCallback", + "android.app.ITaskStackListener", + "android.app.IUiModeManager", + "android.app.IUriGrantsManager", + "android.app.IUserSwitchObserver", + "android.app.IWallpaperManager", + "android.app.job.IJobCallback", + "android.app.job.IJobScheduler", + "android.app.job.IJobService", + "android.app.ondeviceintelligence.IDownloadCallback", + "android.app.ondeviceintelligence.IFeatureCallback", + "android.app.ondeviceintelligence.IFeatureDetailsCallback", + "android.app.ondeviceintelligence.IListFeaturesCallback", + "android.app.ondeviceintelligence.IOnDeviceIntelligenceManager", + "android.app.ondeviceintelligence.IProcessingSignal", + "android.app.ondeviceintelligence.IResponseCallback", + "android.app.ondeviceintelligence.IStreamingResponseCallback", + "android.app.ondeviceintelligence.ITokenInfoCallback", + "android.app.people.IPeopleManager", + "android.app.pinner.IPinnerService", + "android.app.prediction.IPredictionManager", + "android.app.role.IOnRoleHoldersChangedListener", + "android.app.role.IRoleController", + "android.app.role.IRoleManager", + "android.app.sdksandbox.ILoadSdkCallback", + "android.app.sdksandbox.IRequestSurfacePackageCallback", + "android.app.sdksandbox.ISdkSandboxManager", + "android.app.sdksandbox.ISdkSandboxProcessDeathCallback", + "android.app.sdksandbox.ISdkToServiceCallback", + "android.app.sdksandbox.ISharedPreferencesSyncCallback", + "android.app.sdksandbox.IUnloadSdkCallback", + "android.app.sdksandbox.testutils.testscenario.ISdkSandboxTestExecutor", + "android.app.search.ISearchUiManager", + "android.app.slice.ISliceManager", + "android.app.smartspace.ISmartspaceManager", + "android.app.timedetector.ITimeDetectorService", + "android.app.timezonedetector.ITimeZoneDetectorService", + "android.app.trust.ITrustManager", + "android.app.usage.IStorageStatsManager", + "android.app.usage.IUsageStatsManager", + "android.app.wallpapereffectsgeneration.IWallpaperEffectsGenerationManager", + "android.app.wearable.IWearableSensingCallback", + "android.app.wearable.IWearableSensingManager", + "android.bluetooth.IBluetooth", + "android.bluetooth.IBluetoothA2dp", + "android.bluetooth.IBluetoothA2dpSink", + "android.bluetooth.IBluetoothActivityEnergyInfoListener", + "android.bluetooth.IBluetoothAvrcpController", + "android.bluetooth.IBluetoothCallback", + "android.bluetooth.IBluetoothConnectionCallback", + "android.bluetooth.IBluetoothCsipSetCoordinator", + "android.bluetooth.IBluetoothCsipSetCoordinatorLockCallback", + "android.bluetooth.IBluetoothGatt", + "android.bluetooth.IBluetoothGattCallback", + "android.bluetooth.IBluetoothGattServerCallback", + "android.bluetooth.IBluetoothHapClient", + "android.bluetooth.IBluetoothHapClientCallback", + "android.bluetooth.IBluetoothHeadset", + "android.bluetooth.IBluetoothHeadsetClient", + "android.bluetooth.IBluetoothHearingAid", + "android.bluetooth.IBluetoothHidDevice", + "android.bluetooth.IBluetoothHidDeviceCallback", + "android.bluetooth.IBluetoothHidHost", + "android.bluetooth.IBluetoothLeAudio", + "android.bluetooth.IBluetoothLeAudioCallback", + "android.bluetooth.IBluetoothLeBroadcastAssistant", + "android.bluetooth.IBluetoothLeBroadcastAssistantCallback", + "android.bluetooth.IBluetoothLeBroadcastCallback", + "android.bluetooth.IBluetoothLeCallControl", + "android.bluetooth.IBluetoothLeCallControlCallback", + "android.bluetooth.IBluetoothManager", + "android.bluetooth.IBluetoothManagerCallback", + "android.bluetooth.IBluetoothMap", + "android.bluetooth.IBluetoothMapClient", + "android.bluetooth.IBluetoothMcpServiceManager", + "android.bluetooth.IBluetoothMetadataListener", + "android.bluetooth.IBluetoothOobDataCallback", + "android.bluetooth.IBluetoothPan", + "android.bluetooth.IBluetoothPanCallback", + "android.bluetooth.IBluetoothPbap", + "android.bluetooth.IBluetoothPbapClient", + "android.bluetooth.IBluetoothPreferredAudioProfilesCallback", + "android.bluetooth.IBluetoothQualityReportReadyCallback", + "android.bluetooth.IBluetoothSap", + "android.bluetooth.IBluetoothScan", + "android.bluetooth.IBluetoothSocketManager", + "android.bluetooth.IBluetoothVolumeControl", + "android.bluetooth.IBluetoothVolumeControlCallback", + "android.bluetooth.le.IAdvertisingSetCallback", + "android.bluetooth.le.IDistanceMeasurementCallback", + "android.bluetooth.le.IPeriodicAdvertisingCallback", + "android.bluetooth.le.IScannerCallback", + "android.companion.ICompanionDeviceManager", + "android.companion.IOnMessageReceivedListener", + "android.companion.IOnTransportsChangedListener", + "android.companion.virtualcamera.IVirtualCameraCallback", + "android.companion.virtual.IVirtualDevice", + "android.companion.virtual.IVirtualDeviceManager", + "android.companion.virtualnative.IVirtualDeviceManagerNative", + "android.content.IClipboard", + "android.content.IContentService", + "android.content.IIntentReceiver", + "android.content.IIntentSender", + "android.content.integrity.IAppIntegrityManager", + "android.content.IRestrictionsManager", + "android.content.ISyncAdapterUnsyncableAccountCallback", + "android.content.ISyncContext", + "android.content.om.IOverlayManager", + "android.content.pm.dex.IArtManager", + "android.content.pm.dex.ISnapshotRuntimeProfileCallback", + "android.content.pm.IBackgroundInstallControlService", + "android.content.pm.ICrossProfileApps", + "android.content.pm.IDataLoaderManager", + "android.content.pm.IDataLoaderStatusListener", + "android.content.pm.ILauncherApps", + "android.content.pm.IOnChecksumsReadyListener", + "android.content.pm.IOtaDexopt", + "android.content.pm.IPackageDataObserver", + "android.content.pm.IPackageDeleteObserver", + "android.content.pm.IPackageInstaller", + "android.content.pm.IPackageInstallerSession", + "android.content.pm.IPackageInstallerSessionFileSystemConnector", + "android.content.pm.IPackageInstallObserver2", + "android.content.pm.IPackageLoadingProgressCallback", + "android.content.pm.IPackageManager", + "android.content.pm.IPackageManagerNative", + "android.content.pm.IPackageMoveObserver", + "android.content.pm.IPinItemRequest", + "android.content.pm.IShortcutService", + "android.content.pm.IStagedApexObserver", + "android.content.pm.verify.domain.IDomainVerificationManager", + "android.content.res.IResourcesManager", + "android.content.rollback.IRollbackManager", + "android.credentials.ICredentialManager", + "android.debug.IAdbTransport", + "android.devicelock.IDeviceLockService", + "android.devicelock.IGetDeviceIdCallback", + "android.devicelock.IGetKioskAppsCallback", + "android.devicelock.IIsDeviceLockedCallback", + "android.devicelock.IVoidResultCallback", + "android.federatedcompute.aidl.IExampleStoreCallback", + "android.federatedcompute.aidl.IExampleStoreIterator", + "android.federatedcompute.aidl.IExampleStoreIteratorCallback", + "android.federatedcompute.aidl.IExampleStoreService", + "android.federatedcompute.aidl.IFederatedComputeCallback", + "android.federatedcompute.aidl.IFederatedComputeService", + "android.federatedcompute.aidl.IResultHandlingService", + "android.flags.IFeatureFlags", + "android.frameworks.location.altitude.IAltitudeService", + "android.frameworks.vibrator.IVibratorController", + "android.frameworks.vibrator.IVibratorControlService", + "android.gsi.IGsiServiceCallback", + "android.hardware.biometrics.AuthenticationStateListener", + "android.hardware.biometrics.common.ICancellationSignal", + "android.hardware.biometrics.face.IFace", + "android.hardware.biometrics.face.ISession", + "android.hardware.biometrics.face.ISessionCallback", + "android.hardware.biometrics.fingerprint.IFingerprint", + "android.hardware.biometrics.fingerprint.ISession", + "android.hardware.biometrics.fingerprint.ISessionCallback", + "android.hardware.biometrics.IAuthService", + "android.hardware.biometrics.IBiometricAuthenticator", + "android.hardware.biometrics.IBiometricContextListener", + "android.hardware.biometrics.IBiometricSensorReceiver", + "android.hardware.biometrics.IBiometricService", + "android.hardware.biometrics.IBiometricStateListener", + "android.hardware.biometrics.IBiometricSysuiReceiver", + "android.hardware.biometrics.IInvalidationCallback", + "android.hardware.biometrics.ITestSession", + "android.hardware.broadcastradio.IAnnouncementListener", + "android.hardware.broadcastradio.ITunerCallback", + "android.hardware.contexthub.IContextHubCallback", + "android.hardware.devicestate.IDeviceStateManager", + "android.hardware.display.IColorDisplayManager", + "android.hardware.display.IDisplayManager", + "android.hardware.face.IFaceAuthenticatorsRegisteredCallback", + "android.hardware.face.IFaceService", + "android.hardware.face.IFaceServiceReceiver", + "android.hardware.fingerprint.IFingerprintAuthenticatorsRegisteredCallback", + "android.hardware.fingerprint.IFingerprintClientActiveCallback", + "android.hardware.fingerprint.IFingerprintService", + "android.hardware.fingerprint.IFingerprintServiceReceiver", + "android.hardware.fingerprint.IUdfpsOverlayControllerCallback", + "android.hardware.fingerprint.IUdfpsRefreshRateRequestCallback", + "android.hardware.hdmi.IHdmiControlCallback", + "android.hardware.hdmi.IHdmiControlService", + "android.hardware.hdmi.IHdmiDeviceEventListener", + "android.hardware.hdmi.IHdmiHotplugEventListener", + "android.hardware.hdmi.IHdmiSystemAudioModeChangeListener", + "android.hardware.health.IHealthInfoCallback", + "android.hardware.ICameraServiceProxy", + "android.hardware.IConsumerIrService", + "android.hardware.input.IInputManager", + "android.hardware.iris.IIrisService", + "android.hardware.ISensorPrivacyManager", + "android.hardware.ISerialManager", + "android.hardware.lights.ILightsManager", + "android.hardware.location.IContextHubClient", + "android.hardware.location.IContextHubClientCallback", + "android.hardware.location.IContextHubService", + "android.hardware.location.IContextHubTransactionCallback", + "android.hardware.location.ISignificantPlaceProviderManager", + "android.hardware.radio.IAnnouncementListener", + "android.hardware.radio.ICloseHandle", + "android.hardware.radio.ims.media.IImsMedia", + "android.hardware.radio.ims.media.IImsMediaListener", + "android.hardware.radio.ims.media.IImsMediaSession", + "android.hardware.radio.ims.media.IImsMediaSessionListener", + "android.hardware.radio.IRadioService", + "android.hardware.radio.ITuner", + "android.hardware.radio.sap.ISapCallback", + "android.hardware.soundtrigger3.ISoundTriggerHw", + "android.hardware.soundtrigger3.ISoundTriggerHwCallback", + "android.hardware.soundtrigger3.ISoundTriggerHwGlobalCallback", + "android.hardware.soundtrigger.IRecognitionStatusCallback", + "android.hardware.tetheroffload.ITetheringOffloadCallback", + "android.hardware.thermal.IThermalChangedCallback", + "android.hardware.tv.hdmi.cec.IHdmiCecCallback", + "android.hardware.tv.hdmi.connection.IHdmiConnectionCallback", + "android.hardware.tv.hdmi.earc.IEArcCallback", + "android.hardware.usb.gadget.IUsbGadgetCallback", + "android.hardware.usb.IUsbCallback", + "android.hardware.usb.IUsbManager", + "android.hardware.usb.IUsbSerialReader", + "android.hardware.wifi.hostapd.IHostapdCallback", + "android.hardware.wifi.IWifiChipEventCallback", + "android.hardware.wifi.IWifiEventCallback", + "android.hardware.wifi.IWifiNanIfaceEventCallback", + "android.hardware.wifi.IWifiRttControllerEventCallback", + "android.hardware.wifi.IWifiStaIfaceEventCallback", + "android.hardware.wifi.supplicant.INonStandardCertCallback", + "android.hardware.wifi.supplicant.ISupplicantP2pIfaceCallback", + "android.hardware.wifi.supplicant.ISupplicantStaIfaceCallback", + "android.hardware.wifi.supplicant.ISupplicantStaNetworkCallback", + "android.health.connect.aidl.IAccessLogsResponseCallback", + "android.health.connect.aidl.IActivityDatesResponseCallback", + "android.health.connect.aidl.IAggregateRecordsResponseCallback", + "android.health.connect.aidl.IApplicationInfoResponseCallback", + "android.health.connect.aidl.IChangeLogsResponseCallback", + "android.health.connect.aidl.IDataStagingFinishedCallback", + "android.health.connect.aidl.IEmptyResponseCallback", + "android.health.connect.aidl.IGetChangeLogTokenCallback", + "android.health.connect.aidl.IGetHealthConnectDataStateCallback", + "android.health.connect.aidl.IGetHealthConnectMigrationUiStateCallback", + "android.health.connect.aidl.IGetPriorityResponseCallback", + "android.health.connect.aidl.IHealthConnectService", + "android.health.connect.aidl.IInsertRecordsResponseCallback", + "android.health.connect.aidl.IMedicalDataSourceResponseCallback", + "android.health.connect.aidl.IMedicalResourcesResponseCallback", + "android.health.connect.aidl.IMigrationCallback", + "android.health.connect.aidl.IReadMedicalResourcesResponseCallback", + "android.health.connect.aidl.IReadRecordsResponseCallback", + "android.health.connect.aidl.IRecordTypeInfoResponseCallback", + "android.health.connect.exportimport.IImportStatusCallback", + "android.health.connect.exportimport.IQueryDocumentProvidersCallback", + "android.health.connect.exportimport.IScheduledExportStatusCallback", + "android.location.ICountryDetector", + "android.location.IGpsGeofenceHardware", + "android.location.ILocationManager", + "android.location.provider.ILocationProviderManager", + "android.media.IAudioRoutesObserver", + "android.media.IMediaCommunicationService", + "android.media.IMediaCommunicationServiceCallback", + "android.media.IMediaController2", + "android.media.IMediaRoute2ProviderServiceCallback", + "android.media.IMediaRouterService", + "android.media.IMediaSession2", + "android.media.IMediaSession2Service", + "android.media.INativeSpatializerCallback", + "android.media.IPlaybackConfigDispatcher", + "android.media.IRecordingConfigDispatcher", + "android.media.IRemoteDisplayCallback", + "android.media.ISoundDoseCallback", + "android.media.ISpatializerHeadTrackingCallback", + "android.media.ITranscodingClientCallback", + "android.media.metrics.IMediaMetricsManager", + "android.media.midi.IMidiManager", + "android.media.musicrecognition.IMusicRecognitionAttributionTagCallback", + "android.media.musicrecognition.IMusicRecognitionManager", + "android.media.musicrecognition.IMusicRecognitionServiceCallback", + "android.media.projection.IMediaProjection", + "android.media.projection.IMediaProjectionCallback", + "android.media.projection.IMediaProjectionManager", + "android.media.projection.IMediaProjectionWatcherCallback", + "android.media.session.ISession", + "android.media.session.ISessionController", + "android.media.session.ISessionManager", + "android.media.soundtrigger.ISoundTriggerDetectionServiceClient", + "android.media.soundtrigger_middleware.IInjectGlobalEvent", + "android.media.soundtrigger_middleware.IInjectModelEvent", + "android.media.soundtrigger_middleware.IInjectRecognitionEvent", + "android.media.soundtrigger_middleware.ISoundTriggerMiddlewareService", + "android.media.soundtrigger_middleware.ISoundTriggerModule", + "android.media.tv.ad.ITvAdManager", + "android.media.tv.ad.ITvAdSessionCallback", + "android.media.tv.interactive.ITvInteractiveAppManager", + "android.media.tv.interactive.ITvInteractiveAppServiceCallback", + "android.media.tv.interactive.ITvInteractiveAppSessionCallback", + "android.media.tv.ITvInputHardware", + "android.media.tv.ITvInputManager", + "android.media.tv.ITvInputServiceCallback", + "android.media.tv.ITvInputSessionCallback", + "android.media.tv.ITvRemoteServiceInput", + "android.nearby.aidl.IOffloadCallback", + "android.nearby.IBroadcastListener", + "android.nearby.INearbyManager", + "android.nearby.IScanListener", + "android.net.connectivity.aidl.ConnectivityNative", + "android.net.dhcp.IDhcpEventCallbacks", + "android.net.dhcp.IDhcpServer", + "android.net.dhcp.IDhcpServerCallbacks", + "android.net.ICaptivePortal", + "android.net.IConnectivityDiagnosticsCallback", + "android.net.IConnectivityManager", + "android.net.IEthernetManager", + "android.net.IEthernetServiceListener", + "android.net.IIntResultListener", + "android.net.IIpConnectivityMetrics", + "android.net.IIpMemoryStore", + "android.net.IIpMemoryStoreCallbacks", + "android.net.IIpSecService", + "android.net.INetdEventCallback", + "android.net.INetdUnsolicitedEventListener", + "android.net.INetworkActivityListener", + "android.net.INetworkAgent", + "android.net.INetworkAgentRegistry", + "android.net.INetworkInterfaceOutcomeReceiver", + "android.net.INetworkManagementEventObserver", + "android.net.INetworkMonitor", + "android.net.INetworkMonitorCallbacks", + "android.net.INetworkOfferCallback", + "android.net.INetworkPolicyListener", + "android.net.INetworkPolicyManager", + "android.net.INetworkScoreService", + "android.net.INetworkStackConnector", + "android.net.INetworkStackStatusCallback", + "android.net.INetworkStatsService", + "android.net.INetworkStatsSession", + "android.net.IOnCompleteListener", + "android.net.IPacProxyManager", + "android.net.ip.IIpClient", + "android.net.ip.IIpClientCallbacks", + "android.net.ipmemorystore.IOnBlobRetrievedListener", + "android.net.ipmemorystore.IOnL2KeyResponseListener", + "android.net.ipmemorystore.IOnNetworkAttributesRetrievedListener", + "android.net.ipmemorystore.IOnSameL3NetworkResponseListener", + "android.net.ipmemorystore.IOnStatusAndCountListener", + "android.net.ipmemorystore.IOnStatusListener", + "android.net.IQosCallback", + "android.net.ISocketKeepaliveCallback", + "android.net.ITestNetworkManager", + "android.net.ITetheredInterfaceCallback", + "android.net.ITetheringConnector", + "android.net.ITetheringEventCallback", + "android.net.IVpnManager", + "android.net.mdns.aidl.IMDnsEventListener", + "android.net.metrics.INetdEventListener", + "android.net.netstats.IUsageCallback", + "android.net.netstats.provider.INetworkStatsProvider", + "android.net.netstats.provider.INetworkStatsProviderCallback", + "android.net.nsd.INsdManager", + "android.net.nsd.INsdManagerCallback", + "android.net.nsd.INsdServiceConnector", + "android.net.nsd.IOffloadEngine", + "android.net.resolv.aidl.IDnsResolverUnsolicitedEventListener", + "android.net.thread.IActiveOperationalDatasetReceiver", + "android.net.thread.IConfigurationReceiver", + "android.net.thread.IOperationalDatasetCallback", + "android.net.thread.IOperationReceiver", + "android.net.thread.IStateCallback", + "android.net.thread.IThreadNetworkController", + "android.net.thread.IThreadNetworkManager", + "android.net.vcn.IVcnManagementService", + "android.net.wear.ICompanionDeviceManagerProxy", + "android.net.wifi.aware.IWifiAwareDiscoverySessionCallback", + "android.net.wifi.aware.IWifiAwareEventCallback", + "android.net.wifi.aware.IWifiAwareMacAddressProvider", + "android.net.wifi.aware.IWifiAwareManager", + "android.net.wifi.hotspot2.IProvisioningCallback", + "android.net.wifi.IActionListener", + "android.net.wifi.IBooleanListener", + "android.net.wifi.IByteArrayListener", + "android.net.wifi.ICoexCallback", + "android.net.wifi.IDppCallback", + "android.net.wifi.IIntegerListener", + "android.net.wifi.IInterfaceCreationInfoCallback", + "android.net.wifi.ILastCallerListener", + "android.net.wifi.IListListener", + "android.net.wifi.ILocalOnlyConnectionStatusListener", + "android.net.wifi.ILocalOnlyHotspotCallback", + "android.net.wifi.IMacAddressListListener", + "android.net.wifi.IMapListener", + "android.net.wifi.INetworkRequestMatchCallback", + "android.net.wifi.INetworkRequestUserSelectionCallback", + "android.net.wifi.IOnWifiActivityEnergyInfoListener", + "android.net.wifi.IOnWifiDriverCountryCodeChangedListener", + "android.net.wifi.IOnWifiUsabilityStatsListener", + "android.net.wifi.IPnoScanResultsCallback", + "android.net.wifi.IScanDataListener", + "android.net.wifi.IScanResultsCallback", + "android.net.wifi.IScoreUpdateObserver", + "android.net.wifi.ISoftApCallback", + "android.net.wifi.IStringListener", + "android.net.wifi.ISubsystemRestartCallback", + "android.net.wifi.ISuggestionConnectionStatusListener", + "android.net.wifi.ISuggestionUserApprovalStatusListener", + "android.net.wifi.ITrafficStateCallback", + "android.net.wifi.ITwtCallback", + "android.net.wifi.ITwtCapabilitiesListener", + "android.net.wifi.ITwtStatsListener", + "android.net.wifi.IWifiBandsListener", + "android.net.wifi.IWifiConnectedNetworkScorer", + "android.net.wifi.IWifiLowLatencyLockListener", + "android.net.wifi.IWifiManager", + "android.net.wifi.IWifiNetworkSelectionConfigListener", + "android.net.wifi.IWifiNetworkStateChangedListener", + "android.net.wifi.IWifiScanner", + "android.net.wifi.IWifiScannerListener", + "android.net.wifi.IWifiVerboseLoggingStatusChangedListener", + "android.net.wifi.p2p.IWifiP2pListener", + "android.net.wifi.p2p.IWifiP2pManager", + "android.net.wifi.rtt.IRttCallback", + "android.net.wifi.rtt.IWifiRttManager", + "android.ondevicepersonalization.IOnDevicePersonalizationSystemService", + "android.ondevicepersonalization.IOnDevicePersonalizationSystemServiceCallback", + "android.os.IBatteryPropertiesRegistrar", + "android.os.ICancellationSignal", + "android.os.IDeviceIdentifiersPolicyService", + "android.os.IDeviceIdleController", + "android.os.IDumpstate", + "android.os.IDumpstateListener", + "android.os.IExternalVibratorService", + "android.os.IHardwarePropertiesManager", + "android.os.IHintManager", + "android.os.IHintSession", + "android.os.IIncidentCompanion", + "android.os.image.IDynamicSystemService", + "android.os.incremental.IStorageHealthListener", + "android.os.INetworkManagementService", + "android.os.IPendingIntentRef", + "android.os.IPowerStatsService", + "android.os.IProfilingResultCallback", + "android.os.IProfilingService", + "android.os.IProgressListener", + "android.os.IPullAtomCallback", + "android.os.IRecoverySystem", + "android.os.IRemoteCallback", + "android.os.ISecurityStateManager", + "android.os.IServiceCallback", + "android.os.IStatsCompanionService", + "android.os.IStatsManagerService", + "android.os.IStatsQueryCallback", + "android.os.ISystemConfig", + "android.os.ISystemUpdateManager", + "android.os.IThermalEventListener", + "android.os.IUpdateLock", + "android.os.IUserManager", + "android.os.IUserRestrictionsListener", + "android.os.IVibratorManagerService", + "android.os.IVoldListener", + "android.os.IVoldMountCallback", + "android.os.IVoldTaskListener", + "android.os.logcat.ILogcatManagerService", + "android.permission.ILegacyPermissionManager", + "android.permission.IPermissionChecker", + "android.permission.IPermissionManager", + "android.print.IPrintManager", + "android.print.IPrintSpoolerCallbacks", + "android.print.IPrintSpoolerClient", + "android.printservice.IPrintServiceClient", + "android.printservice.recommendation.IRecommendationServiceCallbacks", + "android.provider.aidl.IDeviceConfigManager", + "android.remoteauth.IDeviceDiscoveryListener", + "android.safetycenter.IOnSafetyCenterDataChangedListener", + "android.safetycenter.ISafetyCenterManager", + "android.scheduling.IRebootReadinessManager", + "android.scheduling.IRequestRebootReadinessStatusListener", + "android.security.attestationverification.IAttestationVerificationManagerService", + "android.security.IFileIntegrityService", + "android.security.keystore.IKeyAttestationApplicationIdProvider", + "android.security.rkp.IRegistration", + "android.security.rkp.IRemoteProvisioning", + "android.service.appprediction.IPredictionService", + "android.service.assist.classification.IFieldClassificationCallback", + "android.service.attention.IAttentionCallback", + "android.service.attention.IProximityUpdateCallback", + "android.service.autofill.augmented.IFillCallback", + "android.service.autofill.IConvertCredentialCallback", + "android.service.autofill.IFillCallback", + "android.service.autofill.IInlineSuggestionUiCallback", + "android.service.autofill.ISaveCallback", + "android.service.autofill.ISurfacePackageResultCallback", + "android.service.contentcapture.IContentCaptureServiceCallback", + "android.service.contentcapture.IContentProtectionAllowlistCallback", + "android.service.contentcapture.IDataShareCallback", + "android.service.credentials.IBeginCreateCredentialCallback", + "android.service.credentials.IBeginGetCredentialCallback", + "android.service.credentials.IClearCredentialStateCallback", + "android.service.dreams.IDreamManager", + "android.service.games.IGameServiceController", + "android.service.games.IGameSessionController", + "android.service.notification.IStatusBarNotificationHolder", + "android.service.oemlock.IOemLockService", + "android.service.ondeviceintelligence.IProcessingUpdateStatusCallback", + "android.service.ondeviceintelligence.IRemoteProcessingService", + "android.service.ondeviceintelligence.IRemoteStorageService", + "android.service.persistentdata.IPersistentDataBlockService", + "android.service.resolver.IResolverRankerResult", + "android.service.rotationresolver.IRotationResolverCallback", + "android.service.textclassifier.ITextClassifierCallback", + "android.service.textclassifier.ITextClassifierService", + "android.service.timezone.ITimeZoneProviderManager", + "android.service.trust.ITrustAgentServiceCallback", + "android.service.voice.IDetectorSessionStorageService", + "android.service.voice.IDetectorSessionVisualQueryDetectionCallback", + "android.service.voice.IDspHotwordDetectionCallback", + "android.service.wallpaper.IWallpaperConnection", + "android.speech.IRecognitionListener", + "android.speech.IRecognitionService", + "android.speech.IRecognitionServiceManager", + "android.speech.tts.ITextToSpeechManager", + "android.speech.tts.ITextToSpeechSession", + "android.system.composd.ICompilationTaskCallback", + "android.system.virtualizationmaintenance.IVirtualizationReconciliationCallback", + "android.system.virtualizationservice.IVirtualMachineCallback", + "android.system.vmtethering.IVmTethering", + "android.telephony.imsmedia.IImsAudioSession", + "android.telephony.imsmedia.IImsAudioSessionCallback", + "android.telephony.imsmedia.IImsMedia", + "android.telephony.imsmedia.IImsMediaCallback", + "android.telephony.imsmedia.IImsTextSession", + "android.telephony.imsmedia.IImsTextSessionCallback", + "android.telephony.imsmedia.IImsVideoSession", + "android.telephony.imsmedia.IImsVideoSessionCallback", + "android.tracing.ITracingServiceProxy", + "android.uwb.IOnUwbActivityEnergyInfoListener", + "android.uwb.IUwbAdapter", + "android.uwb.IUwbAdapterStateCallbacks", + "android.uwb.IUwbAdfProvisionStateCallbacks", + "android.uwb.IUwbOemExtensionCallback", + "android.uwb.IUwbRangingCallbacks", + "android.uwb.IUwbVendorUciCallback", + "android.view.autofill.IAutoFillManager", + "android.view.autofill.IAutofillWindowPresenter", + "android.view.contentcapture.IContentCaptureManager", + "android.view.IDisplayChangeWindowCallback", + "android.view.IDisplayWindowListener", + "android.view.IInputFilter", + "android.view.IInputFilterHost", + "android.view.IInputMonitorHost", + "android.view.IRecentsAnimationController", + "android.view.IRemoteAnimationFinishedCallback", + "android.view.ISensitiveContentProtectionManager", + "android.view.IWindowId", + "android.view.IWindowManager", + "android.view.IWindowSession", + "android.view.translation.ITranslationManager", + "android.view.translation.ITranslationServiceCallback", + "android.webkit.IWebViewUpdateService", + "android.window.IBackAnimationFinishedCallback", + "android.window.IDisplayAreaOrganizerController", + "android.window.ITaskFragmentOrganizerController", + "android.window.ITaskOrganizerController", + "android.window.ITransitionMetricsReporter", + "android.window.IUnhandledDragCallback", + "android.window.IWindowContainerToken", + "android.window.IWindowlessStartingSurfaceCallback", + "android.window.IWindowOrganizerController", + "androidx.core.uwb.backend.IUwb", + "androidx.core.uwb.backend.IUwbClient", + "com.android.clockwork.modes.IModeManager", + "com.android.clockwork.modes.IStateChangeListener", + "com.android.clockwork.power.IWearPowerService", + "com.android.devicelockcontroller.IDeviceLockControllerService", + "com.android.devicelockcontroller.storage.IGlobalParametersService", + "com.android.devicelockcontroller.storage.ISetupParametersService", + "com.android.federatedcompute.services.training.aidl.IIsolatedTrainingService", + "com.android.federatedcompute.services.training.aidl.ITrainingResultCallback", + "com.android.internal.app.IAppOpsActiveCallback", + "com.android.internal.app.ILogAccessDialogCallback", + "com.android.internal.app.ISoundTriggerService", + "com.android.internal.app.ISoundTriggerSession", + "com.android.internal.app.IVoiceInteractionAccessibilitySettingsListener", + "com.android.internal.app.IVoiceInteractionManagerService", + "com.android.internal.app.IVoiceInteractionSessionListener", + "com.android.internal.app.IVoiceInteractionSessionShowCallback", + "com.android.internal.app.IVoiceInteractionSoundTriggerSession", + "com.android.internal.app.procstats.IProcessStats", + "com.android.internal.appwidget.IAppWidgetService", + "com.android.internal.backup.ITransportStatusCallback", + "com.android.internal.compat.IOverrideValidator", + "com.android.internal.compat.IPlatformCompat", + "com.android.internal.compat.IPlatformCompatNative", + "com.android.internal.graphics.fonts.IFontManager", + "com.android.internal.inputmethod.IAccessibilityInputMethodSessionCallback", + "com.android.internal.inputmethod.IConnectionlessHandwritingCallback", + "com.android.internal.inputmethod.IImeTracker", + "com.android.internal.inputmethod.IInlineSuggestionsRequestCallback", + "com.android.internal.inputmethod.IInputContentUriToken", + "com.android.internal.inputmethod.IInputMethodPrivilegedOperations", + "com.android.internal.inputmethod.IInputMethodSessionCallback", + "com.android.internal.net.INetworkWatchlistManager", + "com.android.internal.os.IBinaryTransparencyService", + "com.android.internal.os.IDropBoxManagerService", + "com.android.internal.policy.IKeyguardDismissCallback", + "com.android.internal.policy.IKeyguardDrawnCallback", + "com.android.internal.policy.IKeyguardExitCallback", + "com.android.internal.policy.IKeyguardStateCallback", + "com.android.internal.statusbar.IAddTileResultCallback", + "com.android.internal.statusbar.ISessionListener", + "com.android.internal.statusbar.IStatusBarService", + "com.android.internal.telecom.IDeviceIdleControllerAdapter", + "com.android.internal.telecom.IInternalServiceRetriever", + "com.android.internal.telephony.IMms", + "com.android.internal.telephony.ITelephonyRegistry", + "com.android.internal.textservice.ISpellCheckerServiceCallback", + "com.android.internal.textservice.ITextServicesManager", + "com.android.internal.view.IDragAndDropPermissions", + "com.android.internal.view.IInputMethodManager", + "com.android.internal.view.inline.IInlineContentProvider", + "com.android.internal.widget.ILockSettings", + "com.android.net.IProxyPortListener", + "com.android.net.module.util.IRoutingCoordinator", + "com.android.ondevicepersonalization.libraries.plugin.internal.IPluginCallback", + "com.android.ondevicepersonalization.libraries.plugin.internal.IPluginExecutorService", + "com.android.ondevicepersonalization.libraries.plugin.internal.IPluginStateCallback", + "com.android.rkpdapp.IGetKeyCallback", + "com.android.rkpdapp.IGetRegistrationCallback", + "com.android.rkpdapp.IRegistration", + "com.android.rkpdapp.IRemoteProvisioning", + "com.android.rkpdapp.IStoreUpgradedKeyCallback", + "com.android.sdksandbox.IComputeSdkStorageCallback", + "com.android.sdksandbox.ILoadSdkInSandboxCallback", + "com.android.sdksandbox.IRequestSurfacePackageFromSdkCallback", + "com.android.sdksandbox.ISdkSandboxManagerToSdkSandboxCallback", + "com.android.sdksandbox.ISdkSandboxService", + "com.android.sdksandbox.IUnloadSdkInSandboxCallback", + "com.android.server.profcollect.IProviderStatusCallback", + "com.android.server.thread.openthread.IChannelMasksReceiver", + "com.android.server.thread.openthread.INsdPublisher", + "com.android.server.thread.openthread.IOtDaemonCallback", + "com.android.server.thread.openthread.IOtStatusReceiver", + "com.google.android.clockwork.ambient.offload.IDisplayOffloadService", + "com.google.android.clockwork.ambient.offload.IDisplayOffloadTransitionFinishedCallbacks", + "com.google.android.clockwork.healthservices.IHealthService", + "vendor.google_clockwork.healthservices.IHealthServicesCallback", +) diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionAnnotationDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/PermissionAnnotationDetector.kt index 6b50cfd9e5ab..d44c271e734c 100644 --- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/PermissionAnnotationDetector.kt +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/PermissionAnnotationDetector.kt @@ -43,8 +43,14 @@ class PermissionAnnotationDetector : AidlImplementationDetector() { interfaceName: String, body: UBlockExpression ) { + if (!isSystemServicePath(context)) return + if (context.evaluator.isAbstract(node)) return + val fullyQualifiedInterfaceName = + getContainingAidlInterfaceQualified(context, node) ?: return + if (exemptAidlInterfaces.contains(fullyQualifiedInterfaceName)) return + if (AIDL_PERMISSION_ANNOTATIONS.any { node.hasAnnotation(it) }) return context.report( @@ -80,8 +86,7 @@ class PermissionAnnotationDetector : AidlImplementationDetector() { implementation = Implementation( PermissionAnnotationDetector::class.java, Scope.JAVA_FILE_SCOPE - ), - enabledByDefault = false + ) ) } } diff --git a/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetector.kt b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetector.kt new file mode 100644 index 000000000000..1a13c0280ec6 --- /dev/null +++ b/tools/lint/global/checks/src/main/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetector.kt @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2024 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.google.android.lint.aidl + +import com.android.tools.lint.detector.api.Category +import com.android.tools.lint.detector.api.Implementation +import com.android.tools.lint.detector.api.Issue +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.Scope +import com.android.tools.lint.detector.api.Severity +import org.jetbrains.uast.UastCallKind +import org.jetbrains.uast.UBlockExpression +import org.jetbrains.uast.UCallExpression +import org.jetbrains.uast.UElement +import org.jetbrains.uast.UMethod +import org.jetbrains.uast.visitor.AbstractUastVisitor + +/** + * Ensures all AIDL implementations hosted by system_server which don't call other methods are + * annotated with @RequiresNoPermission. AIDL Interfaces part of `exemptAidlInterfaces` are skipped + * during this search to ensure the detector targets only new AIDL Interfaces. + */ +class SimpleRequiresNoPermissionDetector : AidlImplementationDetector() { + override fun visitAidlMethod( + context: JavaContext, + node: UMethod, + interfaceName: String, + body: UBlockExpression + ) { + if (!isSystemServicePath(context)) return + if (context.evaluator.isAbstract(node)) return + + val fullyQualifiedInterfaceName = + getContainingAidlInterfaceQualified(context, node) ?: return + if (exemptAidlInterfaces.contains(fullyQualifiedInterfaceName)) return + + if (node.hasAnnotation(ANNOTATION_REQUIRES_NO_PERMISSION)) return + + if (!isCallingMethod(node)) { + context.report( + ISSUE_SIMPLE_REQUIRES_NO_PERMISSION, + node, + context.getLocation(node), + """ + Method ${node.name} doesn't perform any permission checks, meaning it should \ + be annotated with @RequiresNoPermission. + """.trimMargin() + ) + } + } + + private fun isCallingMethod(node: UMethod): Boolean { + val uCallExpressionVisitor = UCallExpressionVisitor() + node.accept(uCallExpressionVisitor) + + return uCallExpressionVisitor.isCallingMethod + } + + /** + * Visits the body of a `UMethod` and determines if it encounters a `UCallExpression` which is + * a `UastCallKind.METHOD_CALL`. `isCallingMethod` will hold the result of the search procedure. + */ + private class UCallExpressionVisitor : AbstractUastVisitor() { + var isCallingMethod = false + + override fun visitElement(node: UElement): Boolean { + // Stop the search early when a method call has been found. + return isCallingMethod + } + + override fun visitCallExpression(node: UCallExpression): Boolean { + if (node.kind != UastCallKind.METHOD_CALL) return false + + isCallingMethod = true + return true + } + } + + companion object { + + private val EXPLANATION = """ + Method implementations of AIDL Interfaces hosted by the `system_server` which do not + call any other methods should be annotated with @RequiresNoPermission. That is because + not calling any other methods implies that the method does not perform any permission + checking. + + Please migrate to an @RequiresNoPermission annotation. + """.trimIndent() + + @JvmField + val ISSUE_SIMPLE_REQUIRES_NO_PERMISSION = Issue.create( + id = "SimpleRequiresNoPermission", + briefDescription = "System Service APIs not calling other methods should use @RNP", + explanation = EXPLANATION, + category = Category.SECURITY, + priority = 5, + severity = Severity.ERROR, + implementation = Implementation( + SimpleRequiresNoPermissionDetector::class.java, + Scope.JAVA_FILE_SCOPE + ), + ) + } +} diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/PermissionAnnotationDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/PermissionAnnotationDetectorTest.kt new file mode 100644 index 000000000000..824be9309dbc --- /dev/null +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/PermissionAnnotationDetectorTest.kt @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2023 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.google.android.lint.aidl + +import com.android.tools.lint.checks.infrastructure.LintDetectorTest +import com.android.tools.lint.checks.infrastructure.TestLintTask +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Issue + +@Suppress("UnstableApiUsage") +class PermissionAnnotationDetectorTest : LintDetectorTest() { + override fun getDetector(): Detector = + PermissionAnnotationDetector() + + override fun getIssues(): List<Issue> = listOf( + PermissionAnnotationDetector.ISSUE_MISSING_PERMISSION_ANNOTATION, + ) + + override fun lint(): TestLintTask = super.lint().allowMissingSdk(true) + + /** No issue scenario */ + + fun testDoesNotDetectIssuesInCorrectScenario() { + lint() + .files( + java( + createVisitedPath("Foo.java"), + """ + package com.android.server; + public class Foo extends IFoo.Stub { + @Override + @android.annotation.EnforcePermission("android.Manifest.permission.READ_CONTACTS") + public void testMethod() { } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testMissingAnnotation() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public class Bar extends IBar.Stub { + public void testMethod(int parameter1, int parameter2) { } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expect( + """ + src/frameworks/base/services/java/com/android/server/Bar.java:3: Error: The method testMethod is not permission-annotated. [MissingPermissionAnnotation] + public void testMethod(int parameter1, int parameter2) { } + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 1 errors, 0 warnings + """ + ) + } + + fun testMissingAnnotationInIgnoredDirectory() { + lint() + .files( + java( + ignoredPath, + """ + package com.android.server; + public class Bar extends IBar.Stub { + public void testMethod(int parameter1, int parameter2) { } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + // If this test fails, consider the following steps: + // 1. Pick the first entry (interface) from `exemptAidlInterfaces`. + // 2. Change `interfaceIExempted` to use that interface. + // 3. Change this test's class to extend the interface's Stub. + fun testMissingAnnotationAidlInterfaceExempted() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public class Bar extends android.accessibilityservice.IBrailleDisplayConnection.Stub { + public void testMethod() { } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testMissingAnnotationAidlInterfaceAbstractMethod() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public abstract class Bar extends IBar.Stub { + public abstract void testMethod(int parameter1, int parameter2); + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testNoIssueWhenExtendingWithAnotherSubclass() { + lint() + .files( + java( + createVisitedPath("Foo.java"), + """ + package com.android.server; + public class Foo extends IFoo.Stub { + @Override + @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) + public void testMethod() { } + // not an AIDL method, just another method + public void someRandomMethod() { } + } + """ + ) + .indented(), + java( + createVisitedPath("Baz.java"), + """ + package com.android.server; + public class Baz extends Bar { + @Override + public void someRandomMethod() { } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + private val stubs = arrayOf(interfaceIFoo, interfaceIBar, interfaceIExempted) + + private fun createVisitedPath(filename: String) = + "src/frameworks/base/services/java/com/android/server/$filename" + + private val ignoredPath = "src/test/pkg/TestClass.java" +} diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetectorTest.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetectorTest.kt new file mode 100644 index 000000000000..a33b48c7eaa0 --- /dev/null +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/SimpleRequiresNoPermissionDetectorTest.kt @@ -0,0 +1,244 @@ +/* + * Copyright (C) 2024 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.google.android.lint.aidl + +import com.android.tools.lint.checks.infrastructure.LintDetectorTest +import com.android.tools.lint.checks.infrastructure.TestLintTask +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Issue + +class SimpleRequiresNoPermissionDetectorTest : LintDetectorTest() { + override fun getDetector(): Detector = SimpleRequiresNoPermissionDetector() + override fun getIssues(): List<Issue> = listOf( + SimpleRequiresNoPermissionDetector + .ISSUE_SIMPLE_REQUIRES_NO_PERMISSION + ) + + override fun lint(): TestLintTask = super.lint().allowMissingSdk() + + fun testRequiresNoPermissionUsedCorrectly_shouldNotWarn() { + lint() + .files( + java( + createVisitedPath("Foo.java"), + """ + package com.android.server; + public class Foo extends IFoo.Stub { + private int memberInt; + + @Override + @android.annotation.RequiresNoPermission + public void testMethodNoPermission(int parameter1, int parameter2) { + if (parameter1 < parameter2) { + memberInt = parameter1; + } else { + memberInt = parameter2; + } + } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testMissingRequiresNoPermission_shouldWarn() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public class Bar extends IBar.Stub { + private int memberInt; + + @Override + public void testMethod(int parameter1, int parameter2) { + if (parameter1 < parameter2) { + memberInt = parameter1; + } else { + memberInt = parameter2; + } + } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expect( + """ + src/frameworks/base/services/java/com/android/server/Bar.java:5: Error: Method testMethod doesn't perform any permission checks, meaning it should be annotated with @RequiresNoPermission. [SimpleRequiresNoPermission] + @Override + ^ + 1 errors, 0 warnings + """ + ) + } + + fun testMethodOnlyPerformsConstructorCall_shouldWarn() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public class Bar extends IBar.Stub { + private IntPair memberIntPair; + + @Override + public void testMethod(int parameter1, int parameter2) { + memberIntPair = new IntPair(parameter1, parameter2); + } + + private static class IntPair { + public int first; + public int second; + + public IntPair(int first, int second) { + this.first = first; + this.second = second; + } + } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expect( + """ + src/frameworks/base/services/java/com/android/server/Bar.java:5: Error: Method testMethod doesn't perform any permission checks, meaning it should be annotated with @RequiresNoPermission. [SimpleRequiresNoPermission] + @Override + ^ + 1 errors, 0 warnings + """ + ) + } + + fun testMissingRequiresNoPermissionInIgnoredDirectory_shouldNotWarn() { + lint() + .files( + java( + ignoredPath, + """ + package com.android.server; + public class Bar extends IBar.Stub { + @Override + public void testMethod(int parameter1, int parameter2) {} + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testMissingRequiresNoPermissionAbstractMethod_shouldNotWarn() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public abstract class Bar extends IBar.Stub { + private int memberInt; + + @Override + public abstract void testMethodNoPermission(int parameter1, int parameter2); + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + // If this test fails, consider the following steps: + // 1. Pick the first entry (interface) from `exemptAidlInterfaces`. + // 2. Change `interfaceIExempted` to use that interface. + // 3. Change this test's class to extend the interface's Stub. + fun testMissingRequiresNoPermissionAidlInterfaceExempted_shouldNotWarn() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public class Bar extends android.accessibilityservice.IBrailleDisplayConnection.Stub { + public void testMethod(int parameter1, int parameter2) {} + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testMethodMakesAnotherMethodCall_shouldNotWarn() { + lint() + .files( + java( + createVisitedPath("Bar.java"), + """ + package com.android.server; + public class Bar extends IBar.Stub { + private int memberInt; + + @Override + public void testMethod(int parameter1, int parameter2) { + if (!hasPermission()) return; + + if (parameter1 < parameter2) { + memberInt = parameter1; + } else { + memberInt = parameter2; + } + } + + private bool hasPermission() { + // Perform a permission check. + return true; + } + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + private val stubs = arrayOf(interfaceIFoo, interfaceIBar, interfaceIExempted) + + private fun createVisitedPath(filename: String) = + "src/frameworks/base/services/java/com/android/server/$filename" + + private val ignoredPath = "src/test/pkg/TestClass.java" +} diff --git a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt index 2ec8fddbb4e9..18a8f186b624 100644 --- a/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt +++ b/tools/lint/global/checks/src/test/java/com/google/android/lint/aidl/Stubs.kt @@ -85,4 +85,46 @@ val manifestStub: TestFile = java( } } """.trimIndent() -)
\ No newline at end of file +) + +// A service with permission annotation on the method. +val interfaceIFoo: TestFile = java( + """ + public interface IFoo extends android.os.IInterface { + public static abstract class Stub extends android.os.Binder implements IFoo { + } + @Override + @android.annotation.EnforcePermission(android.Manifest.permission.READ_PHONE_STATE) + public void testMethod(); + @Override + @android.annotation.RequiresNoPermission + public void testMethodNoPermission(int parameter1, int parameter2); + @Override + @android.annotation.PermissionManuallyEnforced + public void testMethodManual(); + } + """ +).indented() + +// A service with no permission annotation. +val interfaceIBar: TestFile = java( + """ + public interface IBar extends android.os.IInterface { + public static abstract class Stub extends android.os.Binder implements IBar { + } + public void testMethod(int parameter1, int parameter2); + } + """ +).indented() + +// A service whose AIDL Interface is exempted. +val interfaceIExempted: TestFile = java( + """ + package android.accessibilityservice; + public interface IBrailleDisplayConnection extends android.os.IInterface { + public static abstract class Stub extends android.os.Binder implements IBrailleDisplayConnection { + } + public void testMethod(); + } + """ +).indented() diff --git a/tools/lint/utils/README.md b/tools/lint/utils/README.md new file mode 100644 index 000000000000..b5583c54b25c --- /dev/null +++ b/tools/lint/utils/README.md @@ -0,0 +1,11 @@ +# Utility Android Lint Checks for AOSP + +This directory contains scripts that execute utility Android Lint Checks for AOSP, specifically: +* `enforce_permission_counter.py`: Provides statistics regarding the percentage of annotated/not + annotated `AIDL` methods with `@EnforcePermission` annotations. +* `generate-exempt-aidl-interfaces.sh`: Provides a list of all `AIDL` interfaces in the entire + source tree. + +When adding a new utility Android Lint check to this directory, consider adding any utility or +data processing tool you might require. Make sure that your contribution is documented in this +README file. diff --git a/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt b/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt index fa61c42ef8e6..98428810c0fc 100644 --- a/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt +++ b/tools/lint/utils/checks/src/main/java/com/google/android/lint/AndroidUtilsIssueRegistry.kt @@ -19,6 +19,7 @@ package com.google.android.lint import com.android.tools.lint.client.api.IssueRegistry import com.android.tools.lint.client.api.Vendor import com.android.tools.lint.detector.api.CURRENT_API +import com.google.android.lint.aidl.ExemptAidlInterfacesGenerator import com.google.android.lint.aidl.AnnotatedAidlCounter import com.google.auto.service.AutoService @@ -27,6 +28,7 @@ import com.google.auto.service.AutoService class AndroidUtilsIssueRegistry : IssueRegistry() { override val issues = listOf( AnnotatedAidlCounter.ISSUE_ANNOTATED_AIDL_COUNTER, + ExemptAidlInterfacesGenerator.ISSUE_PERMISSION_ANNOTATION_EXEMPT_AIDL_INTERFACES, ) override val api: Int @@ -38,6 +40,6 @@ class AndroidUtilsIssueRegistry : IssueRegistry() { override val vendor: Vendor = Vendor( vendorName = "Android", feedbackUrl = "http://b/issues/new?component=315013", - contact = "tweek@google.com" + contact = "android-platform-abuse-prevention-withfriends@google.com" ) } diff --git a/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/ExemptAidlInterfacesGenerator.kt b/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/ExemptAidlInterfacesGenerator.kt new file mode 100644 index 000000000000..57c2e5aa9767 --- /dev/null +++ b/tools/lint/utils/checks/src/main/java/com/google/android/lint/aidl/ExemptAidlInterfacesGenerator.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2024 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.google.android.lint.aidl + +import com.android.tools.lint.detector.api.Category +import com.android.tools.lint.detector.api.Context +import com.android.tools.lint.detector.api.Implementation +import com.android.tools.lint.detector.api.Issue +import com.android.tools.lint.detector.api.JavaContext +import com.android.tools.lint.detector.api.Scope +import com.android.tools.lint.detector.api.Severity +import org.jetbrains.uast.UBlockExpression +import org.jetbrains.uast.UMethod + +/** + * Generates a set of fully qualified AIDL Interface names present in the entire source tree with + * the following requirement: their implementations have to be inside directories whose path + * prefixes match `systemServicePathPrefixes`. + */ +class ExemptAidlInterfacesGenerator : AidlImplementationDetector() { + private val targetExemptAidlInterfaceNames = mutableSetOf<String>() + + // We could've improved performance by visiting classes rather than methods, however, this lint + // check won't be run regularly, hence we've decided not to add extra overrides to + // AidlImplementationDetector. + override fun visitAidlMethod( + context: JavaContext, + node: UMethod, + interfaceName: String, + body: UBlockExpression + ) { + if (!isSystemServicePath(context)) return + + val fullyQualifiedInterfaceName = + getContainingAidlInterfaceQualified(context, node) ?: return + + targetExemptAidlInterfaceNames.add("\"$fullyQualifiedInterfaceName\",") + } + + override fun afterCheckEachProject(context: Context) { + if (targetExemptAidlInterfaceNames.isEmpty()) return + + val message = targetExemptAidlInterfaceNames.joinToString("\n") + + context.report( + ISSUE_PERMISSION_ANNOTATION_EXEMPT_AIDL_INTERFACES, + context.getLocation(context.project.dir), + "\n" + message + "\n", + ) + } + + companion object { + @JvmField + val ISSUE_PERMISSION_ANNOTATION_EXEMPT_AIDL_INTERFACES = Issue.create( + id = "PermissionAnnotationExemptAidlInterfaces", + briefDescription = "Returns a set of all AIDL interfaces", + explanation = """ + Produces the exemptAidlInterfaces set used by PermissionAnnotationDetector + """.trimIndent(), + category = Category.SECURITY, + priority = 5, + severity = Severity.INFORMATIONAL, + implementation = Implementation( + ExemptAidlInterfacesGenerator::class.java, + Scope.JAVA_FILE_SCOPE + ) + ) + } +} diff --git a/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/ExemptAidlInterfacesGeneratorTest.kt b/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/ExemptAidlInterfacesGeneratorTest.kt new file mode 100644 index 000000000000..9a17bb4c8d3e --- /dev/null +++ b/tools/lint/utils/checks/src/test/java/com/google/android/lint/aidl/ExemptAidlInterfacesGeneratorTest.kt @@ -0,0 +1,191 @@ +/* + * Copyright (C) 2024 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.google.android.lint.aidl + +import com.android.tools.lint.checks.infrastructure.LintDetectorTest +import com.android.tools.lint.checks.infrastructure.TestFile +import com.android.tools.lint.checks.infrastructure.TestLintTask +import com.android.tools.lint.detector.api.Detector +import com.android.tools.lint.detector.api.Issue + +class ExemptAidlInterfacesGeneratorTest : LintDetectorTest() { + override fun getDetector(): Detector = ExemptAidlInterfacesGenerator() + + override fun getIssues(): List<Issue> = listOf( + ExemptAidlInterfacesGenerator.ISSUE_PERMISSION_ANNOTATION_EXEMPT_AIDL_INTERFACES, + ) + + override fun lint(): TestLintTask = super.lint().allowMissingSdk(true) + + fun testMultipleAidlInterfacesImplemented() { + lint() + .files( + java( + createVisitedPath("TestClass1.java"), + """ + package com.android.server; + public class TestClass1 extends IFoo.Stub { + public void testMethod() {} + } + """ + ) + .indented(), + java( + createVisitedPath("TestClass2.java"), + """ + package com.android.server; + public class TestClass2 extends IBar.Stub { + public void testMethod() {} + } + """ + ) + .indented(), + *stubs, + ) + .run() + .expect( + """ + app: Information: "IFoo", + "IBar", [PermissionAnnotationExemptAidlInterfaces] + 0 errors, 0 warnings + """ + ) + } + + fun testSingleAidlInterfaceRepeated() { + lint() + .files( + java( + createVisitedPath("TestClass1.java"), + """ + package com.android.server; + public class TestClass1 extends IFoo.Stub { + public void testMethod() {} + } + """ + ) + .indented(), + java( + createVisitedPath("TestClass2.java"), + """ + package com.android.server; + public class TestClass2 extends IFoo.Stub { + public void testMethod() {} + } + """ + ) + .indented(), + *stubs, + ) + .run() + .expect( + """ + app: Information: "IFoo", [PermissionAnnotationExemptAidlInterfaces] + 0 errors, 0 warnings + """ + ) + } + + fun testAnonymousClassExtendsAidlStub() { + lint() + .files( + java( + createVisitedPath("TestClass.java"), + """ + package com.android.server; + public class TestClass { + private IBinder aidlImpl = new IFoo.Stub() { + public void testMethod() {} + }; + } + """ + ) + .indented(), + *stubs, + ) + .run() + .expect( + """ + app: Information: "IFoo", [PermissionAnnotationExemptAidlInterfaces] + 0 errors, 0 warnings + """ + ) + } + + fun testNoAidlInterfacesImplemented() { + lint() + .files( + java( + createVisitedPath("TestClass.java"), + """ + package com.android.server; + public class TestClass { + public void testMethod() {} + } + """ + ) + .indented(), + *stubs + ) + .run() + .expectClean() + } + + fun testAidlInterfaceImplementedInIgnoredDirectory() { + lint() + .files( + java( + ignoredPath, + """ + package com.android.server; + public class TestClass1 extends IFoo.Stub { + public void testMethod() {} + } + """ + ) + .indented(), + *stubs, + ) + .run() + .expectClean() + } + + private val interfaceIFoo: TestFile = java( + """ + public interface IFoo extends android.os.IInterface { + public static abstract class Stub extends android.os.Binder implements IFoo {} + public void testMethod(); + } + """ + ).indented() + + private val interfaceIBar: TestFile = java( + """ + public interface IBar extends android.os.IInterface { + public static abstract class Stub extends android.os.Binder implements IBar {} + public void testMethod(); + } + """ + ).indented() + + private val stubs = arrayOf(interfaceIFoo, interfaceIBar) + + private fun createVisitedPath(filename: String) = + "src/frameworks/base/services/java/com/android/server/$filename" + + private val ignoredPath = "src/test/pkg/TestClass.java" +} diff --git a/tools/lint/utils/generate-exempt-aidl-interfaces.sh b/tools/lint/utils/generate-exempt-aidl-interfaces.sh new file mode 100755 index 000000000000..44dcdd74fe06 --- /dev/null +++ b/tools/lint/utils/generate-exempt-aidl-interfaces.sh @@ -0,0 +1,59 @@ +# +# Copyright (C) 2024 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. +# + +# Create a directory for the results and a nested temporary directory. +mkdir -p $ANDROID_BUILD_TOP/out/soong/exempt_aidl_interfaces_generator_output/tmp + +# Create a copy of `AndroidGlobalLintChecker.jar` to restore it afterwards. +cp $ANDROID_BUILD_TOP/prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar \ + $ANDROID_BUILD_TOP/out/soong/exempt_aidl_interfaces_generator_output/AndroidGlobalLintChecker.jar + +# Configure the environment variable required for running the lint check on the entire source tree. +export ANDROID_LINT_CHECK=PermissionAnnotationExemptAidlInterfaces + +# Build the target corresponding to the lint checks present in the `utils` directory. +m AndroidUtilsLintChecker + +# Replace `AndroidGlobalLintChecker.jar` with the newly built `jar` file. +cp $ANDROID_BUILD_TOP/out/host/linux-x86/framework/AndroidUtilsLintChecker.jar \ + $ANDROID_BUILD_TOP/prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar; + +# Run the lint check on the entire source tree. +m lint-check + +# Copy the archive containing the results of `lint-check` into the temporary directory. +cp $ANDROID_BUILD_TOP/out/soong/lint-report-text.zip \ + $ANDROID_BUILD_TOP/out/soong/exempt_aidl_interfaces_generator_output/tmp + +cd $ANDROID_BUILD_TOP/out/soong/exempt_aidl_interfaces_generator_output/tmp + +# Unzip the archive containing the results of `lint-check`. +unzip lint-report-text.zip + +# Concatenate the results of `lint-check` into a single string. +concatenated_reports=$(find . -type f | xargs cat) + +# Extract the fully qualified names of the AIDL Interfaces from the concatenated results. Output +# this list into `out/soong/exempt_aidl_interfaces_generator_output/exempt_aidl_interfaces`. +echo $concatenated_reports | grep -Eo '\"([a-zA-Z0-9_]*\.)+[a-zA-Z0-9_]*\",' | sort | uniq > ../exempt_aidl_interfaces + +# Remove the temporary directory. +rm -rf $ANDROID_BUILD_TOP/out/soong/exempt_aidl_interfaces_generator_output/tmp + +# Restore the original copy of `AndroidGlobalLintChecker.jar` and delete the copy. +cp $ANDROID_BUILD_TOP/out/soong/exempt_aidl_interfaces_generator_output/AndroidGlobalLintChecker.jar \ + $ANDROID_BUILD_TOP/prebuilts/cmdline-tools/AndroidGlobalLintChecker.jar +rm $ANDROID_BUILD_TOP/out/soong/exempt_aidl_interfaces_generator_output/AndroidGlobalLintChecker.jar diff --git a/tools/systemfeatures/Android.bp b/tools/systemfeatures/Android.bp index aca25eb8f603..a9e63289ee93 100644 --- a/tools/systemfeatures/Android.bp +++ b/tools/systemfeatures/Android.bp @@ -5,6 +5,7 @@ package { // to get the below license kinds: // SPDX-license-identifier-Apache-2.0 default_applicable_licenses: ["frameworks_base_license"], + default_team: "trendy_team_system_performance", } java_library_host { @@ -25,8 +26,6 @@ java_binary_host { static_libs: ["systemfeatures-gen-lib"], } -// TODO(b/203143243): Add golden diff test for generated sources. -// Functional runtime behavior is covered in systemfeatures-gen-tests. genrule { name: "systemfeatures-gen-tests-srcs", cmd: "$(location systemfeatures-gen-tool) com.android.systemfeatures.RwNoFeatures --readonly=false > $(location RwNoFeatures.java) && " + @@ -42,11 +41,12 @@ genrule { tools: ["systemfeatures-gen-tool"], } +// Functional runtime behavior testing. java_test_host { name: "systemfeatures-gen-tests", test_suites: ["general-tests"], srcs: [ - "tests/**/*.java", + "tests/src/**/*.java", ":systemfeatures-gen-tests-srcs", ], test_options: { @@ -61,3 +61,33 @@ java_test_host { "truth", ], } + +// Rename the goldens as they may be copied into the source tree, and we don't +// need or want the usual `.java` linting (e.g., copyright checks). +genrule { + name: "systemfeatures-gen-tests-golden-srcs", + cmd: "for f in $(in); do cp $$f $(genDir)/tests/gen/$$(basename $$f).gen; done", + srcs: [":systemfeatures-gen-tests-srcs"], + out: [ + "tests/gen/RwNoFeatures.java.gen", + "tests/gen/RoNoFeatures.java.gen", + "tests/gen/RwFeatures.java.gen", + "tests/gen/RoFeatures.java.gen", + ], +} + +// Golden output testing. Golden sources can be updated via: +// $ANDROID_BUILD_TOP/frameworks/base/tools/systemfeatures/tests/golden_test.sh --update +sh_test_host { + name: "systemfeatures-gen-golden-tests", + src: "tests/golden_test.sh", + filename: "systemfeatures-gen-golden-tests.sh", + test_config: "tests/systemfeatures-gen-golden-tests.xml", + data: [ + "tests/golden/**/*.java*", + ":systemfeatures-gen-tests-golden-srcs", + ], + test_options: { + unit_test: true, + }, +} diff --git a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt index e537ffcb56bd..5df453deaf2a 100644 --- a/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt +++ b/tools/systemfeatures/src/com/android/systemfeatures/SystemFeaturesGenerator.kt @@ -142,6 +142,10 @@ object SystemFeaturesGenerator { // TODO(b/203143243): Add validation of build vs runtime values to ensure consistency. JavaFile.builder(outputClassName.packageName(), classBuilder.build()) + .indent(" ") + .skipJavaLangImports(true) + .addFileComment("This file is auto-generated. DO NOT MODIFY.\n") + .addFileComment("Args: ${args.joinToString(" \\\n ")}") .build() .writeTo(System.out) } @@ -178,6 +182,7 @@ object SystemFeaturesGenerator { val methodBuilder = MethodSpec.methodBuilder(methodName) .addModifiers(Modifier.PUBLIC, Modifier.STATIC) + .addJavadoc("Check for ${feature.name}.\n\n@hide") .returns(Boolean::class.java) .addParameter(CONTEXT_CLASS, "context") @@ -228,6 +233,7 @@ object SystemFeaturesGenerator { MethodSpec.methodBuilder("maybeHasFeature") .addModifiers(Modifier.PUBLIC, Modifier.STATIC) .addAnnotation(ClassName.get("android.annotation", "Nullable")) + .addJavadoc("@hide") .returns(Boolean::class.javaObjectType) // Use object type for nullability .addParameter(String::class.java, "featureName") .addParameter(Int::class.java, "version") diff --git a/tools/systemfeatures/tests/golden/RoFeatures.java.gen b/tools/systemfeatures/tests/golden/RoFeatures.java.gen new file mode 100644 index 000000000000..724639b52d23 --- /dev/null +++ b/tools/systemfeatures/tests/golden/RoFeatures.java.gen @@ -0,0 +1,88 @@ +// This file is auto-generated. DO NOT MODIFY. +// Args: com.android.systemfeatures.RoFeatures \ +// --readonly=true \ +// --feature=WATCH:1 \ +// --feature=WIFI:0 \ +// --feature=VULKAN:-1 \ +// --feature=AUTO: \ +// --feature-apis=WATCH,PC +package com.android.systemfeatures; + +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageManager; +import com.android.aconfig.annotations.AssumeFalseForR8; +import com.android.aconfig.annotations.AssumeTrueForR8; + +/** + * @hide + */ +public final class RoFeatures { + /** + * Check for FEATURE_WATCH. + * + * @hide + */ + @AssumeTrueForR8 + public static boolean hasFeatureWatch(Context context) { + return true; + } + + /** + * Check for FEATURE_PC. + * + * @hide + */ + public static boolean hasFeaturePc(Context context) { + return hasFeatureFallback(context, PackageManager.FEATURE_PC); + } + + /** + * Check for FEATURE_WIFI. + * + * @hide + */ + @AssumeTrueForR8 + public static boolean hasFeatureWifi(Context context) { + return true; + } + + /** + * Check for FEATURE_VULKAN. + * + * @hide + */ + @AssumeFalseForR8 + public static boolean hasFeatureVulkan(Context context) { + return false; + } + + /** + * Check for FEATURE_AUTO. + * + * @hide + */ + @AssumeFalseForR8 + public static boolean hasFeatureAuto(Context context) { + return false; + } + + private static boolean hasFeatureFallback(Context context, String featureName) { + return context.getPackageManager().hasSystemFeature(featureName, 0); + } + + /** + * @hide + */ + @Nullable + public static Boolean maybeHasFeature(String featureName, int version) { + switch (featureName) { + case PackageManager.FEATURE_WATCH: return 1 >= version; + case PackageManager.FEATURE_WIFI: return 0 >= version; + case PackageManager.FEATURE_VULKAN: return -1 >= version; + case PackageManager.FEATURE_AUTO: return false; + default: break; + } + return null; + } +} diff --git a/tools/systemfeatures/tests/golden/RoNoFeatures.java.gen b/tools/systemfeatures/tests/golden/RoNoFeatures.java.gen new file mode 100644 index 000000000000..59c5b4e8fecb --- /dev/null +++ b/tools/systemfeatures/tests/golden/RoNoFeatures.java.gen @@ -0,0 +1,35 @@ +// This file is auto-generated. DO NOT MODIFY. +// Args: com.android.systemfeatures.RoNoFeatures \ +// --readonly=true \ +// --feature-apis=WATCH +package com.android.systemfeatures; + +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageManager; + +/** + * @hide + */ +public final class RoNoFeatures { + /** + * Check for FEATURE_WATCH. + * + * @hide + */ + public static boolean hasFeatureWatch(Context context) { + return hasFeatureFallback(context, PackageManager.FEATURE_WATCH); + } + + private static boolean hasFeatureFallback(Context context, String featureName) { + return context.getPackageManager().hasSystemFeature(featureName, 0); + } + + /** + * @hide + */ + @Nullable + public static Boolean maybeHasFeature(String featureName, int version) { + return null; + } +} diff --git a/tools/systemfeatures/tests/golden/RwFeatures.java.gen b/tools/systemfeatures/tests/golden/RwFeatures.java.gen new file mode 100644 index 000000000000..6f897591e48f --- /dev/null +++ b/tools/systemfeatures/tests/golden/RwFeatures.java.gen @@ -0,0 +1,65 @@ +// This file is auto-generated. DO NOT MODIFY. +// Args: com.android.systemfeatures.RwFeatures \ +// --readonly=false \ +// --feature=WATCH:1 \ +// --feature=WIFI:0 \ +// --feature=VULKAN:-1 \ +// --feature=AUTO: +package com.android.systemfeatures; + +import android.annotation.Nullable; +import android.content.Context; +import android.content.pm.PackageManager; + +/** + * @hide + */ +public final class RwFeatures { + /** + * Check for FEATURE_WATCH. + * + * @hide + */ + public static boolean hasFeatureWatch(Context context) { + return hasFeatureFallback(context, PackageManager.FEATURE_WATCH); + } + + /** + * Check for FEATURE_WIFI. + * + * @hide + */ + public static boolean hasFeatureWifi(Context context) { + return hasFeatureFallback(context, PackageManager.FEATURE_WIFI); + } + + /** + * Check for FEATURE_VULKAN. + * + * @hide + */ + public static boolean hasFeatureVulkan(Context context) { + return hasFeatureFallback(context, PackageManager.FEATURE_VULKAN); + } + + /** + * Check for FEATURE_AUTO. + * + * @hide + */ + public static boolean hasFeatureAuto(Context context) { + return hasFeatureFallback(context, PackageManager.FEATURE_AUTO); + } + + private static boolean hasFeatureFallback(Context context, String featureName) { + return context.getPackageManager().hasSystemFeature(featureName, 0); + } + + /** + * @hide + */ + @Nullable + public static Boolean maybeHasFeature(String featureName, int version) { + return null; + } +} diff --git a/tools/systemfeatures/tests/golden/RwNoFeatures.java.gen b/tools/systemfeatures/tests/golden/RwNoFeatures.java.gen new file mode 100644 index 000000000000..2111d564f28d --- /dev/null +++ b/tools/systemfeatures/tests/golden/RwNoFeatures.java.gen @@ -0,0 +1,24 @@ +// This file is auto-generated. DO NOT MODIFY. +// Args: com.android.systemfeatures.RwNoFeatures \ +// --readonly=false +package com.android.systemfeatures; + +import android.annotation.Nullable; +import android.content.Context; + +/** + * @hide + */ +public final class RwNoFeatures { + private static boolean hasFeatureFallback(Context context, String featureName) { + return context.getPackageManager().hasSystemFeature(featureName, 0); + } + + /** + * @hide + */ + @Nullable + public static Boolean maybeHasFeature(String featureName, int version) { + return null; + } +} diff --git a/tools/systemfeatures/tests/golden_test.sh b/tools/systemfeatures/tests/golden_test.sh new file mode 100755 index 000000000000..c2492542bc37 --- /dev/null +++ b/tools/systemfeatures/tests/golden_test.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash + +# Copyright (C) 2024 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. + +set -e + +GEN_DIR="tests/gen" +GOLDEN_DIR="tests/golden" + +if [[ $(basename $0) == "golden_test.sh" ]]; then + # We're running via command-line, so we need to: + # 1) manually update generated srcs + # 2) use absolute paths + if [ -z $ANDROID_BUILD_TOP ]; then + echo "You need to source and lunch before you can use this script directly." + exit 1 + fi + GEN_DIR="$ANDROID_BUILD_TOP/out/soong/.intermediates/frameworks/base/tools/systemfeatures/systemfeatures-gen-tests-golden-srcs/gen/$GEN_DIR" + GOLDEN_DIR="$ANDROID_BUILD_TOP/frameworks/base/tools/systemfeatures/$GOLDEN_DIR" + rm -rf "$GEN_DIR" + "$ANDROID_BUILD_TOP"/build/soong/soong_ui.bash --make-mode systemfeatures-gen-tests-golden-srcs +fi + +if [[ "$1" == "--update" ]]; then + rm -rf "$GOLDEN_DIR" + cp -R "$GEN_DIR" "$GOLDEN_DIR" + echo "Updated golden test files." +else + echo "Running diff from test output against golden test files..." + if diff -ruN "$GOLDEN_DIR" "$GEN_DIR" ; then + echo "No changes." + else + echo + echo "----------------------------------------------------------------------------------------" + echo "If changes look OK, run:" + echo " \$ANDROID_BUILD_TOP/frameworks/base/tools/systemfeatures/tests/golden_test.sh --update" + echo "----------------------------------------------------------------------------------------" + exit 1 + fi +fi diff --git a/tools/systemfeatures/tests/Context.java b/tools/systemfeatures/tests/src/Context.java index 630bc0771a01..630bc0771a01 100644 --- a/tools/systemfeatures/tests/Context.java +++ b/tools/systemfeatures/tests/src/Context.java diff --git a/tools/systemfeatures/tests/PackageManager.java b/tools/systemfeatures/tests/src/PackageManager.java index db670482065a..db670482065a 100644 --- a/tools/systemfeatures/tests/PackageManager.java +++ b/tools/systemfeatures/tests/src/PackageManager.java diff --git a/tools/systemfeatures/tests/SystemFeaturesGeneratorTest.java b/tools/systemfeatures/tests/src/SystemFeaturesGeneratorTest.java index 6dfd244a807b..6dfd244a807b 100644 --- a/tools/systemfeatures/tests/SystemFeaturesGeneratorTest.java +++ b/tools/systemfeatures/tests/src/SystemFeaturesGeneratorTest.java diff --git a/tools/systemfeatures/tests/systemfeatures-gen-golden-tests.xml b/tools/systemfeatures/tests/systemfeatures-gen-golden-tests.xml new file mode 100644 index 000000000000..e3a5841d8abb --- /dev/null +++ b/tools/systemfeatures/tests/systemfeatures-gen-golden-tests.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2024 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. +--> +<configuration description="Runs systemfeatures-gen golden diff test"> + <test class="com.android.tradefed.testtype.binary.ExecutableHostTest" > + <option name="binary" value="systemfeatures-gen-golden-tests.sh"/> + </test> +</configuration> |