summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp2
-rw-r--r--Android.bp13
-rw-r--r--FF_LEADS_OWNERS10
-rw-r--r--cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java3
-rw-r--r--core/api/current.txt16
-rw-r--r--core/api/system-current.txt4
-rw-r--r--core/api/test-current.txt23
-rw-r--r--core/java/android/app/AppCompatCallbacks.java1
-rw-r--r--core/java/android/app/AppOpsManager.java70
-rw-r--r--core/java/android/app/ForegroundServiceTypePolicy.java1
-rw-r--r--core/java/android/app/compat/ChangeIdStateCache.java13
-rw-r--r--core/java/android/app/compat/ChangeIdStateQuery.java1
-rw-r--r--core/java/android/app/compat/CompatChanges.java1
-rw-r--r--core/java/android/app/compat/PackageOverride.java1
-rw-r--r--core/java/android/content/pm/PackageManager.java48
-rw-r--r--core/java/android/content/pm/ServiceInfo.java2
-rw-r--r--core/java/android/hardware/contexthub/OWNERS2
-rw-r--r--core/java/android/os/OWNERS6
-rw-r--r--core/java/android/permission/flags.aconfig18
-rw-r--r--core/java/android/security/flags.aconfig8
-rw-r--r--core/java/android/telephony/SubscriptionPlan.java71
-rw-r--r--core/java/com/android/internal/compat/AndroidBuildClassifier.java1
-rw-r--r--core/java/com/android/internal/compat/ChangeReporter.java1
-rw-r--r--core/java/com/android/internal/compat/CompatibilityChangeConfig.java1
-rw-r--r--core/java/com/android/internal/compat/CompatibilityChangeInfo.java1
-rw-r--r--core/java/com/android/internal/compat/CompatibilityOverrideConfig.java1
-rw-r--r--core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java1
-rw-r--r--core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java1
-rw-r--r--core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java1
-rw-r--r--core/java/com/android/internal/compat/OverrideAllowedState.java1
-rw-r--r--core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java26
-rw-r--r--core/jni/android_util_Process.cpp3
-rw-r--r--core/jni/com_android_internal_content_FileSystemUtils.cpp19
-rw-r--r--core/jni/com_android_internal_content_FileSystemUtils.h10
-rw-r--r--core/res/Android.bp1
-rw-r--r--core/res/AndroidManifest.xml10
-rw-r--r--core/res/res/values/strings.xml5
-rw-r--r--core/tests/coretests/src/android/os/OWNERS3
-rw-r--r--data/sounds/Android.bp304
-rw-r--r--errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java2
-rw-r--r--keystore/java/Android.bp8
-rw-r--r--keystore/java/android/security/KeyStore2.java14
-rw-r--r--keystore/java/android/security/KeyStore2HalCurrent.java30
-rw-r--r--keystore/java/android/security/KeyStore2HalLatest.java31
-rw-r--r--keystore/java/android/security/keystore/KeyStoreManager.java35
-rw-r--r--media/java/android/media/MediaCodec.java166
-rw-r--r--media/java/android/media/MediaCodecInfo.java2
-rw-r--r--media/java/android/media/MediaFormat.java4
-rw-r--r--media/jni/Android.bp1
-rw-r--r--media/jni/android_media_MediaCodec.cpp147
-rw-r--r--media/jni/android_media_MediaCodec.h2
-rw-r--r--native/graphics/jni/Android.bp2
-rw-r--r--nfc/api/current.txt3
-rw-r--r--nfc/api/system-current.txt20
-rw-r--r--nfc/java/android/nfc/INfcAdapter.aidl2
-rw-r--r--nfc/java/android/nfc/INfcCardEmulation.aidl2
-rw-r--r--nfc/java/android/nfc/INfcOemExtensionCallback.aidl5
-rw-r--r--nfc/java/android/nfc/NfcAdapter.java51
-rw-r--r--nfc/java/android/nfc/NfcOemExtension.java124
-rw-r--r--nfc/java/android/nfc/OemLogItems.java14
-rw-r--r--nfc/java/android/nfc/cardemulation/CardEmulation.java79
-rw-r--r--nfc/java/android/nfc/flags.aconfig16
-rw-r--r--packages/SettingsLib/res/values/strings.xml6
-rw-r--r--packages/Shell/AndroidManifest.xml3
-rw-r--r--packages/Shell/OWNERS1
-rw-r--r--ravenwood/Framework.bp3
-rw-r--r--ravenwood/TEST_MAPPING4
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java6
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java81
-rw-r--r--ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java12
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java33
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java11
-rw-r--r--ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java4
-rw-r--r--ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java47
-rwxr-xr-xravenwood/scripts/run-ravenwood-tests.sh16
-rw-r--r--ravenwood/tests/bivalentinst/Android.bp7
-rw-r--r--ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java10
-rw-r--r--ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java12
-rw-r--r--ravenwood/tests/bivalenttest/Android.bp5
-rw-r--r--ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java10
-rw-r--r--ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt46
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java9
-rw-r--r--ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java3
-rw-r--r--ravenwood/tests/runtime-test/Android.bp2
-rw-r--r--ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java4
-rw-r--r--ravenwood/texts/ravenwood-annotation-allowed-classes.txt6
-rw-r--r--ravenwood/texts/ravenwood-services-policies.txt11
-rwxr-xr-xravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh3
-rw-r--r--services/core/java/com/android/server/biometrics/BiometricService.java11
-rw-r--r--services/core/java/com/android/server/biometrics/PreAuthInfo.java8
-rw-r--r--services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java5
-rw-r--r--services/core/java/com/android/server/compat/CompatChange.java1
-rw-r--r--services/core/java/com/android/server/compat/CompatConfig.java44
-rw-r--r--services/core/java/com/android/server/compat/OverrideValidatorImpl.java1
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompat.java18
-rw-r--r--services/core/java/com/android/server/compat/PlatformCompatNative.java1
-rw-r--r--services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java1
-rw-r--r--services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java1
-rw-r--r--services/core/java/com/android/server/display/OWNERS2
-rw-r--r--services/core/java/com/android/server/display/color/TintController.java39
-rw-r--r--services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java1
-rw-r--r--services/core/java/com/android/server/integrity/model/BitInputStream.java72
-rw-r--r--services/core/java/com/android/server/integrity/model/BitOutputStream.java105
-rw-r--r--services/core/java/com/android/server/integrity/model/ByteTrackedOutputStream.java63
-rw-r--r--services/core/java/com/android/server/integrity/model/ComponentBitSize.java45
-rw-r--r--services/core/java/com/android/server/integrity/model/IndexingFileConstants.java27
-rw-r--r--services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java93
-rw-r--r--services/core/java/com/android/server/integrity/model/RuleMetadata.java41
-rw-r--r--services/core/java/com/android/server/location/contexthub/OWNERS1
-rw-r--r--services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowOrganizerController.java3
-rw-r--r--services/java/com/android/server/SystemServer.java5
-rw-r--r--services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java4
-rw-r--r--services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java12
-rw-r--r--services/tests/apexsystemservices/services/Android.bp1
-rw-r--r--services/tests/servicestests/Android.bp36
-rw-r--r--services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java25
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java21
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java1
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/model/ByteTrackedOutputStreamTest.java70
-rw-r--r--services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java128
-rw-r--r--services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java4
-rw-r--r--services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java5
124 files changed, 1878 insertions, 839 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index e71ded922ae6..8ced596a6762 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -101,6 +101,7 @@ aconfig_declarations_group {
"framework-jobscheduler-job.flags-aconfig-java",
"framework_graphics_flags_java_lib",
"hwui_flags_java_lib",
+ "keystore2_flags_java-framework",
"power_flags_lib",
"sdk_sandbox_flags_lib",
"surfaceflinger_flags_java_lib",
@@ -374,6 +375,7 @@ java_aconfig_library {
min_sdk_version: "30",
apex_available: [
"//apex_available:platform",
+ "com.android.btservices",
"com.android.mediaprovider",
"com.android.permission",
],
diff --git a/Android.bp b/Android.bp
index d2e80034423b..dc48668220bc 100644
--- a/Android.bp
+++ b/Android.bp
@@ -105,7 +105,6 @@ filegroup {
":android.hardware.radio.data-V3-java-source",
":android.hardware.radio.network-V3-java-source",
":android.hardware.radio.voice-V3-java-source",
- ":android.hardware.security.keymint-V3-java-source",
":android.hardware.security.secureclock-V1-java-source",
":android.hardware.thermal-V2-java-source",
":android.hardware.tv.tuner-V2-java-source",
@@ -114,7 +113,6 @@ filegroup {
":android.security.legacykeystore-java-source",
":android.security.maintenance-java-source",
":android.security.metrics-java-source",
- ":android.system.keystore2-V4-java-source",
":android.hardware.cas-V1-java-source",
":credstore_aidl",
":dumpstate_aidl",
@@ -149,7 +147,16 @@ filegroup {
":framework-javastream-protos",
":statslog-framework-java-gen", // FrameworkStatsLog.java
":audio_policy_configuration_V7_0",
- ],
+ ] + select(release_flag("RELEASE_ATTEST_MODULES"), {
+ true: [
+ ":android.hardware.security.keymint-V4-java-source",
+ ":android.system.keystore2-V5-java-source",
+ ],
+ default: [
+ ":android.hardware.security.keymint-V3-java-source",
+ ":android.system.keystore2-V4-java-source",
+ ],
+ }),
}
java_library {
diff --git a/FF_LEADS_OWNERS b/FF_LEADS_OWNERS
new file mode 100644
index 000000000000..a650c6b7a26f
--- /dev/null
+++ b/FF_LEADS_OWNERS
@@ -0,0 +1,10 @@
+bills@google.com
+carmenjackson@google.com
+nalini@google.com
+nosh@google.com
+olilan@google.com
+philipcuadra@google.com
+rajekumar@google.com
+shayba@google.com
+timmurray@google.com
+zezeozue@google.com
diff --git a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
index f726361effd6..a88796c38166 100644
--- a/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
+++ b/cmds/uiautomator/library/core-src/com/android/uiautomator/core/AccessibilityNodeInfoDumper.java
@@ -217,6 +217,9 @@ public class AccessibilityNodeInfoDumper {
serializer.attribute("", "selected", Boolean.toString(node.isSelected()));
serializer.attribute("", "bounds", AccessibilityNodeInfoHelper.getVisibleBoundsInScreen(
node, width, height).toShortString());
+ serializer.attribute("", "drawing-order", Integer.toString(node.getDrawingOrder()));
+ serializer.attribute("", "hint", safeCharSeqToString(node.getHintText()));
+
int count = node.getChildCount();
for (int i = 0; i < count; i++) {
AccessibilityNodeInfo child = node.getChild(i);
diff --git a/core/api/current.txt b/core/api/current.txt
index 519deac25177..280e99613914 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -239,6 +239,7 @@ package android {
field public static final String PROVIDE_OWN_AUTOFILL_SUGGESTIONS = "android.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS";
field public static final String PROVIDE_REMOTE_CREDENTIALS = "android.permission.PROVIDE_REMOTE_CREDENTIALS";
field public static final String QUERY_ALL_PACKAGES = "android.permission.QUERY_ALL_PACKAGES";
+ field @FlaggedApi("android.permission.flags.ranging_permission_enabled") public static final String RANGING = "android.permission.RANGING";
field public static final String READ_ASSISTANT_APP_SEARCH_DATA = "android.permission.READ_ASSISTANT_APP_SEARCH_DATA";
field public static final String READ_BASIC_PHONE_STATE = "android.permission.READ_BASIC_PHONE_STATE";
field public static final String READ_CALENDAR = "android.permission.READ_CALENDAR";
@@ -13108,6 +13109,7 @@ package android.content.pm {
field public static final String FEATURE_BACKUP = "android.software.backup";
field public static final String FEATURE_BLUETOOTH = "android.hardware.bluetooth";
field public static final String FEATURE_BLUETOOTH_LE = "android.hardware.bluetooth_le";
+ field @FlaggedApi("com.android.ranging.flags.ranging_cs_enabled") public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING = "android.hardware.bluetooth_le.channel_sounding";
field public static final String FEATURE_CAMERA = "android.hardware.camera";
field public static final String FEATURE_CAMERA_ANY = "android.hardware.camera.any";
field public static final String FEATURE_CAMERA_AR = "android.hardware.camera.ar";
@@ -13509,7 +13511,7 @@ package android.content.pm {
field public static final int FLAG_STOP_WITH_TASK = 1; // 0x1
field public static final int FLAG_USE_APP_ZYGOTE = 8; // 0x8
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CAMERA}, anyOf={android.Manifest.permission.CAMERA}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CAMERA = 64; // 0x40
- field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE}, anyOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, android.Manifest.permission.NFC, android.Manifest.permission.TRANSMIT_IR, android.Manifest.permission.UWB_RANGING}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
+ field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE}, anyOf={android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.CHANGE_NETWORK_STATE, android.Manifest.permission.CHANGE_WIFI_STATE, android.Manifest.permission.CHANGE_WIFI_MULTICAST_STATE, android.Manifest.permission.NFC, android.Manifest.permission.TRANSMIT_IR, android.Manifest.permission.UWB_RANGING, android.Manifest.permission.RANGING}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_CONNECTED_DEVICE = 16; // 0x10
field @RequiresPermission(value=android.Manifest.permission.FOREGROUND_SERVICE_DATA_SYNC, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_DATA_SYNC = 1; // 0x1
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_HEALTH}, anyOf={android.Manifest.permission.ACTIVITY_RECOGNITION, android.Manifest.permission.BODY_SENSORS, android.Manifest.permission.HIGH_SAMPLING_RATE_SENSORS}) public static final int FOREGROUND_SERVICE_TYPE_HEALTH = 256; // 0x100
field @RequiresPermission(allOf={android.Manifest.permission.FOREGROUND_SERVICE_LOCATION}, anyOf={android.Manifest.permission.ACCESS_COARSE_LOCATION, android.Manifest.permission.ACCESS_FINE_LOCATION}, conditional=true) public static final int FOREGROUND_SERVICE_TYPE_LOCATION = 8; // 0x8
@@ -22796,7 +22798,6 @@ package android.media {
method public boolean isVendor();
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_MEMORY_SAFE = 1; // 0x1
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_SANDBOXED = 0; // 0x0
- field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2; // 0x2
}
public static final class MediaCodecInfo.AudioCapabilities {
@@ -23687,7 +23688,6 @@ package android.media {
field public static final int COLOR_TRANSFER_ST2084 = 6; // 0x6
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_MEMORY_SAFE = 2; // 0x2
field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_SANDBOXED = 1; // 0x1
- field @FlaggedApi("android.media.codec.in_process_sw_audio_codec") public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 4; // 0x4
field public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode";
field public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
field public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
@@ -40034,8 +40034,10 @@ package android.security.keystore {
method @NonNull public java.util.List<java.security.cert.X509Certificate> getGrantedCertificateChainFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
method @NonNull public java.security.Key getGrantedKeyFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
method @NonNull public java.security.KeyPair getGrantedKeyPairFromId(long) throws android.security.keystore.KeyPermanentlyInvalidatedException, java.security.UnrecoverableKeyException;
+ method @FlaggedApi("android.security.keystore2.attest_modules") @NonNull public byte[] getSupplementaryAttestationInfo(int) throws android.security.KeyStoreException;
method public long grantKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
method public void revokeKeyAccess(@NonNull String, int) throws android.security.KeyStoreException, java.security.UnrecoverableKeyException;
+ field public static final int MODULE_HASH = -1879047468; // 0x900002d4
}
public class SecureKeyImportUnavailableException extends java.security.ProviderException {
@@ -45999,6 +46001,8 @@ package android.telephony {
method public long getDataUsageBytes();
method public long getDataUsageTime();
method @NonNull public int[] getNetworkTypes();
+ method @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") @Nullable public java.time.ZonedDateTime getPlanEndDate();
+ method @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public int getSubscriptionStatus();
method @Nullable public CharSequence getSummary();
method @Nullable public CharSequence getTitle();
method public void writeToParcel(android.os.Parcel, int);
@@ -46009,6 +46013,11 @@ package android.telephony {
field public static final int LIMIT_BEHAVIOR_DISABLED = 0; // 0x0
field public static final int LIMIT_BEHAVIOR_THROTTLED = 2; // 0x2
field public static final int LIMIT_BEHAVIOR_UNKNOWN = -1; // 0xffffffff
+ field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_ACTIVE = 1; // 0x1
+ field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_INACTIVE = 2; // 0x2
+ field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_SUSPENDED = 4; // 0x4
+ field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_TRIAL = 3; // 0x3
+ field @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") public static final int SUBSCRIPTION_STATUS_UNKNOWN = 0; // 0x0
field public static final long TIME_UNKNOWN = -1L; // 0xffffffffffffffffL
}
@@ -46020,6 +46029,7 @@ package android.telephony {
method public android.telephony.SubscriptionPlan.Builder setDataLimit(long, int);
method public android.telephony.SubscriptionPlan.Builder setDataUsage(long, long);
method @NonNull public android.telephony.SubscriptionPlan.Builder setNetworkTypes(@NonNull int[]);
+ method @FlaggedApi("com.android.internal.telephony.flags.subscription_plan_allow_status_and_end_date") @NonNull public android.telephony.SubscriptionPlan.Builder setSubscriptionStatus(int);
method public android.telephony.SubscriptionPlan.Builder setSummary(@Nullable CharSequence);
method public android.telephony.SubscriptionPlan.Builder setTitle(@Nullable CharSequence);
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 1019ce80c34d..f94c97e2076c 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -684,13 +684,17 @@ package android.app {
field public static final String OPSTR_PLAY_AUDIO = "android:play_audio";
field public static final String OPSTR_POST_NOTIFICATION = "android:post_notification";
field public static final String OPSTR_PROJECT_MEDIA = "android:project_media";
+ field @FlaggedApi("android.permission.flags.ranging_permission_enabled") public static final String OPSTR_RANGING = "android:ranging";
field @FlaggedApi("android.view.contentprotection.flags.rapid_clear_notifications_by_listener_app_op_enabled") public static final String OPSTR_RAPID_CLEAR_NOTIFICATIONS_BY_LISTENER = "android:rapid_clear_notifications_by_listener";
field public static final String OPSTR_READ_CLIPBOARD = "android:read_clipboard";
+ field @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled") public static final String OPSTR_READ_HEART_RATE = "android:read_heart_rate";
field public static final String OPSTR_READ_ICC_SMS = "android:read_icc_sms";
field public static final String OPSTR_READ_MEDIA_AUDIO = "android:read_media_audio";
field public static final String OPSTR_READ_MEDIA_IMAGES = "android:read_media_images";
field public static final String OPSTR_READ_MEDIA_VIDEO = "android:read_media_video";
field public static final String OPSTR_READ_MEDIA_VISUAL_USER_SELECTED = "android:read_media_visual_user_selected";
+ field @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled") public static final String OPSTR_READ_OXYGEN_SATURATION = "android:read_oxygen_saturation";
+ field @FlaggedApi("android.permission.flags.replace_body_sensor_permission_enabled") public static final String OPSTR_READ_SKIN_TEMPERATURE = "android:read_skin_temperature";
field public static final String OPSTR_READ_WRITE_HEALTH_DATA = "android:read_write_health_data";
field public static final String OPSTR_RECEIVE_AMBIENT_TRIGGER_AUDIO = "android:receive_ambient_trigger_audio";
field public static final String OPSTR_RECEIVE_EMERGENCY_BROADCAST = "android:receive_emergency_broadcast";
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 79c4fb653542..59327c8afecc 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -2044,6 +2044,29 @@ package android.media {
method public boolean isAidlHal();
}
+ public final class MediaCodec {
+ method @FlaggedApi("android.media.codec.codec_availability") @NonNull public static java.util.List<android.media.MediaCodec.GlobalResourceInfo> getGloballyAvailableResources();
+ method @FlaggedApi("android.media.codec.codec_availability") @NonNull public java.util.List<android.media.MediaCodec.InstanceResourceInfo> getRequiredResources();
+ }
+
+ public abstract static class MediaCodec.Callback {
+ method @FlaggedApi("android.media.codec.codec_availability") public void onRequiredResourcesChanged(@NonNull android.media.MediaCodec);
+ }
+
+ @FlaggedApi("android.media.codec.codec_availability") public static final class MediaCodec.GlobalResourceInfo {
+ ctor public MediaCodec.GlobalResourceInfo();
+ method public long getAvailable();
+ method public long getCapacity();
+ method @NonNull public String getName();
+ }
+
+ @FlaggedApi("android.media.codec.codec_availability") public static final class MediaCodec.InstanceResourceInfo {
+ ctor public MediaCodec.InstanceResourceInfo();
+ method @NonNull public String getName();
+ method public long getPerFrameCount();
+ method public long getStaticCount();
+ }
+
public static final class MediaCodecInfo.VideoCapabilities.PerformancePoint {
ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(int, int, int, int, @NonNull android.util.Size);
ctor public MediaCodecInfo.VideoCapabilities.PerformancePoint(@NonNull android.media.MediaCodecInfo.VideoCapabilities.PerformancePoint, @NonNull android.util.Size);
diff --git a/core/java/android/app/AppCompatCallbacks.java b/core/java/android/app/AppCompatCallbacks.java
index f2debfcfa6b1..4ef8eb7b93d6 100644
--- a/core/java/android/app/AppCompatCallbacks.java
+++ b/core/java/android/app/AppCompatCallbacks.java
@@ -28,6 +28,7 @@ import java.util.Arrays;
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class AppCompatCallbacks implements Compatibility.BehaviorChangeDelegate {
private final long[] mDisabledChanges;
private final long[] mLoggableChanges;
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 091d5ab8534d..3eea9033e6c4 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -54,6 +54,7 @@ import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.database.DatabaseUtils;
import android.health.connect.HealthConnectManager;
+import android.health.connect.HealthPermissions;
import android.media.AudioAttributes.AttributeUsage;
import android.media.MediaRouter2;
import android.os.Binder;
@@ -1608,9 +1609,25 @@ public class AppOpsManager {
public static final int OP_RECEIVE_SENSITIVE_NOTIFICATIONS =
AppProtoEnums.APP_OP_RECEIVE_SENSITIVE_NOTIFICATIONS;
+ /** @hide Access to read heart rate sensor. */
+ public static final int OP_READ_HEART_RATE = AppProtoEnums.APP_OP_READ_HEART_RATE;
+
+ /** @hide Access to read skin temperature. */
+ public static final int OP_READ_SKIN_TEMPERATURE = AppProtoEnums.APP_OP_READ_SKIN_TEMPERATURE;
+
+ /**
+ * Allows an app to range with nearby devices using any ranging technology available.
+ *
+ * @hide
+ */
+ public static final int OP_RANGING = AppProtoEnums.APP_OP_RANGING;
+
+ /** @hide Access to read oxygen saturation. */
+ public static final int OP_READ_OXYGEN_SATURATION = AppProtoEnums.APP_OP_READ_OXYGEN_SATURATION;
+
/** @hide */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
- public static final int _NUM_OP = 149;
+ public static final int _NUM_OP = 153;
/**
* All app ops represented as strings.
@@ -1763,6 +1780,10 @@ public class AppOpsManager {
OPSTR_UNARCHIVAL_CONFIRMATION,
OPSTR_EMERGENCY_LOCATION,
OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS,
+ OPSTR_READ_HEART_RATE,
+ OPSTR_READ_SKIN_TEMPERATURE,
+ OPSTR_RANGING,
+ OPSTR_READ_OXYGEN_SATURATION,
})
public @interface AppOpString {}
@@ -2500,6 +2521,26 @@ public class AppOpsManager {
public static final String OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS =
"android:receive_sensitive_notifications";
+ /** @hide Access to read heart rate sensor. */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED)
+ public static final String OPSTR_READ_HEART_RATE = "android:read_heart_rate";
+
+ /** @hide Access to read oxygen saturation. */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED)
+ public static final String OPSTR_READ_OXYGEN_SATURATION = "android:read_oxygen_saturation";
+
+ /** @hide Access to read skin temperature. */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_REPLACE_BODY_SENSOR_PERMISSION_ENABLED)
+ public static final String OPSTR_READ_SKIN_TEMPERATURE = "android:read_skin_temperature";
+
+ /** @hide Access to ranging */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_RANGING_PERMISSION_ENABLED)
+ public static final String OPSTR_RANGING = "android:ranging";
+
/** {@link #sAppOpsToNote} not initialized yet for this op */
private static final byte SHOULD_COLLECT_NOTE_OP_NOT_INITIALIZED = 0;
/** Should not collect noting of this app-op in {@link #sAppOpsToNote} */
@@ -2571,8 +2612,13 @@ public class AppOpsManager {
OP_BLUETOOTH_ADVERTISE,
OP_UWB_RANGING,
OP_NEARBY_WIFI_DEVICES,
+ Flags.rangingPermissionEnabled() ? OP_RANGING : OP_NONE,
// Notifications
OP_POST_NOTIFICATION,
+ // Health
+ Flags.replaceBodySensorPermissionEnabled() ? OP_READ_HEART_RATE : OP_NONE,
+ Flags.replaceBodySensorPermissionEnabled() ? OP_READ_SKIN_TEMPERATURE : OP_NONE,
+ Flags.replaceBodySensorPermissionEnabled() ? OP_READ_OXYGEN_SATURATION : OP_NONE,
};
/**
@@ -3080,6 +3126,24 @@ public class AppOpsManager {
new AppOpInfo.Builder(OP_RECEIVE_SENSITIVE_NOTIFICATIONS,
OPSTR_RECEIVE_SENSITIVE_NOTIFICATIONS, "RECEIVE_SENSITIVE_NOTIFICATIONS")
.setDefaultMode(MODE_IGNORED).build(),
+ new AppOpInfo.Builder(OP_READ_HEART_RATE, OPSTR_READ_HEART_RATE, "READ_HEART_RATE")
+ .setPermission(Flags.replaceBodySensorPermissionEnabled()
+ ? HealthPermissions.READ_HEART_RATE : null)
+ .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
+ new AppOpInfo.Builder(OP_READ_SKIN_TEMPERATURE, OPSTR_READ_SKIN_TEMPERATURE,
+ "READ_SKIN_TEMPERATURE").setPermission(
+ Flags.replaceBodySensorPermissionEnabled()
+ ? HealthPermissions.READ_SKIN_TEMPERATURE : null)
+ .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
+ new AppOpInfo.Builder(OP_RANGING, OPSTR_RANGING, "RANGING")
+ .setPermission(Flags.rangingPermissionEnabled()
+ ? Manifest.permission.RANGING : null)
+ .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
+ new AppOpInfo.Builder(OP_READ_OXYGEN_SATURATION, OPSTR_READ_OXYGEN_SATURATION,
+ "READ_OXYGEN_SATURATION").setPermission(
+ Flags.replaceBodySensorPermissionEnabled()
+ ? HealthPermissions.READ_OXYGEN_SATURATION : null)
+ .setDefaultMode(AppOpsManager.MODE_ALLOWED).build(),
};
// The number of longs needed to form a full bitmask of app ops
@@ -3133,6 +3197,10 @@ public class AppOpsManager {
}
}
for (int op : RUNTIME_PERMISSION_OPS) {
+ if (op == OP_NONE) {
+ // Skip ops with a disabled feature flag.
+ continue;
+ }
if (sAppOpInfos[op].permission != null) {
sPermToOp.put(sAppOpInfos[op].permission, op);
}
diff --git a/core/java/android/app/ForegroundServiceTypePolicy.java b/core/java/android/app/ForegroundServiceTypePolicy.java
index d1e517bbd03c..16444dc5adde 100644
--- a/core/java/android/app/ForegroundServiceTypePolicy.java
+++ b/core/java/android/app/ForegroundServiceTypePolicy.java
@@ -398,6 +398,7 @@ public abstract class ForegroundServiceTypePolicy {
new RegularPermission(Manifest.permission.NFC),
new RegularPermission(Manifest.permission.TRANSMIT_IR),
new RegularPermission(Manifest.permission.UWB_RANGING),
+ new RegularPermission(Manifest.permission.RANGING),
new UsbDevicePermission(),
new UsbAccessoryPermission(),
}, false),
diff --git a/core/java/android/app/compat/ChangeIdStateCache.java b/core/java/android/app/compat/ChangeIdStateCache.java
index dea4e9c82f56..a185d6a48a62 100644
--- a/core/java/android/app/compat/ChangeIdStateCache.java
+++ b/core/java/android/app/compat/ChangeIdStateCache.java
@@ -29,13 +29,24 @@ import com.android.internal.compat.IPlatformCompat;
* Handles caching of calls to {@link com.android.internal.compat.IPlatformCompat}
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class ChangeIdStateCache
extends PropertyInvalidatedCache<ChangeIdStateQuery, Boolean> {
private static final String CACHE_KEY = "cache_key.is_compat_change_enabled";
private static final int MAX_ENTRIES = 64;
- private static boolean sDisabled = false;
+ private static boolean sDisabled = getDefaultDisabled();
private volatile IPlatformCompat mPlatformCompat;
+
+ @android.ravenwood.annotation.RavenwoodReplace
+ private static boolean getDefaultDisabled() {
+ return false;
+ }
+
+ private static boolean getDefaultDisabled$ravenwood() {
+ return true; // TODO(b/376676753) Disable the cache for now.
+ }
+
/** @hide */
public ChangeIdStateCache() {
super(MAX_ENTRIES, CACHE_KEY);
diff --git a/core/java/android/app/compat/ChangeIdStateQuery.java b/core/java/android/app/compat/ChangeIdStateQuery.java
index 7598d6c90d3d..26d9ab65417e 100644
--- a/core/java/android/app/compat/ChangeIdStateQuery.java
+++ b/core/java/android/app/compat/ChangeIdStateQuery.java
@@ -35,6 +35,7 @@ import java.util.Objects;
* @hide
*/
@Immutable
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
final class ChangeIdStateQuery {
static final int QUERY_BY_PACKAGE_NAME = 0;
diff --git a/core/java/android/app/compat/CompatChanges.java b/core/java/android/app/compat/CompatChanges.java
index d7b2ab4351a4..643d4c96f7b9 100644
--- a/core/java/android/app/compat/CompatChanges.java
+++ b/core/java/android/app/compat/CompatChanges.java
@@ -39,6 +39,7 @@ import java.util.Set;
* @hide
*/
@SystemApi
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatChanges {
private static final ChangeIdStateCache QUERY_CACHE = new ChangeIdStateCache();
diff --git a/core/java/android/app/compat/PackageOverride.java b/core/java/android/app/compat/PackageOverride.java
index ebc2945fb1a0..ffc1eec05667 100644
--- a/core/java/android/app/compat/PackageOverride.java
+++ b/core/java/android/app/compat/PackageOverride.java
@@ -36,6 +36,7 @@ import java.util.Objects;
* @hide
*/
@SystemApi
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class PackageOverride {
/** @hide */
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 8de86d5b60a0..0ed9c87e3d51 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -292,6 +292,10 @@ public abstract class PackageManager {
* <p>
* The value of a property will only have a single type, as defined by
* the property itself.
+ *
+ * <p class="note"><strong>Note:</strong>
+ * In android version {@link Build.VERSION_CODES#VANILLA_ICE_CREAM} and earlier,
+ * the {@code equals} and {@code hashCode} methods for this class may not function as expected.
*/
public static final class Property implements Parcelable {
private static final int TYPE_BOOLEAN = 1;
@@ -523,6 +527,40 @@ public abstract class PackageManager {
return new Property[size];
}
};
+
+ @Override
+ public boolean equals(Object obj) {
+ if (!(obj instanceof Property)) {
+ return false;
+ }
+ final Property property = (Property) obj;
+ return mType == property.mType &&
+ Objects.equals(mName, property.mName) &&
+ Objects.equals(mClassName, property.mClassName) &&
+ Objects.equals(mPackageName, property.mPackageName) &&
+ (mType == TYPE_BOOLEAN ? mBooleanValue == property.mBooleanValue :
+ mType == TYPE_FLOAT ? Float.compare(mFloatValue, property.mFloatValue) == 0 :
+ mType == TYPE_INTEGER ? mIntegerValue == property.mIntegerValue :
+ mType == TYPE_RESOURCE ? mIntegerValue == property.mIntegerValue :
+ mStringValue.equals(property.mStringValue));
+ }
+
+ @Override
+ public int hashCode() {
+ int result = Objects.hash(mName, mType, mClassName, mPackageName);
+ if (mType == TYPE_BOOLEAN) {
+ result = 31 * result + (mBooleanValue ? 1 : 0);
+ } else if (mType == TYPE_FLOAT) {
+ result = 31 * result + Float.floatToIntBits(mFloatValue);
+ } else if (mType == TYPE_INTEGER) {
+ result = 31 * result + mIntegerValue;
+ } else if (mType == TYPE_RESOURCE) {
+ result = 31 * result + mIntegerValue;
+ } else if (mType == TYPE_STRING) {
+ result = 31 * result + mStringValue.hashCode();
+ }
+ return result;
+ }
}
/**
@@ -3126,6 +3164,16 @@ public abstract class PackageManager {
/**
* Feature for {@link #getSystemAvailableFeatures} and
+ * {@link #hasSystemFeature}: The device is capable of ranging with
+ * other devices using channel sounding via Bluetooth Low Energy radio.
+ */
+ @FlaggedApi(com.android.ranging.flags.Flags.FLAG_RANGING_CS_ENABLED)
+ @SdkConstant(SdkConstantType.FEATURE)
+ public static final String FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING =
+ "android.hardware.bluetooth_le.channel_sounding";
+
+ /**
+ * Feature for {@link #getSystemAvailableFeatures} and
* {@link #hasSystemFeature}: The device has a camera facing away
* from the screen.
*/
diff --git a/core/java/android/content/pm/ServiceInfo.java b/core/java/android/content/pm/ServiceInfo.java
index 5b0cee75e591..4285b0a2b91a 100644
--- a/core/java/android/content/pm/ServiceInfo.java
+++ b/core/java/android/content/pm/ServiceInfo.java
@@ -251,6 +251,7 @@ public class ServiceInfo extends ComponentInfo
* {@link android.Manifest.permission#NFC},
* {@link android.Manifest.permission#TRANSMIT_IR},
* {@link android.Manifest.permission#UWB_RANGING},
+ * {@link android.Manifest.permission#RANGING},
* or has been granted the access to one of the attached USB devices/accessories.
*/
@RequiresPermission(
@@ -267,6 +268,7 @@ public class ServiceInfo extends ComponentInfo
Manifest.permission.NFC,
Manifest.permission.TRANSMIT_IR,
Manifest.permission.UWB_RANGING,
+ Manifest.permission.RANGING,
},
conditional = true
)
diff --git a/core/java/android/hardware/contexthub/OWNERS b/core/java/android/hardware/contexthub/OWNERS
new file mode 100644
index 000000000000..a65a2bf9ee36
--- /dev/null
+++ b/core/java/android/hardware/contexthub/OWNERS
@@ -0,0 +1,2 @@
+# ContextHub team
+file:platform/system/chre:/OWNERS
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index 590ddb404b63..e63b6648a9ef 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -78,6 +78,9 @@ per-file PatternMatcher* = file:/PACKAGE_MANAGER_OWNERS
# PermissionEnforcer
per-file PermissionEnforcer.java = tweek@google.com, brufino@google.com
+# RemoteCallbackList
+per-file RemoteCallbackList.java = shayba@google.com
+
# ART
per-file ArtModuleServiceManager.java = file:platform/art:/OWNERS
@@ -125,3 +128,6 @@ per-file StatsServiceManager.java = file:/services/core/java/com/android/server/
# Dropbox
per-file DropBoxManager* = mwachens@google.com
+
+# Flags
+per-file flags.aconfig = file:/FF_LEADS_OWNERS
diff --git a/core/java/android/permission/flags.aconfig b/core/java/android/permission/flags.aconfig
index e029e520f1b1..5c54ecdc3336 100644
--- a/core/java/android/permission/flags.aconfig
+++ b/core/java/android/permission/flags.aconfig
@@ -213,3 +213,21 @@ flag {
purpose: PURPOSE_BUGFIX
}
}
+
+flag {
+ name: "replace_body_sensor_permission_enabled"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "android_health_services"
+ description: "Enables replacement of BODY_SENSORS/BODY_SENSORS_BACKGROUND permissions with granular health permissions READ_HEART_RATE, READ_SKIN_TEMPERATURE, READ_OXYGEN_SATURATION, and READ_HEALTH_DATA_IN_BACKGROUND"
+ bug: "364638912"
+}
+
+flag {
+ name: "ranging_permission_enabled"
+ is_fixed_read_only: true
+ is_exported: true
+ namespace: "uwb"
+ description: "This fixed read-only flag is used to enable new ranging permission for all ranging use cases."
+ bug: "370977414"
+}
diff --git a/core/java/android/security/flags.aconfig b/core/java/android/security/flags.aconfig
index 3f4f79072124..5d1d7583d8f8 100644
--- a/core/java/android/security/flags.aconfig
+++ b/core/java/android/security/flags.aconfig
@@ -115,6 +115,14 @@ flag {
}
flag {
+ name: "protect_device_config_flags"
+ namespace: "psap_ai"
+ description: "Feature flag to limit adb shell to allowlisted flags"
+ bug: "364083026"
+ is_fixed_read_only: true
+}
+
+flag {
name: "keystore_grant_api"
namespace: "hardware_backed_security"
description: "Feature flag for exposing KeyStore grant APIs"
diff --git a/core/java/android/telephony/SubscriptionPlan.java b/core/java/android/telephony/SubscriptionPlan.java
index 7b48a16c2227..4c59a8589df2 100644
--- a/core/java/android/telephony/SubscriptionPlan.java
+++ b/core/java/android/telephony/SubscriptionPlan.java
@@ -18,6 +18,7 @@ package android.telephony;
import android.annotation.BytesLong;
import android.annotation.CurrentTimeMillisLong;
+import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -28,6 +29,7 @@ import android.telephony.Annotation.NetworkType;
import android.util.Range;
import android.util.RecurrenceRule;
+import com.android.internal.telephony.flags.Flags;
import com.android.internal.util.Preconditions;
import java.lang.annotation.Retention;
@@ -83,6 +85,33 @@ public final class SubscriptionPlan implements Parcelable {
/** Value indicating a timestamp is unknown. */
public static final long TIME_UNKNOWN = -1;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(prefix = { "SUBSCRIPTION_STATUS_" }, value = {
+ SUBSCRIPTION_STATUS_UNKNOWN,
+ SUBSCRIPTION_STATUS_ACTIVE,
+ SUBSCRIPTION_STATUS_INACTIVE,
+ SUBSCRIPTION_STATUS_TRIAL,
+ SUBSCRIPTION_STATUS_SUSPENDED
+ })
+ public @interface SubscriptionStatus {}
+
+ /** Subscription status is unknown. */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public static final int SUBSCRIPTION_STATUS_UNKNOWN = 0;
+ /** Subscription is active. */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public static final int SUBSCRIPTION_STATUS_ACTIVE = 1;
+ /** Subscription is inactive. */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public static final int SUBSCRIPTION_STATUS_INACTIVE = 2;
+ /** Subscription is in a trial period. */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public static final int SUBSCRIPTION_STATUS_TRIAL = 3;
+ /** Subscription is suspended. */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public static final int SUBSCRIPTION_STATUS_SUSPENDED = 4;
+
private final RecurrenceRule cycleRule;
private CharSequence title;
private CharSequence summary;
@@ -91,6 +120,7 @@ public final class SubscriptionPlan implements Parcelable {
private long dataUsageBytes = BYTES_UNKNOWN;
private long dataUsageTime = TIME_UNKNOWN;
private @NetworkType int[] networkTypes;
+ private int mSubscriptionStatus = SUBSCRIPTION_STATUS_UNKNOWN;
private SubscriptionPlan(RecurrenceRule cycleRule) {
this.cycleRule = Preconditions.checkNotNull(cycleRule);
@@ -107,6 +137,7 @@ public final class SubscriptionPlan implements Parcelable {
dataUsageBytes = source.readLong();
dataUsageTime = source.readLong();
networkTypes = source.createIntArray();
+ mSubscriptionStatus = source.readInt();
}
@Override
@@ -124,6 +155,7 @@ public final class SubscriptionPlan implements Parcelable {
dest.writeLong(dataUsageBytes);
dest.writeLong(dataUsageTime);
dest.writeIntArray(networkTypes);
+ dest.writeInt(mSubscriptionStatus);
}
@Override
@@ -137,13 +169,14 @@ public final class SubscriptionPlan implements Parcelable {
.append(" dataUsageBytes=").append(dataUsageBytes)
.append(" dataUsageTime=").append(dataUsageTime)
.append(" networkTypes=").append(Arrays.toString(networkTypes))
+ .append(" subscriptionStatus=").append(mSubscriptionStatus)
.append("}").toString();
}
@Override
public int hashCode() {
return Objects.hash(cycleRule, title, summary, dataLimitBytes, dataLimitBehavior,
- dataUsageBytes, dataUsageTime, Arrays.hashCode(networkTypes));
+ dataUsageBytes, dataUsageTime, Arrays.hashCode(networkTypes), mSubscriptionStatus);
}
@Override
@@ -157,7 +190,8 @@ public final class SubscriptionPlan implements Parcelable {
&& dataLimitBehavior == other.dataLimitBehavior
&& dataUsageBytes == other.dataUsageBytes
&& dataUsageTime == other.dataUsageTime
- && Arrays.equals(networkTypes, other.networkTypes);
+ && Arrays.equals(networkTypes, other.networkTypes)
+ && mSubscriptionStatus == other.mSubscriptionStatus;
}
return false;
}
@@ -179,6 +213,13 @@ public final class SubscriptionPlan implements Parcelable {
return cycleRule;
}
+ /** Return the end date of this plan, or null if no end date exists. */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public @Nullable ZonedDateTime getPlanEndDate() {
+ // ZonedDateTime is immutable, so no need to create a defensive copy.
+ return cycleRule.end;
+ }
+
/** Return the short title of this plan. */
public @Nullable CharSequence getTitle() {
return title;
@@ -238,6 +279,16 @@ public final class SubscriptionPlan implements Parcelable {
}
/**
+ * Returns the status of the subscription plan.
+ *
+ * @return The subscription status, or {@link #SUBSCRIPTION_STATUS_UNKNOWN} if not available.
+ */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public @SubscriptionStatus int getSubscriptionStatus() {
+ return mSubscriptionStatus;
+ }
+
+ /**
* Builder for a {@link SubscriptionPlan}.
*/
public static class Builder {
@@ -382,5 +433,21 @@ public final class SubscriptionPlan implements Parcelable {
TelephonyManager.getAllNetworkTypes().length);
return this;
}
+
+ /**
+ * Set the subscription status.
+ *
+ * @param subscriptionStatus the current subscription status
+ */
+ @FlaggedApi(Flags.FLAG_SUBSCRIPTION_PLAN_ALLOW_STATUS_AND_END_DATE)
+ public @NonNull Builder setSubscriptionStatus(@SubscriptionStatus int subscriptionStatus) {
+ if (subscriptionStatus < SUBSCRIPTION_STATUS_UNKNOWN
+ || subscriptionStatus > SUBSCRIPTION_STATUS_SUSPENDED) {
+ throw new IllegalArgumentException(
+ "Subscription status must be defined with a valid value");
+ }
+ plan.mSubscriptionStatus = subscriptionStatus;
+ return this;
+ }
}
}
diff --git a/core/java/com/android/internal/compat/AndroidBuildClassifier.java b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
index 364db06976a0..19f8889996dc 100644
--- a/core/java/com/android/internal/compat/AndroidBuildClassifier.java
+++ b/core/java/com/android/internal/compat/AndroidBuildClassifier.java
@@ -22,6 +22,7 @@ import android.os.Build;
* Platform private class for determining the type of Android build installed.
*
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class AndroidBuildClassifier {
public boolean isDebuggableBuild() {
diff --git a/core/java/com/android/internal/compat/ChangeReporter.java b/core/java/com/android/internal/compat/ChangeReporter.java
index ded142ce49e5..bfa122b8aa6d 100644
--- a/core/java/com/android/internal/compat/ChangeReporter.java
+++ b/core/java/com/android/internal/compat/ChangeReporter.java
@@ -42,6 +42,7 @@ import java.util.function.Function;
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class ChangeReporter {
private static final String TAG = "CompatChangeReporter";
private static final Function<Integer, Set<ChangeReport>> NEW_CHANGE_REPORT_SET =
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
index 182dba71d0d7..8fd914aecf55 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeConfig.java
@@ -28,6 +28,7 @@ import java.util.Set;
* Parcelable containing compat config overrides for a given application.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityChangeConfig implements Parcelable {
private final ChangeConfig mChangeConfig;
diff --git a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
index 03fe4551c249..505fd2319a6b 100644
--- a/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
+++ b/core/java/com/android/internal/compat/CompatibilityChangeInfo.java
@@ -25,6 +25,7 @@ import android.os.Parcelable;
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class CompatibilityChangeInfo implements Parcelable {
private final long mChangeId;
private final @Nullable String mName;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
index 9a02b7b7aae9..32206c9950dd 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverrideConfig.java
@@ -28,6 +28,7 @@ import java.util.Map;
* Parcelable containing compat config overrides for a given application.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverrideConfig implements Parcelable {
public final Map<Long, PackageOverride> overrides;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java b/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java
index 8652bb6d05e4..998b48a8a76e 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesByPackageConfig.java
@@ -26,6 +26,7 @@ import java.util.Map;
* Parcelable containing compat config overrides by application.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverridesByPackageConfig implements Parcelable {
public final Map<String, CompatibilityOverrideConfig> packageNameToOverrides;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java
index b408d6440070..c0e2217d509e 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveByPackageConfig.java
@@ -29,6 +29,7 @@ import java.util.Map;
* IDs.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverridesToRemoveByPackageConfig implements Parcelable {
public final Map<String, CompatibilityOverridesToRemoveConfig> packageNameToOverridesToRemove;
diff --git a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
index e85afefdc39a..10461ec0b4c6 100644
--- a/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
+++ b/core/java/com/android/internal/compat/CompatibilityOverridesToRemoveConfig.java
@@ -30,6 +30,7 @@ import java.util.Set;
* <p>This class is separate from CompatibilityOverrideConfig since we only need change IDs.
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatibilityOverridesToRemoveConfig implements Parcelable {
public final Set<Long> changeIds;
diff --git a/core/java/com/android/internal/compat/OverrideAllowedState.java b/core/java/com/android/internal/compat/OverrideAllowedState.java
index e408be2ab471..f018c3a830bd 100644
--- a/core/java/com/android/internal/compat/OverrideAllowedState.java
+++ b/core/java/com/android/internal/compat/OverrideAllowedState.java
@@ -27,6 +27,7 @@ import java.lang.annotation.RetentionPolicy;
/**
* This class contains all the possible override allowed states.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class OverrideAllowedState implements Parcelable {
@IntDef({
ALLOWED,
diff --git a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
index a69d2e4f4dca..8df3f2abcafd 100644
--- a/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
+++ b/core/java/com/android/internal/ravenwood/RavenwoodEnvironment.java
@@ -15,6 +15,12 @@
*/
package com.android.internal.ravenwood;
+import static android.os.Build.VERSION_CODES.S;
+import static android.os.Build.VERSION_CODES.UPSIDE_DOWN_CAKE;
+
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.Disabled;
+import android.compat.annotation.EnabledAfter;
import android.ravenwood.annotation.RavenwoodKeepWholeClass;
import android.ravenwood.annotation.RavenwoodRedirect;
import android.ravenwood.annotation.RavenwoodRedirectionClass;
@@ -78,4 +84,24 @@ public final class RavenwoodEnvironment {
public String getRavenwoodRuntimePath() {
throw notSupportedOnDevice();
}
+
+ /** @hide */
+ public static class CompatIdsForTest {
+ // Enabled by default
+ /** Used for testing */
+ @ChangeId
+ public static final long TEST_COMPAT_ID_1 = 368131859L;
+
+ /** Used for testing */
+ @Disabled
+ @ChangeId public static final long TEST_COMPAT_ID_2 = 368131701L;
+
+ /** Used for testing */
+ @EnabledAfter(targetSdkVersion = S)
+ @ChangeId public static final long TEST_COMPAT_ID_3 = 368131659L;
+
+ /** Used for testing */
+ @EnabledAfter(targetSdkVersion = UPSIDE_DOWN_CAKE)
+ @ChangeId public static final long TEST_COMPAT_ID_4 = 368132057L;
+ }
}
diff --git a/core/jni/android_util_Process.cpp b/core/jni/android_util_Process.cpp
index 4cc904153aac..4369cb0d82b4 100644
--- a/core/jni/android_util_Process.cpp
+++ b/core/jni/android_util_Process.cpp
@@ -33,6 +33,7 @@
#include <algorithm>
#include <array>
+#include <cctype>
#include <cstring>
#include <limits>
#include <memory>
@@ -1004,6 +1005,8 @@ jboolean android_os_Process_parseProcLineArray(JNIEnv* env, jobject clazz,
}
}
if ((mode&PROC_OUT_STRING) != 0 && di < NS) {
+ std::replace_if(buffer+start, buffer+end,
+ [](unsigned char c){ return !std::isprint(c); }, '?');
jstring str = env->NewStringUTF(buffer+start);
env->SetObjectArrayElement(outStrings, di, str);
}
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.cpp b/core/jni/com_android_internal_content_FileSystemUtils.cpp
index 6c72544a7958..76ead2a3ca31 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.cpp
+++ b/core/jni/com_android_internal_content_FileSystemUtils.cpp
@@ -22,7 +22,6 @@
#include <android-base/hex.h>
#include <android-base/unique_fd.h>
#include <bionic/macros.h>
-#include <elf.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -204,7 +203,8 @@ bool punchHoles(const char *filePath, const uint64_t offset,
return true;
}
-bool punchHolesInElf64(const char *filePath, const uint64_t offset) {
+bool getLoadSegmentPhdrs(const char *filePath, const uint64_t offset,
+ std::vector<Elf64_Phdr> &programHeaders) {
// Open Elf file
Elf64_Ehdr ehdr;
std::ifstream inputStream(filePath, std::ifstream::in);
@@ -227,11 +227,6 @@ bool punchHolesInElf64(const char *filePath, const uint64_t offset) {
uint64_t programHeaderOffset = ehdr.e_phoff;
uint16_t programHeaderNum = ehdr.e_phnum;
- IF_ALOGD() {
- ALOGD("Punching holes in file: %s programHeaderOffset: %" PRIu64 " programHeaderNum: %hu",
- filePath, programHeaderOffset, programHeaderNum);
- }
-
// if this is a zip file, also consider elf offset inside a file
uint64_t phOffset;
if (__builtin_add_overflow(offset, programHeaderOffset, &phOffset)) {
@@ -240,7 +235,6 @@ bool punchHolesInElf64(const char *filePath, const uint64_t offset) {
}
inputStream.seekg(phOffset);
- std::vector<Elf64_Phdr> programHeaders;
for (int headerIndex = 0; headerIndex < programHeaderNum; headerIndex++) {
Elf64_Phdr header;
inputStream.read((char *)&header, sizeof(header));
@@ -254,6 +248,15 @@ bool punchHolesInElf64(const char *filePath, const uint64_t offset) {
programHeaders.push_back(header);
}
+ return true;
+}
+
+bool punchHolesInElf64(const char *filePath, const uint64_t offset) {
+ std::vector<Elf64_Phdr> programHeaders;
+ if (!getLoadSegmentPhdrs(filePath, offset, programHeaders)) {
+ ALOGE("Failed to read program headers from ELF file.");
+ return false;
+ }
return punchHoles(filePath, offset, programHeaders);
}
diff --git a/core/jni/com_android_internal_content_FileSystemUtils.h b/core/jni/com_android_internal_content_FileSystemUtils.h
index 52445e2b4229..4a95686c5a0c 100644
--- a/core/jni/com_android_internal_content_FileSystemUtils.h
+++ b/core/jni/com_android_internal_content_FileSystemUtils.h
@@ -15,8 +15,11 @@
*/
#pragma once
+#include <elf.h>
#include <sys/types.h>
+#include <vector>
+
namespace android {
/*
@@ -35,4 +38,11 @@ bool punchHolesInElf64(const char* filePath, uint64_t offset);
*/
bool punchHolesInZip(const char* filePath, uint64_t offset, uint16_t extraFieldLen);
+/*
+ * This function reads program headers from ELF file. ELF can be specified with file path directly
+ * or it should be at offset inside Apk. Program headers passed to function is populated.
+ */
+bool getLoadSegmentPhdrs(const char* filePath, const uint64_t offset,
+ std::vector<Elf64_Phdr>& programHeaders);
+
} // namespace android \ No newline at end of file
diff --git a/core/res/Android.bp b/core/res/Android.bp
index a44e92ca4019..4254a47877da 100644
--- a/core/res/Android.bp
+++ b/core/res/Android.bp
@@ -163,6 +163,7 @@ android_app {
"android.net.platform.flags-aconfig",
"com.android.window.flags.window-aconfig",
"android.permission.flags-aconfig",
+ "ranging_aconfig_flags",
],
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index e4c56a613f12..101ba119b496 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2406,6 +2406,16 @@
android:label="@string/permlab_nearby_wifi_devices"
android:protectionLevel="dangerous" />
+ <!-- Required to be able to range to devices using generic ranging module.
+ @FlaggedApi("android.permission.flags.ranging_permission_enabled")
+ <p>Protection level: dangerous -->
+ <permission android:name="android.permission.RANGING"
+ android:permissionGroup="android.permission-group.UNDEFINED"
+ android:description="@string/permdesc_ranging"
+ android:label="@string/permlab_ranging"
+ android:protectionLevel="dangerous"
+ android:featureFlag="android.permission.flags.ranging_permission_enabled"/>
+
<!-- @SystemApi @TestApi Allows an application to suspend other apps, which will prevent the
user from using them until they are unsuspended.
@hide
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 1a2f0ccb06ba..aa192ec8d454 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1770,6 +1770,11 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=140]-->
<string name="permdesc_nearby_wifi_devices">Allows the app to advertise, connect, and determine the relative position of nearby Wi\u2011Fi devices</string>
+ <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=50]-->
+ <string name="permlab_ranging">determine relative position between nearby devices</string>
+ <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. [CHAR LIMIT=120]-->
+ <string name="permdesc_ranging">Allow the app to determine relative position between nearby devices</string>
+
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_preferredPaymentInfo">Preferred NFC Payment Service Information</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
diff --git a/core/tests/coretests/src/android/os/OWNERS b/core/tests/coretests/src/android/os/OWNERS
index 6149382d0800..4620cb8d8148 100644
--- a/core/tests/coretests/src/android/os/OWNERS
+++ b/core/tests/coretests/src/android/os/OWNERS
@@ -12,3 +12,6 @@ per-file PerformanceHintManagerTest.java = file:/ADPF_OWNERS
# Caching
per-file IpcDataCache* = file:/PERFORMANCE_OWNERS
+
+# RemoteCallbackList
+per-file RemoteCallbackListTest.java = shayba@google.com
diff --git a/data/sounds/Android.bp b/data/sounds/Android.bp
new file mode 100644
index 000000000000..65d4872cdc16
--- /dev/null
+++ b/data/sounds/Android.bp
@@ -0,0 +1,304 @@
+// 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 {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+phony {
+ name: "frameworks_sounds",
+ required: [
+ "frameworks_alarm_sounds",
+ "frameworks_notifications_sounds",
+ "frameworks_ringtones_sounds",
+ "frameworks_ui_sounds",
+ "frameworks_ui_48k_sounds",
+ ],
+}
+
+prebuilt_media {
+ name: "frameworks_alarm_sounds",
+ srcs: [
+ "Alarm_Beep_01.ogg",
+ "Alarm_Beep_02.ogg",
+ "Alarm_Beep_03.ogg",
+ "Alarm_Buzzer.ogg",
+ "Alarm_Classic.ogg",
+ "Alarm_Rooster_02.ogg",
+ "alarms/ogg/Argon.ogg",
+ "alarms/ogg/Barium.ogg",
+ "alarms/ogg/Carbon.ogg",
+ "alarms/ogg/Helium.ogg",
+ "alarms/ogg/Krypton.ogg",
+ "alarms/ogg/Neon.ogg",
+ "alarms/ogg/Neptunium.ogg",
+ "alarms/ogg/Osmium.ogg",
+ "alarms/ogg/Oxygen.ogg",
+ "alarms/ogg/Platinum.ogg",
+ "alarms/ogg/Promethium.ogg",
+ "alarms/ogg/Scandium.ogg",
+ ],
+ relative_install_path: "audio/alarms",
+ product_specific: true,
+ no_full_install: true,
+}
+
+prebuilt_media {
+ name: "frameworks_notifications_sounds",
+ srcs: [
+ "notifications/ogg/Adara.ogg",
+ "notifications/Aldebaran.ogg",
+ "notifications/Altair.ogg",
+ "notifications/ogg/Alya.ogg",
+ "notifications/Antares.ogg",
+ "notifications/ogg/Antimony.ogg",
+ "notifications/ogg/Arcturus.ogg",
+ "notifications/ogg/Argon.ogg",
+ "notifications/Beat_Box_Android.ogg",
+ "notifications/ogg/Bellatrix.ogg",
+ "notifications/ogg/Beryllium.ogg",
+ "notifications/Betelgeuse.ogg",
+ "newwavelabs/CaffeineSnake.ogg",
+ "notifications/Canopus.ogg",
+ "notifications/ogg/Capella.ogg",
+ "notifications/Castor.ogg",
+ "notifications/ogg/CetiAlpha.ogg",
+ "notifications/ogg/Cobalt.ogg",
+ "notifications/Cricket.ogg",
+ "newwavelabs/DearDeer.ogg",
+ "notifications/Deneb.ogg",
+ "notifications/Doink.ogg",
+ "newwavelabs/DontPanic.ogg",
+ "notifications/Drip.ogg",
+ "notifications/Electra.ogg",
+ "F1_MissedCall.ogg",
+ "F1_New_MMS.ogg",
+ "F1_New_SMS.ogg",
+ "notifications/ogg/Fluorine.ogg",
+ "notifications/Fomalhaut.ogg",
+ "notifications/ogg/Gallium.ogg",
+ "notifications/Heaven.ogg",
+ "notifications/ogg/Helium.ogg",
+ "newwavelabs/Highwire.ogg",
+ "notifications/ogg/Hojus.ogg",
+ "notifications/ogg/Iridium.ogg",
+ "notifications/ogg/Krypton.ogg",
+ "newwavelabs/KzurbSonar.ogg",
+ "notifications/ogg/Lalande.ogg",
+ "notifications/Merope.ogg",
+ "notifications/ogg/Mira.ogg",
+ "newwavelabs/OnTheHunt.ogg",
+ "notifications/ogg/Palladium.ogg",
+ "notifications/Plastic_Pipe.ogg",
+ "notifications/ogg/Polaris.ogg",
+ "notifications/ogg/Pollux.ogg",
+ "notifications/ogg/Procyon.ogg",
+ "notifications/ogg/Proxima.ogg",
+ "notifications/ogg/Radon.ogg",
+ "notifications/ogg/Rubidium.ogg",
+ "notifications/ogg/Selenium.ogg",
+ "notifications/ogg/Shaula.ogg",
+ "notifications/Sirrah.ogg",
+ "notifications/SpaceSeed.ogg",
+ "notifications/ogg/Spica.ogg",
+ "notifications/ogg/Strontium.ogg",
+ "notifications/ogg/Syrma.ogg",
+ "notifications/TaDa.ogg",
+ "notifications/ogg/Talitha.ogg",
+ "notifications/ogg/Tejat.ogg",
+ "notifications/ogg/Thallium.ogg",
+ "notifications/Tinkerbell.ogg",
+ "notifications/ogg/Upsilon.ogg",
+ "notifications/ogg/Vega.ogg",
+ "newwavelabs/Voila.ogg",
+ "notifications/ogg/Xenon.ogg",
+ "notifications/ogg/Zirconium.ogg",
+ "notifications/arcturus.ogg",
+ "notifications/moonbeam.ogg",
+ "notifications/pixiedust.ogg",
+ "notifications/pizzicato.ogg",
+ "notifications/regulus.ogg",
+ "notifications/sirius.ogg",
+ "notifications/tweeters.ogg",
+ "notifications/vega.ogg",
+ ],
+ relative_install_path: "audio/notifications",
+ product_specific: true,
+ no_full_install: true,
+}
+
+prebuilt_media {
+ name: "frameworks_ringtones_sounds",
+ srcs: [
+ "ringtones/ANDROMEDA.ogg",
+ "ringtones/ogg/Andromeda.ogg",
+ "ringtones/ogg/Aquila.ogg",
+ "ringtones/ogg/ArgoNavis.ogg",
+ "ringtones/ogg/Atria.ogg",
+ "ringtones/BOOTES.ogg",
+ "newwavelabs/Backroad.ogg",
+ "newwavelabs/BeatPlucker.ogg",
+ "newwavelabs/BentleyDubs.ogg",
+ "newwavelabs/Big_Easy.ogg",
+ "newwavelabs/BirdLoop.ogg",
+ "newwavelabs/Bollywood.ogg",
+ "newwavelabs/BussaMove.ogg",
+ "ringtones/CANISMAJOR.ogg",
+ "ringtones/CASSIOPEIA.ogg",
+ "newwavelabs/Cairo.ogg",
+ "newwavelabs/Calypso_Steel.ogg",
+ "ringtones/ogg/CanisMajor.ogg",
+ "newwavelabs/CaribbeanIce.ogg",
+ "ringtones/ogg/Carina.ogg",
+ "ringtones/ogg/Centaurus.ogg",
+ "newwavelabs/Champagne_Edition.ogg",
+ "newwavelabs/Club_Cubano.ogg",
+ "newwavelabs/CrayonRock.ogg",
+ "newwavelabs/CrazyDream.ogg",
+ "newwavelabs/CurveBall.ogg",
+ "ringtones/ogg/Cygnus.ogg",
+ "newwavelabs/DancinFool.ogg",
+ "newwavelabs/Ding.ogg",
+ "newwavelabs/DonMessWivIt.ogg",
+ "ringtones/ogg/Draco.ogg",
+ "newwavelabs/DreamTheme.ogg",
+ "newwavelabs/Eastern_Sky.ogg",
+ "newwavelabs/Enter_the_Nexus.ogg",
+ "ringtones/Eridani.ogg",
+ "newwavelabs/EtherShake.ogg",
+ "ringtones/FreeFlight.ogg",
+ "newwavelabs/FriendlyGhost.ogg",
+ "newwavelabs/Funk_Yall.ogg",
+ "newwavelabs/GameOverGuitar.ogg",
+ "newwavelabs/Gimme_Mo_Town.ogg",
+ "ringtones/ogg/Girtab.ogg",
+ "newwavelabs/Glacial_Groove.ogg",
+ "newwavelabs/Growl.ogg",
+ "newwavelabs/HalfwayHome.ogg",
+ "ringtones/ogg/Hydra.ogg",
+ "newwavelabs/InsertCoin.ogg",
+ "ringtones/ogg/Kuma.ogg",
+ "newwavelabs/LoopyLounge.ogg",
+ "newwavelabs/LoveFlute.ogg",
+ "ringtones/Lyra.ogg",
+ "ringtones/ogg/Machina.ogg",
+ "newwavelabs/MidEvilJaunt.ogg",
+ "newwavelabs/MildlyAlarming.ogg",
+ "newwavelabs/Nairobi.ogg",
+ "newwavelabs/Nassau.ogg",
+ "newwavelabs/NewPlayer.ogg",
+ "newwavelabs/No_Limits.ogg",
+ "newwavelabs/Noises1.ogg",
+ "newwavelabs/Noises2.ogg",
+ "newwavelabs/Noises3.ogg",
+ "newwavelabs/OrganDub.ogg",
+ "ringtones/ogg/Orion.ogg",
+ "ringtones/PERSEUS.ogg",
+ "newwavelabs/Paradise_Island.ogg",
+ "ringtones/ogg/Pegasus.ogg",
+ "ringtones/ogg/Perseus.ogg",
+ "newwavelabs/Playa.ogg",
+ "ringtones/ogg/Pyxis.ogg",
+ "ringtones/ogg/Rasalas.ogg",
+ "newwavelabs/Revelation.ogg",
+ "ringtones/ogg/Rigel.ogg",
+ "Ring_Classic_02.ogg",
+ "Ring_Digital_02.ogg",
+ "Ring_Synth_02.ogg",
+ "Ring_Synth_04.ogg",
+ "newwavelabs/Road_Trip.ogg",
+ "newwavelabs/RomancingTheTone.ogg",
+ "newwavelabs/Safari.ogg",
+ "newwavelabs/Savannah.ogg",
+ "ringtones/ogg/Scarabaeus.ogg",
+ "ringtones/ogg/Sceptrum.ogg",
+ "newwavelabs/Seville.ogg",
+ "newwavelabs/Shes_All_That.ogg",
+ "newwavelabs/SilkyWay.ogg",
+ "newwavelabs/SitarVsSitar.ogg",
+ "ringtones/ogg/Solarium.ogg",
+ "newwavelabs/SpringyJalopy.ogg",
+ "newwavelabs/Steppin_Out.ogg",
+ "newwavelabs/Terminated.ogg",
+ "ringtones/Testudo.ogg",
+ "ringtones/ogg/Themos.ogg",
+ "newwavelabs/Third_Eye.ogg",
+ "newwavelabs/Thunderfoot.ogg",
+ "newwavelabs/TwirlAway.ogg",
+ "ringtones/URSAMINOR.ogg",
+ "ringtones/ogg/UrsaMinor.ogg",
+ "newwavelabs/VeryAlarmed.ogg",
+ "ringtones/Vespa.ogg",
+ "newwavelabs/World.ogg",
+ "ringtones/ogg/Zeta.ogg",
+ "ringtones/hydra.ogg",
+ ],
+ relative_install_path: "audio/ringtones",
+ product_specific: true,
+ no_full_install: true,
+}
+
+prebuilt_media {
+ name: "frameworks_ui_48k_sounds",
+ srcs: [
+ "effects/ogg/Effect_Tick_48k.ogg",
+ "effects/ogg/KeypressDelete_120_48k.ogg",
+ "effects/ogg/KeypressReturn_120_48k.ogg",
+ "effects/ogg/KeypressSpacebar_120_48k.ogg",
+ "effects/ogg/KeypressStandard_120_48k.ogg",
+ "effects/ogg/KeypressInvalid_120_48k.ogg",
+ "effects/ogg/Trusted_48k.ogg",
+ "effects/ogg/VideoRecord_48k.ogg",
+ "effects/ogg/VideoStop_48k.ogg",
+ "effects/ogg/camera_click_48k.ogg",
+ ],
+ dsts: [
+ "Effect_Tick.ogg",
+ "KeypressDelete.ogg",
+ "KeypressReturn.ogg",
+ "KeypressSpacebar.ogg",
+ "KeypressStandard.ogg",
+ "KeypressInvalid.ogg",
+ "Trusted.ogg",
+ "VideoRecord.ogg",
+ "VideoStop.ogg",
+ "camera_click.ogg",
+ ],
+ relative_install_path: "audio/ui",
+ product_specific: true,
+ no_full_install: true,
+}
+
+prebuilt_media {
+ name: "frameworks_ui_sounds",
+ srcs: [
+ "effects/ogg/Dock.ogg",
+ "effects/ogg/Lock.ogg",
+ "effects/ogg/LowBattery.ogg",
+ "effects/ogg/Undock.ogg",
+ "effects/ogg/Unlock.ogg",
+ "effects/ogg/WirelessChargingStarted.ogg",
+ "effects/ogg/camera_focus.ogg",
+ "effects/ogg/ChargingStarted.ogg",
+ "effects/ogg/InCallNotification.ogg",
+ "effects/ogg/NFCFailure.ogg",
+ "effects/ogg/NFCInitiated.ogg",
+ "effects/ogg/NFCSuccess.ogg",
+ "effects/ogg/NFCTransferComplete.ogg",
+ "effects/ogg/NFCTransferInitiated.ogg",
+ ],
+ relative_install_path: "audio/ui",
+ product_specific: true,
+ no_full_install: true,
+}
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java
index cae5d8e6846d..35b2375fbc46 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/EfficientParcelableChecker.java
@@ -96,7 +96,7 @@ public final class EfficientParcelableChecker extends BugChecker
}
if (WRITE_PARCELABLE.matches(tree, state)) {
return buildDescription(tree)
- .setMessage("Recommended to use 'item.writeToParcel()' to improve "
+ .setMessage("Recommended to use 'writeTypedObject()' to improve "
+ "efficiency; saves overhead of Parcelable class name")
.build();
}
diff --git a/keystore/java/Android.bp b/keystore/java/Android.bp
index 21edff1e1c96..264ac5ff1d92 100644
--- a/keystore/java/Android.bp
+++ b/keystore/java/Android.bp
@@ -13,5 +13,13 @@ filegroup {
"**/*.java",
"**/*.aidl",
],
+ exclude_srcs: select(release_flag("RELEASE_ATTEST_MODULES"), {
+ true: [
+ "android/security/KeyStore2HalCurrent.java",
+ ],
+ default: [
+ "android/security/KeyStore2HalLatest.java",
+ ],
+ }),
visibility: ["//frameworks/base"],
}
diff --git a/keystore/java/android/security/KeyStore2.java b/keystore/java/android/security/KeyStore2.java
index dd703f5eefb9..f5cf571ad955 100644
--- a/keystore/java/android/security/KeyStore2.java
+++ b/keystore/java/android/security/KeyStore2.java
@@ -101,7 +101,7 @@ public class KeyStore2 {
R execute(IKeystoreService service) throws RemoteException;
}
- private <R> R handleRemoteExceptionWithRetry(@NonNull CheckedRemoteRequest<R> request)
+ <R> R handleRemoteExceptionWithRetry(@NonNull CheckedRemoteRequest<R> request)
throws KeyStoreException {
IKeystoreService service = getService(false /* retryLookup */);
boolean firstTry = true;
@@ -369,6 +369,18 @@ public class KeyStore2 {
}
}
+ /**
+ * Returns tag-specific info required to interpret a tag's attested value.
+ * @see IKeystoreService#getSupplementaryAttestationInfo(Tag) for more details.
+ * @param tag
+ * @return
+ * @throws KeyStoreException
+ * @hide
+ */
+ public byte[] getSupplementaryAttestationInfo(int tag) throws KeyStoreException {
+ return KeyStore2HalVersion.getSupplementaryAttestationInfoHelper(tag, this);
+ }
+
static KeyStoreException getKeyStoreException(int errorCode, String serviceErrorMessage) {
if (errorCode > 0) {
// KeyStore layer error
diff --git a/keystore/java/android/security/KeyStore2HalCurrent.java b/keystore/java/android/security/KeyStore2HalCurrent.java
new file mode 100644
index 000000000000..f4d8fe65c995
--- /dev/null
+++ b/keystore/java/android/security/KeyStore2HalCurrent.java
@@ -0,0 +1,30 @@
+/*
+ * 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 android.security;
+
+/**
+ * @hide This class is necessary to allow the version of the AIDL interface for Keystore and
+* KeyMint used in KeyStore2.java to differ by BUILD flag `RELEASE_ATTEST_MODULES`. When
+* `RELEASE_ATTEST_MODULES` is not set, this file is included, and the current HALs for Keystore
+* (V4) and KeyMint (V3) are used.
+*/
+class KeyStore2HalVersion {
+ public static byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
+ throws KeyStoreException {
+ return new byte[0];
+ }
+}
diff --git a/keystore/java/android/security/KeyStore2HalLatest.java b/keystore/java/android/security/KeyStore2HalLatest.java
new file mode 100644
index 000000000000..b6e1cbb4cbb6
--- /dev/null
+++ b/keystore/java/android/security/KeyStore2HalLatest.java
@@ -0,0 +1,31 @@
+/*
+ * 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 android.security;
+
+/**
+ * @hide This class is necessary to allow the version of the AIDL interface for Keystore and
+* KeyMint used in KeyStore2.java to differ by BUILD flag `RELEASE_ATTEST_MODULES`. When
+* `RELEASE_ATTEST_MODULES` is set, this file is included, and the latest HALs for Keystore (V5)
+* and KeyMint (V4) are used.
+*/
+class KeyStore2HalVersion {
+ public byte[] getSupplementaryAttestationInfoHelper(int tag, KeyStore2 ks)
+ throws KeyStoreException {
+ return ks.handleRemoteExceptionWithRetry(
+ (service) -> service.getSupplementaryAttestationInfo(tag));
+ }
+}
diff --git a/keystore/java/android/security/keystore/KeyStoreManager.java b/keystore/java/android/security/keystore/KeyStoreManager.java
index e6091c1da8a5..740ccb53a691 100644
--- a/keystore/java/android/security/keystore/KeyStoreManager.java
+++ b/keystore/java/android/security/keystore/KeyStoreManager.java
@@ -17,9 +17,11 @@
package android.security.keystore;
import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.SystemService;
import android.content.Context;
+import android.hardware.security.keymint.TagType;
import android.security.KeyStore2;
import android.security.KeyStoreException;
import android.security.keystore2.AndroidKeyStoreProvider;
@@ -32,6 +34,8 @@ import android.util.Log;
import com.android.internal.annotations.GuardedBy;
import java.io.ByteArrayInputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.security.Key;
import java.security.KeyPair;
import java.security.PublicKey;
@@ -299,6 +303,37 @@ public final class KeyStoreManager {
return Collections.emptyList();
}
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(value = {MODULE_HASH})
+ public @interface SupplementaryAttestationInfoTagEnum {}
+
+ /**
+ * When passed into getSupplementaryAttestationInfo, getSupplementaryAttestationInfo returns the
+ * DER-encoded structure corresponding to the `Modules` schema described in the KeyMint HAL's
+ * KeyCreationResult.aidl. The SHA-256 hash of this encoded structure is what's included with
+ * the tag in attestations.
+ */
+ // TODO(b/369375199): Replace with Tag.MODULE_HASH when flagging is removed.
+ public static final int MODULE_HASH = TagType.BYTES | 724;
+
+ /**
+ * Returns tag-specific data required to interpret a tag's attested value.
+ *
+ * When performing key attestation, the obtained attestation certificate contains a list of tags
+ * and their corresponding attested values. For some tags, additional information about the
+ * attested value can be queried via this API. See individual tags for specifics.
+ *
+ * @param tag tag for which info is being requested
+ * @return tag-specific info
+ * @throws KeyStoreException if the requested info is not available
+ */
+ @FlaggedApi(android.security.keystore2.Flags.FLAG_ATTEST_MODULES)
+ public @NonNull byte[] getSupplementaryAttestationInfo(
+ @SupplementaryAttestationInfoTagEnum int tag) throws KeyStoreException {
+ return mKeyStore2.getSupplementaryAttestationInfo(tag);
+ }
+
/**
* Returns a new {@link KeyDescriptor} instance in the app domain / namespace with the {@code
* alias} set to the provided value.
diff --git a/media/java/android/media/MediaCodec.java b/media/java/android/media/MediaCodec.java
index 2ae89d3300c1..82e950365850 100644
--- a/media/java/android/media/MediaCodec.java
+++ b/media/java/android/media/MediaCodec.java
@@ -16,6 +16,7 @@
package android.media;
+import static android.media.codec.Flags.FLAG_CODEC_AVAILABILITY;
import static android.media.codec.Flags.FLAG_NULL_OUTPUT_SURFACE;
import static android.media.codec.Flags.FLAG_REGION_OF_INTEREST;
import static android.media.codec.Flags.FLAG_SUBSESSION_METRICS;
@@ -29,6 +30,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.ImageFormat;
import android.graphics.Rect;
@@ -1843,6 +1845,12 @@ final public class MediaCodec {
*/
private static final int CB_METRICS_FLUSHED = 8;
+ /**
+ * Callback ID to notify the change in resource requirement
+ * for the codec component.
+ */
+ private static final int CB_REQUIRED_RESOURCES_CHANGE = 9;
+
private class EventHandler extends Handler {
private MediaCodec mCodec;
@@ -2017,13 +2025,19 @@ final public class MediaCodec {
case CB_METRICS_FLUSHED:
{
-
if (GetFlag(() -> android.media.codec.Flags.subsessionMetrics())) {
mCallback.onMetricsFlushed(mCodec, (PersistableBundle)msg.obj);
}
break;
}
+ case CB_REQUIRED_RESOURCES_CHANGE: {
+ if (android.media.codec.Flags.codecAvailability()) {
+ mCallback.onRequiredResourcesChanged(mCodec);
+ }
+ break;
+ }
+
default:
{
break;
@@ -2302,6 +2316,70 @@ final public class MediaCodec {
}
/**
+ * @hide
+ * Abstraction for the Global Codec resources.
+ * This encapsulates all the available codec resources on the device.
+ *
+ * To be able to enforce and test the implementation of codec availability hal APIs,
+ * globally available codec resources are exposed only as TestApi.
+ * This will be tracked and verified through cts.
+ */
+ @FlaggedApi(FLAG_CODEC_AVAILABILITY)
+ @TestApi
+ public static final class GlobalResourceInfo {
+ /**
+ * Identifier for the Resource type.
+ */
+ String mName;
+ /**
+ * Total count/capacity of resources of this type.
+ */
+ long mCapacity;
+ /**
+ * Available count of this resource type.
+ */
+ long mAvailable;
+
+ @NonNull
+ public String getName() {
+ return mName;
+ }
+
+ public long getCapacity() {
+ return mCapacity;
+ }
+
+ public long getAvailable() {
+ return mAvailable;
+ }
+ };
+
+ /**
+ * @hide
+ * Get a list of globally available codec resources.
+ *
+ * To be able to enforce and test the implementation of codec availability hal APIs,
+ * it is exposed only as TestApi.
+ * This will be tracked and verified through cts.
+ *
+ * This returns a {@link java.util.List} list of codec resources.
+ * For every {@link GlobalResourceInfo} in the list, it encapsulates the
+ * information about each resources available globaly on device.
+ *
+ * @return A list of available device codec resources; an empty list if no
+ * device codec resources are available.
+ * @throws UnsupportedOperationException if not implemented.
+ */
+ @FlaggedApi(FLAG_CODEC_AVAILABILITY)
+ @TestApi
+ public static @NonNull List<GlobalResourceInfo> getGloballyAvailableResources() {
+ return native_getGloballyAvailableResources();
+ }
+
+ @NonNull
+ private static native List<GlobalResourceInfo> native_getGloballyAvailableResources();
+
+ /**
* Configures a component.
*
* @param format The format of the input data (decoder) or the desired
@@ -2443,6 +2521,73 @@ final public class MediaCodec {
}
/**
+ * @hide
+ * Abstraction for the resources associated with a codec instance.
+ * This encapsulates the required codec resources for a configured codec instance.
+ *
+ * To be able to enforce and test the implementation of codec availability hal APIs,
+ * required codec resources are exposed only as TestApi.
+ * This will be tracked and verified through cts.
+ */
+ @FlaggedApi(FLAG_CODEC_AVAILABILITY)
+ @TestApi
+ public static final class InstanceResourceInfo {
+ /**
+ * Identifier for the Resource type.
+ */
+ String mName;
+ /**
+ * Required resource count of this type.
+ */
+ long mStaticCount;
+ /**
+ * Per frame resource requirement of this resource type.
+ */
+ long mPerFrameCount;
+
+ @NonNull
+ public String getName() {
+ return mName;
+ }
+
+ public long getStaticCount() {
+ return mStaticCount;
+ }
+
+ public long getPerFrameCount() {
+ return mPerFrameCount;
+ }
+ };
+
+ /**
+ * @hide
+ * Get a list of required codec resources for this configuration.
+ *
+ * To be able to enforce and test the implementation of codec availability hal APIs,
+ * it is exposed only as TestApi.
+ * This will be tracked and verified through cts.
+ *
+ * This returns a {@link java.util.List} list of codec resources.
+ * For every {@link GlobalResourceInfo} in the list, it encapsulates the
+ * information about each resources required for the current configuration.
+ *
+ * NOTE: This may only be called after {@link #configure}.
+ *
+ * @return A list of required device codec resources; an empty list if no
+ * device codec resources are required.
+ * @throws IllegalStateException if the codec wasn't configured yet.
+ * @throws UnsupportedOperationException if not implemented.
+ */
+ @FlaggedApi(FLAG_CODEC_AVAILABILITY)
+ @TestApi
+ public @NonNull List<InstanceResourceInfo> getRequiredResources() {
+ return native_getRequiredResources();
+ }
+
+ @NonNull
+ private native List<InstanceResourceInfo> native_getRequiredResources();
+
+ /**
* Dynamically sets the output surface of a codec.
* <p>
* This can only be used if the codec was configured with an output surface. The
@@ -5740,6 +5885,25 @@ final public class MediaCodec {
@NonNull MediaCodec codec, @NonNull PersistableBundle metrics) {
// default implementation ignores this callback.
}
+
+ /**
+ * @hide
+ * Called when there is a change in the required resources for the codec.
+ * <p>
+ * Upon receiving this notification, the updated resource requirement
+ * can be queried through {@link #getRequiredResources}.
+ *
+ * @param codec The MediaCodec object.
+ */
+ @FlaggedApi(FLAG_CODEC_AVAILABILITY)
+ @TestApi
+ public void onRequiredResourcesChanged(@NonNull MediaCodec codec) {
+ /*
+ * A default implementation for backward compatibility.
+ * Since this is a TestApi, we are not enforcing the callback to be
+ * overridden.
+ */
+ }
}
private void postEventFromNative(
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 96edd63a9b12..782db358bf9f 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -1876,6 +1876,8 @@ public final class MediaCodecInfo {
* Codecs with this security model is not included in
* {@link MediaCodecList#REGULAR_CODECS}, but included in
* {@link MediaCodecList#ALL_CODECS}.
+ *
+ * @hide
*/
@FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC)
public static final int SECURITY_MODEL_TRUSTED_CONTENT_ONLY = 2;
diff --git a/media/java/android/media/MediaFormat.java b/media/java/android/media/MediaFormat.java
index bd65b2ecb76a..bc09aee9ac11 100644
--- a/media/java/android/media/MediaFormat.java
+++ b/media/java/android/media/MediaFormat.java
@@ -1748,6 +1748,7 @@ public final class MediaFormat {
(1 << MediaCodecInfo.SECURITY_MODEL_MEMORY_SAFE);
/**
* Flag for {@link MediaCodecInfo#SECURITY_MODEL_TRUSTED_CONTENT_ONLY}.
+ * @hide
*/
@FlaggedApi(FLAG_IN_PROCESS_SW_AUDIO_CODEC)
public static final int FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY =
@@ -1759,8 +1760,7 @@ public final class MediaFormat {
* The associated value is a flag of the following values:
* {@link FLAG_SECURITY_MODEL_SANDBOXED},
* {@link FLAG_SECURITY_MODEL_MEMORY_SAFE},
- * {@link FLAG_SECURITY_MODEL_TRUSTED_CONTENT_ONLY}. The default value is
- * {@link FLAG_SECURITY_MODEL_SANDBOXED}.
+ * The default value is {@link FLAG_SECURITY_MODEL_SANDBOXED}.
* <p>
* When passed to {@link MediaCodecList#findDecoderForFormat} or
* {@link MediaCodecList#findEncoderForFormat}, MediaCodecList filters
diff --git a/media/jni/Android.bp b/media/jni/Android.bp
index 7f487e51f7e8..13dc748aa691 100644
--- a/media/jni/Android.bp
+++ b/media/jni/Android.bp
@@ -104,6 +104,7 @@ cc_library_shared {
"libgrallocusage",
"libmedia_midiiowrapper",
"android.companion.virtualdevice.flags-aconfig-cc",
+ "android.media.codec-aconfig-cc",
"android.media.playback.flags-aconfig-cc",
],
diff --git a/media/jni/android_media_MediaCodec.cpp b/media/jni/android_media_MediaCodec.cpp
index 001653b08f0c..fc184fe5c872 100644
--- a/media/jni/android_media_MediaCodec.cpp
+++ b/media/jni/android_media_MediaCodec.cpp
@@ -39,6 +39,8 @@
#include <C2Buffer.h>
#include <C2PlatformSupport.h>
+#include <android_media_codec.h>
+
#include <android/hardware/cas/native/1.0/IDescrambler.h>
#include <android_runtime/android_hardware_HardwareBuffer.h>
@@ -189,6 +191,22 @@ static struct {
jmethodID setId;
} gBufferInfo;
+static struct {
+ jclass clazz;
+ jmethodID ctorId;
+ jfieldID resourceId;
+ jfieldID capacityId;
+ jfieldID availableId;
+} gGlobalResourceInfo;
+
+static struct {
+ jclass clazz;
+ jmethodID ctorId;
+ jfieldID resourceId;
+ jfieldID staticCountId;
+ jfieldID perFrameCountId;
+} gInstanceResourceInfo;
+
struct fields_t {
jmethodID postEventFromNativeID;
jmethodID lockAndGetContextID;
@@ -1129,6 +1147,37 @@ status_t JMediaCodec::unsubscribeFromVendorParameters(JNIEnv *env, jobject names
return mCodec->unsubscribeFromVendorParameters(names);
}
+static jobject getJavaResources(
+ JNIEnv *env,
+ const std::vector<MediaCodec::InstanceResourceInfo>& resources) {
+ jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
+ for (const MediaCodec::InstanceResourceInfo& res : resources) {
+ ScopedLocalRef<jobject> object{env, env->NewObject(
+ gInstanceResourceInfo.clazz, gInstanceResourceInfo.ctorId)};
+ ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
+ env->SetObjectField(object.get(), gInstanceResourceInfo.resourceId, nameStr.get());
+ env->SetLongField(object.get(),
+ gInstanceResourceInfo.staticCountId,
+ (jlong)res.mStaticCount);
+ env->SetLongField(object.get(),
+ gInstanceResourceInfo.perFrameCountId,
+ (jlong)res.mPerFrameCount);
+ (void)env->CallBooleanMethod(resourcesObj, gArrayListInfo.addId, object.get());
+ }
+
+ return resourcesObj;
+}
+
+status_t JMediaCodec::getRequiredResources(JNIEnv *env, jobject *resourcesObj) {
+ std::vector<MediaCodec::InstanceResourceInfo> resources;
+ status_t status = mCodec->getRequiredResources(resources);
+ if (status != OK) {
+ return status;
+ }
+ *resourcesObj = getJavaResources(env, resources);
+ return OK;
+}
+
static jthrowable createCodecException(
JNIEnv *env, status_t err, int32_t actionCode, const char *msg = NULL) {
ScopedLocalRef<jclass> clazz(
@@ -1475,6 +1524,10 @@ void JMediaCodec::handleCallback(const sp<AMessage> &msg) {
obj = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL);
break;
}
+ case MediaCodec::CB_REQUIRED_RESOURCES_CHANGED:
+ {
+ break;
+ }
default:
TRESPASS();
@@ -3560,6 +3613,64 @@ static void android_media_MediaCodec_unsubscribeFromVendorParameters(
return;
}
+static jobject getJavaResources(
+ JNIEnv *env,
+ const std::vector<MediaCodec::GlobalResourceInfo>& resources) {
+ jobject resourcesObj = env->NewObject(gArrayListInfo.clazz, gArrayListInfo.ctorId);
+ for (const MediaCodec::GlobalResourceInfo& res : resources) {
+ ScopedLocalRef<jobject> object{env, env->NewObject(
+ gGlobalResourceInfo.clazz, gGlobalResourceInfo.ctorId)};
+ ScopedLocalRef<jstring> nameStr{env, env->NewStringUTF(res.mName.c_str())};
+ env->SetObjectField(object.get(), gInstanceResourceInfo.resourceId, nameStr.get());
+ env->SetLongField(object.get(), gGlobalResourceInfo.capacityId, (jlong)res.mCapacity);
+ env->SetLongField(object.get(), gGlobalResourceInfo.availableId, (jlong)res.mAvailable);
+ (void)env->CallBooleanMethod(resourcesObj, gArrayListInfo.addId, object.get());
+ }
+
+ return resourcesObj;
+}
+
+static jobject android_media_MediaCodec_getGloballyAvailableResources(
+ JNIEnv *env, jobject thiz) {
+ (void)thiz;
+ std::vector<MediaCodec::GlobalResourceInfo> resources;
+ status_t status = MediaCodec::getGloballyAvailableResources(resources);
+ if (status != OK) {
+ if (status == ERROR_UNSUPPORTED) {
+ jniThrowException(env, "java/lang/UnsupportedOperationException",
+ "Function Not Implemented");
+ } else {
+ throwExceptionAsNecessary(env, status, nullptr);
+ }
+ return nullptr;
+ }
+
+ return getJavaResources(env, resources);
+}
+
+static jobject android_media_MediaCodec_getRequiredResources(
+ JNIEnv *env, jobject thiz) {
+ sp<JMediaCodec> codec = getMediaCodec(env, thiz);
+ if (codec == nullptr || codec->initCheck() != OK) {
+ throwExceptionAsNecessary(env, INVALID_OPERATION, codec);
+ return nullptr;
+ }
+
+ jobject ret = nullptr;
+ status_t status = codec->getRequiredResources(env, &ret);
+ if (status != OK) {
+ if (status == ERROR_UNSUPPORTED) {
+ jniThrowException(env, "java/lang/UnsupportedOperationException",
+ "Function Not Implemented");
+ } else {
+ throwExceptionAsNecessary(env, status, nullptr);
+ }
+ return nullptr;
+ }
+
+ return ret;
+}
+
static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) {
ScopedLocalRef<jclass> clazz(
env, env->FindClass("android/media/MediaCodec"));
@@ -3905,6 +4016,36 @@ static void android_media_MediaCodec_native_init(JNIEnv *env, jclass) {
gFields.bufferInfoOffset = env->GetFieldID(clazz.get(), "offset", "I");
gFields.bufferInfoPresentationTimeUs =
env->GetFieldID(clazz.get(), "presentationTimeUs", "J");
+
+ // Since these TestApis are defined under the flag, make sure they are
+ // accessed only when the flag is set.
+ if (android::media::codec::codec_availability()) {
+ clazz.reset(env->FindClass("android/media/MediaCodec$GlobalResourceInfo"));
+ CHECK(clazz.get() != NULL);
+ gGlobalResourceInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());
+ gGlobalResourceInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V");
+ CHECK(gGlobalResourceInfo.ctorId != NULL);
+ gGlobalResourceInfo.resourceId =
+ env->GetFieldID(clazz.get(), "mName", "Ljava/lang/String;");
+ CHECK(gGlobalResourceInfo.resourceId != NULL);
+ gGlobalResourceInfo.capacityId = env->GetFieldID(clazz.get(), "mCapacity", "J");
+ CHECK(gGlobalResourceInfo.capacityId != NULL);
+ gGlobalResourceInfo.availableId = env->GetFieldID(clazz.get(), "mAvailable", "J");
+ CHECK(gGlobalResourceInfo.availableId != NULL);
+
+ clazz.reset(env->FindClass("android/media/MediaCodec$InstanceResourceInfo"));
+ CHECK(clazz.get() != NULL);
+ gInstanceResourceInfo.clazz = (jclass)env->NewGlobalRef(clazz.get());
+ gInstanceResourceInfo.ctorId = env->GetMethodID(clazz.get(), "<init>", "()V");
+ CHECK(gInstanceResourceInfo.ctorId != NULL);
+ gInstanceResourceInfo.resourceId =
+ env->GetFieldID(clazz.get(), "mName", "Ljava/lang/String;");
+ CHECK(gInstanceResourceInfo.resourceId != NULL);
+ gInstanceResourceInfo.staticCountId= env->GetFieldID(clazz.get(), "mStaticCount", "J");
+ CHECK(gInstanceResourceInfo.staticCountId != NULL);
+ gInstanceResourceInfo.perFrameCountId = env->GetFieldID(clazz.get(), "mPerFrameCount", "J");
+ CHECK(gInstanceResourceInfo.perFrameCountId != NULL);
+ }
}
static void android_media_MediaCodec_native_setup(
@@ -4261,6 +4402,12 @@ static const JNINativeMethod gMethods[] = {
{ "native_finalize", "()V",
(void *)android_media_MediaCodec_native_finalize },
+
+ { "native_getGloballyAvailableResources", "()Ljava/util/List;",
+ (void *)android_media_MediaCodec_getGloballyAvailableResources},
+
+ { "native_getRequiredResources", "()Ljava/util/List;",
+ (void *)android_media_MediaCodec_getRequiredResources},
};
static const JNINativeMethod gLinearBlockMethods[] = {
diff --git a/media/jni/android_media_MediaCodec.h b/media/jni/android_media_MediaCodec.h
index c9b6b7f6f337..930dbbeb7f30 100644
--- a/media/jni/android_media_MediaCodec.h
+++ b/media/jni/android_media_MediaCodec.h
@@ -185,6 +185,8 @@ struct JMediaCodec : public AHandler {
status_t unsubscribeFromVendorParameters(JNIEnv *env, jobject names);
+ status_t getRequiredResources(JNIEnv *env, jobject *resourcesObj);
+
bool hasCryptoOrDescrambler() { return mHasCryptoOrDescrambler; }
const sp<ICrypto> &getCrypto() { return mCrypto; }
diff --git a/native/graphics/jni/Android.bp b/native/graphics/jni/Android.bp
index 0fb3049f63d8..962f54d6a23f 100644
--- a/native/graphics/jni/Android.bp
+++ b/native/graphics/jni/Android.bp
@@ -45,8 +45,10 @@ cc_library_shared {
header_libs: [
"jni_headers",
+ "native_headers",
"libhwui_internal_headers",
],
+ export_header_lib_headers: ["native_headers"],
static_libs: ["libarect"],
diff --git a/nfc/api/current.txt b/nfc/api/current.txt
index 008120429c40..9a7a39f213ee 100644
--- a/nfc/api/current.txt
+++ b/nfc/api/current.txt
@@ -81,11 +81,14 @@ package android.nfc {
method @FlaggedApi("android.nfc.enable_nfc_reader_option") public boolean isReaderOptionSupported();
method public boolean isSecureNfcEnabled();
method public boolean isSecureNfcSupported();
+ method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAllowed();
+ method @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public boolean isTagIntentAppPreferenceSupported();
method @FlaggedApi("android.nfc.enable_nfc_charging") public boolean isWlcEnabled();
method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void resetDiscoveryTechnology(@NonNull android.app.Activity);
method @FlaggedApi("android.nfc.enable_nfc_set_discovery_tech") public void setDiscoveryTechnology(@NonNull android.app.Activity, int, int);
method @FlaggedApi("android.nfc.nfc_observe_mode") public boolean setObserveModeEnabled(boolean);
field public static final String ACTION_ADAPTER_STATE_CHANGED = "android.nfc.action.ADAPTER_STATE_CHANGED";
+ field @FlaggedApi("android.nfc.nfc_check_tag_intent_preference") public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE = "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
field public static final String ACTION_NDEF_DISCOVERED = "android.nfc.action.NDEF_DISCOVERED";
field @RequiresPermission(android.Manifest.permission.NFC_PREFERRED_PAYMENT_INFO) public static final String ACTION_PREFERRED_PAYMENT_CHANGED = "android.nfc.action.PREFERRED_PAYMENT_CHANGED";
field public static final String ACTION_TAG_DISCOVERED = "android.nfc.action.TAG_DISCOVERED";
diff --git a/nfc/api/system-current.txt b/nfc/api/system-current.txt
index a23845fa17e9..15814edcd86a 100644
--- a/nfc/api/system-current.txt
+++ b/nfc/api/system-current.txt
@@ -11,7 +11,6 @@ package android.nfc {
method @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.Map<java.lang.String,java.lang.Boolean> getTagIntentAppPreferenceForUser(int);
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOn();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public boolean isControllerAlwaysOnSupported();
- method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public boolean isTagIntentAppPreferenceSupported();
method @RequiresPermission(android.Manifest.permission.NFC_SET_CONTROLLER_ALWAYS_ON) public void registerControllerAlwaysOnListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.ControllerAlwaysOnListener);
method @FlaggedApi("android.nfc.nfc_vendor_cmd") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void registerNfcVendorNciCallback(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.NfcVendorNciCallback);
method @FlaggedApi("android.nfc.enable_nfc_charging") public void registerWlcStateListener(@NonNull java.util.concurrent.Executor, @NonNull android.nfc.NfcAdapter.WlcStateListener);
@@ -57,6 +56,7 @@ package android.nfc {
@FlaggedApi("android.nfc.nfc_oem_extension") public final class NfcOemExtension {
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void clearPreference();
+ method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int forceRoutingTableCommit();
method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull public java.util.List<java.lang.String> getActiveNfceeList();
method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public android.nfc.RoutingStatus getRoutingStatus();
method @FlaggedApi("android.nfc.nfc_oem_extension") @NonNull @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public java.util.List<android.nfc.NfcRoutingTableEntry> getRoutingTable();
@@ -73,6 +73,9 @@ package android.nfc {
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 triggerInitialization();
method @FlaggedApi("android.nfc.nfc_oem_extension") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void unregisterCallback(@NonNull android.nfc.NfcOemExtension.Callback);
+ field public static final int COMMIT_ROUTING_STATUS_FAILED = 3; // 0x3
+ field public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6; // 0x6
+ field public static final int COMMIT_ROUTING_STATUS_OK = 0; // 0x0
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
@@ -89,13 +92,15 @@ package android.nfc {
method public void onBootFinished(int);
method public void onBootStarted();
method public void onCardEmulationActivated(boolean);
- method public void onDisable(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onDisableFinished(int);
+ method public void onDisableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onDisableStarted();
method public void onEeListenActivated(boolean);
- method public void onEnable(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method public void onEeUpdated();
method public void onEnableFinished(int);
+ method public void onEnableRequested(@NonNull java.util.function.Consumer<java.lang.Boolean>);
method public void onEnableStarted();
+ method public void onExtractOemPackages(@NonNull android.nfc.NdefMessage, @NonNull java.util.function.Consumer<java.util.List<java.lang.String>>);
method public void onGetOemAppSearchIntent(@NonNull java.util.List<java.lang.String>, @NonNull java.util.function.Consumer<android.content.Intent>);
method public void onHceEventReceived(int);
method public void onLaunchHceAppChooserActivity(@NonNull String, @NonNull java.util.List<android.nfc.cardemulation.ApduServiceInfo>, @NonNull android.content.ComponentName, @NonNull String);
@@ -106,7 +111,8 @@ package android.nfc {
method public void onReaderOptionChanged(boolean);
method public void onRfDiscoveryStarted(boolean);
method public void onRfFieldActivated(boolean);
- method public void onRoutingChanged();
+ method public void onRoutingChanged(@NonNull java.util.function.Consumer<java.lang.Boolean>);
+ method public void onRoutingTableFull();
method public void onStateUpdated(int);
method public void onTagConnected(boolean);
method public void onTagDispatch(@NonNull java.util.function.Consumer<java.lang.Boolean>);
@@ -182,6 +188,12 @@ package android.nfc.cardemulation {
method @FlaggedApi("android.nfc.enable_nfc_mainline") @NonNull public java.util.List<android.nfc.cardemulation.ApduServiceInfo> getServices(@NonNull String, int);
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);
+ method @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public int setServiceEnabledForCategoryOther(@NonNull android.content.ComponentName, boolean);
+ field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3; // 0x3
+ field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1; // 0x1
+ field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2; // 0x2
+ field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4; // 0x4
+ field @FlaggedApi("android.nfc.nfc_set_service_enabled_for_category_other") public static final int SET_SERVICE_ENABLED_STATUS_OK = 0; // 0x0
}
}
diff --git a/nfc/java/android/nfc/INfcAdapter.aidl b/nfc/java/android/nfc/INfcAdapter.aidl
index 40fd0683f465..a08b55fe86b8 100644
--- a/nfc/java/android/nfc/INfcAdapter.aidl
+++ b/nfc/java/android/nfc/INfcAdapter.aidl
@@ -120,4 +120,6 @@ interface INfcAdapter
boolean isTagPresent();
List<Entry> getRoutingTableEntryList();
void indicateDataMigration(boolean inProgress, String pkg);
+ int commitRouting();
+ boolean isTagIntentAllowed(in String pkg, in int Userid);
}
diff --git a/nfc/java/android/nfc/INfcCardEmulation.aidl b/nfc/java/android/nfc/INfcCardEmulation.aidl
index 5e2e92d958a4..633d8bfbbb67 100644
--- a/nfc/java/android/nfc/INfcCardEmulation.aidl
+++ b/nfc/java/android/nfc/INfcCardEmulation.aidl
@@ -47,7 +47,7 @@ interface INfcCardEmulation
boolean unsetPreferredService();
boolean supportsAidPrefixRegistration();
ApduServiceInfo getPreferredPaymentService(int userHandle);
- boolean setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status);
+ int setServiceEnabledForCategoryOther(int userHandle, in ComponentName app, boolean status);
boolean isDefaultPaymentRegistered();
void overrideRoutingTable(int userHandle, String protocol, String technology, in String pkg);
diff --git a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
index b102e873d737..e5eac0b4d6fd 100644
--- a/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
+++ b/nfc/java/android/nfc/INfcOemExtensionCallback.aidl
@@ -41,16 +41,19 @@ interface INfcOemExtensionCallback {
void onEnableFinished(int status);
void onDisableFinished(int status);
void onTagDispatch(in ResultReceiver isSkipped);
- void onRoutingChanged();
+ void onRoutingChanged(in ResultReceiver isSkipped);
void onHceEventReceived(int action);
void onReaderOptionChanged(boolean enabled);
void onCardEmulationActivated(boolean isActivated);
void onRfFieldActivated(boolean isActivated);
void onRfDiscoveryStarted(boolean isDiscoveryStarted);
void onEeListenActivated(boolean isActivated);
+ void onEeUpdated();
void onGetOemAppSearchIntent(in List<String> firstPackage, in ResultReceiver intentConsumer);
void onNdefMessage(in Tag tag, in NdefMessage message, in ResultReceiver hasOemExecutableContent);
void onLaunchHceAppChooserActivity(in String selectedAid, in List<ApduServiceInfo> services, in ComponentName failedComponent, in String category);
void onLaunchHceTapAgainActivity(in ApduServiceInfo service, in String category);
+ void onRoutingTableFull();
void onLogEventNotified(in OemLogItems item);
+ void onExtractOemPackages(in NdefMessage message, in ResultReceiver packageReceiver);
}
diff --git a/nfc/java/android/nfc/NfcAdapter.java b/nfc/java/android/nfc/NfcAdapter.java
index c5d8191b22e6..056844f38f3c 100644
--- a/nfc/java/android/nfc/NfcAdapter.java
+++ b/nfc/java/android/nfc/NfcAdapter.java
@@ -49,6 +49,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.util.Log;
import java.io.IOException;
@@ -2505,22 +2506,22 @@ public final class NfcAdapter {
}
/**
- * Checks if the device supports Tag application preference.
+ * Checks if the device supports Tag Intent App Preference functionality.
+ *
+ * When supported, {@link #ACTION_NDEF_DISCOVERED}, {@link #ACTION_TECH_DISCOVERED} or
+ * {@link #ACTION_TAG_DISCOVERED} will not be dispatched to an Activity if
+ * {@link isTagIntentAllowed} returns {@code false}.
*
* @return {@code true} if the device supports Tag application preference, {@code false}
* otherwise
* @throws UnsupportedOperationException if FEATURE_NFC is unavailable
- *
- * @hide
*/
- @SystemApi
- @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
public boolean isTagIntentAppPreferenceSupported() {
if (!sHasNfcFeature) {
throw new UnsupportedOperationException();
}
return callServiceReturn(() -> sService.isTagIntentAppPreferenceSupported(), false);
-
}
/**
@@ -2895,4 +2896,42 @@ public final class NfcAdapter {
}
return mNfcOemExtension;
}
+
+ /**
+ * Activity action: Bring up the settings page that allows the user to enable or disable tag
+ * intent reception for apps.
+ *
+ * <p>This will direct user to the settings page shows a list that asks users whether
+ * they want to allow or disallow the package to start an activity when a tag is discovered.
+ *
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
+ public static final String ACTION_CHANGE_TAG_INTENT_PREFERENCE =
+ "android.nfc.action.CHANGE_TAG_INTENT_PREFERENCE";
+
+ /**
+ * Checks whether the user has disabled the calling app from receiving NFC tag intents.
+ *
+ * <p>This method checks whether the caller package name is either not present in the user
+ * disabled list or is explicitly allowed by the user.
+ *
+ * @return {@code true} if an app is either not present in the list or is added to the list
+ * with the flag set to {@code true}. Otherwise, it returns {@code false}.
+ * It also returns {@code true} if {@link isTagIntentAppPreferenceSupported} returns
+ * {@code false}.
+ *
+ * @throws UnsupportedOperationException if FEATURE_NFC is unavailable.
+ */
+ @FlaggedApi(Flags.FLAG_NFC_CHECK_TAG_INTENT_PREFERENCE)
+ public boolean isTagIntentAllowed() {
+ if (!sHasNfcFeature) {
+ throw new UnsupportedOperationException();
+ }
+ if (!isTagIntentAppPreferenceSupported()) {
+ return true;
+ }
+ return callServiceReturn(() -> sService.isTagIntentAllowed(mContext.getPackageName(),
+ UserHandle.myUserId()), false);
+ }
}
diff --git a/nfc/java/android/nfc/NfcOemExtension.java b/nfc/java/android/nfc/NfcOemExtension.java
index abd99bc02f55..9ed678fe6014 100644
--- a/nfc/java/android/nfc/NfcOemExtension.java
+++ b/nfc/java/android/nfc/NfcOemExtension.java
@@ -23,11 +23,11 @@ import static android.nfc.cardemulation.CardEmulation.routeIntToString;
import android.Manifest;
import android.annotation.CallbackExecutor;
+import android.annotation.DurationMillisLong;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
import android.annotation.SystemApi;
import android.content.ComponentName;
import android.content.Context;
@@ -194,6 +194,30 @@ public final class NfcOemExtension {
public @interface StatusCode {}
/**
+ * Routing commit succeeded.
+ */
+ public static final int COMMIT_ROUTING_STATUS_OK = 0;
+ /**
+ * Routing commit failed.
+ */
+ public static final int COMMIT_ROUTING_STATUS_FAILED = 3;
+ /**
+ * Routing commit failed due to the update is in progress.
+ */
+ public static final int COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS = 6;
+
+ /**
+ * Status codes returned when calling {@link #forceRoutingTableCommit()}
+ * @hide
+ */
+ @IntDef(prefix = "COMMIT_ROUTING_STATUS_", value = {
+ COMMIT_ROUTING_STATUS_OK,
+ COMMIT_ROUTING_STATUS_FAILED,
+ COMMIT_ROUTING_STATUS_FAILED_UPDATE_IN_PROGRESS,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface CommitRoutingStatusCode {}
+ /**
* Interface for Oem extensions for NFC.
*/
public interface Callback {
@@ -233,8 +257,7 @@ public final class NfcOemExtension {
* {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
* false if NFC cannot be enabled at this time.
*/
- @SuppressLint("MethodNameTense")
- void onEnable(@NonNull Consumer<Boolean> isAllowed);
+ void onEnableRequested(@NonNull Consumer<Boolean> isAllowed);
/**
* Method to check if Nfc is allowed to be disabled by OEMs.
* @param isAllowed The {@link Consumer} to be completed. If disabling NFC is allowed,
@@ -242,7 +265,7 @@ public final class NfcOemExtension {
* {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
* false if NFC cannot be disabled at this time.
*/
- void onDisable(@NonNull Consumer<Boolean> isAllowed);
+ void onDisableRequested(@NonNull Consumer<Boolean> isAllowed);
/**
* Callback to indicate that Nfc starts to boot.
@@ -255,7 +278,7 @@ public final class NfcOemExtension {
void onEnableStarted();
/**
- * Callback to indicate that Nfc starts to enable.
+ * Callback to indicate that Nfc starts to disable.
*/
void onDisableStarted();
@@ -287,8 +310,12 @@ public final class NfcOemExtension {
/**
* Notifies routing configuration is changed.
+ * @param isCommitRoutingSkipped The {@link Consumer} to be
+ * completed. If routing commit should be skipped,
+ * the {@link Consumer#accept(Object)} should be called with
+ * {@link Boolean#TRUE}, otherwise call with {@link Boolean#FALSE}.
*/
- void onRoutingChanged();
+ void onRoutingChanged(@NonNull Consumer<Boolean> isCommitRoutingSkipped);
/**
* API to activate start stop cpu boost on hce event.
@@ -340,6 +367,15 @@ public final class NfcOemExtension {
void onEeListenActivated(boolean isActivated);
/**
+ * Notifies that some NFCEE (NFC Execution Environment) has been updated.
+ *
+ * <p> This indicates that some applet has been installed/updated/removed in
+ * one of the NFCEE's.
+ * </p>
+ */
+ void onEeUpdated();
+
+ /**
* Gets the intent to find the OEM package in the OEM App market. If the consumer returns
* {@code null} or a timeout occurs, the intent from the first available package will be
* used instead.
@@ -394,10 +430,30 @@ public final class NfcOemExtension {
void onLaunchHceTapAgainDialog(@NonNull ApduServiceInfo service, @NonNull String category);
/**
+ * Callback to indicate that routing table is full and the OEM can optionally launch a
+ * dialog to request the user to remove some Card Emulation apps from the device to free
+ * routing table space.
+ */
+ void onRoutingTableFull();
+
+ /**
* Callback when OEM specified log event are notified.
* @param item the log items that contains log information of NFC event.
*/
void onLogEventNotified(@NonNull OemLogItems item);
+
+ /**
+ * Callback to to extract OEM defined packages from given NDEF message when
+ * a NFC tag is detected. These are used to handle NFC tags encoded with a
+ * proprietary format for storing app name (Android native app format).
+ *
+ * @param message NDEF message containing OEM package names
+ * @param packageConsumer The {@link Consumer} to be completed.
+ * The {@link Consumer#accept(Object)} should be called with
+ * the list of package names.
+ */
+ void onExtractOemPackages(@NonNull NdefMessage message,
+ @NonNull Consumer<List<String>> packageConsumer);
}
@@ -598,12 +654,12 @@ public final class NfcOemExtension {
/**
* Pauses NFC tag reader mode polling for a {@code timeoutInMs} millisecond.
* In case of {@code timeoutInMs} is zero or invalid polling will be stopped indefinitely
- * use {@link #resumePolling() to resume the polling.
- * @param timeoutInMs the pause polling duration in millisecond
+ * use {@link #resumePolling()} to resume the polling.
+ * @param timeoutInMs the pause polling duration in millisecond, ranging from 0 to 40000.
*/
@FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
@RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
- public void pausePolling(int timeoutInMs) {
+ public void pausePolling(@DurationMillisLong int timeoutInMs) {
NfcAdapter.callService(() -> NfcAdapter.sService.pausePolling(timeoutInMs));
}
@@ -734,6 +790,18 @@ public final class NfcOemExtension {
return result;
}
+ /**
+ * API to force a routing table commit.
+ * @return a {@link StatusCode} to indicate if commit routing succeeded or not
+ */
+ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ @FlaggedApi(Flags.FLAG_NFC_OEM_EXTENSION)
+ @CommitRoutingStatusCode
+ public int forceRoutingTableCommit() {
+ return NfcAdapter.callServiceReturn(
+ () -> NfcAdapter.sService.commitRouting(), COMMIT_ROUTING_STATUS_FAILED);
+ }
+
private final class NfcOemExtensionCallback extends INfcOemExtensionCallback.Stub {
@Override
@@ -771,6 +839,12 @@ public final class NfcOemExtension {
}
@Override
+ public void onEeUpdated() throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(null, (Object input) -> cb.onEeUpdated(), ex));
+ }
+
+ @Override
public void onStateUpdated(int state) throws RemoteException {
mCallbackMap.forEach((cb, ex) ->
handleVoidCallback(state, cb::onStateUpdated, ex));
@@ -792,13 +866,13 @@ public final class NfcOemExtension {
public void onEnable(ResultReceiver isAllowed) throws RemoteException {
mCallbackMap.forEach((cb, ex) ->
handleVoidCallback(
- new ReceiverWrapper<>(isAllowed), cb::onEnable, ex));
+ new ReceiverWrapper<>(isAllowed), cb::onEnableRequested, ex));
}
@Override
public void onDisable(ResultReceiver isAllowed) throws RemoteException {
mCallbackMap.forEach((cb, ex) ->
handleVoidCallback(
- new ReceiverWrapper<>(isAllowed), cb::onDisable, ex));
+ new ReceiverWrapper<>(isAllowed), cb::onDisableRequested, ex));
}
@Override
public void onBootStarted() throws RemoteException {
@@ -837,9 +911,10 @@ public final class NfcOemExtension {
new ReceiverWrapper<>(isSkipped), cb::onTagDispatch, ex));
}
@Override
- public void onRoutingChanged() throws RemoteException {
+ public void onRoutingChanged(ResultReceiver isSkipped) throws RemoteException {
mCallbackMap.forEach((cb, ex) ->
- handleVoidCallback(null, (Object input) -> cb.onRoutingChanged(), ex));
+ handleVoidCallback(
+ new ReceiverWrapper<>(isSkipped), cb::onRoutingChanged, ex));
}
@Override
public void onHceEventReceived(int action) throws RemoteException {
@@ -853,6 +928,12 @@ public final class NfcOemExtension {
handleVoidCallback(enabled, cb::onReaderOptionChanged, ex));
}
+ public void onRoutingTableFull() throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoidCallback(null,
+ (Object input) -> cb.onRoutingTableFull(), ex));
+ }
+
@Override
public void onGetOemAppSearchIntent(List<String> packages, ResultReceiver intentConsumer)
throws RemoteException {
@@ -912,6 +993,15 @@ public final class NfcOemExtension {
handleVoidCallback(item, cb::onLogEventNotified, ex));
}
+ @Override
+ public void onExtractOemPackages(NdefMessage message, ResultReceiver packageConsumer)
+ throws RemoteException {
+ mCallbackMap.forEach((cb, ex) ->
+ handleVoid2ArgCallback(message,
+ new ReceiverWrapper<>(packageConsumer),
+ cb::onExtractOemPackages, ex));
+ }
+
private <T> void handleVoidCallback(
T input, Consumer<T> callbackMethod, Executor executor) {
synchronized (mLock) {
@@ -1022,8 +1112,14 @@ public final class NfcOemExtension {
Bundle bundle = new Bundle();
bundle.putParcelable("intent", (Intent) result);
mResultReceiver.send(0, bundle);
+ } else if (result instanceof List<?> list) {
+ if (list.stream().allMatch(String.class::isInstance)) {
+ Bundle bundle = new Bundle();
+ bundle.putStringArray("packageNames",
+ list.stream().map(pkg -> (String) pkg).toArray(String[]::new));
+ mResultReceiver.send(0, bundle);
+ }
}
-
}
@Override
diff --git a/nfc/java/android/nfc/OemLogItems.java b/nfc/java/android/nfc/OemLogItems.java
index 6671941c1cc9..4f3e1999f5d3 100644
--- a/nfc/java/android/nfc/OemLogItems.java
+++ b/nfc/java/android/nfc/OemLogItems.java
@@ -142,8 +142,11 @@ public final class OemLogItems implements Parcelable {
dest.writeByteArray(mCommandApdus);
dest.writeInt(mResponseApdus.length);
dest.writeByteArray(mResponseApdus);
- dest.writeLong(mRfFieldOnTime.getEpochSecond());
- dest.writeInt(mRfFieldOnTime.getNano());
+ dest.writeBoolean(mRfFieldOnTime != null);
+ if (mRfFieldOnTime != null) {
+ dest.writeLong(mRfFieldOnTime.getEpochSecond());
+ dest.writeInt(mRfFieldOnTime.getNano());
+ }
dest.writeParcelable(mTag, 0);
}
@@ -305,7 +308,12 @@ public final class OemLogItems implements Parcelable {
in.readByteArray(this.mCommandApdus);
this.mResponseApdus = new byte[in.readInt()];
in.readByteArray(this.mResponseApdus);
- this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());
+ boolean isRfFieldOnTimeSet = in.readBoolean();
+ if (isRfFieldOnTimeSet) {
+ this.mRfFieldOnTime = Instant.ofEpochSecond(in.readLong(), in.readInt());
+ } else {
+ this.mRfFieldOnTime = null;
+ }
this.mTag = in.readParcelable(Tag.class.getClassLoader(), Tag.class);
}
diff --git a/nfc/java/android/nfc/cardemulation/CardEmulation.java b/nfc/java/android/nfc/cardemulation/CardEmulation.java
index eb28c3b9c930..891752475824 100644
--- a/nfc/java/android/nfc/cardemulation/CardEmulation.java
+++ b/nfc/java/android/nfc/cardemulation/CardEmulation.java
@@ -185,6 +185,65 @@ public final class CardEmulation {
@FlaggedApi(Flags.FLAG_NFC_OVERRIDE_RECOVER_ROUTING_TABLE)
public static final int PROTOCOL_AND_TECHNOLOGY_ROUTE_UNSET = -1;
+ /**
+ * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
+ * succeeded.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
+ public static final int SET_SERVICE_ENABLED_STATUS_OK = 0;
+
+ /**
+ * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
+ * failed due to the unsupported feature.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
+ public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED = 1;
+
+ /**
+ * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
+ * failed due to the invalid service.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
+ public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE = 2;
+
+ /**
+ * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
+ * failed due to the service is already set to the requested status.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
+ public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET = 3;
+
+ /**
+ * Status code returned when {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
+ * failed due to unknown error.
+ * @hide
+ */
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
+ public static final int SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR = 4;
+
+ /**
+ * Status code returned by {@link #setServiceEnabledForCategoryOther(ComponentName, boolean)}
+ * @hide
+ */
+ @IntDef(prefix = "SET_SERVICE_ENABLED_STATUS_", value = {
+ SET_SERVICE_ENABLED_STATUS_OK,
+ SET_SERVICE_ENABLED_STATUS_FAILURE_FEATURE_UNSUPPORTED,
+ SET_SERVICE_ENABLED_STATUS_FAILURE_INVALID_SERVICE,
+ SET_SERVICE_ENABLED_STATUS_FAILURE_ALREADY_SET,
+ SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface SetServiceEnabledStatusCode {}
+
static boolean sIsInitialized = false;
static HashMap<Context, CardEmulation> sCardEmus = new HashMap<Context, CardEmulation>();
static INfcCardEmulation sService;
@@ -883,22 +942,24 @@ public final class CardEmulation {
}
/**
- * Allows to set or unset preferred service (category other) to avoid AID Collision.
+ * Allows to set or unset preferred service (category other) to avoid AID Collision. The user
+ * should use corresponding context using {@link Context#createContextAsUser(UserHandle, int)}
*
* @param service The ComponentName of the service
* @param status true to enable, false to disable
- * @param userId the user handle of the user whose information is being requested.
- * @return set service for the category and true if service is already set return false.
+ * @return true if preferred service is successfully set or unset, otherwise return false.
*
* @hide
*/
- public boolean setServiceEnabledForCategoryOther(ComponentName service, boolean status,
- int userId) {
- if (service == null) {
- throw new NullPointerException("activity or service or category is null");
- }
+ @SystemApi
+ @FlaggedApi(Flags.FLAG_NFC_SET_SERVICE_ENABLED_FOR_CATEGORY_OTHER)
+ @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
+ @SetServiceEnabledStatusCode
+ public int setServiceEnabledForCategoryOther(@NonNull ComponentName service,
+ boolean status) {
return callServiceReturn(() ->
- sService.setServiceEnabledForCategoryOther(userId, service, status), false);
+ sService.setServiceEnabledForCategoryOther(mContext.getUser().getIdentifier(),
+ service, status), SET_SERVICE_ENABLED_STATUS_FAILURE_UNKNOWN_ERROR);
}
/** @hide */
diff --git a/nfc/java/android/nfc/flags.aconfig b/nfc/java/android/nfc/flags.aconfig
index 34f020012d3c..ee287aba709f 100644
--- a/nfc/java/android/nfc/flags.aconfig
+++ b/nfc/java/android/nfc/flags.aconfig
@@ -173,3 +173,19 @@ flag {
description: "Share wallet role routing priority with associated services"
bug: "366243361"
}
+
+flag {
+ name: "nfc_set_service_enabled_for_category_other"
+ is_exported: true
+ namespace: "nfc"
+ description: "Enable set service enabled for category other"
+ bug: "338157113"
+}
+
+flag {
+ name: "nfc_check_tag_intent_preference"
+ is_exported: true
+ namespace: "nfc"
+ description: "App can check its tag intent preference status"
+ bug: "335916336"
+}
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index dd6545b24c07..06d451f6f8ab 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -821,9 +821,9 @@
<!-- Title of checkbox setting that enables the Linux terminal app. [CHAR LIMIT=32] -->
<string name="enable_linux_terminal_title">Linux development environment</string>
- <!-- Summary of checkbox setting that enables the Linux terminal app. [CHAR LIMIT=64] -->
- <string name="enable_linux_terminal_summary">Run Linux terminal on Android</string>
- <!-- Disclaimer below the checkbox that disabling the Linux terminal app would clear its data. [CHAR LIMIT=64] -->
+ <!-- Summary of checkbox setting that enables the Linux terminal app. [CHAR LIMIT=none] -->
+ <string name="enable_linux_terminal_summary">(Experimental) Run Linux terminal on Android</string>
+ <!-- Disclaimer below the checkbox that disabling the Linux terminal app would clear its data. [CHAR LIMIT=none] -->
<string name="disable_linux_terminal_disclaimer">If you disable, Linux terminal data will be cleared</string>
<!-- HDCP checking title, used for debug purposes only. [CHAR LIMIT=25] -->
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 18dd5c10384f..676ff97226ed 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -715,6 +715,9 @@
<uses-permission android:name="android.permission.UWB_PRIVILEGED" />
<uses-permission android:name="android.permission.UWB_RANGING" />
+ <!-- Permission required for CTS test - CtsRangingTestCases -->
+ <uses-permission android:name="android.permission.RANGING" />
+
<!-- Permission required for CTS test - CtsAlarmManagerTestCases -->
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
diff --git a/packages/Shell/OWNERS b/packages/Shell/OWNERS
index 177f86b08864..c3ecff418075 100644
--- a/packages/Shell/OWNERS
+++ b/packages/Shell/OWNERS
@@ -11,3 +11,4 @@ patb@google.com
cbrubaker@google.com
omakoto@google.com
michaelwr@google.com
+ronish@google.com
diff --git a/ravenwood/Framework.bp b/ravenwood/Framework.bp
index d20773844df3..99fc31b258e9 100644
--- a/ravenwood/Framework.bp
+++ b/ravenwood/Framework.bp
@@ -214,7 +214,8 @@ java_genrule {
java_genrule {
name: "services.core.ravenwood",
- defaults: ["ravenwood-internal-only-visibility-genrule"],
+ // This is used by unit tests too (so tests will be able to access HSG-processed implementation)
+ // so it's visible to all.
cmd: "cp $(in) $(out)",
srcs: [
":services.core.ravenwood-base{ravenwood.jar}",
diff --git a/ravenwood/TEST_MAPPING b/ravenwood/TEST_MAPPING
index a1243e37003e..cb54e9f56c0c 100644
--- a/ravenwood/TEST_MAPPING
+++ b/ravenwood/TEST_MAPPING
@@ -113,11 +113,11 @@
"host": true
},
{
- "name": "FrameworksMockingServicesTestsRavenwood",
+ "name": "FrameworksServicesTestsRavenwood_Compat",
"host": true
},
{
- "name": "FrameworksServicesTestsRavenwood",
+ "name": "FrameworksServicesTestsRavenwood_Uri",
"host": true
},
{
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
index 869d854f7b23..9b71f8050c80 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodAwareTestRunner.java
@@ -30,6 +30,8 @@ import android.util.Log;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.ravenwood.common.RavenwoodCommonUtils;
+
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runner.Runner;
@@ -229,7 +231,9 @@ public final class RavenwoodAwareTestRunner extends RavenwoodAwareTestRunnerBase
s.evaluate();
onAfter(description, scope, order, null);
} catch (Throwable t) {
- if (onAfter(description, scope, order, t)) {
+ var shouldReportFailure = RavenwoodCommonUtils.runIgnoringException(
+ () -> onAfter(description, scope, order, t));
+ if (shouldReportFailure == null || shouldReportFailure) {
throw t;
}
}
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
index c5a9c7b28ad3..1c1f15761329 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodRuntimeEnvironmentController.java
@@ -22,6 +22,8 @@ import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_INST_R
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_RESOURCE_APK;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERBOSE_LOGGING;
import static com.android.ravenwood.common.RavenwoodCommonUtils.RAVENWOOD_VERSION_JAVA_SYSPROP;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.parseNullableInt;
+import static com.android.ravenwood.common.RavenwoodCommonUtils.withDefault;
import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.any;
@@ -30,17 +32,22 @@ import static org.mockito.Mockito.mock;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.AppCompatCallbacks;
import android.app.Instrumentation;
import android.app.ResourcesManager;
import android.app.UiAutomation;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.os.Binder;
import android.os.Build;
+import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Process_ravenwood;
import android.os.ServiceManager;
+import android.os.ServiceManager.ServiceNotFoundException;
import android.os.SystemProperties;
import android.provider.DeviceConfig_host;
import android.system.ErrnoException;
@@ -58,6 +65,7 @@ import com.android.ravenwood.common.RavenwoodCommonUtils;
import com.android.ravenwood.common.RavenwoodRuntimeException;
import com.android.ravenwood.common.SneakyThrow;
import com.android.server.LocalServices;
+import com.android.server.compat.PlatformCompat;
import org.junit.runner.Description;
@@ -149,6 +157,13 @@ public class RavenwoodRuntimeEnvironmentController {
private static RavenwoodAwareTestRunner sRunner;
private static RavenwoodSystemProperties sProps;
+ private static final int DEFAULT_TARGET_SDK_LEVEL = VERSION_CODES.CUR_DEVELOPMENT;
+ private static final String DEFAULT_PACKAGE_NAME = "com.android.ravenwoodtests.defaultname";
+
+ private static int sTargetSdkLevel;
+ private static String sTestPackageName;
+ private static String sTargetPackageName;
+
/**
* Initialize the global environment.
*/
@@ -230,9 +245,22 @@ public class RavenwoodRuntimeEnvironmentController {
System.setProperty("android.junit.runner",
"androidx.test.internal.runner.junit4.AndroidJUnit4ClassRunner");
+ loadRavenwoodProperties();
+
assertMockitoVersion();
}
+ private static void loadRavenwoodProperties() {
+ var props = RavenwoodSystemProperties.readProperties("ravenwood.properties");
+
+ sTargetSdkLevel = withDefault(
+ parseNullableInt(props.get("targetSdkVersionInt")), DEFAULT_TARGET_SDK_LEVEL);
+ sTargetPackageName = withDefault(props.get("packageName"), DEFAULT_PACKAGE_NAME);
+ sTestPackageName = withDefault(props.get("instPackageName"), sTargetPackageName);
+
+ // TODO(b/377765941) Read them from the manifest too?
+ }
+
/**
* Initialize the environment.
*/
@@ -251,7 +279,9 @@ public class RavenwoodRuntimeEnvironmentController {
initInner(runner.mState.getConfig());
} catch (Exception th) {
Log.e(TAG, "init() failed", th);
- reset();
+
+ RavenwoodCommonUtils.runIgnoringException(()-> reset());
+
SneakyThrow.sneakyThrow(th);
}
}
@@ -262,6 +292,14 @@ public class RavenwoodRuntimeEnvironmentController {
Thread.setDefaultUncaughtExceptionHandler(sUncaughtExceptionHandler);
}
+ config.mTargetPackageName = sTargetPackageName;
+ config.mTestPackageName = sTestPackageName;
+ config.mTargetSdkLevel = sTargetSdkLevel;
+
+ Log.i(TAG, "TargetPackageName=" + sTargetPackageName);
+ Log.i(TAG, "TestPackageName=" + sTestPackageName);
+ Log.i(TAG, "TargetSdkLevel=" + sTargetSdkLevel);
+
RavenwoodRuntimeState.sUid = config.mUid;
RavenwoodRuntimeState.sPid = config.mPid;
RavenwoodRuntimeState.sTargetSdkLevel = config.mTargetSdkLevel;
@@ -331,6 +369,8 @@ public class RavenwoodRuntimeEnvironmentController {
RavenwoodSystemServer.init(config);
+ initializeCompatIds(config);
+
if (ENABLE_TIMEOUT_STACKS) {
sPendingTimeout = sTimeoutExecutor.schedule(
RavenwoodRuntimeEnvironmentController::dumpStacks,
@@ -342,12 +382,43 @@ public class RavenwoodRuntimeEnvironmentController {
* Partially re-initialize after each test method invocation
*/
public static void reinit() {
- var config = sRunner.mState.getConfig();
- Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+ // sRunner could be null, if there was a failure in the initialization.
+ if (sRunner != null) {
+ var config = sRunner.mState.getConfig();
+ Binder.restoreCallingIdentity(packBinderIdentityToken(false, config.mUid, config.mPid));
+ }
+ }
+
+ private static void initializeCompatIds(RavenwoodConfig config) {
+ // Set up compat-IDs for the app side.
+ // TODO: Inside the system server, all the compat-IDs should be enabled,
+ // Due to the `AppCompatCallbacks.install(new long[0], new long[0])` call in
+ // SystemServer.
+
+ // Compat framework only uses the package name and the target SDK level.
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.packageName = config.mTargetPackageName;
+ appInfo.targetSdkVersion = config.mTargetSdkLevel;
+
+ PlatformCompat platformCompat = null;
+ try {
+ platformCompat = (PlatformCompat) ServiceManager.getServiceOrThrow(
+ Context.PLATFORM_COMPAT_SERVICE);
+ } catch (ServiceNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+
+ var disabledChanges = platformCompat.getDisabledChanges(appInfo);
+ var loggableChanges = platformCompat.getLoggableChanges(appInfo);
+
+ AppCompatCallbacks.install(disabledChanges, loggableChanges);
}
/**
* De-initialize.
+ *
+ * Note, we call this method when init() fails too, so this method should deal with
+ * any partially-initialized states.
*/
public static void reset() {
if (RAVENWOOD_VERBOSE_LOGGING) {
@@ -379,7 +450,9 @@ public class RavenwoodRuntimeEnvironmentController {
config.mState.mSystemServerContext.cleanUp();
}
- Looper.getMainLooper().quit();
+ if (Looper.getMainLooper() != null) {
+ Looper.getMainLooper().quit();
+ }
Looper.clearMainLooperForTest();
ActivityManager.reset$ravenwood();
diff --git a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
index f198a08a50e3..438a2bfa7a14 100644
--- a/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
+++ b/ravenwood/junit-impl-src/android/platform/test/ravenwood/RavenwoodSystemServer.java
@@ -17,7 +17,9 @@
package android.platform.test.ravenwood;
import android.content.ClipboardManager;
+import android.content.Context;
import android.hardware.SerialManager;
+import android.os.ServiceManager;
import android.os.SystemClock;
import android.ravenwood.example.BlueManager;
import android.ravenwood.example.RedManager;
@@ -27,6 +29,8 @@ import android.util.ArraySet;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemServiceManager;
+import com.android.server.compat.PlatformCompat;
+import com.android.server.compat.PlatformCompatNative;
import com.android.server.utils.TimingsTraceAndSlog;
import java.util.List;
@@ -65,6 +69,14 @@ public class RavenwoodSystemServer {
private static SystemServiceManager sServiceManager;
public static void init(RavenwoodConfig config) {
+ // Always start PlatformCompat, regardless of the requested services.
+ // PlatformCompat is not really a SystemService, so it won't receive boot phases / etc.
+ // This initialization code is copied from SystemServer.java.
+ PlatformCompat platformCompat = new PlatformCompat(config.mState.mSystemServerContext);
+ ServiceManager.addService(Context.PLATFORM_COMPAT_SERVICE, platformCompat);
+ ServiceManager.addService(Context.PLATFORM_COMPAT_NATIVE_SERVICE,
+ new PlatformCompatNative(platformCompat));
+
// Avoid overhead if no services required
if (config.mServicesRequired.isEmpty()) return;
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
index 3ed8b0a748e1..619c8e30c78e 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodConfig.java
@@ -22,7 +22,6 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.Instrumentation;
import android.content.Context;
-import android.os.Build;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@@ -30,16 +29,12 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.ArrayList;
import java.util.List;
-import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
/**
- * Represents how to configure the ravenwood environment for a test class.
- *
- * If a ravenwood test class has a public static field with the {@link Config} annotation,
- * Ravenwood will extract the config from it and initializes the environment. The type of the
- * field must be of {@link RavenwoodConfig}.
+ * @deprecated This class will be removed. Reach out to g/ravenwood if you need any features in it.
*/
+@Deprecated
public final class RavenwoodConfig {
/**
* Use this to mark a field as the configuration.
@@ -66,7 +61,7 @@ public final class RavenwoodConfig {
String mTestPackageName;
String mTargetPackageName;
- int mTargetSdkLevel = Build.VERSION_CODES.CUR_DEVELOPMENT;
+ int mTargetSdkLevel;
final RavenwoodSystemProperties mSystemProperties = new RavenwoodSystemProperties();
@@ -91,12 +86,6 @@ public final class RavenwoodConfig {
return RavenwoodRule.isOnRavenwood();
}
- private void setDefaults() {
- if (mTargetPackageName == null) {
- mTargetPackageName = mTestPackageName;
- }
- }
-
public static class Builder {
private final RavenwoodConfig mConfig = new RavenwoodConfig();
@@ -120,28 +109,27 @@ public final class RavenwoodConfig {
}
/**
- * Configure the package name of the test, which corresponds to
- * {@link Instrumentation#getContext()}.
+ * @deprecated no longer used. Package name is set in the build file. (for now)
*/
+ @Deprecated
public Builder setPackageName(@NonNull String packageName) {
- mConfig.mTestPackageName = Objects.requireNonNull(packageName);
return this;
}
/**
- * Configure the package name of the target app, which corresponds to
- * {@link Instrumentation#getTargetContext()}. Defaults to {@link #setPackageName}.
+ * @deprecated no longer used. Package name is set in the build file. (for now)
*/
+ @Deprecated
public Builder setTargetPackageName(@NonNull String packageName) {
- mConfig.mTargetPackageName = Objects.requireNonNull(packageName);
return this;
}
+
/**
- * Configure the target SDK level of the test.
+ * @deprecated no longer used. Target SDK level is set in the build file. (for now)
*/
+ @Deprecated
public Builder setTargetSdkLevel(int sdkLevel) {
- mConfig.mTargetSdkLevel = sdkLevel;
return this;
}
@@ -205,7 +193,6 @@ public final class RavenwoodConfig {
}
public RavenwoodConfig build() {
- mConfig.setDefaults();
return mConfig;
}
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
index bfa3802ce583..f7acd9022300 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodRule.java
@@ -36,10 +36,8 @@ import java.util.Objects;
import java.util.regex.Pattern;
/**
- * @deprecated Use {@link RavenwoodConfig} to configure the ravenwood environment instead.
- * A {@link RavenwoodRule} is no longer needed for {@link DisabledOnRavenwood}. To get the
- * {@link Context} and {@link Instrumentation}, use
- * {@link androidx.test.platform.app.InstrumentationRegistry} instead.
+ * @deprecated This class is undergoing a major change. Reach out to g/ravenwood if you need
+ * any featues in it.
*/
@Deprecated
public final class RavenwoodRule implements TestRule {
@@ -128,11 +126,10 @@ public final class RavenwoodRule implements TestRule {
}
/**
- * Configure the identity of this process to be the given package name for the duration
- * of the test. Has no effect on non-Ravenwood environments.
+ * @deprecated no longer used.
*/
+ @Deprecated
public Builder setPackageName(@NonNull String packageName) {
- mBuilder.setPackageName(packageName);
return this;
}
diff --git a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
index 3e4619f55c6d..9bd376a76f77 100644
--- a/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
+++ b/ravenwood/junit-src/android/platform/test/ravenwood/RavenwoodSystemProperties.java
@@ -52,7 +52,7 @@ public class RavenwoodSystemProperties {
"vendor_dlkm",
};
- private static Map<String, String> readProperties(String propFile) {
+ static Map<String, String> readProperties(String propFile) {
// Use an ordered map just for cleaner dump log.
final Map<String, String> ret = new LinkedHashMap<>();
try {
@@ -60,7 +60,7 @@ public class RavenwoodSystemProperties {
.map(String::trim)
.filter(s -> !s.startsWith("#"))
.map(s -> s.split("\\s*=\\s*", 2))
- .filter(a -> a.length == 2)
+ .filter(a -> a.length == 2 && a[1].length() > 0)
.forEach(a -> ret.put(a[0], a[1]));
} catch (IOException e) {
throw new RuntimeException(e);
diff --git a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
index 520f050f0655..2a04d4469ef4 100644
--- a/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
+++ b/ravenwood/runtime-common-src/com/android/ravenwood/common/RavenwoodCommonUtils.java
@@ -30,6 +30,7 @@ import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
+import java.util.function.Supplier;
public class RavenwoodCommonUtils {
private static final String TAG = "RavenwoodCommonUtils";
@@ -277,11 +278,55 @@ public class RavenwoodCommonUtils {
(isStatic ? "static" : "")));
}
+ /**
+ * Run a supplier and swallow the exception, if any.
+ *
+ * It's a dangerous function. Only use it in an exception handler where we don't want to crash.
+ */
+ @Nullable
+ public static <T> T runIgnoringException(@NonNull Supplier<T> s) {
+ try {
+ return s.get();
+ } catch (Throwable th) {
+ log(TAG, "Warning: Exception detected! " + getStackTraceString(th));
+ }
+ return null;
+ }
+
+ /**
+ * Run a runnable and swallow the exception, if any.
+ *
+ * It's a dangerous function. Only use it in an exception handler where we don't want to crash.
+ */
+ public static void runIgnoringException(@NonNull Runnable r) {
+ runIgnoringException(() -> {
+ r.run();
+ return null;
+ });
+ }
+
@NonNull
- public static String getStackTraceString(@Nullable Throwable th) {
+ public static String getStackTraceString(@NonNull Throwable th) {
StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter);
th.printStackTrace(writer);
return stringWriter.toString();
}
+
+ /** Same as {@link Integer#parseInt(String)} but accepts null and returns null. */
+ @Nullable
+ public static Integer parseNullableInt(@Nullable String value) {
+ if (value == null) {
+ return null;
+ }
+ return Integer.parseInt(value);
+ }
+
+ /**
+ * @return {@code value} if it's non-null. Otherwise, returns {@code def}.
+ */
+ @Nullable
+ public static <T> T withDefault(@Nullable T value, @Nullable T def) {
+ return value != null ? value : def;
+ }
}
diff --git a/ravenwood/scripts/run-ravenwood-tests.sh b/ravenwood/scripts/run-ravenwood-tests.sh
index fe2269a8dc38..27c5ea1bd0d7 100755
--- a/ravenwood/scripts/run-ravenwood-tests.sh
+++ b/ravenwood/scripts/run-ravenwood-tests.sh
@@ -33,7 +33,7 @@ include_re=""
exclude_re=""
smoke_exclude_re=""
dry_run=""
-while getopts "sx:f:dt" opt; do
+while getopts "sx:f:dtb" opt; do
case "$opt" in
s)
# Remove slow tests.
@@ -52,8 +52,13 @@ case "$opt" in
dry_run="echo"
;;
t)
+ # Redirect log to terminal
export RAVENWOOD_LOG_OUT=$(tty)
;;
+ b)
+ # Build only
+ ATEST=m
+ ;;
'?')
exit 1
;;
@@ -99,11 +104,16 @@ done
# Calculate the removed tests.
-diff="$(diff <(echo "${all_tests[@]}" | tr ' ' '\n') <(echo "${targets[@]}" | tr ' ' '\n') )"
+diff="$(diff <(echo "${all_tests[@]}" | tr ' ' '\n') <(echo "${targets[@]}" | tr ' ' '\n') | grep -v [0-9] )"
if [[ "$diff" != "" ]]; then
echo "Excluded tests:"
echo "$diff"
fi
-$dry_run ${ATEST:-atest} "${targets[@]}"
+run() {
+ echo "Running: ${@}"
+ "${@}"
+}
+
+run $dry_run ${ATEST:-atest} "${targets[@]}"
diff --git a/ravenwood/tests/bivalentinst/Android.bp b/ravenwood/tests/bivalentinst/Android.bp
index 41e45e5a6d95..31e3bcc3634f 100644
--- a/ravenwood/tests/bivalentinst/Android.bp
+++ b/ravenwood/tests/bivalentinst/Android.bp
@@ -27,6 +27,9 @@ android_ravenwood_test {
"junit",
"truth",
],
+
+ package_name: "com.android.ravenwood.bivalentinsttest_self_inst",
+
resource_apk: "RavenwoodBivalentInstTest_self_inst_device",
auto_gen_config: true,
}
@@ -53,6 +56,10 @@ android_ravenwood_test {
"truth",
],
resource_apk: "RavenwoodBivalentInstTestTarget",
+
+ package_name: "com.android.ravenwood.bivalentinst_target_app",
+ inst_package_name: "com.android.ravenwood.bivalentinsttest_nonself_inst",
+
inst_resource_apk: "RavenwoodBivalentInstTest_nonself_inst_device",
auto_gen_config: true,
}
diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
index ed1992cdd1ea..919aa439d4ef 100644
--- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
+++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_nonself.java
@@ -19,9 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Context;
-import android.platform.test.annotations.DisabledOnRavenwood;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -34,18 +31,13 @@ import org.junit.runner.RunWith;
* Tests for the case where the instrumentation target is _not_ the test APK itself.
*/
@RunWith(AndroidJUnit4.class)
-@DisabledOnRavenwood(reason="AOSP is missing resources support")
+@android.platform.test.annotations.DisabledOnRavenwood(reason = "AOSP is missing resources support")
public class RavenwoodInstrumentationTest_nonself {
private static final String TARGET_PACKAGE_NAME =
"com.android.ravenwood.bivalentinst_target_app";
private static final String TEST_PACKAGE_NAME =
"com.android.ravenwood.bivalentinsttest_nonself_inst";
- @Config
- public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
- .setPackageName(TEST_PACKAGE_NAME)
- .setTargetPackageName(TARGET_PACKAGE_NAME)
- .build();
private static Instrumentation sInstrumentation;
private static Context sTestContext;
diff --git a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
index b5bafc435845..81cfa662920c 100644
--- a/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
+++ b/ravenwood/tests/bivalentinst/test/com/android/ravenwoodtest/bivalentinst/RavenwoodInstrumentationTest_self.java
@@ -19,9 +19,6 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Instrumentation;
import android.content.Context;
-import android.platform.test.annotations.DisabledOnRavenwood;
-import android.platform.test.ravenwood.RavenwoodConfig;
-import android.platform.test.ravenwood.RavenwoodConfig.Config;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -34,7 +31,7 @@ import org.junit.runner.RunWith;
* Tests for the case where the instrumentation target is the test APK itself.
*/
@RunWith(AndroidJUnit4.class)
-@DisabledOnRavenwood(reason="AOSP is missing resources support")
+@android.platform.test.annotations.DisabledOnRavenwood(reason = "AOSP is missing resources support")
public class RavenwoodInstrumentationTest_self {
private static final String TARGET_PACKAGE_NAME =
@@ -42,13 +39,6 @@ public class RavenwoodInstrumentationTest_self {
private static final String TEST_PACKAGE_NAME =
"com.android.ravenwood.bivalentinsttest_self_inst";
- @Config
- public static final RavenwoodConfig sConfig = new RavenwoodConfig.Builder()
- .setPackageName(TEST_PACKAGE_NAME)
- .setTargetPackageName(TARGET_PACKAGE_NAME)
- .build();
-
-
private static Instrumentation sInstrumentation;
private static Context sTestContext;
private static Context sTargetContext;
diff --git a/ravenwood/tests/bivalenttest/Android.bp b/ravenwood/tests/bivalenttest/Android.bp
index 4895a1a6d1a2..ac545dfb06cc 100644
--- a/ravenwood/tests/bivalenttest/Android.bp
+++ b/ravenwood/tests/bivalenttest/Android.bp
@@ -58,6 +58,9 @@ java_defaults {
java_defaults {
name: "ravenwood-bivalent-device-defaults",
defaults: ["ravenwood-bivalent-defaults"],
+
+ target_sdk_version: "34", // For compat-framework tests
+
// TODO(b/371215487): migrate bivalenttest.ravenizer tests to another architecture
exclude_srcs: [
"test/**/ravenizer/*.java",
@@ -81,6 +84,8 @@ java_defaults {
android_ravenwood_test {
name: "RavenwoodBivalentTest",
defaults: ["ravenwood-bivalent-defaults"],
+ target_sdk_version: "34",
+ package_name: "com.android.ravenwoodtest.bivalenttest",
auto_gen_config: true,
}
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
index a5a16c14600b..306c2b39c70d 100644
--- a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/RavenwoodConfigTest.java
@@ -20,8 +20,6 @@ import static android.platform.test.ravenwood.RavenwoodConfig.isOnRavenwood;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
-import android.platform.test.ravenwood.RavenwoodConfig;
-
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
@@ -33,13 +31,7 @@ import org.junit.runner.RunWith;
*/
@RunWith(AndroidJUnit4.class)
public class RavenwoodConfigTest {
- private static final String PACKAGE_NAME = "com.test";
-
- @RavenwoodConfig.Config
- public static RavenwoodConfig sConfig =
- new RavenwoodConfig.Builder()
- .setPackageName(PACKAGE_NAME)
- .build();
+ private static final String PACKAGE_NAME = "com.android.ravenwoodtest.bivalenttest";
@Test
public void testConfig() {
diff --git a/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
new file mode 100644
index 000000000000..882c91c43ee9
--- /dev/null
+++ b/ravenwood/tests/bivalenttest/test/com/android/ravenwoodtest/bivalenttest/compat/RavenwoodCompatFrameworkTest.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.ravenwoodtest.bivalenttest.compat
+
+import android.app.compat.CompatChanges
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.internal.ravenwood.RavenwoodEnvironment.CompatIdsForTest
+import org.junit.Assert
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class RavenwoodCompatFrameworkTest {
+ @Test
+ fun testEnabled() {
+ Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_1))
+ }
+
+ @Test
+ fun testDisabled() {
+ Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_2))
+ }
+
+ @Test
+ fun testEnabledAfterSForUApps() {
+ Assert.assertTrue(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_3))
+ }
+
+ @Test
+ fun testEnabledAfterUForUApps() {
+ Assert.assertFalse(CompatChanges.isChangeEnabled(CompatIdsForTest.TEST_COMPAT_ID_4))
+ }
+}
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
index 02d10732245d..f94b98bc1fb8 100644
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerConfigValidationTest.java
@@ -24,6 +24,7 @@ import android.platform.test.ravenwood.RavenwoodRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
+import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TestRule;
@@ -32,6 +33,10 @@ import org.junit.runner.RunWith;
/**
* Test for @Config field extraction and validation.
+ *
+ * TODO(b/377765941) Most of the tests here will be obsolete and deleted with b/377765941, but
+ * some of the tests may need to be re-implemented one way or another. (e.g. the package name
+ * test.) Until that happens, we'll keep all tests here but add an {@code @Ignore} instead.
*/
@NoRavenizer // This class shouldn't be executed with RavenwoodAwareTestRunner.
public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase {
@@ -59,6 +64,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,0,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class ConfigInBaseClassTest extends ConfigInBaseClass {
@Test
public void test() {
@@ -83,6 +89,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,0,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class ConfigOverridingTest extends ConfigInBaseClass {
static String PACKAGE_NAME_OVERRIDE = "com.ConfigOverridingTest";
@@ -376,6 +383,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,0,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class RuleInBaseClassSuccessTest extends RuleInBaseClass {
@Test
@@ -437,6 +445,7 @@ public class RavenwoodRunnerConfigValidationTest extends RavenwoodRunnerTestBase
testRunFinished: 1,1,0,0
""")
// CHECKSTYLE:ON
+ @Ignore // Package name is no longer set via config.
public static class RuleWithDifferentTypeInBaseClassSuccessTest extends RuleWithDifferentTypeInBaseClass {
@Test
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
index f7a2198a9bc4..0e3d053e90b1 100644
--- a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/runnercallbacktests/RavenwoodRunnerTestBase.java
@@ -25,6 +25,8 @@ import android.util.Log;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
+
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.Description;
import org.junit.runner.JUnitCore;
@@ -103,6 +105,7 @@ public abstract class RavenwoodRunnerTestBase {
var thisClass = this.getClass();
var ret = Arrays.stream(thisClass.getNestMembers())
.filter((c) -> c.getAnnotation(Expected.class) != null)
+ .filter((c) -> c.getAnnotation(Ignore.class) == null)
.toArray(Class[]::new);
assertThat(ret.length).isGreaterThan(0);
diff --git a/ravenwood/tests/runtime-test/Android.bp b/ravenwood/tests/runtime-test/Android.bp
index 0c0df1f993aa..c3520031ea7d 100644
--- a/ravenwood/tests/runtime-test/Android.bp
+++ b/ravenwood/tests/runtime-test/Android.bp
@@ -9,7 +9,7 @@ package {
android_ravenwood_test {
name: "RavenwoodRuntimeTest",
-
+ target_sdk_version: "34",
libs: [
"ravenwood-helper-runtime",
],
diff --git a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
index 52bf92e25f19..eeb71100cd9d 100644
--- a/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
+++ b/ravenwood/tests/services-test/test/com/android/ravenwoodtest/servicestest/RavenwoodServicesTest.java
@@ -24,7 +24,6 @@ import static org.junit.Assert.fail;
import android.content.Context;
import android.hardware.SerialManager;
import android.hardware.SerialManagerInternal;
-import android.platform.test.annotations.DisabledOnRavenwood;
import android.platform.test.ravenwood.RavenwoodConfig;
import android.platform.test.ravenwood.RavenwoodConfig.Config;
@@ -70,7 +69,8 @@ public class RavenwoodServicesTest {
}
@Test
- @DisabledOnRavenwood(reason="AOSP is missing resources support")
+ @android.platform.test.annotations.DisabledOnRavenwood(
+ reason = "AOSP is missing resources support")
public void testSimple() {
// Verify that we can obtain a manager, and talk to the backend service, and that no
// serial ports are configured by default
diff --git a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
index 5d24c3aea728..39e0cf90698e 100644
--- a/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
+++ b/ravenwood/texts/ravenwood-annotation-allowed-classes.txt
@@ -366,3 +366,9 @@ com.android.server.utils.TimingsTraceAndSlog
android.os.IpcDataCache
android.app.PropertyInvalidatedCache
+
+android.app.compat.*
+com.android.server.compat.*
+com.android.internal.compat.*
+android.app.AppCompatCallbacks
+
diff --git a/ravenwood/texts/ravenwood-services-policies.txt b/ravenwood/texts/ravenwood-services-policies.txt
index cc2fa602b3c3..530e5c8f5986 100644
--- a/ravenwood/texts/ravenwood-services-policies.txt
+++ b/ravenwood/texts/ravenwood-services-policies.txt
@@ -1 +1,12 @@
# Ravenwood "policy" file for services.core.
+
+# Auto-generated from XSD
+class com.android.server.compat.config.Change keepclass
+class com.android.server.compat.config.Config keepclass
+class com.android.server.compat.config.XmlParser keepclass
+class com.android.server.compat.overrides.ChangeOverrides keepclass
+class com.android.server.compat.overrides.OverrideValue keepclass
+class com.android.server.compat.overrides.Overrides keepclass
+class com.android.server.compat.overrides.RawOverrideValue keepclass
+class com.android.server.compat.overrides.XmlParser keepclass
+class com.android.server.compat.overrides.XmlWriter keepclass \ No newline at end of file
diff --git a/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh b/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
index 3726ca972564..b389a67a8e4c 100755
--- a/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
+++ b/ravenwood/tools/hoststubgen/test-tiny-framework/diff-and-update-golden.sh
@@ -30,7 +30,7 @@ help() {
EOF
}
-source "${0%/*}"/../../common.sh
+source "${0%/*}"/../common.sh
SCRIPT_NAME="${0##*/}"
@@ -61,7 +61,6 @@ esac
done
shift $(($OPTIND - 1))
-
# Build the dump files, which are the input of this test.
run m dump-jar tiny-framework-dump-test
diff --git a/services/core/java/com/android/server/biometrics/BiometricService.java b/services/core/java/com/android/server/biometrics/BiometricService.java
index 0e81eb914697..c31a4fb3569d 100644
--- a/services/core/java/com/android/server/biometrics/BiometricService.java
+++ b/services/core/java/com/android/server/biometrics/BiometricService.java
@@ -95,6 +95,7 @@ import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Supplier;
/**
@@ -126,7 +127,7 @@ public class BiometricService extends SystemService {
IGateKeeperService mGateKeeper;
// Get and cache the available biometric authenticators and their associated info.
- final ArrayList<BiometricSensor> mSensors = new ArrayList<>();
+ final CopyOnWriteArrayList<BiometricSensor> mSensors = new CopyOnWriteArrayList<>();
@VisibleForTesting
BiometricStrengthController mBiometricStrengthController;
@@ -150,13 +151,13 @@ public class BiometricService extends SystemService {
@NonNull private final Set<Integer> mSensorsPendingInvalidation;
public static InvalidationTracker start(@NonNull Context context,
- @NonNull ArrayList<BiometricSensor> sensors,
- int userId, int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
+ @NonNull List<BiometricSensor> sensors, int userId,
+ int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
return new InvalidationTracker(context, sensors, userId, fromSensorId, clientCallback);
}
private InvalidationTracker(@NonNull Context context,
- @NonNull ArrayList<BiometricSensor> sensors, int userId,
+ @NonNull List<BiometricSensor> sensors, int userId,
int fromSensorId, @NonNull IInvalidationCallback clientCallback) {
mClientCallback = clientCallback;
mSensorsPendingInvalidation = new ArraySet<>();
@@ -692,7 +693,7 @@ public class BiometricService extends SystemService {
@android.annotation.EnforcePermission(android.Manifest.permission.USE_BIOMETRIC_INTERNAL)
@Override
- public synchronized void registerAuthenticator(int id, int modality,
+ public void registerAuthenticator(int id, int modality,
@Authenticators.Types int strength,
@NonNull IBiometricAuthenticator authenticator) {
diff --git a/services/core/java/com/android/server/biometrics/PreAuthInfo.java b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
index f085647c9676..645206a91c0a 100644
--- a/services/core/java/com/android/server/biometrics/PreAuthInfo.java
+++ b/services/core/java/com/android/server/biometrics/PreAuthInfo.java
@@ -174,10 +174,6 @@ class PreAuthInfo {
return BIOMETRIC_NO_HARDWARE;
}
- if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) {
- return BIOMETRIC_HARDWARE_NOT_DETECTED;
- }
-
final boolean wasStrongEnough =
Utils.isAtLeastStrength(sensor.oemStrength, requestedStrength);
final boolean isStrongEnough =
@@ -189,6 +185,10 @@ class PreAuthInfo {
return BIOMETRIC_INSUFFICIENT_STRENGTH;
}
+ if (sensor.modality == TYPE_FACE && biometricCameraManager.isAnyCameraUnavailable()) {
+ return BIOMETRIC_HARDWARE_NOT_DETECTED;
+ }
+
try {
if (!sensor.impl.isHardwareDetected(opPackageName)) {
return BIOMETRIC_HARDWARE_NOT_DETECTED;
diff --git a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
index 82d5d4d8141d..e8786be4d8e6 100644
--- a/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
+++ b/services/core/java/com/android/server/biometrics/sensors/BiometricScheduler.java
@@ -677,10 +677,11 @@ public class BiometricScheduler<T, U> {
* Start the timeout for the watchdog.
*/
public void startWatchdog() {
- if (mCurrentOperation == null) {
+ final BiometricSchedulerOperation operation = mCurrentOperation;
+ if (operation == null) {
+ Slog.e(TAG, "Current operation is null,no need to start watchdog");
return;
}
- final BiometricSchedulerOperation operation = mCurrentOperation;
mHandler.postDelayed(() -> {
if (operation == mCurrentOperation && !operation.isFinished()) {
Counter.logIncrement("biometric.value_scheduler_watchdog_triggered_count");
diff --git a/services/core/java/com/android/server/compat/CompatChange.java b/services/core/java/com/android/server/compat/CompatChange.java
index a40dd7919402..c3d88e3e6eb1 100644
--- a/services/core/java/com/android/server/compat/CompatChange.java
+++ b/services/core/java/com/android/server/compat/CompatChange.java
@@ -50,6 +50,7 @@ import java.util.concurrent.ConcurrentHashMap;
*
* <p>Note, this class is not thread safe so callers must ensure thread safety.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class CompatChange extends CompatibilityChangeInfo {
/**
diff --git a/services/core/java/com/android/server/compat/CompatConfig.java b/services/core/java/com/android/server/compat/CompatConfig.java
index 79025d00d128..e89f43bd7196 100644
--- a/services/core/java/com/android/server/compat/CompatConfig.java
+++ b/services/core/java/com/android/server/compat/CompatConfig.java
@@ -42,6 +42,7 @@ import com.android.internal.compat.CompatibilityOverridesToRemoveByPackageConfig
import com.android.internal.compat.CompatibilityOverridesToRemoveConfig;
import com.android.internal.compat.IOverrideValidator;
import com.android.internal.compat.OverrideAllowedState;
+import com.android.internal.ravenwood.RavenwoodEnvironment;
import com.android.server.compat.config.Change;
import com.android.server.compat.config.Config;
import com.android.server.compat.overrides.ChangeOverrides;
@@ -63,6 +64,7 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Predicate;
import javax.xml.datatype.DatatypeConfigurationException;
@@ -72,12 +74,16 @@ import javax.xml.datatype.DatatypeConfigurationException;
* <p>It stores the default configuration for each change, and any per-package overrides that have
* been configured.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
final class CompatConfig {
private static final String TAG = "CompatConfig";
private static final String APP_COMPAT_DATA_DIR = "/data/misc/appcompat";
private static final String STATIC_OVERRIDES_PRODUCT_DIR = "/product/etc/appcompat";
private static final String OVERRIDES_FILE = "compat_framework_overrides.xml";
+ private static final String APP_COMPAT_DATA_DIR_RAVENWOOD = "/ravenwood-data/";
+ private static final String OVERRIDES_FILE_RAVENWOOD = "compat-config.xml";
+
private final ConcurrentHashMap<Long, CompatChange> mChanges = new ConcurrentHashMap<>();
private final OverrideValidatorImpl mOverrideValidator;
@@ -98,19 +104,32 @@ final class CompatConfig {
static CompatConfig create(AndroidBuildClassifier androidBuildClassifier, Context context) {
CompatConfig config = new CompatConfig(androidBuildClassifier, context);
- config.initConfigFromLib(Environment.buildPath(
+ config.loadConfigFiles();
+ config.initOverrides();
+ config.invalidateCache();
+ return config;
+ }
+
+ @android.ravenwood.annotation.RavenwoodReplace
+ private void loadConfigFiles() {
+ initConfigFromLib(Environment.buildPath(
Environment.getRootDirectory(), "etc", "compatconfig"));
- config.initConfigFromLib(Environment.buildPath(
+ initConfigFromLib(Environment.buildPath(
Environment.getRootDirectory(), "system_ext", "etc", "compatconfig"));
List<ApexManager.ActiveApexInfo> apexes = ApexManager.getInstance().getActiveApexInfos();
for (ApexManager.ActiveApexInfo apex : apexes) {
- config.initConfigFromLib(Environment.buildPath(
+ initConfigFromLib(Environment.buildPath(
apex.apexDirectory, "etc", "compatconfig"));
}
- config.initOverrides();
- config.invalidateCache();
- return config;
+ }
+
+ @SuppressWarnings("unused")
+ private void loadConfigFiles$ravenwood() {
+ final var configDir = new File(
+ RavenwoodEnvironment.getInstance().getRavenwoodRuntimePath()
+ + APP_COMPAT_DATA_DIR_RAVENWOOD);
+ initConfigFromLib(configDir, (file) -> file.getName().endsWith(OVERRIDES_FILE_RAVENWOOD));
}
/**
@@ -678,12 +697,25 @@ final class CompatConfig {
return changeInfos;
}
+ /**
+ * Load all config files in a given directory.
+ */
void initConfigFromLib(File libraryDir) {
+ initConfigFromLib(libraryDir, (file) -> true);
+ }
+
+ /**
+ * Load config files in a given directory, but only the ones that match {@code includingFilter}.
+ */
+ void initConfigFromLib(File libraryDir, Predicate<File> includingFilter) {
if (!libraryDir.exists() || !libraryDir.isDirectory()) {
Slog.d(TAG, "No directory " + libraryDir + ", skipping");
return;
}
for (File f : libraryDir.listFiles()) {
+ if (!includingFilter.test(f)) {
+ continue;
+ }
Slog.d(TAG, "Found a config file: " + f.getPath());
//TODO(b/138222363): Handle duplicate ids across config files.
readConfig(f);
diff --git a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
index e3b6d032b7f0..362c69797161 100644
--- a/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
+++ b/services/core/java/com/android/server/compat/OverrideValidatorImpl.java
@@ -45,6 +45,7 @@ import com.android.internal.compat.OverrideAllowedState;
/**
* Implementation of the policy for allowing compat change overrides.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class OverrideValidatorImpl extends IOverrideValidator.Stub {
private AndroidBuildClassifier mAndroidBuildClassifier;
diff --git a/services/core/java/com/android/server/compat/PlatformCompat.java b/services/core/java/com/android/server/compat/PlatformCompat.java
index df49affa4d6f..2186e2a397c5 100644
--- a/services/core/java/com/android/server/compat/PlatformCompat.java
+++ b/services/core/java/com/android/server/compat/PlatformCompat.java
@@ -36,6 +36,7 @@ import android.content.pm.PackageManagerInternal;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
+import android.os.PermissionEnforcer;
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -65,6 +66,7 @@ import java.util.Map;
/**
* System server internal API for gating and reporting compatibility changes.
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class PlatformCompat extends IPlatformCompat.Stub {
private static final String TAG = "Compatibility";
@@ -75,6 +77,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
private final AndroidBuildClassifier mBuildClassifier;
public PlatformCompat(Context context) {
+ super(PermissionEnforcer.fromContext(context));
mContext = context;
mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
mBuildClassifier = new AndroidBuildClassifier();
@@ -84,6 +87,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
@VisibleForTesting
PlatformCompat(Context context, CompatConfig compatConfig,
AndroidBuildClassifier buildClassifier) {
+ super(PermissionEnforcer.fromContext(context));
mContext = context;
mChangeReporter = new ChangeReporter(ChangeReporter.SOURCE_SYSTEM_SERVER);
mCompatConfig = compatConfig;
@@ -492,6 +496,7 @@ public class PlatformCompat extends IPlatformCompat.Stub {
packageName, 0, Process.myUid(), userId);
}
+ @android.ravenwood.annotation.RavenwoodReplace
private void killPackage(String packageName) {
int uid = LocalServices.getService(PackageManagerInternal.class).getPackageUid(packageName,
0, UserHandle.myUserId());
@@ -505,6 +510,13 @@ public class PlatformCompat extends IPlatformCompat.Stub {
killUid(UserHandle.getAppId(uid));
}
+ @SuppressWarnings("unused")
+ private void killPackage$ravenwood(String packageName) {
+ // TODO Maybe crash if the package is the self.
+ Slog.w(TAG, "killPackage() is ignored on Ravenwood: packageName=" + packageName);
+ }
+
+ @android.ravenwood.annotation.RavenwoodReplace
private void killUid(int appId) {
final long identity = Binder.clearCallingIdentity();
try {
@@ -519,6 +531,12 @@ public class PlatformCompat extends IPlatformCompat.Stub {
}
}
+ @SuppressWarnings("unused")
+ private void killUid$ravenwood(int appId) {
+ // TODO Maybe crash if the UID is the self.
+ Slog.w(TAG, "killUid() is ignored on Ravenwood: appId=" + appId);
+ }
+
private void checkAllCompatOverridesAreOverridable(Collection<Long> changeIds) {
for (Long changeId : changeIds) {
if (isKnownChangeId(changeId) && !mCompatConfig.isOverridable(changeId)) {
diff --git a/services/core/java/com/android/server/compat/PlatformCompatNative.java b/services/core/java/com/android/server/compat/PlatformCompatNative.java
index 5d7af650db0b..7a3feb515706 100644
--- a/services/core/java/com/android/server/compat/PlatformCompatNative.java
+++ b/services/core/java/com/android/server/compat/PlatformCompatNative.java
@@ -23,6 +23,7 @@ import com.android.internal.compat.IPlatformCompatNative;
/**
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public class PlatformCompatNative extends IPlatformCompatNative.Stub {
private final PlatformCompat mPlatformCompat;
diff --git a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java
index e8762a3e935c..0ec68792a886 100644
--- a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java
+++ b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesParser.java
@@ -46,6 +46,7 @@ import java.util.regex.Pattern;
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
final class AppCompatOverridesParser {
/**
* Flag for specifying all compat change IDs owned by a namespace. See {@link
diff --git a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
index fe002ce00d32..8637d2dfe565 100644
--- a/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
+++ b/services/core/java/com/android/server/compat/overrides/AppCompatOverridesService.java
@@ -68,6 +68,7 @@ import java.util.Set;
*
* @hide
*/
+@android.ravenwood.annotation.RavenwoodKeepWholeClass
public final class AppCompatOverridesService {
private static final String TAG = "AppCompatOverridesService";
diff --git a/services/core/java/com/android/server/display/OWNERS b/services/core/java/com/android/server/display/OWNERS
index 9439eaa3a4c6..9f0cabfd9208 100644
--- a/services/core/java/com/android/server/display/OWNERS
+++ b/services/core/java/com/android/server/display/OWNERS
@@ -1,5 +1,4 @@
michaelwr@google.com
-dangittik@google.com
hackbod@google.com
ogunwale@google.com
santoscordon@google.com
@@ -7,5 +6,6 @@ flc@google.com
wilczynskip@google.com
brup@google.com
petsjonkin@google.com
+olb@google.com
per-file ColorDisplayService.java=christyfranks@google.com
diff --git a/services/core/java/com/android/server/display/color/TintController.java b/services/core/java/com/android/server/display/color/TintController.java
index 716661dd6c3c..68dc80fa51c8 100644
--- a/services/core/java/com/android/server/display/color/TintController.java
+++ b/services/core/java/com/android/server/display/color/TintController.java
@@ -19,6 +19,7 @@ package com.android.server.display.color;
import android.animation.ValueAnimator;
import android.content.Context;
import android.util.Slog;
+import com.android.internal.annotations.GuardedBy;
import java.io.PrintWriter;
@@ -29,23 +30,33 @@ abstract class TintController {
*/
private static final long TRANSITION_DURATION = 3000L;
+ private final Object mLock = new Object();
+
+ @GuardedBy("mLock")
private ValueAnimator mAnimator;
+ @GuardedBy("mLock")
private Boolean mIsActivated;
public ValueAnimator getAnimator() {
- return mAnimator;
+ synchronized (mLock) {
+ return mAnimator;
+ }
}
public void setAnimator(ValueAnimator animator) {
- mAnimator = animator;
+ synchronized (mLock) {
+ mAnimator = animator;
+ }
}
/**
* Cancel the animator if it's still running.
*/
public void cancelAnimator() {
- if (mAnimator != null) {
- mAnimator.cancel();
+ synchronized (mLock) {
+ if (mAnimator != null) {
+ mAnimator.cancel();
+ }
}
}
@@ -53,22 +64,30 @@ abstract class TintController {
* End the animator if it's still running, jumping to the end state.
*/
public void endAnimator() {
- if (mAnimator != null) {
- mAnimator.end();
- mAnimator = null;
+ synchronized (mLock) {
+ if (mAnimator != null) {
+ mAnimator.end();
+ mAnimator = null;
+ }
}
}
public void setActivated(Boolean isActivated) {
- mIsActivated = isActivated;
+ synchronized (mLock) {
+ mIsActivated = isActivated;
+ }
}
public boolean isActivated() {
- return mIsActivated != null && mIsActivated;
+ synchronized (mLock) {
+ return mIsActivated != null && mIsActivated;
+ }
}
public boolean isActivatedStateNotSet() {
- return mIsActivated == null;
+ synchronized (mLock) {
+ return mIsActivated == null;
+ }
}
public long getTransitionDurationMilliseconds() {
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index bb4ae96da53b..a132876b72a3 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -46,7 +46,6 @@ import android.util.Slog;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.server.LocalServices;
-import com.android.server.integrity.model.RuleMetadata;
import java.io.File;
import java.nio.charset.StandardCharsets;
diff --git a/services/core/java/com/android/server/integrity/model/BitInputStream.java b/services/core/java/com/android/server/integrity/model/BitInputStream.java
deleted file mode 100644
index e7cc81eab26b..000000000000
--- a/services/core/java/com/android/server/integrity/model/BitInputStream.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-/** A wrapper class for reading a stream of bits.
- *
- * <p>Note: this class reads from underlying stream byte-by-byte. It is advised to apply buffering
- * to underlying streams.
- */
-public class BitInputStream {
-
- private long mBitsRead;
-
- private InputStream mInputStream;
-
- private byte mCurrentByte;
-
- public BitInputStream(InputStream inputStream) {
- mInputStream = inputStream;
- }
-
- /**
- * Read the next number of bits from the stream.
- *
- * @param numOfBits The number of bits to read.
- * @return The value read from the stream.
- */
- public int getNext(int numOfBits) throws IOException {
- int component = 0;
- int count = 0;
-
- while (count++ < numOfBits) {
- if (mBitsRead % 8 == 0) {
- mCurrentByte = getNextByte();
- }
- int offset = 7 - (int) (mBitsRead % 8);
-
- component <<= 1;
- component |= (mCurrentByte >>> offset) & 1;
-
- mBitsRead++;
- }
-
- return component;
- }
-
- /** Check if there are bits left in the stream. */
- public boolean hasNext() throws IOException {
- return mInputStream.available() > 0;
- }
-
- private byte getNextByte() throws IOException {
- return (byte) mInputStream.read();
- }
-}
diff --git a/services/core/java/com/android/server/integrity/model/BitOutputStream.java b/services/core/java/com/android/server/integrity/model/BitOutputStream.java
deleted file mode 100644
index 14b35fd016eb..000000000000
--- a/services/core/java/com/android/server/integrity/model/BitOutputStream.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import static com.android.server.integrity.model.ComponentBitSize.BYTE_BITS;
-
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Arrays;
-
-/** A wrapper class for writing a stream of bits. */
-public class BitOutputStream {
-
- private static final int BUFFER_SIZE = 4 * 1024;
-
- private int mNextBitIndex;
-
- private final OutputStream mOutputStream;
- private final byte[] mBuffer;
-
- public BitOutputStream(OutputStream outputStream) {
- mBuffer = new byte[BUFFER_SIZE];
- mNextBitIndex = 0;
- mOutputStream = outputStream;
- }
-
- /**
- * Set the next number of bits in the stream to value.
- *
- * @param numOfBits The number of bits used to represent the value.
- * @param value The value to convert to bits.
- */
- public void setNext(int numOfBits, int value) throws IOException {
- if (numOfBits <= 0) {
- return;
- }
-
- // optional: we can do some clever size checking to "OR" an entire segment of bits instead
- // of setting bits one by one, but it is probably not worth it.
- int nextBitMask = 1 << (numOfBits - 1);
- while (numOfBits-- > 0) {
- setNext((value & nextBitMask) != 0);
- nextBitMask >>>= 1;
- }
- }
-
- /**
- * Set the next bit in the stream to value.
- *
- * @param value The value to set the bit to
- */
- public void setNext(boolean value) throws IOException {
- int byteToWrite = mNextBitIndex / BYTE_BITS;
- if (byteToWrite == BUFFER_SIZE) {
- mOutputStream.write(mBuffer);
- reset();
- byteToWrite = 0;
- }
- if (value) {
- mBuffer[byteToWrite] |= 1 << (BYTE_BITS - 1 - (mNextBitIndex % BYTE_BITS));
- }
- mNextBitIndex++;
- }
-
- /** Set the next bit in the stream to true. */
- public void setNext() throws IOException {
- setNext(/* value= */ true);
- }
-
- /**
- * Flush the data written to the underlying {@link java.io.OutputStream}. Any unfinished bytes
- * will be padded with 0.
- */
- public void flush() throws IOException {
- int endByte = mNextBitIndex / BYTE_BITS;
- if (mNextBitIndex % BYTE_BITS != 0) {
- // If next bit is not the first bit of a byte, then mNextBitIndex / BYTE_BITS would be
- // the byte that includes already written bits. We need to increment it so this byte
- // gets written.
- endByte++;
- }
- mOutputStream.write(mBuffer, 0, endByte);
- reset();
- }
-
- /** Reset this output stream to start state. */
- private void reset() {
- mNextBitIndex = 0;
- Arrays.fill(mBuffer, (byte) 0);
- }
-}
diff --git a/services/core/java/com/android/server/integrity/model/ByteTrackedOutputStream.java b/services/core/java/com/android/server/integrity/model/ByteTrackedOutputStream.java
deleted file mode 100644
index ceed054e4a53..000000000000
--- a/services/core/java/com/android/server/integrity/model/ByteTrackedOutputStream.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import java.io.IOException;
-import java.io.OutputStream;
-
-/**
- * An output stream that tracks the total number written bytes since construction and allows
- * querying this value any time during the execution.
- *
- * <p>This class is used for constructing the rule indexing.
- */
-public class ByteTrackedOutputStream extends OutputStream {
-
- private int mWrittenBytesCount;
- private final OutputStream mOutputStream;
-
- public ByteTrackedOutputStream(OutputStream outputStream) {
- mWrittenBytesCount = 0;
- mOutputStream = outputStream;
- }
-
- @Override
- public void write(int b) throws IOException {
- mWrittenBytesCount++;
- mOutputStream.write(b);
- }
-
- /**
- * Writes the given bytes into the output stream provided in constructor and updates the total
- * number of written bytes.
- */
- @Override
- public void write(byte[] bytes) throws IOException {
- write(bytes, 0, bytes.length);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- mWrittenBytesCount += len;
- mOutputStream.write(b, off, len);
- }
-
- /** Returns the total number of bytes written into the output stream at the requested time. */
- public int getWrittenBytesCount() {
- return mWrittenBytesCount;
- }
-}
diff --git a/services/core/java/com/android/server/integrity/model/ComponentBitSize.java b/services/core/java/com/android/server/integrity/model/ComponentBitSize.java
deleted file mode 100644
index 94e6708c3038..000000000000
--- a/services/core/java/com/android/server/integrity/model/ComponentBitSize.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import android.content.integrity.Rule;
-
-/**
- * A helper class containing information about the binary representation of different {@link Rule}
- * components.
- */
-public final class ComponentBitSize {
- public static final int FORMAT_VERSION_BITS = 8;
-
- public static final int EFFECT_BITS = 3;
- public static final int KEY_BITS = 4;
- public static final int OPERATOR_BITS = 3;
- public static final int CONNECTOR_BITS = 2;
- public static final int SEPARATOR_BITS = 3;
- public static final int VALUE_SIZE_BITS = 8;
- public static final int IS_HASHED_BITS = 1;
-
- public static final int ATOMIC_FORMULA_START = 0;
- public static final int COMPOUND_FORMULA_START = 1;
- public static final int COMPOUND_FORMULA_END = 2;
- public static final int INSTALLER_ALLOWED_BY_MANIFEST_START = 3;
-
- public static final int DEFAULT_FORMAT_VERSION = 1;
- public static final int SIGNAL_BIT = 1;
-
- public static final int BYTE_BITS = 8;
-}
diff --git a/services/core/java/com/android/server/integrity/model/IndexingFileConstants.java b/services/core/java/com/android/server/integrity/model/IndexingFileConstants.java
deleted file mode 100644
index 0c4052adc3ed..000000000000
--- a/services/core/java/com/android/server/integrity/model/IndexingFileConstants.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-/** A helper class containing special indexing file constants. */
-public final class IndexingFileConstants {
- // We empirically experimented with different block sizes and identified that 50 is in the
- // optimal range of efficient computation.
- public static final int INDEXING_BLOCK_SIZE = 50;
-
- public static final String START_INDEXING_KEY = "START_KEY";
- public static final String END_INDEXING_KEY = "END_KEY";
-}
diff --git a/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java b/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java
deleted file mode 100644
index b0647fc46473..000000000000
--- a/services/core/java/com/android/server/integrity/model/IntegrityCheckResult.java
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import android.annotation.Nullable;
-import android.content.integrity.Rule;
-
-import java.util.Collections;
-import java.util.List;
-
-/**
- * A class encapsulating the result from the evaluation engine after evaluating rules against app
- * install metadata.
- *
- * <p>It contains the outcome effect (whether to allow or block the install), and the rule causing
- * that effect.
- */
-public final class IntegrityCheckResult {
-
- public enum Effect {
- ALLOW,
- DENY
- }
-
- private final Effect mEffect;
- private final List<Rule> mRuleList;
-
- private IntegrityCheckResult(Effect effect, @Nullable List<Rule> ruleList) {
- this.mEffect = effect;
- this.mRuleList = ruleList;
- }
-
- public Effect getEffect() {
- return mEffect;
- }
-
- public List<Rule> getMatchedRules() {
- return mRuleList;
- }
-
- /**
- * Create an ALLOW evaluation outcome.
- *
- * @return An evaluation outcome with ALLOW effect and no rule.
- */
- public static IntegrityCheckResult allow() {
- return new IntegrityCheckResult(Effect.ALLOW, Collections.emptyList());
- }
-
- /**
- * Create an ALLOW evaluation outcome.
- *
- * @return An evaluation outcome with ALLOW effect and rule causing that effect.
- */
- public static IntegrityCheckResult allow(List<Rule> ruleList) {
- return new IntegrityCheckResult(Effect.ALLOW, ruleList);
- }
-
- /**
- * Create a DENY evaluation outcome.
- *
- * @param ruleList All valid rules that cause the DENY effect.
- * @return An evaluation outcome with DENY effect and rule causing that effect.
- */
- public static IntegrityCheckResult deny(List<Rule> ruleList) {
- return new IntegrityCheckResult(Effect.DENY, ruleList);
- }
-
- /** Returns true when the {@code mEffect} is caused by an app certificate mismatch. */
- public boolean isCausedByAppCertRule() {
- return mRuleList.stream().anyMatch(rule -> rule.getFormula().isAppCertificateFormula());
- }
-
- /** Returns true when the {@code mEffect} is caused by an installer rule. */
- public boolean isCausedByInstallerRule() {
- return mRuleList.stream().anyMatch(rule -> rule.getFormula().isInstallerFormula());
- }
-
-}
diff --git a/services/core/java/com/android/server/integrity/model/RuleMetadata.java b/services/core/java/com/android/server/integrity/model/RuleMetadata.java
deleted file mode 100644
index 6b582ae7b5f2..000000000000
--- a/services/core/java/com/android/server/integrity/model/RuleMetadata.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import android.annotation.Nullable;
-
-/** Data class containing relevant metadata associated with a rule set. */
-public class RuleMetadata {
-
- private final String mRuleProvider;
- private final String mVersion;
-
- public RuleMetadata(String ruleProvider, String version) {
- mRuleProvider = ruleProvider;
- mVersion = version;
- }
-
- @Nullable
- public String getRuleProvider() {
- return mRuleProvider;
- }
-
- @Nullable
- public String getVersion() {
- return mVersion;
- }
-}
diff --git a/services/core/java/com/android/server/location/contexthub/OWNERS b/services/core/java/com/android/server/location/contexthub/OWNERS
index c62e3237e487..6536ca084421 100644
--- a/services/core/java/com/android/server/location/contexthub/OWNERS
+++ b/services/core/java/com/android/server/location/contexthub/OWNERS
@@ -1,3 +1,4 @@
bduddie@google.com
+arthuri@google.com
matthewsedam@google.com
stange@google.com
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index ada812e58e77..d99fc3eda5d3 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -235,6 +235,7 @@ final class DefaultPermissionGrantPolicy {
NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.BLUETOOTH_SCAN);
NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.UWB_RANGING);
NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.NEARBY_WIFI_DEVICES);
+ NEARBY_DEVICES_PERMISSIONS.add(Manifest.permission.RANGING);
}
private static final Set<String> NOTIFICATION_PERMISSIONS = new ArraySet<>();
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 89ddb3fd3e88..a17de65bf7f5 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -824,7 +824,8 @@ class WindowOrganizerController extends IWindowOrganizerController.Stub
if (windowingMode > -1) {
if (mService.isInLockTaskMode()
- && WindowConfiguration.inMultiWindowMode(windowingMode)) {
+ && WindowConfiguration.inMultiWindowMode(windowingMode)
+ && !container.isEmbedded()) {
Slog.w(TAG, "Dropping unsupported request to set multi-window windowing mode"
+ " during locked task mode.");
return effects;
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 52a2fd6e4955..688312e7e004 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -2968,7 +2968,10 @@ public final class SystemServer implements Dumpable {
if (com.android.ranging.flags.Flags.rangingStackEnabled()) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_UWB)
|| context.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_WIFI_RTT)) {
+ PackageManager.FEATURE_WIFI_RTT)
+ || (com.android.ranging.flags.Flags.rangingCsEnabled()
+ && context.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_BLUETOOTH_LE_CHANNEL_SOUNDING))) {
t.traceBegin("RangingService");
// TODO: b/375264320 - Remove after RELEASE_RANGING_STACK is ramped to next.
try {
diff --git a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
index 4e868887ea1b..e307e529a40b 100644
--- a/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
+++ b/services/profcollect/src/com/android/server/profcollect/ProfcollectForwardingService.java
@@ -144,6 +144,10 @@ public final class ProfcollectForwardingService extends SystemService {
public void onBootPhase(int phase) {
if (phase == PHASE_SYSTEM_SERVICES_READY) {
UsbManager usbManager = getContext().getSystemService(UsbManager.class);
+ if (usbManager == null) {
+ mAdbActive = false;
+ return;
+ }
mAdbActive = ((usbManager.getCurrentFunctions() & UsbManager.FUNCTION_ADB) == 1);
Log.d(LOG_TAG, "ADB is " + mAdbActive + " on system startup");
}
diff --git a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
index 08155c7b3f98..9772ef929eae 100644
--- a/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
+++ b/services/tests/VpnTests/java/com/android/server/connectivity/VpnTest.java
@@ -2380,10 +2380,14 @@ public class VpnTest extends VpnTestBase {
@Test
public void doTestMigrateIkeSession_Vcn() throws Exception {
final int expectedKeepalive = 2097; // Any unlikely number will do
- final NetworkCapabilities vcnNc = new NetworkCapabilities.Builder()
- .addTransportType(TRANSPORT_CELLULAR)
- .setTransportInfo(new VcnTransportInfo(TEST_SUB_ID, expectedKeepalive))
- .build();
+ final NetworkCapabilities vcnNc =
+ new NetworkCapabilities.Builder()
+ .addTransportType(TRANSPORT_CELLULAR)
+ .setTransportInfo(
+ new VcnTransportInfo.Builder()
+ .setMinUdpPort4500NatTimeoutSeconds(expectedKeepalive)
+ .build())
+ .build();
final Ikev2VpnProfile ikev2VpnProfile = makeIkeV2VpnProfile(
true /* isAutomaticIpVersionSelectionEnabled */,
true /* isAutomaticNattKeepaliveTimerEnabled */,
diff --git a/services/tests/apexsystemservices/services/Android.bp b/services/tests/apexsystemservices/services/Android.bp
index 477ea4cdad37..70d84dcf6007 100644
--- a/services/tests/apexsystemservices/services/Android.bp
+++ b/services/tests/apexsystemservices/services/Android.bp
@@ -17,4 +17,5 @@ java_library {
],
visibility: ["//frameworks/base/services/tests/apexsystemservices:__subpackages__"],
apex_available: ["//apex_available:anyapex"],
+ compile_dex: true,
}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index d336c9962c17..c09886807884 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -149,21 +149,49 @@ android_test {
resource_zips: [":FrameworksServicesTests_apks_as_resources"],
}
-android_ravenwood_test {
- name: "FrameworksServicesTestsRavenwood",
+java_defaults {
+ name: "FrameworksServicesTestsRavenwood-defaults",
libs: [
"android.test.mock.stubs.system",
],
static_libs: [
"androidx.annotation_annotation",
"androidx.test.rules",
- "services.core",
"flag-junit",
],
+ auto_gen_config: true,
+}
+
+// Unit tests for UriGrantManager, running on ravenwood.
+// Note UriGrantManager does not support Ravenwood (yet). We're just running the original
+// unit tests as is on Ravenwood. So here, we use the original "services.core", because
+// "services.core.ravenwood" doesn't have the target code.
+// (Compare to FrameworksServicesTestsRavenwood_Compat, which does support Ravenwood.)
+android_ravenwood_test {
+ name: "FrameworksServicesTestsRavenwood_Uri",
+ defaults: ["FrameworksServicesTestsRavenwood-defaults"],
+ team: "trendy_team_ravenwood",
+ static_libs: [
+ "services.core",
+ ],
srcs: [
"src/com/android/server/uri/**/*.java",
],
- auto_gen_config: true,
+}
+
+// Unit tests for compat-framework.
+// Compat-framework does support Ravenwood, and it uses the ravenwood anottations,
+// so we link "services.core.ravenwood".
+android_ravenwood_test {
+ name: "FrameworksServicesTestsRavenwood_Compat",
+ defaults: ["FrameworksServicesTestsRavenwood-defaults"],
+ team: "trendy_team_ravenwood",
+ static_libs: [
+ "services.core.ravenwood",
+ ],
+ srcs: [
+ "src/com/android/server/compat/**/*.java",
+ ],
}
java_library {
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
index b40d7ee39a4c..67202174535c 100644
--- a/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
+++ b/services/tests/servicestests/src/com/android/server/biometrics/PreAuthInfoTest.java
@@ -20,6 +20,7 @@ import static android.app.admin.DevicePolicyManager.KEYGUARD_DISABLE_FEATURES_NO
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FACE;
import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRINT;
import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_HW_UNAVAILABLE;
+import static android.hardware.biometrics.BiometricManager.BIOMETRIC_ERROR_NO_HARDWARE;
import static com.android.server.biometrics.sensors.LockoutTracker.LOCKOUT_NONE;
@@ -55,6 +56,7 @@ public class PreAuthInfoTest {
@Rule
public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+ private static final int USER_ID = 0;
private static final int SENSOR_ID_FINGERPRINT = 0;
private static final int SENSOR_ID_FACE = 1;
private static final String TEST_PACKAGE_NAME = "PreAuthInfoTestPackage";
@@ -184,6 +186,20 @@ public class PreAuthInfoTest {
assertThat(preAuthInfo.eligibleSensors.get(0).modality).isEqualTo(TYPE_FINGERPRINT);
}
+ @Test
+ public void prioritizeStrengthErrorBeforeCameraUnavailableError() throws Exception {
+ final BiometricSensor sensor = getFaceSensorWithStrength(
+ BiometricManager.Authenticators.BIOMETRIC_WEAK);
+ final PromptInfo promptInfo = new PromptInfo();
+ promptInfo.setAuthenticators(BiometricManager.Authenticators.BIOMETRIC_STRONG);
+ promptInfo.setNegativeButtonText(TEST_PACKAGE_NAME);
+ final PreAuthInfo preAuthInfo = PreAuthInfo.create(mTrustManager, mDevicePolicyManager,
+ mSettingObserver, List.of(sensor), USER_ID , promptInfo, TEST_PACKAGE_NAME,
+ false /* checkDevicePolicyManager */, mContext, mBiometricCameraManager);
+
+ assertThat(preAuthInfo.getCanAuthenticateResult()).isEqualTo(BIOMETRIC_ERROR_NO_HARDWARE);
+ }
+
private BiometricSensor getFingerprintSensor() {
BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FINGERPRINT,
TYPE_FINGERPRINT, BiometricManager.Authenticators.BIOMETRIC_STRONG,
@@ -202,9 +218,10 @@ public class PreAuthInfoTest {
return sensor;
}
- private BiometricSensor getFaceSensor() {
+ private BiometricSensor getFaceSensorWithStrength(
+ @BiometricManager.Authenticators.Types int sensorStrength) {
BiometricSensor sensor = new BiometricSensor(mContext, SENSOR_ID_FACE, TYPE_FACE,
- BiometricManager.Authenticators.BIOMETRIC_STRONG, mFaceAuthenticator) {
+ sensorStrength, mFaceAuthenticator) {
@Override
boolean confirmationAlwaysRequired(int userId) {
return false;
@@ -218,4 +235,8 @@ public class PreAuthInfoTest {
return sensor;
}
+
+ private BiometricSensor getFaceSensor() {
+ return getFaceSensorWithStrength(BiometricManager.Authenticators.BIOMETRIC_STRONG);
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
index 36b163ec84b6..3d695a68f1f9 100644
--- a/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/CompatConfigTest.java
@@ -18,12 +18,12 @@ package com.android.server.compat;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.testng.Assert.assertThrows;
import android.app.compat.ChangeIdStateCache;
import android.app.compat.PackageOverride;
diff --git a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
index 9accd49bc392..79f0673d91bd 100644
--- a/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
+++ b/services/tests/servicestests/src/com/android/server/compat/PlatformCompatTest.java
@@ -18,6 +18,7 @@ package com.android.server.compat;
import static com.google.common.truth.Truth.assertThat;
+import static org.junit.Assert.assertThrows;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.never;
@@ -25,13 +26,15 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.internal.verification.VerificationModeFactory.times;
-import static org.testng.Assert.assertThrows;
import android.compat.Compatibility.ChangeConfig;
+import android.content.AttributionSource;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Build;
+import android.os.PermissionEnforcer;
+import android.permission.PermissionCheckerManager;
import androidx.test.runner.AndroidJUnit4;
@@ -77,6 +80,22 @@ public class PlatformCompatTest {
.thenReturn(-1);
when(mPackageManager.getApplicationInfo(eq(PACKAGE_NAME), anyInt()))
.thenThrow(new PackageManager.NameNotFoundException());
+
+ var allGrantingPermissionEnforcer = new PermissionEnforcer() {
+ @Override
+ protected int checkPermission(String permission, AttributionSource source) {
+ return PermissionCheckerManager.PERMISSION_GRANTED;
+ }
+
+ @Override
+ protected int checkPermission(String permission, int pid, int uid) {
+ return PermissionCheckerManager.PERMISSION_GRANTED;
+ }
+ };
+
+ when(mContext.getSystemService(eq(Context.PERMISSION_ENFORCER_SERVICE)))
+ .thenReturn(allGrantingPermissionEnforcer);
+
mCompatConfig = new CompatConfig(mBuildClassifier, mContext);
mPlatformCompat = new PlatformCompat(mContext, mCompatConfig, mBuildClassifier);
// Assume userdebug/eng non-final build
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
index 93aa10b9112f..fd221185bacf 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -68,7 +68,6 @@ import androidx.test.InstrumentationRegistry;
import com.android.internal.R;
import com.android.server.compat.PlatformCompat;
-import com.android.server.integrity.model.IntegrityCheckResult;
import com.android.server.testutils.TestUtils;
import org.junit.After;
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/ByteTrackedOutputStreamTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/ByteTrackedOutputStreamTest.java
deleted file mode 100644
index 57274bf13499..000000000000
--- a/services/tests/servicestests/src/com/android/server/integrity/model/ByteTrackedOutputStreamTest.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.io.ByteArrayOutputStream;
-
-@RunWith(JUnit4.class)
-public class ByteTrackedOutputStreamTest {
-
- @Test
- public void testConstructorStartsWithZeroBytesWritten() {
- ByteTrackedOutputStream byteTrackedOutputStream =
- new ByteTrackedOutputStream(new ByteArrayOutputStream());
-
- assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(0);
- }
-
- @Test
- public void testSuccessfulWriteAndValidateWrittenBytesCount_directFromByteArray()
- throws Exception {
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- ByteTrackedOutputStream byteTrackedOutputStream = new ByteTrackedOutputStream(outputStream);
-
- byte[] outputContent = "This is going to be outputed for tests.".getBytes();
- byteTrackedOutputStream.write(outputContent);
-
- assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(outputContent.length);
- assertThat(outputStream.toByteArray().length).isEqualTo(outputContent.length);
- }
-
- @Test
- public void testSuccessfulWriteAndValidateWrittenBytesCount_fromBitStream() throws Exception {
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- ByteTrackedOutputStream byteTrackedOutputStream = new ByteTrackedOutputStream(outputStream);
-
- BitOutputStream bitOutputStream = new BitOutputStream(byteTrackedOutputStream);
- bitOutputStream.setNext(/* numOfBits= */5, /* value= */1);
- bitOutputStream.flush();
-
- // Even though we wrote 5 bits, this will complete to 1 byte.
- assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(1);
-
- // Add a bit less than 2 bytes (10 bits).
- bitOutputStream.setNext(/* numOfBits= */10, /* value= */1);
- bitOutputStream.flush();
- assertThat(byteTrackedOutputStream.getWrittenBytesCount()).isEqualTo(3);
-
- assertThat(outputStream.toByteArray().length).isEqualTo(3);
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java b/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java
deleted file mode 100644
index d31ed689a7da..000000000000
--- a/services/tests/servicestests/src/com/android/server/integrity/model/IntegrityCheckResultTest.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.integrity.model;
-
-import static com.google.common.truth.Truth.assertThat;
-
-import android.content.integrity.AtomicFormula;
-import android.content.integrity.CompoundFormula;
-import android.content.integrity.Rule;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-import java.util.Arrays;
-import java.util.Collections;
-
-@RunWith(JUnit4.class)
-public class IntegrityCheckResultTest {
-
- @Test
- public void createAllowResult() {
- IntegrityCheckResult allowResult = IntegrityCheckResult.allow();
-
- assertThat(allowResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.ALLOW);
- assertThat(allowResult.getMatchedRules()).isEmpty();
- }
-
- @Test
- public void createAllowResultWithRule() {
- String packageName = "com.test.deny";
- Rule forceAllowRule =
- new Rule(
- new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
- packageName),
- Rule.FORCE_ALLOW);
-
- IntegrityCheckResult allowResult =
- IntegrityCheckResult.allow(Collections.singletonList(forceAllowRule));
-
- assertThat(allowResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.ALLOW);
- assertThat(allowResult.getMatchedRules()).containsExactly(forceAllowRule);
- }
-
- @Test
- public void createDenyResultWithRule() {
- String packageName = "com.test.deny";
- Rule failedRule =
- new Rule(
- new AtomicFormula.StringAtomicFormula(AtomicFormula.PACKAGE_NAME,
- packageName),
- Rule.DENY);
-
- IntegrityCheckResult denyResult =
- IntegrityCheckResult.deny(Collections.singletonList(failedRule));
-
- assertThat(denyResult.getEffect()).isEqualTo(IntegrityCheckResult.Effect.DENY);
- assertThat(denyResult.getMatchedRules()).containsExactly(failedRule);
- }
-
- @Test
- public void isDenyCausedByAppCertificate() {
- String packageName = "com.test.deny";
- String appCert = "app-cert";
- Rule failedRule =
- new Rule(
- new CompoundFormula(
- CompoundFormula.AND,
- Arrays.asList(
- new AtomicFormula.StringAtomicFormula(
- AtomicFormula.PACKAGE_NAME, packageName),
- new AtomicFormula.StringAtomicFormula(
- AtomicFormula.APP_CERTIFICATE, appCert))),
- Rule.DENY);
- Rule otherFailedRule =
- new Rule(
- new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE,
- AtomicFormula.EQ, 12),
- Rule.DENY);
-
- IntegrityCheckResult denyResult =
- IntegrityCheckResult.deny(Arrays.asList(failedRule, otherFailedRule));
-
- assertThat(denyResult.isCausedByAppCertRule()).isTrue();
- assertThat(denyResult.isCausedByInstallerRule()).isFalse();
- }
-
- @Test
- public void isDenyCausedByInstaller() {
- String packageName = "com.test.deny";
- String appCert = "app-cert";
- Rule failedRule =
- new Rule(
- new CompoundFormula(
- CompoundFormula.AND,
- Arrays.asList(
- new AtomicFormula.StringAtomicFormula(
- AtomicFormula.PACKAGE_NAME, packageName),
- new AtomicFormula.StringAtomicFormula(
- AtomicFormula.INSTALLER_CERTIFICATE, appCert))),
- Rule.DENY);
- Rule otherFailedRule =
- new Rule(
- new AtomicFormula.LongAtomicFormula(AtomicFormula.VERSION_CODE,
- AtomicFormula.EQ, 12),
- Rule.DENY);
-
- IntegrityCheckResult denyResult =
- IntegrityCheckResult.deny(Arrays.asList(failedRule, otherFailedRule));
-
- assertThat(denyResult.isCausedByAppCertRule()).isFalse();
- assertThat(denyResult.isCausedByInstallerRule()).isTrue();
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
index 24abc183cad1..f5494534716a 100644
--- a/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/uri/UriGrantsManagerServiceTest.java
@@ -61,7 +61,6 @@ import android.os.Process;
import android.os.UserHandle;
import android.platform.test.flag.junit.FlagsParameterization;
import android.platform.test.flag.junit.SetFlagsRule;
-import android.platform.test.ravenwood.RavenwoodRule;
import android.util.ArraySet;
import org.junit.Before;
@@ -77,9 +76,6 @@ import java.util.Set;
@RunWith(Parameterized.class)
public class UriGrantsManagerServiceTest {
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule();
-
/**
* Why this class needs to test all combinations of
* {@link android.security.Flags#FLAG_CONTENT_URI_PERMISSION_APIS}:
diff --git a/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java b/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java
index 611c51463246..fe66f738487d 100644
--- a/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java
+++ b/services/tests/servicestests/src/com/android/server/uri/UriPermissionTest.java
@@ -37,18 +37,13 @@ import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;
import android.os.SystemClock;
-import android.platform.test.ravenwood.RavenwoodRule;
import org.junit.Before;
-import org.junit.Rule;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
public class UriPermissionTest {
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule();
-
@Mock
private UriGrantsManagerInternal mService;