Merge "SuspendSepolicyTests: Use target device grep" into main
diff --git a/keystore2/OWNERS b/keystore2/OWNERS
new file mode 100644
index 0000000..f09d658
--- /dev/null
+++ b/keystore2/OWNERS
@@ -0,0 +1 @@
+file:platform/system/security:/keystore2/OWNERS
diff --git a/keystore2/aidl/Android.bp b/keystore2/aidl/Android.bp
index a88f0a3..31853ee 100644
--- a/keystore2/aidl/Android.bp
+++ b/keystore2/aidl/Android.bp
@@ -20,7 +20,7 @@
name: "android.system.keystore2",
vendor_available: true,
srcs: ["android/system/keystore2/*.aidl"],
- imports: ["android.hardware.security.keymint-V3"],
+ defaults: ["android.hardware.security.keymint-latest-defaults"],
stability: "vintf",
backend: {
java: {
@@ -56,16 +56,13 @@
},
],
- frozen: true,
+ frozen: false,
}
-// Note: This should always be one version ahead of the last frozen version
-latest_android_system_keystore = "android.system.keystore-V4"
-
aidl_interface_defaults {
- name: "latest_android_system_keystore_import_interface",
+ name: "android.system.keystore2-latest-defaults",
imports: [
- latest_android_system_keystore,
+ "android.system.keystore2-V5",
],
}
diff --git a/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/IKeystoreService.aidl b/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/IKeystoreService.aidl
index d2f03cf..0c292c8 100644
--- a/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/IKeystoreService.aidl
+++ b/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/IKeystoreService.aidl
@@ -47,4 +47,5 @@
void ungrant(in android.system.keystore2.KeyDescriptor key, in int granteeUid);
int getNumberOfEntries(in android.system.keystore2.Domain domain, in long nspace);
android.system.keystore2.KeyDescriptor[] listEntriesBatched(in android.system.keystore2.Domain domain, in long nspace, in @nullable String startingPastAlias);
+ byte[] getSupplementaryAttestationInfo(in android.hardware.security.keymint.Tag tag);
}
diff --git a/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/ResponseCode.aidl b/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/ResponseCode.aidl
index e1ff0bb..51dddf0 100644
--- a/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/ResponseCode.aidl
+++ b/keystore2/aidl/aidl_api/android.system.keystore2/current/android/system/keystore2/ResponseCode.aidl
@@ -55,4 +55,5 @@
OUT_OF_KEYS_TRANSIENT_ERROR = 25,
OUT_OF_KEYS_PERMANENT_ERROR = 26,
GET_ATTESTATION_APPLICATION_ID_FAILED = 27,
+ INFO_NOT_AVAILABLE = 28,
}
diff --git a/keystore2/aidl/android/system/keystore2/IKeystoreService.aidl b/keystore2/aidl/android/system/keystore2/IKeystoreService.aidl
index 9beac0a..666985c 100644
--- a/keystore2/aidl/android/system/keystore2/IKeystoreService.aidl
+++ b/keystore2/aidl/android/system/keystore2/IKeystoreService.aidl
@@ -17,14 +17,15 @@
package android.system.keystore2;
import android.hardware.security.keymint.SecurityLevel;
+import android.hardware.security.keymint.Tag;
import android.system.keystore2.Domain;
import android.system.keystore2.IKeystoreSecurityLevel;
import android.system.keystore2.KeyDescriptor;
import android.system.keystore2.KeyEntryResponse;
/**
- * `IKeystoreService` is the primary interface to Keystore. It provides
- * access simple database bound requests. Request that require interactions
+ * `IKeystoreService` is the primary interface to Keystore. It primarily provides
+ * access to simple database bound requests. Request that require interactions
* with a KeyMint backend are delegated to `IKeystoreSecurityLevel` which
* may be acquired through this interface as well.
*
@@ -246,4 +247,19 @@
KeyDescriptor[] listEntriesBatched(in Domain domain, in long nspace,
in @nullable String startingPastAlias);
+ /**
+ * Returns tag-specific info required to interpret a tag's attested value.
+ * Attested values themselves are located in the attestation certificate.
+ *
+ * The semantics of the return value is specific to the input tag:
+ *
+ * o Tag::MODULE_HASH: 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.
+ *
+ * ## Error conditions
+ * `ResponseCode::INVALID_ARGUMENT` if `tag` is not specified in the list above.
+ * `ResponseCode::INFO_NOT_AVAILABLE` if `IKeystoreService` does not have the requested info.
+ */
+ byte[] getSupplementaryAttestationInfo(in Tag tag);
}
diff --git a/keystore2/aidl/android/system/keystore2/ResponseCode.aidl b/keystore2/aidl/android/system/keystore2/ResponseCode.aidl
index 4fe7db3..0424f5b 100644
--- a/keystore2/aidl/android/system/keystore2/ResponseCode.aidl
+++ b/keystore2/aidl/android/system/keystore2/ResponseCode.aidl
@@ -137,4 +137,8 @@
*/
GET_ATTESTATION_APPLICATION_ID_FAILED = 27,
+ /**
+ * Indicates that some information is not available.
+ */
+ INFO_NOT_AVAILABLE = 28,
}
diff --git a/media/Android.bp b/media/Android.bp
index 5ba8985..07671fc 100644
--- a/media/Android.bp
+++ b/media/Android.bp
@@ -68,7 +68,6 @@
"aidl/android/media/audio/common/AudioOffloadInfo.aidl",
"aidl/android/media/audio/common/AudioOutputFlags.aidl",
"aidl/android/media/audio/common/AudioPlaybackRate.aidl",
- "aidl/android/media/audio/common/AudioPolicyForcedConfig.aidl",
"aidl/android/media/audio/common/AudioPolicyForceUse.aidl",
"aidl/android/media/audio/common/AudioPort.aidl",
"aidl/android/media/audio/common/AudioPortConfig.aidl",
@@ -83,6 +82,7 @@
"aidl/android/media/audio/common/AudioStreamType.aidl",
"aidl/android/media/audio/common/AudioUsage.aidl",
"aidl/android/media/audio/common/AudioUuid.aidl",
+ "aidl/android/media/audio/common/AudioVolumeGroupChangeEvent.aidl",
"aidl/android/media/audio/common/Boolean.aidl",
"aidl/android/media/audio/common/Byte.aidl",
"aidl/android/media/audio/common/ExtraAudioDescriptor.aidl",
@@ -340,3 +340,110 @@
latest_android_media_soundtrigger_types,
],
}
+
+aidl_interface {
+ name: "android.media.audio.eraser.types",
+ vendor_available: true,
+ host_supported: true,
+ flags: [
+ "-Werror",
+ "-Weverything",
+ ],
+ local_include_dir: "aidl",
+ srcs: [
+ "aidl/android/media/audio/eraser/Capability.aidl",
+ "aidl/android/media/audio/eraser/Classification.aidl",
+ "aidl/android/media/audio/eraser/ClassificationConfig.aidl",
+ "aidl/android/media/audio/eraser/ClassificationMetadata.aidl",
+ "aidl/android/media/audio/eraser/ClassificationMetadataList.aidl",
+ "aidl/android/media/audio/eraser/ClassifierCapability.aidl",
+ "aidl/android/media/audio/eraser/Configuration.aidl",
+ "aidl/android/media/audio/eraser/IEraserCallback.aidl",
+ "aidl/android/media/audio/eraser/Mode.aidl",
+ "aidl/android/media/audio/eraser/RemixerCapability.aidl",
+ "aidl/android/media/audio/eraser/SeparatorCapability.aidl",
+ "aidl/android/media/audio/eraser/SoundClassification.aidl",
+ ],
+ stability: "vintf",
+ backend: {
+ cpp: {
+ enabled: true,
+ },
+ java: {
+ sdk_version: "module_current",
+ },
+ },
+ imports: [
+ latest_android_media_audio_common_types,
+ ],
+ frozen: false,
+}
+
+// Note: This should always be one version ahead of the last frozen version
+latest_android_media_audio_eraser_types = "android.media.audio.eraser.types-V1"
+
+cc_defaults {
+ name: "latest_android_media_audio_eraser_types_cpp_shared",
+ shared_libs: [
+ latest_android_media_audio_eraser_types + "-cpp",
+ ],
+}
+
+cc_defaults {
+ name: "latest_android_media_audio_eraser_types_cpp_export_shared",
+ defaults: [
+ "latest_android_media_audio_eraser_types_cpp_shared",
+ ],
+ export_shared_lib_headers: [
+ latest_android_media_audio_eraser_types + "-cpp",
+ ],
+}
+
+cc_defaults {
+ name: "latest_android_media_audio_eraser_types_cpp_static",
+ static_libs: [
+ latest_android_media_audio_eraser_types + "-cpp",
+ ],
+}
+
+cc_defaults {
+ name: "latest_android_media_audio_eraser_types_cpp_export_static",
+ defaults: [
+ "latest_android_media_audio_eraser_types_cpp_static",
+ ],
+ export_static_lib_headers: [
+ latest_android_media_audio_eraser_types + "-cpp",
+ ],
+}
+
+cc_defaults {
+ name: "latest_android_media_audio_eraser_types_ndk_shared",
+ shared_libs: [
+ latest_android_media_audio_eraser_types + "-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "latest_android_media_audio_eraser_types_ndk_static",
+ static_libs: [
+ latest_android_media_audio_eraser_types + "-ndk",
+ ],
+}
+
+cc_defaults {
+ name: "latest_android_media_audio_eraser_types_cpp_target_shared",
+ target: {
+ android: {
+ shared_libs: [
+ latest_android_media_audio_eraser_types + "-cpp",
+ ],
+ },
+ },
+}
+
+aidl_interface_defaults {
+ name: "latest_android_media_audio_eraser_types_import_interface",
+ imports: [
+ latest_android_media_audio_eraser_types,
+ ],
+}
diff --git a/media/aidl/android/media/audio/common/AudioHalCapConfiguration.aidl b/media/aidl/android/media/audio/common/AudioHalCapConfiguration.aidl
index 6432d84..18d9df4 100644
--- a/media/aidl/android/media/audio/common/AudioHalCapConfiguration.aidl
+++ b/media/aidl/android/media/audio/common/AudioHalCapConfiguration.aidl
@@ -37,7 +37,7 @@
* └──────────────────────────┘ ┌───► │ │
* │ │ name │ │
* ┌──────────────────────────┐ │ ┌┼─rule │ │
- * │ AudioHalCapComain │ │ ││ parameterSettings[]───────────┼──┘
+ * │ AudioHalCapDomain │ │ ││ parameterSettings[]───────────┼──┘
* │ │ │ │└───────────────────────────────┘
* ┌──►name │ │ │
* │ │configurations[]──────────┼─┘ │┌───────────────────────────────┐
diff --git a/media/aidl/android/media/audio/common/AudioHalCapCriterionV2.aidl b/media/aidl/android/media/audio/common/AudioHalCapCriterionV2.aidl
index b131358..2416bca 100644
--- a/media/aidl/android/media/audio/common/AudioHalCapCriterionV2.aidl
+++ b/media/aidl/android/media/audio/common/AudioHalCapCriterionV2.aidl
@@ -20,7 +20,6 @@
import android.media.audio.common.AudioDeviceDescription;
import android.media.audio.common.AudioMode;
import android.media.audio.common.AudioPolicyForceUse;
-import android.media.audio.common.AudioPolicyForcedConfig;
/**
* AudioHalCapCriterion is a wrapper for a CriterionType and its default value.
@@ -36,6 +35,7 @@
* bitfield, it can have several values). Rules expected on inclusive or exclusive will be
* different.
*/
+ @Backing(type="byte")
@VintfStability
enum LogicalDisjunction {
EXCLUSIVE = 0,
@@ -47,12 +47,13 @@
*/
@VintfStability
parcelable ForceConfigForUse {
- /** Force usage addressed by this criterion. */
- AudioPolicyForceUse forceUse = AudioPolicyForceUse.MEDIA;
/** List of supported value by this criterion. */
- AudioPolicyForcedConfig[] values;
- /** Default configuration applied if none is provided. */
- AudioPolicyForcedConfig defaultValue = AudioPolicyForcedConfig.NONE;
+ AudioPolicyForceUse[] values;
+ /**
+ * Default configuration applied if none is provided. This is the default-initialized
+ * value of 'AudioPolicyForceUse' which is 'forMedia = NONE'.
+ */
+ AudioPolicyForceUse defaultValue;
/** Logic followed by this criterion, only one value at given time. */
LogicalDisjunction logic = LogicalDisjunction.EXCLUSIVE;
}
@@ -69,6 +70,10 @@
/** Logic followed by this criterion, only one value at given time. */
LogicalDisjunction logic = LogicalDisjunction.EXCLUSIVE;
}
+ /**
+ * Available device type criterion. It is used to force routing when an input or
+ * output device of a certain type is available.
+ */
@VintfStability
parcelable AvailableDevices {
/** List if supported values (aka audio devices) by this criterion. */
@@ -76,6 +81,10 @@
/** Logic followed by this criterion, multiple devices can be selected/available. */
LogicalDisjunction logic = LogicalDisjunction.INCLUSIVE;
}
+ /**
+ * Available device with a certain address criterion. It is used to force routing
+ * when an input or output device at the certain address is available.
+ */
@VintfStability
parcelable AvailableDevicesAddresses {
/** List if supported values (aka audio device addresses) by this criterion. */
@@ -83,22 +92,11 @@
/** Logic followed by this criterion, multiple device addresses can be available. */
LogicalDisjunction logic = LogicalDisjunction.INCLUSIVE;
}
+
AvailableDevices availableInputDevices;
AvailableDevices availableOutputDevices;
AvailableDevicesAddresses availableInputDevicesAddresses;
AvailableDevicesAddresses availableOutputDevicesAddresses;
TelephonyMode telephonyMode;
ForceConfigForUse forceConfigForUse;
-
- /**
- * Supported criterion types for Configurable Audio Policy Engine.
- */
- @VintfStability
- union Type {
- AudioDeviceDescription availableDevicesType;
- AudioDeviceAddress availableDevicesAddressesType;
- AudioMode telephonyModeType;
- AudioPolicyForcedConfig forcedConfigType;
- }
- Type type;
}
diff --git a/media/aidl/android/media/audio/common/AudioHalCapDomain.aidl b/media/aidl/android/media/audio/common/AudioHalCapDomain.aidl
index 6b9196c..4e79304 100644
--- a/media/aidl/android/media/audio/common/AudioHalCapDomain.aidl
+++ b/media/aidl/android/media/audio/common/AudioHalCapDomain.aidl
@@ -28,8 +28,7 @@
@VintfStability
parcelable AudioHalCapDomain {
/**
- * Name of the configurable domain. It must be unique for the given instance of parameter
- * framework.
+ * Name of the configurable domain. It must be unique within the CAP configuration.
*/
@utf8InCpp String name;
/**
diff --git a/media/aidl/android/media/audio/common/AudioHalCapParameter.aidl b/media/aidl/android/media/audio/common/AudioHalCapParameter.aidl
index 665625e..f26afcd 100644
--- a/media/aidl/android/media/audio/common/AudioHalCapParameter.aidl
+++ b/media/aidl/android/media/audio/common/AudioHalCapParameter.aidl
@@ -23,44 +23,64 @@
import android.media.audio.common.AudioStreamType;
/**
- * Defines the audio Cap Engine Parameters expected to be controlled by the configurable engine.
+ * Defines the audio CAP Engine Parameters expected to be controlled by the configurable engine.
* These parameters deal with:
- * Volume Profile: for volume curve selection (e.g. dtmf follows call curves during call).
* Output/Input device selection for a given strategy based on:
- * -the type (each device will be a bit in a bitfield, allowing to select multiple devices).
- * -the address
+ * -the type (each device will be a bit in a bitfield, allowing to select multiple devices);
+ * -the address.
+ * Volume Profile: for volume curve selection (e.g. dtmf follows call curves during call).
*
* {@hide}
*/
@VintfStability
union AudioHalCapParameter {
@VintfStability
+ parcelable StrategyDevice {
+ AudioDeviceDescription device;
+ // AudioHalProductStrategy.id
+ int id = AudioProductStrategyType.SYS_RESERVED_NONE;
+ /**
+ * Specifies whether the device is selected or not selected in the configuration.
+ */
+ boolean isSelected;
+ }
+ @VintfStability
+ parcelable InputSourceDevice {
+ AudioDeviceDescription device;
+ AudioSource inputSource = AudioSource.DEFAULT;
+ /**
+ * Specifies whether the device is selected or not selected in the configuration.
+ */
+ boolean isSelected;
+ }
+ @VintfStability
parcelable StrategyDeviceAddress {
AudioDeviceAddress deviceAddress;
// AudioHalProductStrategy.id
int id = AudioProductStrategyType.SYS_RESERVED_NONE;
}
@VintfStability
- parcelable StrategyDevice {
- AudioDeviceDescription device;
- // AudioHalProductStrategy.id
- int id = AudioProductStrategyType.SYS_RESERVED_NONE;
- boolean isSelected;
- }
- @VintfStability
- parcelable InputSourceDevice {
- AudioDeviceDescription device;
- AudioSource inputSource = AudioSource.DEFAULT;
- boolean isSelected;
- }
- @VintfStability
parcelable StreamVolumeProfile {
AudioStreamType stream = AudioStreamType.INVALID;
AudioStreamType profile = AudioStreamType.INVALID;
}
+ /**
+ * Parameter allowing to choose a device by its type and associate
+ * the choice with a product strategy.
+ */
StrategyDevice selectedStrategyDevice;
- StrategyDeviceAddress strategyDeviceAddress;
+ /**
+ * Parameter allowing to choose an input device by and source type.
+ */
InputSourceDevice selectedInputSourceDevice;
+ /**
+ * Parameter allowing to choose a particular device by its address and
+ * associate the choice with a product strategy.
+ */
+ StrategyDeviceAddress strategyDeviceAddress;
+ /**
+ * Parameter dealing with volume curve selection.
+ */
StreamVolumeProfile streamVolumeProfile;
}
diff --git a/media/aidl/android/media/audio/common/AudioHalCapRule.aidl b/media/aidl/android/media/audio/common/AudioHalCapRule.aidl
index aa52796..8f98db8 100644
--- a/media/aidl/android/media/audio/common/AudioHalCapRule.aidl
+++ b/media/aidl/android/media/audio/common/AudioHalCapRule.aidl
@@ -27,9 +27,9 @@
* -type of criterion:
* -inclusive -> match rules are "Includes" or "Excludes"
* -exclusive -> match rules are "Is" or "IsNot" aka equal or different
- * -Name of the criterion must match the provided name in AudioHalCapCriterion
+ * -Name of the criterion must match the provided name in AudioHalCapCriterionV2
* -Value of the criterion must match the provided list of literal values from
- * AudioHalCapCriterionType
+ * associated AudioHalCapCriterionV2 values
* Example of rule:
* ALL
* ANY
@@ -105,14 +105,11 @@
parcelable CriterionRule {
MatchingRule matchingRule = MatchingRule.INVALID;
/*
- * Must be one of the name defined by {@see AudioHalCapCriterionV2}.
+ * Must be one of the names defined by {@see AudioHalCapCriterionV2}.
+ * By convention, when AudioHalCapCriterionV2 is used as a rule, the rule uses
+ * the first element of the 'values' field which must be a non-empty array.
*/
- AudioHalCapCriterionV2 criterion;
- /*
- * Must be one of the value defined by {@see AudioHalCapCriterionV2::Type}.
- * Must be one of the associated {@see AudioHalCapCriterionV2} values.
- */
- AudioHalCapCriterionV2.Type criterionTypeValue;
+ AudioHalCapCriterionV2 criterionAndValue;
}
/*
* Defines the AND or OR'ed logcal rule between provided criterion rules if any and provided
diff --git a/media/aidl/android/media/audio/common/AudioHalProductStrategy.aidl b/media/aidl/android/media/audio/common/AudioHalProductStrategy.aidl
index c3bc656..612db84 100644
--- a/media/aidl/android/media/audio/common/AudioHalProductStrategy.aidl
+++ b/media/aidl/android/media/audio/common/AudioHalProductStrategy.aidl
@@ -29,6 +29,15 @@
@JavaDerive(equals=true, toString=true)
@VintfStability
parcelable AudioHalProductStrategy {
+ @VintfStability
+ @Backing(type="int")
+ enum ZoneId {
+ /**
+ * Value indicating that there is no explicit zone associated to the product strategy
+ * It is the case for non-automotive products or for default zone for automotive.
+ */
+ DEFAULT = 0,
+ }
/**
* Defines the start of the vendor-defined product strategies
*/
@@ -55,4 +64,16 @@
* must not be null for any.
*/
@nullable @utf8InCpp String name;
+ /**
+ * Audio zone id can be used to independently manage audio routing and volume for different
+ * audio device configurations.
+ * In automotive for example, audio zone id can be used to route different user id to different
+ * audio zones. Thus providing independent audio routing and volume management for each user
+ * in the car.
+ * Note:
+ * 1/ Audio zone id must begin at DEFAULT and increment respectively from DEFAULT
+ * (i.e. DEFAULT + 1...).
+ * 2/ Audio zone id can be held by one or more product strategy(ies).
+ */
+ int zoneId = ZoneId.DEFAULT;
}
diff --git a/media/aidl/android/media/audio/common/AudioPolicyForceUse.aidl b/media/aidl/android/media/audio/common/AudioPolicyForceUse.aidl
index f20948c..4a67851 100644
--- a/media/aidl/android/media/audio/common/AudioPolicyForceUse.aidl
+++ b/media/aidl/android/media/audio/common/AudioPolicyForceUse.aidl
@@ -16,20 +16,92 @@
package android.media.audio.common;
/**
- * List of usages to be used in addition to forced config in order to force the audio routing.
+ * "Force Use" specifies high-level routing policies which are used
+ * in order to override the usual routing behavior.
*
* {@hide}
*/
-@Backing(type="int")
@SuppressWarnings(value={"redundant-name"})
@VintfStability
-enum AudioPolicyForceUse {
- COMMUNICATION = 0,
- MEDIA = 1,
- RECORD = 2,
- DOCK = 3,
- SYSTEM = 4,
- HDMI_SYSTEM_AUDIO = 5,
- ENCODED_SURROUND = 6,
- VIBRATE_RINGING = 7,
+union AudioPolicyForceUse {
+ @Backing(type="byte")
+ @VintfStability
+ enum CommunicationDeviceCategory {
+ NONE = 0,
+ SPEAKER,
+ BT_SCO,
+ BT_BLE,
+ WIRED_ACCESSORY,
+ }
+ @Backing(type="byte")
+ @VintfStability
+ enum MediaDeviceCategory {
+ NONE = 0,
+ SPEAKER,
+ HEADPHONES,
+ BT_A2DP,
+ ANALOG_DOCK,
+ DIGITAL_DOCK,
+ WIRED_ACCESSORY,
+ NO_BT_A2DP,
+ }
+ @Backing(type="byte")
+ @VintfStability
+ enum DockType {
+ NONE = 0,
+ BT_CAR_DOCK,
+ BT_DESK_DOCK,
+ ANALOG_DOCK,
+ DIGITAL_DOCK,
+ WIRED_ACCESSORY,
+ }
+ @Backing(type="byte")
+ @VintfStability
+ enum EncodedSurroundConfig {
+ UNSPECIFIED = 0,
+ NEVER,
+ ALWAYS,
+ MANUAL,
+ }
+
+ /**
+ * Configures the audio device used for media playback.
+ * This is also the default value.
+ */
+ MediaDeviceCategory forMedia = MediaDeviceCategory.NONE;
+ /**
+ * Configures the audio device used for "communication" (telephony, VoIP) use cases.
+ * Note that 'BT_BLE' and 'WIRED_ACCESSORY' can not be used in this case.
+ */
+ CommunicationDeviceCategory forCommunication = CommunicationDeviceCategory.NONE;
+ /**
+ * Configures the audio device used for recording.
+ * Note that 'SPEAKER' and 'BT_BLE' can not be used in this case.
+ */
+ CommunicationDeviceCategory forRecord = CommunicationDeviceCategory.NONE;
+ /**
+ * Configures whether in muted audio mode ringing should also be sent to a BT device.
+ * Note that 'SPEAKER' and 'WIRED_ACCESSORY' can not be used in this case.
+ */
+ CommunicationDeviceCategory forVibrateRinging = CommunicationDeviceCategory.NONE;
+ /**
+ * Specifies whether the phone is currently placed into a dock. The value of
+ * specifies the kind of the dock. This field may also be used that sending
+ * of audio to the dock is overridden by another device.
+ */
+ DockType dock = DockType.NONE;
+ /**
+ * Specifies whether enforcing of certain sounds is enabled, for example,
+ * enforcing of the camera shutter sound.
+ */
+ boolean systemSounds = false;
+ /**
+ * Specifies whether sending of system audio via HDMI is enabled.
+ */
+ boolean hdmiSystemAudio = false;
+ /**
+ * Configures whether support for encoded surround formats is enabled for
+ * applications.
+ */
+ EncodedSurroundConfig encodedSurround = EncodedSurroundConfig.UNSPECIFIED;
}
diff --git a/media/aidl/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl/android/media/audio/common/AudioPolicyForcedConfig.aidl
deleted file mode 100644
index 2acf4e1..0000000
--- a/media/aidl/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.media.audio.common;
-
-/**
- * List of forced configurations aka device categories to be used in addition to the force use
- * in order to force the audio routing.
- *
- * {@hide}
- */
-@Backing(type="int")
-@SuppressWarnings(value={"redundant-name"})
-@VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- /** A2DP sink is not preferred to speaker or wired HS */
- NO_BT_A2DP = 10,
- /**
- * Sink selected to render system enforced sound in certain countries for legal reason.
- * (like camera shutter tone in Japan).
- */
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
-}
diff --git a/media/aidl/android/media/audio/common/AudioPortDeviceExt.aidl b/media/aidl/android/media/audio/common/AudioPortDeviceExt.aidl
index 4de32c7..f04c9a7 100644
--- a/media/aidl/android/media/audio/common/AudioPortDeviceExt.aidl
+++ b/media/aidl/android/media/audio/common/AudioPortDeviceExt.aidl
@@ -16,6 +16,7 @@
package android.media.audio.common;
+import android.media.audio.common.AudioChannelLayout;
import android.media.audio.common.AudioDevice;
import android.media.audio.common.AudioFormatDescription;
@@ -59,4 +60,16 @@
* default device port in a HAL module in each I/O direction.
*/
const int FLAG_INDEX_DEFAULT_DEVICE = 0;
+
+ /**
+ * A channel layout that represents the physical layout of output speakers.
+ *
+ * If set, only the `layoutMask` variant of AudioChannelLayout is valid and
+ * supported for this field.
+ *
+ * The layoutMask only indicates which speaker channels are present, the
+ * physical layout of the speakers should be informed by a standard for
+ * multi-channel sound playback systems, such as ITU-R BS.2051.
+ */
+ @nullable AudioChannelLayout speakerLayout;
}
diff --git a/media/aidl/android/media/audio/common/AudioVolumeGroupChangeEvent.aidl b/media/aidl/android/media/audio/common/AudioVolumeGroupChangeEvent.aidl
new file mode 100644
index 0000000..f79e6a5
--- /dev/null
+++ b/media/aidl/android/media/audio/common/AudioVolumeGroupChangeEvent.aidl
@@ -0,0 +1,98 @@
+/*
+ * Copyright 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.media.audio.common;
+
+/**
+ * Audio Volume Group Change Event.
+ *
+ * {@hide}
+ */
+@SuppressWarnings(value={"redundant-name"}) // for VOLUME_FLAG_*
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable AudioVolumeGroupChangeEvent {
+ /**
+ * Shall show a toast containing the current volume.
+ */
+ const int VOLUME_FLAG_SHOW_UI = 1 << 0;
+ /**
+ * Whether to include ringer modes as possible options when changing volume..
+ */
+ const int VOLUME_FLAG_ALLOW_RINGER_MODES = 1 << 1;
+ /**
+ * Whether to play a sound when changing the volume.
+ */
+ const int VOLUME_FLAG_PLAY_SOUND = 1 << 2;
+ /**
+ * Removes any sounds/vibrate that may be in the queue, or are playing.
+ */
+ const int VOLUME_FLAG_REMOVE_SOUND_AND_VIBRATE = 1 << 3;
+ /**
+ * Whether to vibrate if going into the vibrate ringer mode.
+ */
+ const int VOLUME_FLAG_VIBRATE = 1 << 4;
+ /**
+ * Indicates to VolumePanel that the volume slider should be disabled as user cannot
+ * change the volume.
+ */
+ const int VOLUME_FLAG_FIXED_VOLUME = 1 << 5;
+ /**
+ * Indicates the volume set/adjust call is for Bluetooth absolute volume.
+ */
+ const int VOLUME_FLAG_BLUETOOTH_ABS_VOLUME = 1 << 6;
+ /**
+ * Adjusting the volume was prevented due to silent mode, display a hint in the UI.
+ */
+ const int VOLUME_FLAG_SHOW_SILENT_HINT = 1 << 7;
+ /**
+ * Indicates the volume call is for Hdmi Cec system audio volume.
+ */
+ const int VOLUME_FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8;
+ /**
+ * Indicates that this should only be handled if media is actively playing.
+ */
+ const int VOLUME_FLAG_ACTIVE_MEDIA_ONLY = 1 << 9;
+ /**
+ * Like FLAG_SHOW_UI, but only dialog warnings and confirmations, no sliders.
+ */
+ const int VOLUME_FLAG_SHOW_UI_WARNINGS = 1 << 10;
+ /**
+ * Adjusting the volume down from vibrated was prevented, display a hint in the UI.
+ */
+ const int VOLUME_FLAG_SHOW_VIBRATE_HINT = 1 << 11;
+ /**
+ * Adjusting the volume due to a hardware key press.
+ */
+ const int VOLUME_FLAG_FROM_KEY = 1 << 12;
+ /**
+ * Indicates that an absolute volume controller is notifying AudioService of a change in the
+ * volume or mute status of an external audio system..
+ */
+ const int VOLUME_FLAG_ABSOLUTE_VOLUME = 1 << 13;
+
+ /** Unique identifier of the volume group. */
+ int groupId;
+ /** Index in UI applied. */
+ int volumeIndex;
+ /** Muted attribute, orthogonal to volume index. */
+ boolean muted;
+ /**
+ * Bitmask indicating a suggested UI behavior or characterising the volume event.
+ * The bit masks are defined in the constants prefixed by VOLUME_FLAG_*.
+ */
+ int flags;
+}
diff --git a/media/aidl/android/media/audio/eraser/Capability.aidl b/media/aidl/android/media/audio/eraser/Capability.aidl
new file mode 100644
index 0000000..a7627e5
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/Capability.aidl
@@ -0,0 +1,80 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.common.AudioChannelLayout;
+import android.media.audio.eraser.ClassifierCapability;
+import android.media.audio.eraser.Mode;
+import android.media.audio.eraser.RemixerCapability;
+import android.media.audio.eraser.SeparatorCapability;
+
+/**
+ * Represents the capability of an audio eraser.
+ *
+ * This parcelable defines the supported input/output data formats, available work modes, and the
+ * specific capabilities of the sound classifier, separator, and remixer components within the
+ * eraser effect.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable Capability {
+ /**
+ * List of supported sample rates for the eraser.
+ *
+ * The output audio sample rate will be the same as the input.
+ */
+ int[] sampleRates;
+
+ /**
+ * List of supported channel layouts for the eraser.
+ *
+ * The output audio channel layout will be the same as the input.
+ */
+ AudioChannelLayout[] channelLayouts;
+
+ /**
+ * List of supported work modes.
+ *
+ * Defines the different operational modes (e.g., `ERASER`, `CLASSIFIER`) that the eraser can
+ * work in.
+ */
+ Mode[] modes;
+
+ /**
+ * Separator capability.
+ *
+ * Specifies the capabilities of the sound separator component within the eraser effect,
+ * including the maximum number of sound sources it can separate.
+ */
+ SeparatorCapability separator;
+
+ /**
+ * Classifier capability.
+ *
+ * Specifies the capabilities of the sound classifier component within the eraser effect,
+ * including the sound classifications it can detect.
+ */
+ ClassifierCapability classifier;
+
+ /**
+ * Remixer capability.
+ *
+ * Specifies the capabilities of the sound remixer component within the eraser effect,
+ * including the gainFactor range supported.
+ */
+ RemixerCapability remixer;
+}
diff --git a/media/aidl/android/media/audio/eraser/Classification.aidl b/media/aidl/android/media/audio/eraser/Classification.aidl
new file mode 100644
index 0000000..16aa1ce
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/Classification.aidl
@@ -0,0 +1,37 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.eraser.SoundClassification;
+
+/**
+ * Represents a sound classification category.
+ *
+ * The classification includes the top-level sound category based on the AudioSet ontology.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable Classification {
+ /**
+ * The top-level sounds classification supported.
+ *
+ * This field specifies the primary sound category that this classification represents,
+ * as defined in the AudioSet ontology. It helps identify the general type of sound,
+ * such as HUMAN, ANIMAL, MUSIC, etc.
+ */
+ SoundClassification classification = SoundClassification.HUMAN;
+}
diff --git a/media/aidl/android/media/audio/eraser/ClassificationConfig.aidl b/media/aidl/android/media/audio/eraser/ClassificationConfig.aidl
new file mode 100644
index 0000000..ab5191e
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/ClassificationConfig.aidl
@@ -0,0 +1,125 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.eraser.Classification;
+
+/**
+ * Configuration for the eraser to apply specific gain adjustments to certain sound classifications.
+ *
+ * Gain is applied to the audio signal by scaling the amplitude of the output audio based on the
+ * classification of the input sound.
+ * If a classification exists in the configuration list, the remixer applies the specified gain to
+ * the output audio when the confidence score is higher than `confidenceThreshold`. If a
+ * classification is not present in the configuration, it is considered to have a gain of 1.0
+ * (no gain adjustment).
+ * If a ClassificationConfig contains an empty classification list, the same threshold and gain
+ * specified in the ClassificationConfig will be applied to all classifications not explicitly
+ * configured.
+ *
+ * Examples:
+ *
+ * 1. {classifications = [{classification = SoundClassification.NATURE},
+ * {classification = SoundClassification.ENVIRONMENT}],
+ * confidenceThreshold = 0.8,
+ * gainFactor = 0.0}
+ *
+ * - If the input audio is classified as NATURE or ENVIRONMENT, with a confidence score higher
+ * than 0.8, the output audio will be muted.
+ * - If the classification confidence score is 0.8 or lower, or if the audio is classified
+ * differently, the output audio remains unchanged.
+ *
+ * 2. {classifications = [{classification = SoundClassification.MUSIC}],
+ * confidenceThreshold = 0.6,
+ * gainFactor = 0.5}
+ *
+ * - If the input audio is classified as MUSIC with a confidence score higher than 0.6, the
+ * output audio should have a gain factor of 0.5 (reduced by half).
+ * - If the classification confidence score is 0.6 or lower, or if the audio is classified
+ * differently, the output audio remains unchanged.
+ *
+ * 3. When combined as a list, the eraser can be configured to apply different gainFactor to
+ * a classifications when confideence score is higher than the corresponding threshold.
+ * [{classifications = [{classification = SoundClassification.NATURE}],
+ * confidenceThreshold = 0.8,
+ * gainFactor = 0.0},
+ * {classifications = [{classification = SoundClassification.MUSIC}],
+ * confidenceThreshold = 0.8,
+ * gainFactor = 0.6},
+ * {classifications = [{classification = SoundClassification.MUSIC}],
+ * confidenceThreshold = 0.5,
+ * gainFactor = 0.5}]
+ *
+ * - If the input audio is classified as NATURE, and the confidence score is higher than 0.8,
+ * the output audio classification will be muted (gainFactor = 0.0).
+ *
+ * - If the input audio is classified as MUSIC with a confidence score higher than 0.8, the
+ * output audio classification will have a gain factor of 0.6. If the input audio is
+ * classified as MUSIC with a confidence score higher than 0.5, the output audio
+ * classification will have a gain factor of 0.5.
+ *
+ * - For all other sound classifications, the audio signal remains unchanged (gainFactor = 1.0).
+ *
+ * 4. [{classifications = [{classification = SoundClassification.HUMAN}],
+ * confidenceThreshold = 0.8,
+ * gainFactor = 1.0},
+ * {classifications = [],
+ * confidenceThreshold = 0.0,
+ * gainFactor = 0.5}]
+ *
+ * - If the input audio is classified as HUMAN, and the confidence score is higher than 0.8, the
+ * output audio classification will remains unchanged.
+ *
+ * - For all other sound classifications, the audio signal will have a gain factor of 0.5.
+ *
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable ClassificationConfig {
+ /**
+ * List of sound classifications to which this configuration applies.
+ *
+ * Each entry specifies a sound classification (e.g., MUSIC, NATURE) targeted by this
+ * configuration.
+ */
+ Classification[] classifications;
+
+ /**
+ * Confidence threshold in the range of [0.0, 1.0], only apply the gainFactor when the
+ * classifier's confidence score for the specified classifications exceeds this threshold.
+ *
+ * Default Value is 0.0 which means apply gain regardless of confidence score.
+ */
+ float confidenceThreshold = 0f;
+
+ /**
+ * Gain factor to apply to the output audio when the specified classifications are detected.
+ * Gain factor is applied by multiplying the amplitude of the audio signal by the `gainFactor`.
+ *
+ * - A `gainFactor` of `1.0` means no gain adjustment (the original volume is preserved).
+ * - A `gainFactor` of `0.5` reduces the amplitude of the audio by half.
+ * - A `gainFactor` of `0.0` mutes the audio.
+ * - A `gainFactor` > `1.0` amplifies the audio signal, increasing its volume (useful for
+ * compressor and amplification cases).
+ * - A `gainFactor` < `0.0` inverts the phase of the audio signal (useful for phase
+ * cancellation or specific spatial audio manipulation).
+ *
+ * The `gainFactor` must be within the `gainFactorRange` defined in `RemixerCapability`, the
+ * default value is `1.0`.
+ */
+ float gainFactor = 1f;
+}
diff --git a/media/aidl/android/media/audio/eraser/ClassificationMetadata.aidl b/media/aidl/android/media/audio/eraser/ClassificationMetadata.aidl
new file mode 100644
index 0000000..cc79c37
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/ClassificationMetadata.aidl
@@ -0,0 +1,42 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.eraser.Classification;
+
+/**
+ * Metadata generated by a sound classification task.
+ *
+ * This parcelable contains the classification result for a segment of the audio stream, along with
+ * a confidence score indicating the certainty of the classification.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable ClassificationMetadata {
+ /**
+ * Confidence score for the classification, ranging from 0.0 to 1.0.
+ *
+ * This score reflects the classifier's confidence in the result, with higher values
+ * representing greater confidence in the prediction.
+ */
+ float confidenceScore;
+
+ /**
+ * The classification result, indicating the top-level sound classification.
+ */
+ Classification classification;
+}
diff --git a/media/aidl/android/media/audio/eraser/ClassificationMetadataList.aidl b/media/aidl/android/media/audio/eraser/ClassificationMetadataList.aidl
new file mode 100644
index 0000000..3a5dd16
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/ClassificationMetadataList.aidl
@@ -0,0 +1,82 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.eraser.ClassificationMetadata;
+
+/**
+ * List of active `ClassificationMetadata` aligned to a specific timestamp.
+ *
+ * A `ClassificationMetadata` is considered active when the `confidenceScore` exceeds the
+ * `ClassificationConfig.confidenceThreshold`.
+ *
+ * The classifier component in the eraser must maintain the active metadata list when an
+ * `IEraserCallback` is configured and send the list via `onClassifierUpdate` whenever a change
+ * occurs.
+ */
+
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable ClassificationMetadataList {
+ /**
+ * Timestamp in milliseconds within the audio stream that this classification result is aligned
+ * with, the timestamp is calculated with audio frames the eraser effect received, starting
+ * from the first frame processed by the eraser effect.
+ *
+ * The `timeMs` indicates the starting point in the audio stream that the classification results
+ * in this metadata list apply to.
+ * Each classifier process window produces a list of `ClassificationMetadata`. The `timeMs` in
+ * the metadata list always aligns with the start of the window (the starting point of the audio
+ * segment processed by the classifier).
+ * In rare cases where the classifier produces an identical list of classifications for
+ * consecutive windows (including confidence scores), the `onClassifierUpdate` callback will
+ * only be triggered once for the first process window, with a `timeMs` indicating the start of
+ * that window. No further `onClassifierUpdate` callbacks will be made for the subsequent
+ * windows, as there is no meaningful change in the classification results. This avoids
+ * redundant updates when the classification remains the same across windows.
+ *
+ * Client Usage:
+ * The `timeMs` allows clients to map the classification results back to a specific portion of
+ * the audio stream. Clients can use this information to synchronize classification results
+ * with the audio data or other events. Each metadata list update corresponds to one window of
+ * classified audio, and the `timeMs` will always point to the start of that window.
+ *
+ * For an example, below is an audio stream timeline with a 1 second classifier window.
+ * Audio stream:
+ * |==========>=========|============>=========|===========>==========|===========>=========|
+ * 0 1000 2000 3000 4000
+ * | | | |
+ * V V V V
+ * [{HUMAN, 0.8}] [{HUMAN, 0.8}, [{HUMAN, 0.8}, [{HUMAN, 0.8}]
+ * | {NATURE, 0.4}] {NATURE, 0.4}] |
+ * | | |
+ * V V V
+ * onClassifierUpdate onClassifierUpdate onClassifierUpdate
+ * timeMs: 0 timeMs: 1000 timeMs: 3000
+ * [{HUMAN, 0.8}] [{HUMAN, 0.8}, [{HUMAN, 0.8}]
+ * {NATURE, 0.4}]
+ */
+ int timeMs;
+
+ /**
+ * List of classification metadata, including the sound classification, confidence score, and
+ * a duration since when the sound class was considered active.
+ *
+ * Metadatas in the list should be ranked in descending order based on the confidence score.
+ */
+ ClassificationMetadata[] metadatas;
+}
diff --git a/media/aidl/android/media/audio/eraser/ClassifierCapability.aidl b/media/aidl/android/media/audio/eraser/ClassifierCapability.aidl
new file mode 100644
index 0000000..5348086
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/ClassifierCapability.aidl
@@ -0,0 +1,48 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.eraser.Classification;
+
+/**
+ * Represents the capabilities of a sound classifier component.
+ *
+ * This parcelable contains a list of supported sound classifications that the classifier can
+ * recognize and process.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable ClassifierCapability {
+ /**
+ * The window size of the classifier model in milliseconds.
+ *
+ * Indicates the duration over which the classifier processes audio data to output a
+ * classification result.
+ *
+ * Clients can expect to receive updates at most once per window.
+ */
+ int windowSizeMs;
+
+ /**
+ * List of supported sound classifications.
+ *
+ * Each entry specifies a sound classification category that the classifier can recognize, such
+ * as `HUMAN`, `MUSIC`, `ANIMAL`, etc. This defines the types of sounds the classifier is
+ * capable of identifying in the input audio.
+ */
+ Classification[] supportedClassifications;
+}
diff --git a/media/aidl/android/media/audio/eraser/Configuration.aidl b/media/aidl/android/media/audio/eraser/Configuration.aidl
new file mode 100644
index 0000000..b693244
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/Configuration.aidl
@@ -0,0 +1,54 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.eraser.ClassificationConfig;
+import android.media.audio.eraser.IEraserCallback;
+import android.media.audio.eraser.Mode;
+
+/**
+ * Eraser configurations. Configuration for eraser operation mode, sound classification behaviors,
+ * and an optional callback interface.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable Configuration {
+ /**
+ * Work mode for the eraser, specifies the current operating mode of the eraser effect.
+ */
+ Mode mode = Mode.ERASER;
+
+ /**
+ * List of eraser configurations.
+ * Each configuration defines the behavior for specific sound classifications, allowing
+ * different gain factors and confidence thresholds to be applied based on classification
+ * results.
+ */
+ ClassificationConfig[] classificationConfigs;
+
+ /**
+ * Maximum number of classification metadata generated from the sound classification.
+ *
+ * Default value set to 5.
+ */
+ int maxClassificationMetadata = 5;
+
+ /**
+ * Optional callback inerface to get the eraser effect results.
+ */
+ @nullable IEraserCallback callback;
+}
diff --git a/media/aidl/android/media/audio/eraser/IEraserCallback.aidl b/media/aidl/android/media/audio/eraser/IEraserCallback.aidl
new file mode 100644
index 0000000..4863ba5
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/IEraserCallback.aidl
@@ -0,0 +1,50 @@
+/*
+ * 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.media.audio.eraser;
+
+import android.media.audio.eraser.ClassificationMetadataList;
+
+/**
+ * Callback interface for delivering results from the eraser effect.
+ */
+@VintfStability
+interface IEraserCallback {
+ /**
+ * Provides classifier updates, including sound classifications and their confidence scores,
+ * along with the associated timestamp for a given `soundSourceId`.
+ *
+ * The callback is invoked when there is a change in the list of active classification metadata
+ * for each sound source. Changes include the addition and removal of a classification, or
+ * a change in the condidence score.
+ *
+ * The number of metadata elements in the `ClassificationMetadataList.metadatas` list will not
+ * exceed the `maxClassificationMetadata` set in `android.media.audio.eraser.Configuration`.
+ *
+ * Different classifiers may have varying window sizes, regardless of the window size, the
+ * classifier updates occur at most once per window per sound source.
+ *
+ * @param soundSourceId The identifier for the sound source being classified. In ERASER mode,
+ * this identifies the separated sound source.
+ * - In CLASSIFIER mode, the `soundSourceId` is always `0` as there is only one sound
+ * source for the eraser effect.
+ * - In ERASER mode, the `soundSourceId` range is [0, `maxSoundSources - 1`], where
+ * `maxSoundSources` is defined in the eraser capability through `SeparatorCapability`.
+ *
+ * @param metadata The classification metadata list for the current sound source.
+ */
+ oneway void onClassifierUpdate(in int soundSourceId, in ClassificationMetadataList metadata);
+}
diff --git a/media/aidl/android/media/audio/eraser/Mode.aidl b/media/aidl/android/media/audio/eraser/Mode.aidl
new file mode 100644
index 0000000..30745c5
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/Mode.aidl
@@ -0,0 +1,58 @@
+/*
+ * 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.media.audio.eraser;
+
+/**
+ * Defines the operational mode of the Eraser effect.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+@Backing(type="byte")
+enum Mode {
+ /**
+ * ERASER mode: The effect operates as an automatic sound eraser.
+ *
+ * In this mode, the Eraser effect processes the input audio using the Sound Separator,
+ * Sound Classifier, and Remixer components. The sound to be erased or retained is determined
+ * by the classifications and gain adjustments specified in eraser configuration.
+ *
+ * - The Sound Separator separates the input audio into multiple sound sources.
+ * - The Sound Classifier analyzes each separated sound to determine its sound category.
+ * - The Remixer applies gain adjustments based on the classifications and configurations, and
+ * re-mix the processed sounds back into a single output audio stream.
+ *
+ * Requirements: To operate in this mode, the effect must support the classifier, separator,
+ * and remixer capabilities.
+ *
+ * Use Cases: Selectively suppressing or enhancing specific sounds in the audio stream,
+ * such as removing background noise or isolating desired sound sources.
+ */
+ ERASER,
+
+ /**
+ * CLASSIFIER mode: The effect operates as a sound classifier.
+ *
+ * In this mode, the Sound Classifier analyzes the input audio in real-time and emits
+ * classification results based on the sound categories detected. The input audio is directly
+ * passed through to the output without any modification.
+ *
+ * Use Cases: Useful for applications that need to detect specific sound events, monitor audio
+ * content, or provide real-time visual feedback on audio classifications, without altering the
+ * original audio stream.
+ */
+ CLASSIFIER,
+}
diff --git a/media/aidl/android/media/audio/eraser/RemixerCapability.aidl b/media/aidl/android/media/audio/eraser/RemixerCapability.aidl
new file mode 100644
index 0000000..0c89fc1
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/RemixerCapability.aidl
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.media.audio.eraser;
+
+/**
+ * Represents the capabilities of a sound remixer component.
+ *
+ * This parcelable defines the supported range of gainFactors that the remixer can apply to the
+ * audio signal.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable RemixerCapability {
+ /**
+ * Indicates whether sound remixer is supported.
+ *
+ * If `supported` is true, the sound remixer can adjust the gain of the audio signal based on
+ * the provided classifications and gainFactors, and remix the separated sounds into one.
+ */
+ boolean supported;
+
+ /**
+ * Minimum gainFactor supported by the sound remixer.
+ *
+ * Specifies the lowest gainFactor that the remixer can apply. A gainFactor of `0.0`
+ * typically mutes the sound. In some less common cases, a remixer can support a negative
+ * `gainFactor`, which enables some use cases like phase inversion and noise cancellation.
+ *
+ * The minimum gainFactor must be at least `0.0`. The default minimum gainFactor for a remixer
+ * is `0.0` (the sound is muted).
+ */
+ float minGainFactor = 0f;
+
+ /**
+ * Maximum gainFactor supported by the sound remixer.
+ *
+ * Specifies the highest gainFactor that the remixer can apply. A gainFactor of `1.0` means no
+ * adjustment to the sound's original volume. In the case of gainFactor greater than `1.0`, the
+ * remixer may apply amplification to the audio signal.
+ *
+ * The maximum gainFactor must be at least `1.0`, and the default maximum gainFactor for a
+ * remixer is `1.0` (no gain adjustment to the sound).
+ */
+ float maxGainFactor = 1f;
+}
diff --git a/media/aidl/android/media/audio/eraser/SeparatorCapability.aidl b/media/aidl/android/media/audio/eraser/SeparatorCapability.aidl
new file mode 100644
index 0000000..93b959c
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/SeparatorCapability.aidl
@@ -0,0 +1,55 @@
+/*
+ * 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.media.audio.eraser;
+
+/**
+ * Represents the capabilities of a sound separator component.
+ *
+ * This parcelable includes the maximum number of sound sources that can be separated
+ * simultaneously.
+ */
+@JavaDerive(equals=true, toString=true)
+@VintfStability
+parcelable SeparatorCapability {
+ /**
+ * Indicates whether sound separation is supported.
+ *
+ * Note: If sound separation is supported, the effect must also support sound remixing to
+ * handle the separated audio streams, and produce remixed audio as output.
+ */
+ boolean supported;
+
+ /**
+ * The minimum number of sound sources a sound separator must support.
+ */
+ const int MIN_SOUND_SOURCE_SUPPORTED = 2;
+
+ /**
+ * Maximum number of sound sources that can be separated.
+ *
+ * Specifies the maximum number of individual sound sources that the separator can process
+ * simultaneously.
+ *
+ * Each separated sound source have an soundSourceId, range in [0, maxSoundSources -1]. In
+ * ERASER mode, each sound source will be classified with a classifier, identified by the
+ * soundSourceId.
+ *
+ * The minimum value of `maxSoundSources` is 2 as defined by `MIN_SOUND_SOURCE_SUPPORTED`, the
+ * default value is 4.
+ */
+ int maxSoundSources = 4;
+}
diff --git a/media/aidl/android/media/audio/eraser/SoundClassification.aidl b/media/aidl/android/media/audio/eraser/SoundClassification.aidl
new file mode 100644
index 0000000..6ec9b43
--- /dev/null
+++ b/media/aidl/android/media/audio/eraser/SoundClassification.aidl
@@ -0,0 +1,75 @@
+/*
+ * 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.media.audio.eraser;
+
+/**
+ * The sound classification is based on the top-level categories of the "AudioSet ontology".
+ *
+ * The AudioSet ontology is a hierarchical collection of sound event classes.
+ * For more details, refer to the ICASSP 2017 paper: "AudioSet: An ontology and human-labeled
+ * dataset for audio events".
+ * https://research.google/pubs/audio-set-an-ontology-and-human-labeled-dataset-for-audio-events/
+ */
+@JavaDerive(equals=true, toString=true)
+@Backing(type="int")
+@VintfStability
+enum SoundClassification {
+ /**
+ * Sounds produced by the human body through the actions of the individual.
+ */
+ HUMAN,
+
+ /**
+ * All sound produced by the bodies and actions of nonhuman animals.
+ */
+ ANIMAL,
+
+ /**
+ * Sounds produced by natural sources in their normal soundscape, excluding animal and human
+ * sounds.
+ */
+ NATURE,
+
+ /**
+ * Music is an art form and cultural activity whose medium is sound and silence. The common
+ * elements of music are pitch, rhythm, dynamics, and the sonic qualities of timbre and texture.
+ */
+ MUSIC,
+
+ /**
+ * Set of sound classes referring to sounds that are immediately understood by listeners as
+ * arising from specific objects (rather than being heard more literally as "sounds").
+ */
+ THINGS,
+
+ /**
+ * Portmanteau class for sounds that do not immediately suggest specific source objects, but
+ * which are more likely to be perceived and described according to their acoustic properties.
+ */
+ AMBIGUOUS,
+
+ /**
+ * A class for sound categories that suggest information about attributes other than the
+ * foreground or target objects.
+ */
+ ENVIRONMENT,
+
+ /**
+ * Vendor customizable extension, for possible classifications not listed above.
+ */
+ VENDOR_EXTENSION,
+}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapCriterionV2.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapCriterionV2.aidl
index fd17d6f..b5ceee3 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapCriterionV2.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapCriterionV2.aidl
@@ -41,17 +41,15 @@
android.media.audio.common.AudioHalCapCriterionV2.AvailableDevicesAddresses availableOutputDevicesAddresses;
android.media.audio.common.AudioHalCapCriterionV2.TelephonyMode telephonyMode;
android.media.audio.common.AudioHalCapCriterionV2.ForceConfigForUse forceConfigForUse;
- android.media.audio.common.AudioHalCapCriterionV2.Type type;
- @VintfStability
+ @Backing(type="byte") @VintfStability
enum LogicalDisjunction {
EXCLUSIVE = 0,
INCLUSIVE,
}
@VintfStability
parcelable ForceConfigForUse {
- android.media.audio.common.AudioPolicyForceUse forceUse = android.media.audio.common.AudioPolicyForceUse.MEDIA;
- android.media.audio.common.AudioPolicyForcedConfig[] values;
- android.media.audio.common.AudioPolicyForcedConfig defaultValue = android.media.audio.common.AudioPolicyForcedConfig.NONE;
+ android.media.audio.common.AudioPolicyForceUse[] values;
+ android.media.audio.common.AudioPolicyForceUse defaultValue;
android.media.audio.common.AudioHalCapCriterionV2.LogicalDisjunction logic = android.media.audio.common.AudioHalCapCriterionV2.LogicalDisjunction.EXCLUSIVE;
}
@VintfStability
@@ -70,11 +68,4 @@
android.media.audio.common.AudioDeviceAddress[] values;
android.media.audio.common.AudioHalCapCriterionV2.LogicalDisjunction logic = android.media.audio.common.AudioHalCapCriterionV2.LogicalDisjunction.INCLUSIVE;
}
- @VintfStability
- union Type {
- android.media.audio.common.AudioDeviceDescription availableDevicesType;
- android.media.audio.common.AudioDeviceAddress availableDevicesAddressesType;
- android.media.audio.common.AudioMode telephonyModeType;
- android.media.audio.common.AudioPolicyForcedConfig forcedConfigType;
- }
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapParameter.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapParameter.aidl
index 981bd09..c0b1a72 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapParameter.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapParameter.aidl
@@ -36,15 +36,10 @@
@VintfStability
union AudioHalCapParameter {
android.media.audio.common.AudioHalCapParameter.StrategyDevice selectedStrategyDevice;
- android.media.audio.common.AudioHalCapParameter.StrategyDeviceAddress strategyDeviceAddress;
android.media.audio.common.AudioHalCapParameter.InputSourceDevice selectedInputSourceDevice;
+ android.media.audio.common.AudioHalCapParameter.StrategyDeviceAddress strategyDeviceAddress;
android.media.audio.common.AudioHalCapParameter.StreamVolumeProfile streamVolumeProfile;
@VintfStability
- parcelable StrategyDeviceAddress {
- android.media.audio.common.AudioDeviceAddress deviceAddress;
- int id = android.media.audio.common.AudioProductStrategyType.SYS_RESERVED_NONE /* -1 */;
- }
- @VintfStability
parcelable StrategyDevice {
android.media.audio.common.AudioDeviceDescription device;
int id = android.media.audio.common.AudioProductStrategyType.SYS_RESERVED_NONE /* -1 */;
@@ -57,6 +52,11 @@
boolean isSelected;
}
@VintfStability
+ parcelable StrategyDeviceAddress {
+ android.media.audio.common.AudioDeviceAddress deviceAddress;
+ int id = android.media.audio.common.AudioProductStrategyType.SYS_RESERVED_NONE /* -1 */;
+ }
+ @VintfStability
parcelable StreamVolumeProfile {
android.media.audio.common.AudioStreamType stream = android.media.audio.common.AudioStreamType.INVALID;
android.media.audio.common.AudioStreamType profile = android.media.audio.common.AudioStreamType.INVALID;
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapRule.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapRule.aidl
index fb1719c..e106050 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapRule.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalCapRule.aidl
@@ -55,7 +55,6 @@
@VintfStability
parcelable CriterionRule {
android.media.audio.common.AudioHalCapRule.MatchingRule matchingRule = android.media.audio.common.AudioHalCapRule.MatchingRule.INVALID;
- android.media.audio.common.AudioHalCapCriterionV2 criterion;
- android.media.audio.common.AudioHalCapCriterionV2.Type criterionTypeValue;
+ android.media.audio.common.AudioHalCapCriterionV2 criterionAndValue;
}
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalProductStrategy.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalProductStrategy.aidl
index 1144574..9878e37 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalProductStrategy.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioHalProductStrategy.aidl
@@ -38,5 +38,10 @@
int id = android.media.audio.common.AudioProductStrategyType.SYS_RESERVED_NONE /* -1 */;
android.media.audio.common.AudioHalAttributesGroup[] attributesGroups;
@nullable @utf8InCpp String name;
+ int zoneId = android.media.audio.common.AudioHalProductStrategy.ZoneId.DEFAULT /* 0 */;
const int VENDOR_STRATEGY_ID_START = 1000;
+ @Backing(type="int") @VintfStability
+ enum ZoneId {
+ DEFAULT = 0,
+ }
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForceUse.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForceUse.aidl
index 7e69f85..eb883e9 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForceUse.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForceUse.aidl
@@ -33,14 +33,49 @@
package android.media.audio.common;
/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForceUse {
- COMMUNICATION = 0,
- MEDIA = 1,
- RECORD = 2,
- DOCK = 3,
- SYSTEM = 4,
- HDMI_SYSTEM_AUDIO = 5,
- ENCODED_SURROUND = 6,
- VIBRATE_RINGING = 7,
+@SuppressWarnings(value={"redundant-name"}) @VintfStability
+union AudioPolicyForceUse {
+ android.media.audio.common.AudioPolicyForceUse.MediaDeviceCategory forMedia = android.media.audio.common.AudioPolicyForceUse.MediaDeviceCategory.NONE;
+ android.media.audio.common.AudioPolicyForceUse.CommunicationDeviceCategory forCommunication = android.media.audio.common.AudioPolicyForceUse.CommunicationDeviceCategory.NONE;
+ android.media.audio.common.AudioPolicyForceUse.CommunicationDeviceCategory forRecord = android.media.audio.common.AudioPolicyForceUse.CommunicationDeviceCategory.NONE;
+ android.media.audio.common.AudioPolicyForceUse.CommunicationDeviceCategory forVibrateRinging = android.media.audio.common.AudioPolicyForceUse.CommunicationDeviceCategory.NONE;
+ android.media.audio.common.AudioPolicyForceUse.DockType dock = android.media.audio.common.AudioPolicyForceUse.DockType.NONE;
+ boolean systemSounds = false;
+ boolean hdmiSystemAudio = false;
+ android.media.audio.common.AudioPolicyForceUse.EncodedSurroundConfig encodedSurround = android.media.audio.common.AudioPolicyForceUse.EncodedSurroundConfig.UNSPECIFIED;
+ @Backing(type="byte") @VintfStability
+ enum CommunicationDeviceCategory {
+ NONE = 0,
+ SPEAKER,
+ BT_SCO,
+ BT_BLE,
+ WIRED_ACCESSORY,
+ }
+ @Backing(type="byte") @VintfStability
+ enum MediaDeviceCategory {
+ NONE = 0,
+ SPEAKER,
+ HEADPHONES,
+ BT_A2DP,
+ ANALOG_DOCK,
+ DIGITAL_DOCK,
+ WIRED_ACCESSORY,
+ NO_BT_A2DP,
+ }
+ @Backing(type="byte") @VintfStability
+ enum DockType {
+ NONE = 0,
+ BT_CAR_DOCK,
+ BT_DESK_DOCK,
+ ANALOG_DOCK,
+ DIGITAL_DOCK,
+ WIRED_ACCESSORY,
+ }
+ @Backing(type="byte") @VintfStability
+ enum EncodedSurroundConfig {
+ UNSPECIFIED = 0,
+ NEVER,
+ ALWAYS,
+ MANUAL,
+ }
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPortDeviceExt.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPortDeviceExt.aidl
index 24d9b29..2b3e72c 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPortDeviceExt.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPortDeviceExt.aidl
@@ -40,5 +40,6 @@
android.media.audio.common.AudioFormatDescription[] encodedFormats;
int encapsulationModes;
int encapsulationMetadataTypes;
+ @nullable android.media.audio.common.AudioChannelLayout speakerLayout;
const int FLAG_INDEX_DEFAULT_DEVICE = 0;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioVolumeGroupChangeEvent.aidl
similarity index 60%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioVolumeGroupChangeEvent.aidl
index 5135bcd..3a2bc5b 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioVolumeGroupChangeEvent.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2024 The Android Open Source Project
+ * Copyright 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.
@@ -33,23 +33,24 @@
package android.media.audio.common;
/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+@JavaDerive(equals=true, toString=true) @SuppressWarnings(value={"redundant-name"}) @VintfStability
+parcelable AudioVolumeGroupChangeEvent {
+ int groupId;
+ int volumeIndex;
+ boolean muted;
+ int flags;
+ const int VOLUME_FLAG_SHOW_UI = (1 << 0) /* 1 */;
+ const int VOLUME_FLAG_ALLOW_RINGER_MODES = (1 << 1) /* 2 */;
+ const int VOLUME_FLAG_PLAY_SOUND = (1 << 2) /* 4 */;
+ const int VOLUME_FLAG_REMOVE_SOUND_AND_VIBRATE = (1 << 3) /* 8 */;
+ const int VOLUME_FLAG_VIBRATE = (1 << 4) /* 16 */;
+ const int VOLUME_FLAG_FIXED_VOLUME = (1 << 5) /* 32 */;
+ const int VOLUME_FLAG_BLUETOOTH_ABS_VOLUME = (1 << 6) /* 64 */;
+ const int VOLUME_FLAG_SHOW_SILENT_HINT = (1 << 7) /* 128 */;
+ const int VOLUME_FLAG_HDMI_SYSTEM_AUDIO_VOLUME = (1 << 8) /* 256 */;
+ const int VOLUME_FLAG_ACTIVE_MEDIA_ONLY = (1 << 9) /* 512 */;
+ const int VOLUME_FLAG_SHOW_UI_WARNINGS = (1 << 10) /* 1024 */;
+ const int VOLUME_FLAG_SHOW_VIBRATE_HINT = (1 << 11) /* 2048 */;
+ const int VOLUME_FLAG_FROM_KEY = (1 << 12) /* 4096 */;
+ const int VOLUME_FLAG_ABSOLUTE_VOLUME = (1 << 13) /* 8192 */;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Capability.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Capability.aidl
index 5135bcd..a415a42 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Capability.aidl
@@ -31,25 +31,13 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Capability {
+ int[] sampleRates;
+ android.media.audio.common.AudioChannelLayout[] channelLayouts;
+ android.media.audio.eraser.Mode[] modes;
+ android.media.audio.eraser.SeparatorCapability separator;
+ android.media.audio.eraser.ClassifierCapability classifier;
+ android.media.audio.eraser.RemixerCapability remixer;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Classification.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Classification.aidl
index 5135bcd..f90f1c1 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Classification.aidl
@@ -31,25 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Classification {
+ android.media.audio.eraser.SoundClassification classification = android.media.audio.eraser.SoundClassification.HUMAN;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationConfig.aidl
similarity index 76%
rename from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
rename to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationConfig.aidl
index 5135bcd..763352d 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationConfig.aidl
@@ -31,25 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ClassificationConfig {
+ android.media.audio.eraser.Classification[] classifications;
+ float confidenceThreshold = 0f;
+ float gainFactor = 1f;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationMetadata.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationMetadata.aidl
index 5135bcd..cfdbe5b 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationMetadata.aidl
@@ -31,25 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ClassificationMetadata {
+ float confidenceScore;
+ android.media.audio.eraser.Classification classification;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationMetadataList.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationMetadataList.aidl
index 5135bcd..36cef59 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassificationMetadataList.aidl
@@ -31,25 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ClassificationMetadataList {
+ int timeMs;
+ android.media.audio.eraser.ClassificationMetadata[] metadatas;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassifierCapability.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassifierCapability.aidl
index 5135bcd..fadf920 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/ClassifierCapability.aidl
@@ -31,25 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable ClassifierCapability {
+ int windowSizeMs;
+ android.media.audio.eraser.Classification[] supportedClassifications;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Configuration.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Configuration.aidl
index 5135bcd..8da4032 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Configuration.aidl
@@ -31,25 +31,11 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable Configuration {
+ android.media.audio.eraser.Mode mode = android.media.audio.eraser.Mode.ERASER;
+ android.media.audio.eraser.ClassificationConfig[] classificationConfigs;
+ int maxClassificationMetadata = 5;
+ @nullable android.media.audio.eraser.IEraserCallback callback;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/IEraserCallback.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/IEraserCallback.aidl
index 5135bcd..8d53405 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/IEraserCallback.aidl
@@ -31,25 +31,8 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@VintfStability
+interface IEraserCallback {
+ oneway void onClassifierUpdate(in int soundSourceId, in android.media.audio.eraser.ClassificationMetadataList metadata);
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Mode.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Mode.aidl
index 5135bcd..916b314 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/Mode.aidl
@@ -31,25 +31,9 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@Backing(type="byte") @JavaDerive(equals=true, toString=true) @VintfStability
+enum Mode {
+ ERASER,
+ CLASSIFIER,
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/RemixerCapability.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/RemixerCapability.aidl
index 5135bcd..82707b1 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/RemixerCapability.aidl
@@ -31,25 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable RemixerCapability {
+ boolean supported;
+ float minGainFactor = 0f;
+ float maxGainFactor = 1f;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/SeparatorCapability.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/SeparatorCapability.aidl
index 5135bcd..2e983ac 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/SeparatorCapability.aidl
@@ -31,25 +31,10 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@JavaDerive(equals=true, toString=true) @VintfStability
+parcelable SeparatorCapability {
+ boolean supported;
+ int maxSoundSources = 4;
+ const int MIN_SOUND_SOURCE_SUPPORTED = 2;
}
diff --git a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/SoundClassification.aidl
similarity index 75%
copy from media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
copy to media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/SoundClassification.aidl
index 5135bcd..e5483b4 100644
--- a/media/aidl_api/android.media.audio.common.types/current/android/media/audio/common/AudioPolicyForcedConfig.aidl
+++ b/media/aidl_api/android.media.audio.eraser.types/current/android/media/audio/eraser/SoundClassification.aidl
@@ -31,25 +31,15 @@
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
-package android.media.audio.common;
-/* @hide */
-@Backing(type="int") @SuppressWarnings(value={"redundant-name"}) @VintfStability
-enum AudioPolicyForcedConfig {
- NONE = 0,
- SPEAKER = 1,
- HEADPHONES = 2,
- BT_SCO = 3,
- BT_A2DP = 4,
- WIRED_ACCESSORY = 5,
- BT_CAR_DOCK = 6,
- BT_DESK_DOCK = 7,
- ANALOG_DOCK = 8,
- DIGITAL_DOCK = 9,
- NO_BT_A2DP = 10,
- SYSTEM_ENFORCED = 11,
- HDMI_SYSTEM_AUDIO_ENFORCED = 12,
- ENCODED_SURROUND_NEVER = 13,
- ENCODED_SURROUND_ALWAYS = 14,
- ENCODED_SURROUND_MANUAL = 15,
- BT_BLE = 16,
+package android.media.audio.eraser;
+@Backing(type="int") @JavaDerive(equals=true, toString=true) @VintfStability
+enum SoundClassification {
+ HUMAN,
+ ANIMAL,
+ NATURE,
+ MUSIC,
+ THINGS,
+ AMBIGUOUS,
+ ENVIRONMENT,
+ VENDOR_EXTENSION,
}
diff --git a/suspend/1.0/default/Android.bp b/suspend/1.0/default/Android.bp
index 32cd02a..6652b6d 100644
--- a/suspend/1.0/default/Android.bp
+++ b/suspend/1.0/default/Android.bp
@@ -13,11 +13,15 @@
// limitations under the License.
package {
+ default_team: "trendy_team_android_kernel",
default_applicable_licenses: ["Android-Apache-2.0"],
}
cc_defaults {
name: "system_suspend_defaults",
+ defaults: [
+ "aconfig_lib_cc_static_link.defaults",
+ ],
shared_libs: [
"libbase",
"libbinder",
@@ -26,6 +30,10 @@
"libhidlbase",
"liblog",
"libutils",
+ "server_configurable_flags",
+ ],
+ static_libs: [
+ "suspend_service_flags_c_lib",
],
cflags: [
"-Wall",
@@ -67,6 +75,11 @@
],
}
+vintf_fragment {
+ name: "android.system.suspend-service.xml",
+ src: "android.system.suspend-service.xml",
+}
+
cc_binary {
name: "android.system.suspend-service",
relative_install_path: "hw",
@@ -74,7 +87,7 @@
"android.system.suspend-service_defaults",
],
init_rc: ["android.system.suspend-service.rc"],
- vintf_fragments: ["android.system.suspend-service.xml"],
+ vintf_fragment_modules: ["android.system.suspend-service.xml"],
srcs: [
"main.cpp",
],
@@ -200,3 +213,15 @@
"fuzzers/SuspendServiceInternalFuzzer.cpp",
],
}
+
+aconfig_declarations {
+ name: "suspend_service_flags",
+ package: "suspend_service.flags",
+ container: "system",
+ srcs: ["flags.aconfig"],
+}
+
+cc_aconfig_library {
+ name: "suspend_service_flags_c_lib",
+ aconfig_declarations: "suspend_service_flags",
+}
diff --git a/suspend/1.0/default/SuspendControlService.cpp b/suspend/1.0/default/SuspendControlService.cpp
index faadecb..3e88faf 100644
--- a/suspend/1.0/default/SuspendControlService.cpp
+++ b/suspend/1.0/default/SuspendControlService.cpp
@@ -183,7 +183,22 @@
}
suspendService->updateStatsNow();
- suspendService->getStatsList().getWakeLockStats(_aidl_return);
+ suspendService->getStatsList().getWakeLockStats(
+ BnSuspendControlServiceInternal::WAKE_LOCK_INFO_ALL_FIELDS, _aidl_return);
+
+ return binder::Status::ok();
+}
+
+binder::Status SuspendControlServiceInternal::getWakeLockStatsFiltered(
+ int wakeLockInfoFieldBitMask, std::vector<WakeLockInfo>* _aidl_return) {
+ const auto suspendService = mSuspend.promote();
+ if (!suspendService) {
+ return binder::Status::fromExceptionCode(binder::Status::Exception::EX_NULL_POINTER,
+ String8("Null reference to suspendService"));
+ }
+
+ suspendService->updateStatsNow();
+ suspendService->getStatsList().getWakeLockStats(wakeLockInfoFieldBitMask, _aidl_return);
return binder::Status::ok();
}
@@ -282,6 +297,7 @@
"----- Suspend Stats -----\n"
"%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
"%s: %d\n%s: %d\n%s: %d\n%s: %d\n%s: %d\n"
+ "%s: %" PRIu64 "\n%s: %" PRIu64 "\n%s: %" PRIu64 "\n"
"\nLast Failures:\n"
" %s: %s\n"
" %s: %d\n"
@@ -298,6 +314,9 @@
"failed_resume", stats.failedResume,
"failed_resume_early", stats.failedResumeEarly,
"failed_resume_noirq", stats.failedResumeNoirq,
+ "last_hw_sleep", stats.lastHwSleep,
+ "total_hw_sleep", stats.totalHwSleep,
+ "max_hw_sleep", stats.maxHwSleep,
"last_failed_dev", stats.lastFailedDev.c_str(),
"last_failed_errno", stats.lastFailedErrno,
"last_failed_step", stats.lastFailedStep.c_str());
diff --git a/suspend/1.0/default/SuspendControlService.h b/suspend/1.0/default/SuspendControlService.h
index 7d7e0ae..b6e34ff 100644
--- a/suspend/1.0/default/SuspendControlService.h
+++ b/suspend/1.0/default/SuspendControlService.h
@@ -75,6 +75,8 @@
binder::Status forceSuspend(bool* _aidl_return) override;
binder::Status getSuspendStats(SuspendInfo* _aidl_return) override;
binder::Status getWakeLockStats(std::vector<WakeLockInfo>* _aidl_return) override;
+ binder::Status getWakeLockStatsFiltered(int wakeLockInfoFieldBitMask,
+ std::vector<WakeLockInfo>* _aidl_return) override;
binder::Status getWakeupStats(std::vector<WakeupInfo>* _aidl_return) override;
void setSuspendService(const wp<SystemSuspend>& suspend);
diff --git a/suspend/1.0/default/SystemSuspend.cpp b/suspend/1.0/default/SystemSuspend.cpp
index c7b986b..760aea8 100644
--- a/suspend/1.0/default/SystemSuspend.cpp
+++ b/suspend/1.0/default/SystemSuspend.cpp
@@ -28,6 +28,7 @@
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android/binder_manager.h>
+#include <android/system/suspend/internal/ISuspendControlServiceInternal.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
@@ -44,11 +45,14 @@
using ::android::base::CachedProperty;
using ::android::base::Error;
using ::android::base::ParseInt;
+using ::android::base::ParseUint;
using ::android::base::ReadFdToString;
using ::android::base::StringPrintf;
using ::android::base::WriteStringToFd;
using ::std::string;
+using ISCSI = ::android::system::suspend::internal::ISuspendControlServiceInternal;
+
namespace android {
namespace system {
namespace suspend {
@@ -424,7 +428,8 @@
std::stringstream klStats;
klStats << "Kernel wakesource stats: ";
std::vector<WakeLockInfo> wlStats;
- mStatsList.getWakeLockStats(&wlStats);
+ mStatsList.getWakeLockStats(
+ ISCSI::WAKE_LOCK_INFO_ACTIVE_COUNT | ISCSI::WAKE_LOCK_INFO_TOTAL_TIME, &wlStats);
for (const WakeLockInfo& wake : wlStats) {
if ((wake.isKernelWakelock) && (wake.activeCount > 0)) {
@@ -545,6 +550,26 @@
return mWakeupList;
}
+static int parseIntStat(std::string& statName, std::string& valStr) {
+ int statVal = -1;
+ bool parseSuccess = ParseInt(valStr, &statVal);
+ if (!parseSuccess) {
+ LOG(ERROR) << "Failed to parse " << statName << ", val: " << valStr;
+ }
+
+ return statVal;
+}
+
+static uint64_t parseUintStat(std::string& statName, std::string& valStr) {
+ uint64_t statVal = 0;
+ bool parseSuccess = ParseUint(valStr, &statVal);
+ if (!parseSuccess) {
+ LOG(ERROR) << "Failed to parse " << statName << ", val: " << valStr;
+ }
+
+ return statVal;
+}
+
/**
* Returns suspend stats.
*/
@@ -595,37 +620,34 @@
stats.lastFailedDev = valStr;
} else if (statName == "last_failed_step") {
stats.lastFailedStep = valStr;
- } else {
- int statVal = -1;
- bool parseSuccess = ParseInt(valStr, &statVal);
- if (!parseSuccess) {
- LOG(ERROR) << "Failed to parse " << statName << ", val: " << valStr;
- }
- if (statName == "success") {
- stats.success = statVal;
- } else if (statName == "fail") {
- stats.fail = statVal;
- } else if (statName == "failed_freeze") {
- stats.failedFreeze = statVal;
- } else if (statName == "failed_prepare") {
- stats.failedPrepare = statVal;
- } else if (statName == "failed_suspend") {
- stats.failedSuspend = statVal;
- } else if (statName == "failed_suspend_late") {
- stats.failedSuspendLate = statVal;
- } else if (statName == "failed_suspend_noirq") {
- stats.failedSuspendNoirq = statVal;
- } else if (statName == "failed_resume") {
- stats.failedResume = statVal;
- } else if (statName == "failed_resume_early") {
- stats.failedResumeEarly = statVal;
- } else if (statName == "failed_resume_noirq") {
- stats.failedResumeNoirq = statVal;
- } else if (statName == "last_failed_errno") {
- // `errno` will only be negative numbers or 0, so a positive number would
- // indicate a parsing failure.
- stats.lastFailedErrno = parseSuccess ? statVal : 1;
- }
+ } else if (statName == "success") {
+ stats.success = parseIntStat(statName, valStr);
+ } else if (statName == "fail") {
+ stats.fail = parseIntStat(statName, valStr);
+ } else if (statName == "failed_freeze") {
+ stats.failedFreeze = parseIntStat(statName, valStr);
+ } else if (statName == "failed_prepare") {
+ stats.failedPrepare = parseIntStat(statName, valStr);
+ } else if (statName == "failed_suspend") {
+ stats.failedSuspend = parseIntStat(statName, valStr);
+ } else if (statName == "failed_suspend_late") {
+ stats.failedSuspendLate = parseIntStat(statName, valStr);
+ } else if (statName == "failed_suspend_noirq") {
+ stats.failedSuspendNoirq = parseIntStat(statName, valStr);
+ } else if (statName == "failed_resume") {
+ stats.failedResume = parseIntStat(statName, valStr);
+ } else if (statName == "failed_resume_early") {
+ stats.failedResumeEarly = parseIntStat(statName, valStr);
+ } else if (statName == "failed_resume_noirq") {
+ stats.failedResumeNoirq = parseIntStat(statName, valStr);
+ } else if (statName == "last_failed_errno") {
+ stats.lastFailedErrno = parseIntStat(statName, valStr);
+ } else if (statName == "last_hw_sleep") {
+ stats.lastHwSleep = parseUintStat(statName, valStr);
+ } else if (statName == "total_hw_sleep") {
+ stats.totalHwSleep = parseUintStat(statName, valStr);
+ } else if (statName == "max_hw_sleep") {
+ stats.maxHwSleep = parseUintStat(statName, valStr);
}
}
diff --git a/suspend/1.0/default/SystemSuspend.h b/suspend/1.0/default/SystemSuspend.h
index 5f69ce8..b41a732 100644
--- a/suspend/1.0/default/SystemSuspend.h
+++ b/suspend/1.0/default/SystemSuspend.h
@@ -59,6 +59,9 @@
std::string lastFailedDev;
int lastFailedErrno = 0;
std::string lastFailedStep;
+ uint64_t lastHwSleep = 0;
+ uint64_t totalHwSleep = 0;
+ uint64_t maxHwSleep = 0;
};
struct SleepTimeConfig {
diff --git a/suspend/1.0/default/SystemSuspendUnitTest.cpp b/suspend/1.0/default/SystemSuspendUnitTest.cpp
index b751731..f6b6db3 100644
--- a/suspend/1.0/default/SystemSuspendUnitTest.cpp
+++ b/suspend/1.0/default/SystemSuspendUnitTest.cpp
@@ -30,6 +30,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <hidl/HidlTransportSupport.h>
+#include <suspend_service_flags.h>
#include <sys/poll.h>
#include <sys/socket.h>
#include <sys/types.h>
@@ -228,7 +229,8 @@
size_t getActiveWakeLockCount() {
std::vector<WakeLockInfo> wlStats;
- controlServiceInternal->getWakeLockStats(&wlStats);
+ controlServiceInternal->getWakeLockStatsFiltered(
+ ISuspendControlServiceInternal::WAKE_LOCK_INFO_ACTIVE_COUNT, &wlStats);
return count_if(wlStats.begin(), wlStats.end(), [](auto entry) { return entry.isActive; });
}
@@ -1118,8 +1120,10 @@
int64_t failedSuspendLate = 42, int64_t failedSuspendNoirq = 42,
int64_t failedResume = 42, int64_t failedResumeEarly = 42,
int64_t failedResumeNoirq = 42,
- const std::string& lastFailedDev = "fakeDev", int64_t lastFailedErrno = 42,
- const std::string& lastFailedStep = "fakeStep") {
+ const std::string& lastFailedDev = "fakeDev",
+ int64_t lastFailedErrno = -42,
+ const std::string& lastFailedStep = "fakeStep", uint64_t lastHwSleep = 42,
+ uint64_t totalHwSleep = 42, uint64_t maxHwSleep = 523986009990) {
int fd = suspendStatsFd.get();
return writeStatToFile(fd, "success", success) && writeStatToFile(fd, "fail", fail) &&
@@ -1133,7 +1137,10 @@
writeStatToFile(fd, "failed_resume_noirq", failedResumeNoirq) &&
writeStatToFile(fd, "last_failed_dev", lastFailedDev) &&
writeStatToFile(fd, "last_failed_errno", lastFailedErrno) &&
- writeStatToFile(fd, "last_failed_step", lastFailedStep);
+ writeStatToFile(fd, "last_failed_step", lastFailedStep) &&
+ writeStatToFile(fd, "last_hw_sleep", lastHwSleep) &&
+ writeStatToFile(fd, "total_hw_sleep", totalHwSleep) &&
+ writeStatToFile(fd, "max_hw_sleep", maxHwSleep);
}
bool removeDirectoryEntry(const std::string& path) {
@@ -1194,9 +1201,10 @@
/**
* Returns wakelock stats.
*/
- std::vector<WakeLockInfo> getWakelockStats() {
+ std::vector<WakeLockInfo> getWakelockStats(
+ int32_t selectBitmap = ISuspendControlServiceInternal::WAKE_LOCK_INFO_ALL_FIELDS) {
std::vector<WakeLockInfo> wlStats;
- controlServiceInternal->getWakeLockStats(&wlStats);
+ controlServiceInternal->getWakeLockStatsFiltered(selectBitmap, &wlStats);
return wlStats;
}
@@ -1260,6 +1268,24 @@
};
};
+class mock_flag_provider_interface : public suspend_service::flags::flag_provider_interface {
+ public:
+ MOCK_METHOD(bool, fast_kernel_wakelock_reporting, (), (override));
+};
+
+class ParameterizedSystemSuspendSameThreadTest : public SystemSuspendSameThreadTest,
+ public ::testing::WithParamInterface<bool> {
+ protected:
+ void SetUp() override {
+ auto mock_flag_provider = std::make_unique<mock_flag_provider_interface>();
+ ON_CALL(*mock_flag_provider, fast_kernel_wakelock_reporting())
+ .WillByDefault(::testing::Return(GetParam()));
+ suspend_service::flags::provider_ = std::move(mock_flag_provider);
+
+ SystemSuspendSameThreadTest::SetUp();
+ }
+};
+
// Test that getWakeLockStats has correct information about Native WakeLocks.
TEST_F(SystemSuspendSameThreadTest, GetNativeWakeLockStats) {
std::string fakeWlName = "FakeLock";
@@ -1306,8 +1332,11 @@
ASSERT_EQ(nwlInfo.wakeupCount, 0);
}
+INSTANTIATE_TEST_SUITE_P(ParameterizedSystemSuspendSameThreadTest,
+ ParameterizedSystemSuspendSameThreadTest, ::testing::Bool());
+
// Test that getWakeLockStats has correct information about Kernel WakeLocks.
-TEST_F(SystemSuspendSameThreadTest, GetKernelWakeLockStats) {
+TEST_P(ParameterizedSystemSuspendSameThreadTest, GetKernelWakeLockStats) {
std::string fakeKwlName1 = "fakeKwl1";
std::string fakeKwlName2 = "fakeKwl2";
addKernelWakelock(fakeKwlName1);
@@ -1355,7 +1384,7 @@
}
// Test that getWakeLockStats has correct information about Native AND Kernel WakeLocks.
-TEST_F(SystemSuspendSameThreadTest, GetNativeAndKernelWakeLockStats) {
+TEST_P(ParameterizedSystemSuspendSameThreadTest, GetNativeAndKernelWakeLockStats) {
std::string fakeNwlName = "fakeNwl";
std::string fakeKwlName = "fakeKwl";
@@ -1484,8 +1513,11 @@
ASSERT_EQ(stats.failedResumeEarly, 42);
ASSERT_EQ(stats.failedResumeNoirq, 42);
ASSERT_EQ(stats.lastFailedDev, "fakeDev");
- ASSERT_EQ(stats.lastFailedErrno, 42);
+ ASSERT_EQ(stats.lastFailedErrno, -42);
ASSERT_EQ(stats.lastFailedStep, "fakeStep");
+ ASSERT_EQ(stats.lastHwSleep, 42);
+ ASSERT_EQ(stats.totalHwSleep, 42);
+ ASSERT_EQ(stats.maxHwSleep, 523986009990);
}
class SuspendWakeupTest : public ::testing::Test {
@@ -1817,6 +1849,42 @@
ASSERT_EQ(wakeups[2].count, 2);
}
+struct WakeLockInfoField {
+ int32_t bit = 0;
+ std::function<int(WakeLockInfo)> getter;
+ int64_t expectedValue;
+};
+
+// Test that selected fields are properly set.
+TEST_P(ParameterizedSystemSuspendSameThreadTest, GetKernelWakeLockStatsFiltered) {
+ using ISCSI = ISuspendControlServiceInternal;
+ static const WakeLockInfoField FIELDS[] = {
+ {ISCSI::WAKE_LOCK_INFO_ACTIVE_COUNT, [](WakeLockInfo wl) { return wl.activeCount; }, 1},
+ {ISCSI::WAKE_LOCK_INFO_LAST_CHANGE, [](WakeLockInfo wl) { return wl.lastChange; }, 2},
+ {ISCSI::WAKE_LOCK_INFO_MAX_TIME, [](WakeLockInfo wl) { return wl.maxTime; }, 3},
+ {ISCSI::WAKE_LOCK_INFO_TOTAL_TIME, [](WakeLockInfo wl) { return wl.totalTime; }, 4},
+ {ISCSI::WAKE_LOCK_INFO_ACTIVE_TIME, [](WakeLockInfo wl) { return wl.activeTime; }, 5},
+ {ISCSI::WAKE_LOCK_INFO_EVENT_COUNT, [](WakeLockInfo wl) { return wl.eventCount; }, 6},
+ {ISCSI::WAKE_LOCK_INFO_EXPIRE_COUNT, [](WakeLockInfo wl) { return wl.expireCount; }, 7},
+ {ISCSI::WAKE_LOCK_INFO_PREVENT_SUSPEND_TIME,
+ [](WakeLockInfo wl) { return wl.preventSuspendTime; }, 8},
+ {ISCSI::WAKE_LOCK_INFO_WAKEUP_COUNT, [](WakeLockInfo wl) { return wl.wakeupCount; }, 9},
+ };
+
+ std::string fakeKwlName1 = "fakeKwl1";
+ addKernelWakelock(fakeKwlName1, /* activeCount = */ 1, /* activeTime = */ 5,
+ /* eventCount = */ 6,
+ /* expireCount = */ 7, /* lastChange = */ 2, /* maxTime = */ 3,
+ /* preventSuspendTime = */ 8, /* totalTime = */ 4, /* wakeupCount = */ 9);
+ for (auto field : FIELDS) {
+ std::vector<WakeLockInfo> infos = getWakelockStats(field.bit);
+ WakeLockInfo wli;
+ ASSERT_TRUE(findWakeLockInfoByName(infos, fakeKwlName1, &wli));
+ ASSERT_EQ(field.getter(wli), field.expectedValue)
+ << "Bit mask " << field.bit << " had unexpected value";
+ }
+}
+
} // namespace android
int main(int argc, char** argv) {
diff --git a/suspend/1.0/default/WakeLockEntryList.cpp b/suspend/1.0/default/WakeLockEntryList.cpp
index 5a43501..f726586 100644
--- a/suspend/1.0/default/WakeLockEntryList.cpp
+++ b/suspend/1.0/default/WakeLockEntryList.cpp
@@ -20,6 +20,8 @@
#include <android-base/logging.h>
#include <android-base/parseint.h>
#include <android-base/stringprintf.h>
+#include <android/system/suspend/internal/ISuspendControlServiceInternal.h>
+#include <suspend_service_flags.h>
#include <iomanip>
@@ -27,12 +29,37 @@
using android::base::ReadFdToString;
using android::base::Readlink;
using android::base::StringPrintf;
+using suspend_service::flags::fast_kernel_wakelock_reporting;
+
+using ISCSI = ::android::system::suspend::internal::ISuspendControlServiceInternal;
namespace android {
namespace system {
namespace suspend {
namespace V1_0 {
+namespace {
+
+struct BitAndFilename {
+ int32_t bit;
+ std::string filename;
+};
+
+const BitAndFilename FIELDS[] = {
+ {-1, "name"},
+ {ISCSI::WAKE_LOCK_INFO_ACTIVE_COUNT, "active_count"},
+ {ISCSI::WAKE_LOCK_INFO_LAST_CHANGE, "last_change_ms"},
+ {ISCSI::WAKE_LOCK_INFO_MAX_TIME, "max_time_ms"},
+ {ISCSI::WAKE_LOCK_INFO_TOTAL_TIME, "total_time_ms"},
+ {ISCSI::WAKE_LOCK_INFO_ACTIVE_TIME, "active_time_ms"},
+ {ISCSI::WAKE_LOCK_INFO_EVENT_COUNT, "event_count"},
+ {ISCSI::WAKE_LOCK_INFO_EXPIRE_COUNT, "expire_count"},
+ {ISCSI::WAKE_LOCK_INFO_PREVENT_SUSPEND_TIME, "prevent_suspend_time_ms"},
+ {ISCSI::WAKE_LOCK_INFO_WAKEUP_COUNT, "wakeup_count"},
+};
+
+} // namespace
+
static std::ostream& operator<<(std::ostream& out, const WakeLockInfo& entry) {
const char* sep = " | ";
const char* notApplicable = "---";
@@ -65,7 +92,7 @@
std::ostream& operator<<(std::ostream& out, const WakeLockEntryList& list) {
std::vector<WakeLockInfo> wlStats;
- list.getWakeLockStats(&wlStats);
+ list.getWakeLockStats(ISCSI::WAKE_LOCK_INFO_ALL_FIELDS, &wlStats);
int width = 194;
const char* sep = " | ";
std::stringstream ss;
@@ -324,20 +351,146 @@
return info;
}
-void WakeLockEntryList::getKernelWakelockStats(std::vector<WakeLockInfo>* aidl_return) const {
+/*
+ * Creates and returns a kernel wakelock entry with data read from mKernelWakelockStatsFd.
+ * Has been micro-optimized to reduce CPU time and wall time.
+ */
+WakeLockInfo WakeLockEntryList::createKernelEntry(ScratchSpace* ss, int wakeLockInfoFieldBitMask,
+ const std::string& kwlId) const {
+ WakeLockInfo info;
+
+ info.activeCount = 0;
+ info.lastChange = 0;
+ info.maxTime = 0;
+ info.totalTime = 0;
+ info.isActive = false;
+ info.activeTime = 0;
+ info.isKernelWakelock = true;
+
+ info.pid = -1; // N/A
+
+ info.eventCount = 0;
+ info.expireCount = 0;
+ info.preventSuspendTime = 0;
+ info.wakeupCount = 0;
+
+ for (const auto& field : FIELDS) {
+ const bool isNameField = field.bit == -1;
+ if (!isNameField && (wakeLockInfoFieldBitMask & field.bit) == 0) {
+ continue;
+ }
+
+ ss->statName = kwlId + "/" + field.filename;
+ int statFd = -1;
+
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ // Check if we have a valid cached file descriptor.
+ auto it = mFdCache.find(ss->statName);
+ if (it != mFdCache.end() && it->second >= 0) {
+ auto result = lseek(it->second, 0, SEEK_SET);
+ if (result < 0) {
+ PLOG(ERROR) << "Could not seek to start of FD for " << ss->statName;
+ mFdCache.erase(it);
+ PLOG(ERROR) << "Closed the FD.";
+ } else {
+ statFd = it->second;
+ }
+ }
+
+ if (statFd == -1) {
+ unique_fd tmpFd(TEMP_FAILURE_RETRY(
+ openat(mKernelWakelockStatsFd, ss->statName.c_str(), O_CLOEXEC | O_RDONLY)));
+ if (tmpFd < 0) {
+ PLOG(ERROR) << "Error opening " << ss->statName << " for " << kwlId;
+ continue;
+ }
+ statFd = tmpFd;
+ mFdCache.insert(it, {ss->statName, std::move(tmpFd)});
+ }
+ } // mLock is released here
+
+ ss->valStr.clear();
+ ssize_t n;
+ while ((n = TEMP_FAILURE_RETRY(read(statFd, &ss->readBuff[0], sizeof(ss->readBuff)))) > 0) {
+ ss->valStr.append(ss->readBuff, n);
+ }
+ if (n < 0) {
+ PLOG(ERROR) << "Error reading " << ss->statName;
+ {
+ std::lock_guard<std::mutex> lock(mLock);
+ mFdCache.erase(ss->statName);
+ PLOG(ERROR) << "Closed the FD.";
+ }
+ continue;
+ }
+
+ // Trim newline
+ ss->valStr.erase(std::remove(ss->valStr.begin(), ss->valStr.end(), '\n'), ss->valStr.end());
+
+ if (isNameField) {
+ info.name = ss->valStr;
+ continue;
+ }
+
+ int64_t statVal;
+ if (!ParseInt(ss->valStr, &statVal)) {
+ std::string path;
+ if (Readlink(StringPrintf("/proc/self/fd/%d", statFd), &path)) {
+ LOG(ERROR) << "Unexpected format for wakelock stat value (" << ss->valStr
+ << ") from file: " << path;
+ } else {
+ LOG(ERROR) << "Unexpected format for wakelock stat value (" << ss->valStr << ")";
+ }
+ continue;
+ }
+
+ if (field.filename == "active_count") {
+ info.activeCount = statVal;
+ } else if (field.filename == "active_time_ms") {
+ info.activeTime = statVal;
+ } else if (field.filename == "event_count") {
+ info.eventCount = statVal;
+ } else if (field.filename == "expire_count") {
+ info.expireCount = statVal;
+ } else if (field.filename == "last_change_ms") {
+ info.lastChange = statVal;
+ } else if (field.filename == "max_time_ms") {
+ info.maxTime = statVal;
+ } else if (field.filename == "prevent_suspend_time_ms") {
+ info.preventSuspendTime = statVal;
+ } else if (field.filename == "total_time_ms") {
+ info.totalTime = statVal;
+ } else if (field.filename == "wakeup_count") {
+ info.wakeupCount = statVal;
+ }
+ }
+
+ // Derived stats
+ info.isActive = info.activeTime > 0;
+
+ return info;
+}
+
+void WakeLockEntryList::getKernelWakelockStats(int wakeLockInfoFieldBitMask,
+ std::vector<WakeLockInfo>* aidl_return) const {
std::unique_ptr<DIR, decltype(&closedir)> dp(fdopendir(dup(mKernelWakelockStatsFd.get())),
&closedir);
if (dp) {
// rewinddir, else subsequent calls will not get any kernel wakelocks.
rewinddir(dp.get());
+ ScratchSpace ss;
struct dirent* de;
while ((de = readdir(dp.get()))) {
std::string kwlId(de->d_name);
if ((kwlId == ".") || (kwlId == "..")) {
continue;
}
- WakeLockInfo entry = createKernelEntry(kwlId);
+ WakeLockInfo entry = fast_kernel_wakelock_reporting()
+ ? createKernelEntry(&ss, wakeLockInfoFieldBitMask, kwlId)
+ : createKernelEntry(kwlId);
+
aidl_return->emplace_back(std::move(entry));
}
}
@@ -346,7 +499,7 @@
void WakeLockEntryList::updateOnAcquire(const std::string& name, int pid) {
TimestampType timeNow = getTimeNow();
- std::lock_guard<std::mutex> lock(mStatsLock);
+ std::lock_guard<std::mutex> lock(mLock);
auto key = std::make_pair(name, pid);
auto it = mLookupTable.find(key);
@@ -372,7 +525,7 @@
void WakeLockEntryList::updateOnRelease(const std::string& name, int pid) {
TimestampType timeNow = getTimeNow();
- std::lock_guard<std::mutex> lock(mStatsLock);
+ std::lock_guard<std::mutex> lock(mLock);
auto key = std::make_pair(name, pid);
auto it = mLookupTable.find(key);
@@ -406,7 +559,7 @@
* Updates the native wakelock stats based on the current time.
*/
void WakeLockEntryList::updateNow() {
- std::lock_guard<std::mutex> lock(mStatsLock);
+ std::lock_guard<std::mutex> lock(mLock);
TimestampType timeNow = getTimeNow();
@@ -421,15 +574,16 @@
}
}
-void WakeLockEntryList::getWakeLockStats(std::vector<WakeLockInfo>* aidl_return) const {
+void WakeLockEntryList::getWakeLockStats(int wakeLockInfoFieldBitMask,
+ std::vector<WakeLockInfo>* aidl_return) const {
// Under no circumstances should the lock be held while getting kernel wakelock stats
{
- std::lock_guard<std::mutex> lock(mStatsLock);
+ std::lock_guard<std::mutex> lock(mLock);
for (const WakeLockInfo& entry : mStats) {
aidl_return->emplace_back(entry);
}
}
- getKernelWakelockStats(aidl_return);
+ getKernelWakelockStats(wakeLockInfoFieldBitMask, aidl_return);
}
} // namespace V1_0
diff --git a/suspend/1.0/default/WakeLockEntryList.h b/suspend/1.0/default/WakeLockEntryList.h
index 1ebc411..d81727a 100644
--- a/suspend/1.0/default/WakeLockEntryList.h
+++ b/suspend/1.0/default/WakeLockEntryList.h
@@ -49,16 +49,32 @@
// updateNow() should be called before getWakeLockStats() to ensure stats are
// updated wrt the current time.
void updateNow();
- void getWakeLockStats(std::vector<WakeLockInfo>* aidl_return) const;
+ void getWakeLockStats(int wakeLockInfoFieldBitMask,
+ std::vector<WakeLockInfo>* aidl_return) const;
friend std::ostream& operator<<(std::ostream& out, const WakeLockEntryList& list);
private:
- void evictIfFull() REQUIRES(mStatsLock);
- void insertEntry(WakeLockInfo entry) REQUIRES(mStatsLock);
- void deleteEntry(std::list<WakeLockInfo>::iterator entry) REQUIRES(mStatsLock);
+ void evictIfFull() REQUIRES(mLock);
+ void insertEntry(WakeLockInfo entry) REQUIRES(mLock);
+ void deleteEntry(std::list<WakeLockInfo>::iterator entry) REQUIRES(mLock);
WakeLockInfo createNativeEntry(const std::string& name, int pid, TimestampType timeNow) const;
WakeLockInfo createKernelEntry(const std::string& name) const;
- void getKernelWakelockStats(std::vector<WakeLockInfo>* aidl_return) const;
+
+ // Used by createKernelEntry to reduce heap churn on successive calls.
+ struct ScratchSpace {
+ static constexpr const int BUFF_SIZE = 1024;
+ char readBuff[BUFF_SIZE];
+ std::string statName, valStr;
+ ScratchSpace() {
+ valStr.reserve(BUFF_SIZE);
+ statName.reserve(BUFF_SIZE);
+ }
+ };
+ WakeLockInfo createKernelEntry(ScratchSpace* ss, int wakeLockInfoFieldBitMask,
+ const std::string& name) const;
+
+ void getKernelWakelockStats(int wakeLockInfoFieldBitMask,
+ std::vector<WakeLockInfo>* aidl_return) const;
// Hash for WakeLockEntry key (pair<std::string, int>)
struct LockHash {
@@ -67,17 +83,18 @@
}
};
+ mutable std::mutex mLock;
+
size_t mCapacity;
unique_fd mKernelWakelockStatsFd;
-
- mutable std::mutex mStatsLock;
+ mutable std::unordered_map<std::string, unique_fd> mFdCache GUARDED_BY(mLock);
// std::list and std::unordered map are used to support both inserting a stat
// and eviction of the LRU stat in O(1) time. The LRU stat is maintained at
// the back of the list.
- std::list<WakeLockInfo> mStats GUARDED_BY(mStatsLock);
+ std::list<WakeLockInfo> mStats GUARDED_BY(mLock);
std::unordered_map<std::pair<std::string, int>, std::list<WakeLockInfo>::iterator, LockHash>
- mLookupTable GUARDED_BY(mStatsLock);
+ mLookupTable GUARDED_BY(mLock);
};
} // namespace V1_0
diff --git a/suspend/1.0/default/flags.aconfig b/suspend/1.0/default/flags.aconfig
new file mode 100644
index 0000000..5af880d
--- /dev/null
+++ b/suspend/1.0/default/flags.aconfig
@@ -0,0 +1,9 @@
+package: "suspend_service.flags"
+container: "system"
+
+flag {
+ name: "fast_kernel_wakelock_reporting"
+ namespace: "wear_frameworks"
+ description: "Controls using new codepath to speed up polling of /sys/class/wakeup for kernel wakelocks."
+ bug: "364368163"
+}
\ No newline at end of file
diff --git a/suspend/1.0/default/OWNERS b/suspend/OWNERS
similarity index 100%
rename from suspend/1.0/default/OWNERS
rename to suspend/OWNERS
diff --git a/suspend/aidl/Android.bp b/suspend/aidl/Android.bp
index e7f7062..97e0694 100644
--- a/suspend/aidl/Android.bp
+++ b/suspend/aidl/Android.bp
@@ -19,6 +19,7 @@
aidl_interface {
name: "android.system.suspend.control",
local_include_dir: ".",
+ frozen: true,
srcs: [
"android/system/suspend/ISuspendControlService.aidl",
"android/system/suspend/ISuspendCallback.aidl",
diff --git a/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl b/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl
index 8e0a9a2..065d486 100644
--- a/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl
+++ b/suspend/aidl/android/system/suspend/internal/ISuspendControlServiceInternal.aidl
@@ -46,6 +46,12 @@
WakeLockInfo[] getWakeLockStats();
/**
+ * Returns a list of wake lock stats. Fields not selected with the
+ * bit mask are in an undefined state (see WAKE_LOCK_INFO_* below).
+ */
+ WakeLockInfo[] getWakeLockStatsFiltered(int wakeLockInfoFieldBitMask);
+
+ /**
* Returns a list of wakeup stats.
*/
WakeupInfo[] getWakeupStats();
@@ -54,4 +60,27 @@
* Returns stats related to suspend.
*/
SuspendInfo getSuspendStats();
+
+ /**
+ * Used to select fields from WakeLockInfo that getWakeLockStats should return.
+ * This is in addition to the name of the wake lock, which is always returned.
+ */
+ const int WAKE_LOCK_INFO_ACTIVE_COUNT = 1 << 0;
+ const int WAKE_LOCK_INFO_LAST_CHANGE = 1 << 1;
+ const int WAKE_LOCK_INFO_MAX_TIME = 1 << 2;
+ const int WAKE_LOCK_INFO_TOTAL_TIME = 1 << 3;
+ const int WAKE_LOCK_INFO_IS_ACTIVE = 1 << 4;
+ const int WAKE_LOCK_INFO_ACTIVE_TIME = 1 << 5;
+ const int WAKE_LOCK_INFO_IS_KERNEL_WAKELOCK = 1 << 6;
+
+ // Specific to Native wake locks.
+ const int WAKE_LOCK_INFO_PID = 1 << 7;
+
+ // Specific to Kernel wake locks.
+ const int WAKE_LOCK_INFO_EVENT_COUNT = 1 << 8;
+ const int WAKE_LOCK_INFO_EXPIRE_COUNT = 1 << 9;
+ const int WAKE_LOCK_INFO_PREVENT_SUSPEND_TIME = 1 << 10;
+ const int WAKE_LOCK_INFO_WAKEUP_COUNT = 1 << 11;
+
+ const int WAKE_LOCK_INFO_ALL_FIELDS = (1 << 12) - 1;
}
diff --git a/wifi/keystore/1.0/vts/functional/Android.bp b/wifi/keystore/1.0/vts/functional/Android.bp
index 7f13903..d4e6c03 100644
--- a/wifi/keystore/1.0/vts/functional/Android.bp
+++ b/wifi/keystore/1.0/vts/functional/Android.bp
@@ -15,6 +15,7 @@
//
package {
+ default_team: "trendy_team_fwk_wifi_hal",
default_applicable_licenses: ["Android-Apache-2.0"],
}